[WKP-47] Guest demo for unauthenticated users#58
Open
SteadfastKnight wants to merge 31 commits into
Open
Conversation
Frontend: Transloco runtime i18n with lazy per-route scopes; locale signal on UserPreferencesService persisted to localStorage + /api/preferences; Accept-Language interceptor; locale->Transloco bridge in app.config. Language switchers (profile dropdown + personalisation). Charter landing English layer locale-aware + EN/RO swallowtail flags. Locale-aware numeric dates. Backend: nullable user_preferences.locale + migration; SetLocale middleware; lang/ro for auth/validation/passwords/pagination + emails; 6 mailables and blades localized; User implements HasLocalePreference. Tooling: scripts/translate-i18n.mjs (Gemini), check-i18n.mjs CI guard + allowlist. Tests: PHPUnit LocalizationTest, preferences locale cases, interceptor/prefs unit specs, landing + locale-switch e2e. Phase 6 (per-template string extraction) deferred; pending templates allowlisted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract strings from the 6 auth pages (login, register, forgot/reset password, verify-email, verify-email-change) into a new `auth` Transloco scope (EN + RO), and the profile shell + personalisation page into the `profile` scope. Components use the scoped t() directive; client-side error messages go through TranslocoService.translate / reactive error keys. Harden check-i18n.mjs to ignore Angular control-flow (@if/@switch/@case) — this also revealed home/layout/confirmation-dialog/user-menu-dropdown were already clean. Allowlist trimmed 45 -> 33; specs updated with the Transloco testing module. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Introduce a `shared` Transloco scope for reusable cross-page components, provided at the component level so it overrides the ambient route scope. Migrate sort-dropdown and rename-dialog; update the 5 list-page specs that render sort-dropdown to include the Transloco testing module. Allowlist 33 -> 31. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the dashboard recent-activity strings into the `shared` scope, including the TS-computed work-type badges and relative-time labels (via TranslocoService.translate, reactive under the scoped directive). Update home + recent-activity specs for the cascade. Allowlist 31 -> 30. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ants (Phase 6) Complete Phase 6 via a multi-agent workflow: extract every remaining template into Transloco scopes (EN + RO) — documents, extraction, page-linking, book-view, translation (each + reader), dictionary, profile-info/security, the 4 shared dialogs, the 6 layout shell variants, and the 6 home dashboard variants. Each component uses a component-level provideTranslocoScope; new scopes registered in the testing module; cascade specs (layout dispatcher, readers) updated. Harden check-i18n.mjs: handle Angular control-flow conditions containing </> comparisons and @else-if, and skip attribute/expression leakage. Allowlist now holds only 3 intentional templates (charter + console/scriptorium decorative Latin/CLI). All 1073 unit tests pass; guard green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Install/configure @jsverse/transloco-messageformat so ICU plural syntax works;
the extraction scope already used it (was rendering literally). Convert the
bookView documentCount/pageCount from the English {{plural}} suffix hack to
proper ICU one/few/other Romanian forms.
Add a global languages.<code> map (EN + RO) and repoint every per-component
language-name lookup (document-detail, book-view(+reader), translation(+reader),
new-translation-dialog, recent-activity) at it via translate(), replacing the
duplicated English maps. Translate document genres via the documents scope.
All 1073 unit tests pass; i18n guard green (3 intentional templates allowlisted).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ds + personalisation options
- Stamp request locale on all queued mailables (verify/reset/password-changed/email-change/2FA)
- Add lang/{en,ro}/messages.php; replace hardcoded controller literals with __() (full sweep, 9 controllers)
- Populate validation attributes array (RO field names) so :attribute localizes
- Localize layout + palette label/blurb via transloco (profile/{en,ro}.json + template)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Localize ConfirmationService helpers (delete + OCR/extract overrides) via global confirmations.* keys; add localization-guard spec - Fix dialog confirm/cancel buttons inheriting global auth .btn-primary/.btn-secondary styles (uppercase, letter-spacing, width:100%, margin-top) — reset in rename/confirmation/new-translation/avatar-crop dialogs - Rename dialog: group cancel+save, widen card so restore+cancel+save fit one row Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Overlay hid its localized text (font-size:0) + painted a ::after with hardcoded content:'IGNORED'. Render t() in a .ignored-overlay__badge span (uppercase via CSS) so RO shows IGNORATĂ. extraction + page-linking readers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Card formatDate + profile expiry + compendium header date hardcoded en-US (AM/PM, month-first). Add formatLocaleDate/formatDateTime helpers (en->en-US, ro->ro-RO) driven by transloco.getActiveLang(). RO now 24h + RO month/order; EN unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Badges (status/renamed/type/lang/wrong-lang) become borderless lowercase mono tokens with a currentColor dot, distinct from scriptorium cartouches. Status bar shows localized palette + theme labels; RO nav tokens (doc/extr/leg/viz/trad/dicț). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ry alignment Document status badge now localized (uploaded/processing/ready/failed). Personalisation subtitle mentions language. Dictionary word/badge vertically aligned (align-items: center). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire scripts/translate-i18n.mjs (Gemini en->ro seeding) as npm run i18n:translate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
playwright install hung at 100% (download done, extraction stalled) due to a yauzl regression on Node 24.16+/26.x; fixed in Playwright 1.60.0. Was pinned to 1.58.2. Affected CI (node lts/*) and local (Node 26). Verified chromium install now completes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The test created a lone page (page_number=1) expecting link_to_next_page to stay null, but DocumentFactory's page_count is random (1-50). When page_count==1, DocumentPage's creating hook stamps the last page with DOCUMENT_END, making the page linked and flaking the assertion (~2% of runs). Pin page_count=2 so page 1 is never the last page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Required <lang> arg + self-contained LANG_NAMES map; parameterize prompt, output paths and logs. Adapt ICU plural categories to target CLDR; make placeholder parity ICU-aware. Retry transient Gemini failures (429/5xx, network, bad body) with backoff. Update README + memory mirror. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs/acquisition-booklet: modular HTML->PDF sales booklet — build script, per-section sources, embedded fonts, real app screenshots, capture-shots tooling, README, built PDF. Mirror propose-better-tools-quality-first memory into docs/claude-code-memories + sync index. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No longer referenced — replaced by the two themed dashboard shots. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Mirror binding gutter per page (left on recto, right on verso) for double-sided print; folio moves to outer corner on verso. - Add blank verso after cover so the title page sits alone; numbering now starts at the one-minute page. - Spell-check: drop Italian and Latin (don't work), now 5 languages. - Add BINDING-AND-SPIRES.md print/finishing guide; refresh README (folio rules, screenshot slots, gutter, file table). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Recommended weights/finish, coated-vs-uncoated trade-off, bleed/edge-to-edge note, presentation options. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New sections/80-future.html: one curated roadmap page (reading studio, pipeline, scale, output), framed for a buyer. Every item code-audited as not-yet-built; S3 storage marked Planned. - docs/planning/Jira/fetch-backlog.ps1: read-only Jira backlog exporter (paginated search/jql, ADF->text) used to harvest the ideas; backlog.md export gitignored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 'Output & flow' now lists Word (.docx) export with print-ready templates (A6/A5/A4), replacing the misleading 'Print & export finished documents' (Markdown export already ships, noted on the capabilities page). - 'A smarter pipeline' gains PDF illustration extraction (auto-extract embedded images / crop from scans). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the one-off scripts (import-tickets/link-dependencies/link-ticket-deps/update-from-audit) with parameterized tools that read their data from input files: - JiraLib.ps1: shared auth/search/ADF/link/transition helpers (search-by-id workaround; self-calibrating Blocks direction). - import-issues.ps1 (-CsvPath), link-issues.ps1 (-EdgesCsv), update-issues.ps1 (-ChangesJson); fetch-backlog.ps1 kept. - README.md documents formats + gotchas; examples/ preserves the applied datasets (feature tickets, link graphs, audit changes) as worked references. All four dry-run idempotently against the live project (0 failures). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Public /demo walks guests through extraction -> page linking -> book view ->
translation -> translated book view, reusing the real reader components via
route-level DI overrides that serve canned, server-captured data: zero /api,
no AI, resets on exit. Real Vanity Fair fixture with two layers (raw OCR in the
extraction stage; cleaned text + captured Romanian downstream), two view-only
footnotes, charter chrome with wax-seal step pips, in-demo light/dark + palette
personalisation (layouts withheld as a post-signup discovery), Latin landing
links + "Witness the craft" CTA.
Supporting changes:
- ReaderModeService (readonly + hide in-reader back link) consumed by the 4
readers; normalize their back labels to "Back to {Section}".
- Fix DocumentTranslation summary rollup so per-page translate/edit/delete keeps
status in sync (book view no longer reports a complete translation as
incomplete).
- Spell-check popup first-open positioning fix.
Tests + docs: demo service/state/chrome unit specs, guest e2e asserting no /api,
2 backend summary tests, README guest-demo section.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three new business-case pages between the offer and the roadmap: - Proof of a market: peer traction (Transkribus/READ-COOP 400k+ users, 110M+ images, 261 institutions; ABBYY; Google Books), all cited. - What it costs to run at scale: honest MVP ~$0/mo, the single-host OCR ceiling, a costed scaling path, per-tier run cost (100/1k/10k users). - Revenue, profit & scenarios: metered-translation / subscription / self-host-license, profit net of the at-scale infra cost (no hidden COGS). Figures sourced to vendor/research pages (checked Jun 2026). Adds a .fig table style for multi-column figures. Cross-refs by section name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pricing() returned legacy Gemini 1.5 Flash rates ($0.075/$0.30 per 1M tokens); current gemini-2.5-flash is $0.30 in / $2.50 out. Update the endpoint constants, env/config per-book comments (~$0.85 Flash / ~$0.15 Flash-Lite), and the backend + frontend test fixtures. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…icated-users # Conflicts: # docs/claude-code-memories/MEMORY.md
Make GET /api/translation/pricing public (static price list, no user data) so the guest demo fetches live prices instead of a hardcoded copy that drifts. Drop DemoTranslationService.loadPricingRules override + DEMO_PRICING fixture; whitelist the one URL in the no-/api guards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WKP-47 — Guest demo for unauthenticated users
A public, guided
/demolets a logged-out visitor experience the full product flow without signing up: extraction → page linking → book view → translation → translated book view. The real reader components are reused under/demowith route-level DI overrides that serve canned, server-captured data — zero/api, no AI, resets on exit.Highlights
demo.fixture.ts: the raw OCR (with authentic slips) in the extraction stage, and the cleaned source + its captured Romanian downstream — the "best result" a real editor would produce./api). The six layout variants are intentionally withheld as a post-signup discovery.Supporting changes
ReaderModeService(readonly + hide in-reader back link) consumed by the four readers; their back labels normalized to "Back to {Section}".DocumentTranslationsummary now stays in sync on per-page translate / edit / delete, so the book view no longer reports a fully-translated document as "incomplete".Tests & docs
DemoStateService,LayoutDemoComponent.e2e/demo.spec.ts) — walks all five stages and asserts the tour makes zero/apicalls.🤖 Generated with Claude Code