The admin app at cms.quizzja.com: a Next.js BFF over the same ConnectRPC AdminService, with its own design system — purple on lilac, the same press-down shadows. This is where puzzles are generated, reviewed and scheduled, where the lexicon and the store catalogue are kept, and where player feedback is triaged. Role permissions decide which nav entries render at all.
QQuizzja CMS
Sign in with the email and password assigned to your administrator account.
Invalid credentials or this account is not an enabled operator.
Sign in/login · app/login/page.tsxThe only unauthenticated page. Credentials are checked against an enabled operator account, not a player account — a valid Quizzja player who is not an operator is refused with the same message as a wrong password.
Dashboard
Everything generated, reviewed and published, at a glance
NInikolay
48
Generation jobs
41 succeeded
6
Puzzle drafts
Awaiting review
7 / 8
Daily auto-generation
Languages on
132
Activity events
Recent
Recent activity
View all
Generation job 4f21 finished — 12 drafts for Englishgeneration.job.succeeded
Daily published for Bulgarian · 2026-08-22daily.published
Draft “Saturday Standard” approved by nikolaypuzzle.approved
1,480 English words imported from lexgenwords.imported
Generation job 9ab0 running — German 13×13generation.job.running
Daily published for German · 2026-08-22daily.published
“Weekend Cryptic” is livepuzzle.published
Statistics
Jobs by status
Succeeded41
Running2
Queued3
Failed2
Dashboard/ · app/(app)/page.tsxThe operator landing page: four counters over the generation pipeline, the live activity feed, and jobs broken down by status. Every number is a ConnectRPC query against the same AdminService the rest of the CMS uses.
Generate
Queue a generation run against the Go generator
NInikolay
Generate crosswords
Runs on the Go generator over gRPC/h2c
Queued job 9ab0 · 12 drafts requested for English
Last five runs
Job
Language
Size
Status
Drafts
9ab0…
German
13×13
Running
4 / 12
4f21…
English
11×11
Succeeded
12
31c7…
Bulgarian
9×9
Succeeded
8
2d90…
Spanish
15×15
Failed
0
1a55…
French
11×11
Queued
—
Generate/generate · app/(app)/generate/page.tsxWhere puzzles come from. The form queues a River job that the worker hands to the Go generator over gRPC/h2c; the run fills grids by constraint propagation and writes drafts, never published puzzles. Seed is optional and makes a run reproducible.
Daily
Which language has a crossword on which day
NInikolay
5 / 8
Languages live today
2
Gaps to fill today
7 / 8
Languages on auto
7
Day window
17 – 23 August 2026
Published Not published — click to generate Auto-generation off
Future slots appear as not published because the API exposes no forward schedule. A daily generated for a later date becomes visible on that date.
Daily/daily · app/(app)/daily/page.tsxThe seven-day schedule as a grid of language rows. Green is published, a red outline is a gap you can click to generate on the spot, grey means auto-generation is off for that language. This is the screen that keeps Today from being empty in any market.
Catalog
Packs, groups and in-app purchase products
NInikolay
Category (pack)
Group
IAP product
Published products
ID
Type
Store
SKU
Price
Grant
com.quizzja.hints10
Hints
Apple
com.quizzja.hints10
USD 1.99
10
com.quizzja.hints50
Hints
Apple
com.quizzja.hints50
USD 4.99
50
com.quizzja.noads
Remove ads
Apple
com.quizzja.noads
USD 2.99
—
com.quizzja.premium.monthly
Subscription
Apple
com.quizzja.premium.monthly
USD 3.99 / month
—
science-mini
Pack
Stripe
price_1Q…
EUR 2.99
—
Catalog/catalog · app/(app)/catalog/page.tsxThree editors and one table: the packs players browse, the groups that organise them, and the IAP products behind Pro, Remove ads, hint packs and premium packs — with the per-store SKU each one maps to. The players' store catalogue is this table.
Lexicon
Word and clue stock per content language
NInikolay
Content health
Usable means enabled and carrying at least one clue — the pool generation draws from.
✓Largest grid every launched language can fill9×9
Language
Words
Enabled
Usable
Clue coverage
Clues
Approval
Largest grid
Englishen
41,208
38,940
36,112
93%
34,880
Every clue approved
15×15
Bulgarianbg
22,470
21,006
19,884
94%
19,112
118 pending
13×13
Germande
28,115
26,330
24,902
95%
24,110
42 pending
15×15
Spanishes
19,660
18,004
14,220
79%
13,980
310 pending
11×11
Frenchfr
21,330
20,118
18,660
93%
18,220
Every clue approved
13×13
Japaneseja
9,844
8,112
5,006
62%
4,980
520 pending
9×9
Polishpl
6,220
5,880
3,110
53%
3,002
201 pending
9×9
Portuguesept
17,905
16,740
15,220
91%
14,980
76 pending
13×13
2 of 8 launched languages cannot fill an 11×11. Affected languages: Japanese, Polish. Generation at those sizes has no word to place.
Lexicon/lexicon · app/(app)/lexicon/page.tsxThe constraint that decides what can be generated at all: usable words — enabled and carrying a clue — per language and per word length. The verdict line names the largest grid every launched language can fill, and which languages fall short of it.
Translations
Interface strings, per locale
NInikolay
Add or edit string
Saved play.reveal
Strings · de
1,204 total · Unapproved only
Key
Value
Status
nav.today
Today
✓ approved
nav.puzzles
Puzzles
✓ approved
today.greeting
Ready to play?
✓ approved
today.chip
TODAY'S CROSSWORD
✓ approved
play.reveal
Reveal
Pending
play.revealAllTitle
Reveal the whole solution?
Pending
pro.upgrade
Upgrade to Pro
✓ approved
store.tryFree
Try 7 days free
Pending
Translations/translations · app/(app)/translations/page.tsxThe ICU message catalogue behind every client, editable per locale with an approval flag. Source strings live in i18n/source/en.json and travel through Crowdin; this screen is for fixing one string without a round trip.
Generation jobs
Live · auto-refreshing
NInikolay
Generation jobs
Live · auto-refreshing
Job
Status
Progress
Drafts
Message
9ab0… German 13×13
Running
4 / 12
fill 42% · 00:38 elapsed
4f21… English 11×11
Succeeded
12
completed in 01:12
31c7… Bulgarian 9×9
Succeeded
8
completed in 00:41
2d90… Spanish 15×15
Failed
0
no usable word of length 15
1a55… French 11×11
Queued
—
waiting for a generator slot
0e83… Japanese 9×9
Succeeded
6
completed in 00:55
Generation jobs/jobs · app/(app)/jobs/page.tsxEvery generation run, refreshing while any is in flight. A failure reports why in the operator's own terms — the Spanish 15×15 here failed because the lexicon has no usable 15-letter word, which is the Lexicon screen's verdict restated as a job outcome.
Drafts
6 awaiting review
NInikolay
Saturday Standard
English · 11×11 · medium · 38 words · job 4f21 · generated 2 hours ago
1HAYO6AKERERIN738495
✓SymmetryRotational
✓Every word has a clue38 / 38
!Duplicate clue1 found
✓Minimum word length3
ACROSS
1Mown grass, stored dry3
4Sturdy hardwood3
7Downpour4
9Pasture animal that lows3
11Rows of crops5
DOWN
1Farmer's early alarm7
2Autumn harvest4
3Sheep's coat6
5Pasture animal that lows3
6Beehive product5
A clue is used more than once in this puzzle. Edit before publishing.
Generator go/csp · revision r1
Drafts · review queue/drafts · app/(app)/drafts/page.tsxThe gate between generation and publication. A draft is selected on the left and reviewed on the right: the rendered grid, the automated quality checks, and both clue lists with duplicates flagged. Approve, Reject and "Publish now" all write to the audit log.
Activity
Events: 132
NInikolay
Activity
Events: 132
AllGenerationDaily
Generation job 4f21 finished — 12 drafts for English
generation.job.succeededSystem2 minutes ago
Daily published for Bulgarian · 2026-08-22
daily.publishedOperator 4a91c214 minutes ago
Draft “Saturday Standard” approved by nikolay
puzzle.approvedOperator 4a91c21 hour ago
1,480 English words imported from lexgen
words.importedSystem3 hours ago
Generation job 9ab0 running — German 13×13
generation.job.runningSystem3 hours ago
Daily published for German · 2026-08-22
daily.publishedSystem5 hours ago
“Weekend Cryptic” is live
puzzle.publishedOperator 4a91c2yesterday
Activity/activity · app/(app)/activity/page.tsxThe full event feed the dashboard card samples, filterable by domain. Each event names its actor — the system, or the operator id that caused it — so a surprising change on a live language can be traced back in one step.
Feedback
Player bug reports and feature requests
NInikolay
3
New
31
Bugs
18
Feature requests
44
All reports
Inbox
5 shown
All typesAll statusesClear filters
ID
Type
Description
Reporter
Source
Status
Priority
#812
Bug report
Grid scrolls under the keyboard on a 5.4-inch iPhone
alex@example.com
iOS 17.4 · 1.4.0
New
High
#811
Feature request
Please add a dark theme for late-night solving
—
Web · 1.4.0
Triaged
Normal
#809
Bug report
Purchase confirmed but hints not credited
dana@example.com
Android 14 · 1.3.9
In progress
Urgent
#804
Feature request
Let me print a whole pack as one PDF
sam@example.com
macOS 14 · 1.4.0
Planned
Low
#799
Bug report
Bulgarian clue text overflows the clue bar
—
Web · 1.3.8
Resolved
Normal
Player feedback/feedback · app/(app)/feedback/page.tsxEverything submitted from the players' Report a bug and Request a feature dialogs, mirrored into a private GitHub issue. Triage sets status and priority and can carry an internal note; the screen is read-only without FEEDBACK_WRITE.
Audit log
Entries: 1,904
NInikolay
Operator audit log
Entries: 1,904
Time
Operator
Action
Entity
2026-08-22 11:58
4a91c2
puzzle.approve
draft 7c31…
2026-08-22 11:41
4a91c2
daily.generate
de · 2026-08-22
2026-08-22 10:16
4a91c2
word.import
en · 1,480 rows
2026-08-21 17:02
b7e004
operator.update
viewer → editor
2026-08-21 16:55
4a91c2
product.save
com.quizzja.hints50
2026-08-21 09:14
b7e004
puzzle.reject
draft 22ab…
2026-08-20 14:30
4a91c2
translation.approve
de · 84 strings
Audit log/audit · app/(app)/audit/page.tsxEvery operator action, filterable by operator id — approvals, rejections, publishes, product and translation edits, and role changes. Visible only with AUDIT_READ; the nav entry is hidden entirely for roles without it.
Operators
Who can sign in, and what they may do
NInikolay
Operators
5 total
Identity
Email
Role
Status
nikolay
operator@example.com
Administrator
Enabled
Disable
maria.g
editor@example.com
Editor
Enabled
Disable
stefan
editor2@example.com
Editor
Enabled
Disable
reviewer-1
reviewer@example.com
Viewer
Enabled
Disable
old-intern
former@example.com
Viewer
Disabled
Enable
Add or update operator
Only administrators can manage operators. Every change here is written to the audit log.
Operators/operators · app/(app)/operators/page.tsxAdministrator-only. Operators sign in through OIDC and are matched by SSO subject; the role decides which nav entries even render. Disabling an account is preferred over deleting it, so the audit log keeps pointing at a real identity.