User Stories — Manuscript Translator
Canonical, human-readable catalog of every user story for the app. The Azure DevOps board (
Aeonic-Tech / Manuscript Translator) is the system of record for state and execution; this file is the system of record for the story map — what experiences the product promises, how they hang together, and where the gaps are. When you add/close a story on the board, reflect it here.
- Board: Epic → Feature → Product Backlog Item → Task. Stories are PBIs (
As a … I can … so that …). Each links to its ADO item:https://dev.azure.com/Aeonic-Tech/Manuscript%20Translator/_workitems/edit/<id>.- Product intent: a fully automatic translation service — upload → upfront cost estimate → commit/pay → the whole book translates itself (one calibration page first, then automatic batch escalation) → read/export. No human-in-the-loop review. The only brake is affordability. See
spec.mdand the pivot recorddesign/automatic-translation-no-human-gate.md.- Pivot (PBI #1455, 2026-06-25): the human approval/review gate was removed. Stories that assumed a human approves/rejects/edits pages or confirms the source language were rewritten or retired below.
- Last swept: 2026-06-24 (user-story review/spike). Findings in §1.
1. Critical review — findings
A full-backlog sweep on 2026-06-24. The individual stories are high quality (context → current behavior → testable AC → DoD). The portfolio was not — it was a single theme with the rest of the product un-storied.
- The board was one Feature deep. All 17 PBIs hung off Feature #1338 — Library, Queue & Retention. The post-pipeline library/queue/retention UX was thoroughly mapped; almost nothing else was. Fixed: three new Features added (#1356 Accounts, #1361 Billing, #1365 Core Review).
- Stories depended on enablers no story owned. #1345 (pre-expiry warning) and #1352 (batch-ready) both require email verification + a transactional-email provider — owned by nobody. #1351 (cost/balance) depends on "the billing/credit wallet" and names "whitelist/unlimited accounts" — but nothing let a user add funds or an admin grant a whitelist. Fixed: #1357 (verify email), #1362 (top-up), #1364 (admin whitelist).
- The product's heart — the review/approval gate — was barely storied. Only #1353 (resume/ navigate) existed. There was no story for editing/correcting a translation before approving (M3 "manual edits"), retrying a failed page/batch (#1340 mentions a retry "affordance" but nothing owned it), or confirming/correcting the detected source language (M2's remaining work). Fixed: #1366, #1367, #1368. (Superseded by the #1455 pivot, 2026-06-25: the review/approval gate was removed — the product is now a fully automatic service. #1366 (edit-before-approve) and #1368 (confirm source language) are retired; only #1367 (retry a failed page) survives. See the rewritten Feature #1365 below.)*
- Built-but-un-storied flows (see §6). Sign-up, login, upload→create, read-a-page, process-next-batch, and the notification center all exist in code with no story on the board. Retro-documented here for traceability; backfill as
DonePBIs only if you want board-level provenance. (The review→approve / reject-with-correction flows that were here pre-#1455 have been removed — see §6.) - No user stories lived in the repo. They existed only on ADO. Fixed: this file.
Follow-up expansion (same sweep, second pass). Three more themes were scoped into Features + tickets after the first pass: monetization depth — method-aware payments (card/Stripe #1373, cryptocurrency QR #1374), upload-time estimate #1375, per-page purchase #1376 — see payments.md; Admin & Operations #1377 (dashboard #1378, user management #1379, whitelist #1364 moved here); and a standard Affiliate & Referral Program #1380 (#1381–#1385).
Still open / not yet storied — see §7: onboarding that explains the automatic-service flow (upfront estimate → commit → it runs itself), sharing/collaboration, a dedicated a11y pass, and translation quality controls. Left as candidates rather than guessed into tickets.
2. Personas
- Reader/Translator (primary "user"). Uploads a historical book (PDF/scans), sees an upfront cost estimate, commits/pays, then lets the service translate the whole book automatically and reads/exports the finished result (a read-only page-through of original scan beside English). Cares about accuracy, a clear upfront price, and not paying twice.
- Admin/Operator. Runs the service: grants whitelisted/unlimited accounts, and (future) watches queue depth and GPU spend.
3. Story map at a glance
| Feature | Stories | Done | New/Open |
|---|---|---|---|
| #1338 — Library, Queue & Retention | 18 | 9 | 9 |
| #1356 — Accounts, Profile & Settings (new) | 7 | 1 | 6 |
| #1361 — Billing & Credits (new) | 12 | 0 | 12 |
| #1365 — Core Translation & Reading Experience (new) | 4 | 0 | 1 |
| #1377 — Admin & Operations (new) | 3 | 1 | 2 |
| #1380 — Affiliate & Referral Program (new) | 5 | 0 | 5 |
Legend: ✅ Done · 🆕 New (this sweep) · ⏳ New (pre-existing, not started) · 💡 Nice-to-have (post-MVP). Payment design detail: payments.md.
4. Existing Feature
Feature #1338 — User Experience: Library, Queue & Retention
The user-journey layer over the built pipeline: a durable library, a visible/orderable queue, easy (re)download, and a friendly flat 30-day retention story (no extensions — download to keep it).
| ID | Story | Status | Pts |
|---|---|---|---|
| #1339 | …I can see a library of all my projects so I can find past work at a glance | ✅ Done | 5 |
| #1340 | …I can see a live processing queue (queued / processing / complete / failed) | ✅ Done | 5 |
| #1341 | …I can reorder my queue so I control which book is translated next | ⏳ New | 5 |
| #1342 | …I can download a finished translation in a format I choose | ⏳ New | 3 |
| #1343 | …I can re-download a past translation + its source without reprocessing | ✅ Done | 5 |
| #1344 | …I can see when each project expires (flat 30-day retention, no surprises) | ✅ Done | 3 |
| #1345 | …I am warned before a project is deleted so I can re-download it | ⏳ New | 5 |
| #1346 | …retention is a flat 30-day window, no extensions — download your translation to keep it (#2136 decommissioned extensions) | 🚫 Removed | 3 |
| #1347 | …I can delete a project myself (data + storage, zero orphans) | ✅ Done | 3 |
| #1348 | …I can rename a project so my library stays organized | ✅ Done | 2 |
| #1349 | …I can search, filter, and sort my library | ⏳ New | 5 |
| #1350 | …I can see upload progress and cancel an in-flight upload | ✅ Done | 3 |
| #1351 | …I can see a cost estimate and my balance before processing | ✅ Done | 5 |
| #1352 | …I am notified when my translation is ready (fires once when the whole book finishes) — reframed by #1455 from per-batch "ready for review" | ✅ Done | 5 |
| #1353 | …I can resume reading a partially-translated project where I left off | ✅ Done | 5 |
| #1354 | Spike: UX research + design system for the web-app redesign | ⏳ New | 3 |
| #1355 | Redesign the web-app UI (app shell, Solarized-dark, profile menu) | ⏳ New | 8 |
| #1372 | Spike/PBI: Solarized-light theme + theme toggle (linked to #1355) | ⏳ New | — |
Note: #1342 (download) reads as "New" but the underlying export/download endpoints exist — confirm against the running app; it may be closable or reduced to the format-picker UI.
Update (2026-07-02, Spike #1720): confirmed —
POST /projects/{id}/exportalready generates every format on demand (no pre-generation); the only gap is that the format picker inReviewPage.tsxis visible from the moment a project leaves the pre-commit stage instead of only once there's something to download. Decision record:docs/design/output-format-defer-to-download.md; follow-up #1805 (move the picker to a post-completion "Download as …" surface) closes #1342.#1369/#1370/#1371 (Profile/Settings pages, avatars), created by a parallel session, were re-homed under Accounts #1356 and linked to #1359 as their data layer. #1372 (theme) correctly stays here under the UX feature, linked to redesign #1355.
5. New Features (added in the 2026-06-24 sweep)
Feature #1356 — Accounts, Profile & Settings
The account lifecycle around the existing JWT sign-up/login: verify, recover, configure, delete.
| ID | Story | Status | Pts |
|---|---|---|---|
| #1357 | …I can verify my email (unblocks email for #1345 & #1352) | 🆕 New | 5 |
| #1358 | …I can reset a forgotten password | 🆕 New | 5 |
| #1359 | …I can view & edit my profile and preferences (incl. notification prefs) | ✅ Done | 3 |
| #1360 | …I can delete my account and export my data (privacy/GDPR) | 🆕 New | 5 |
| #1369 | Build the Profile page (UI for #1359) | ⏳ New | — |
| #1370 | Build the Settings page — app preferences (UI for #1359) | ⏳ New | — |
| #1371 | Uploadable user avatars (replace initials/glyph) | ⏳ New | — |
#1359 is the data/preferences backend; #1369/#1370 are its UI (linked related). #1369–#1371 came from a parallel session and were re-parented here from #1338.
Feature #1361 — Billing & Credits
The wallet's write side + checkout. Credits model + method-agnostic payments — see payments.md. Every transaction records its payment method.
| ID | Story | Status | Pts |
|---|---|---|---|
| #1362 | …I can top up my balance — method-agnostic checkout umbrella (fixes #1351's over-balance dead-end) | 🆕 New | 5 |
| #1373 | …I can pay by card (Stripe) — PCI-safe, webhook-confirmed | 🆕 New | 5 |
| #1374 | …I can pay with cryptocurrency via a QR checkout (scan, address, live confirmations) | 🆕 New | 8 |
| #1375 | …I can upload a file and get a cost estimate before committing to anything | 🆕 New | 3 |
| #1363 | …I can view my usage & transaction history (per-method, with receipts) | 🆕 New | 3 |
| #1395 | …I can see my credit balance at the top of every page after login (persistent wallet widget) | 🆕 New | 3 |
| #1396 | …I can buy credits in one click from anywhere I need them (entry points into #1362) | 🆕 New | 3 |
| #1397 | …I can see how much translation costs before I commit (pricing transparency) | 🆕 New | 5 |
| #1398 | …I can see what a particular file cost me to translate (per-file actual spend) | 🆕 New | 5 |
| #1399 | …I can see spend across all my files so I can compare & budget | 🆕 New | 5 |
| #1376 | …I can pay to translate a single page (try cheaply) | 💡 Nice-to-have | 3 |
| (moved) | whitelist/unlimited → now #1364 under Admin #1377 | — | — |
Feature #1365 — Core Translation & Reading Experience
The automatic translation flow + the read-only reading/export experience. (Originally framed as "the human-in-the-loop quality gate — the product's reason to exist"; the #1455 pivot, 2026-06-25, removed the gate — translation is now fully automatic, so this Feature is the calibrate-then-auto-advance flow plus reading/exporting the finished result.)
| ID | Story | Status | Pts |
|---|---|---|---|
| ❌ Retired | — | ||
| #1367 | …I can retry a failed page/batch (the one explicit recovery control; owns #1340's retry affordance) | 🆕 New | 3 |
| ❌ Retired | — | ||
| #1386 | …I can upload a PDF and select specific pages to translate (pay for only what I need) | 💡 Nice-to-have | 5 |
Reading the finished translation is now read-only: page through the result (original scan beside the English), see per-page status, and export — there are no approve / reject / edit decision buttons. The completion notification fires once when the whole book finishes ("Translation ready"), not per batch. The new automatic-confirm / auto-advance behaviour and the affordability pause are covered by the existing processing + billing stories (#1351, #1375, #1396); the read-only reading view itself is folded into the redesign (#1355) and the retro-documented review-view flow in §6.
Feature #1377 — Admin & Operations
An operator surface: see everything, manage access. Role-gated.
| ID | Story | Status | Pts |
|---|---|---|---|
| #1378 | (admin) …I can see a dashboard of everything going on (users, jobs, revenue, GPU spend, failures) | ✅ Done | 8 |
| #1379 | (admin) …I can manage users (view, adjust credits, suspend, delete) | 🆕 New | 5 |
| #1364 | (admin) …I can grant an account unlimited/whitelisted billing (owns #1351's flag) | 🆕 New | 3 |
Feature #1380 — Affiliate & Referral Program
A standard creator-referral program: code → free-token signup → commission kickback → payout.
| ID | Story | Status | Pts |
|---|---|---|---|
| #1381 | (affiliate) …I get a unique referral link/code to promote the app | 🆕 New | 3 |
| #1382 | …I can sign up with a referral code and get free tokens | 🆕 New | 3 |
| #1383 | (affiliate) …I earn a commission on referrals' purchases + track earnings | 🆕 New | 5 |
| #1384 | (affiliate) …I can request and receive a payout of my earnings | 🆕 New | 5 |
| #1385 | (admin) …I can manage affiliates, codes, and payouts | 🆕 New | 3 |
6. Implemented but previously un-storied (retro-documented)
These flows exist in code today (src/BookTranslation.Api/Program.cs + src/BookTranslation.Web/index.html) but have no PBI on the board. Captured here for traceability. Backfill as Done PBIs (linked to the PR that shipped them) only if board-level provenance is wanted.
| Story | Where it lives | Note |
|---|---|---|
| As a user, I can sign up for an account (email + password) | POST /auth/register | No email verification yet → #1357 |
| As a user, I can log in / log out | POST /auth/login, JWT bearer | — |
| As a user, I can upload a book and create a project (PDF / image folder) | POST /uploads, POST /projects, GET /uploads/limits | Progress/cancel = #1350 (Done) |
| As a user, I can read a finished page (original scan beside the English) — read-only | result package + BookTranslation.Web reading view, GET …/pages/{n}/image | Navigation/resume = #1353. Post-#1455 there are no approve/reject/edit buttons. |
| (retired) | The system auto-approves a cleanly-processed page. | |
| (retired) | Failed pages are recovered via retry (#1367), not rejection. | |
| As a user, the batch ladder (1→5→25→100→rest) runs automatically to completion | POST …/process-next-batch, POST …/process (each batch auto-confirms + auto-advances via IBatchAutoAdvancer) | Pauses only on affordability; retry = #1367 |
| As a user, I have a notification center (unread, mark-read) | GET/POST /notifications… | Emit/dedup = #1352 (Done) |
7. Coverage gaps — candidates not yet ticketed
Honest unknowns / lower-priority ideas surfaced by the sweep. Promote to PBIs when prioritized; not auto-created to avoid guessing scope.
- Onboarding / first-run. The automatic-service flow (upload → upfront estimate → commit/pay → the book translates itself, pausing only if you run out of credit) is worth a short guided first-run so the upfront-cost-then-hands-off model is clear and the affordability pause isn't surprising.
Operator/admin observability— now ticketed as Admin & Operations #1377 (#1378/#1379/#1364).- Admin: act further on behalf of a user beyond #1379 (resolve a stuck job) — partially covered; promote if needed.
- Multi-format export polish beyond #1342 (DOCX is M3; per-format previews).
- Translation quality controls (opt-in LLM polish pass — spec M3; choosing OCR engine per book — Kraken vs Surya for historical type).
- Sharing / collaboration (read-only share of a finished translation) — likely post-MVP.
- Accessibility as an explicit story (the #1355 redesign sets WCAG AA targets for the shell; a dedicated a11y pass across all flows is broader).
8. Brand & product-vision surfaces (2026-06-24 branding pass)
Two Epics were added to carry branding and the not-yet-storied product surfaces. Detail lives in brand/brand-guide.md, brand/name-kenly.md, and product-vision.md. Product name is now Kenly (getkenly.com).
Epic #1403 — Brand & Identity (Kenly)
| ID | Item | Status | Pts |
|---|---|---|---|
| #1405 | Name & brand guide — foundation (name + domain + docs) | ✅ Done | 2 |
| #1406 | Design the Kenly logo (no paper imagery; symbol-only for favicon) | 🆕 New | 5 |
| #1407 | Define the color system — light & dark (WCAG AA; ⚠️ Solarized collision w/ #1355/#1372) | 🆕 New | 5 |
| #1408 | Implement brand tokens, typography & favicon-in-browser-tab | 🆕 New | 5 |
| #1409 | Apply branding / rename from ManuscriptTranslator (related #1355) | 🆕 New | 5 |
Sequencing: #1406 + #1407 → #1408 → #1409.
Epic #1404 — Product Vision & Surfaces
New surfaces only (accounts/billing/web-frontend already exist under #1356 / #1361 / #1338):
| ID | Feature | Status | Note |
|---|---|---|---|
| #1410 | Public API (GA) | 🆕 New | predecessor of #1411 & #1412; related #1356, #1389 |
| #1411 | MCP server (agent access) | 🆕 New | automatic flow (no approval gate post-#1455); related billing #1361 |
| #1412 | Native desktop apps (right-click → "Ken this") | 🆕 New | spike: MAUI/Avalonia vs Tauri |
These Features have no child PBIs yet — break each down with
/ado-ticketwhen prioritized.
9. How to keep this current
- Adding a story: create the PBI on the board (
/ado-ticket), then add a row to the right Feature table here with its link + status + points. - Closing a story: flip its status here when the PR merges (
/ado-close). - New theme: add a Feature, give it its own subsection, update the §3 map.