Adds an opt-in modal that prompts a PRO user with local data to migrate
their localStorage notes and sessionStorage initiative into the cloud.
- src/lib/client/import.ts: pure helpers (hasLocalData, shouldShowImport)
- src/components/dm/ImportModal.astro: modal UI + import orchestration
with conflict handling for existing "DM Notes" record
- src/i18n/dm-translations.ts: 14 new keys for the import flow
- Wired into both EN and RU dm/index.astro
- tests/import-flow.test.ts: 18 unit tests on the helpers
Local storage is preserved as backup; only a "dm-import-asked" flag is
set after the user makes a decision (import or skip).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix auth anti-patterns (JWT, OAuth, logout, middleware, url.origin)
- Extend DB schema with tier, npcs, counters, translations, notes, initiative
- Expand Open5e TypeScript interfaces (Monster, Spell) to full V2
- Build OpenRouter API client for FREE tier
- Build Kimi API client for PRO tier
- Add comprehensive tests for all modules
- Fix typo "combatантов" -> "участников боя" in dm-translations
- Replace hardcoded English "Result", "Rolls:", "Invalid notation"
in DiceRoller with translation keys
- Translate English aria-labels ("Quick dice selectors", "Roll history",
"Combatants") to Russian
- Move InitiativeTracker hardcoded strings ("Итого", "Инициатива",
"Порядок хода", help text) into the translation file
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bump container max-width and right context column at xl/2xl so the
reference and notes panels get noticeably more room on larger monitors.
Mobile and lg layouts are unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pages /dm/ and /ru/dm/ were static (prerendered), so middleware
never ran and Astro.locals.user was always null. Adding
prerender = false allows middleware to authenticate the user
before page render.
- Change COOKIE_NAME from 'session' to 'auth_token' in oauth.ts
- Update logout.ts to use Headers.append() and SameSite=Lax
- Fixes mismatch where callback set 'session' but middleware read 'auth_token'
Browser cannot parse multiple cookies from a single Set-Cookie header
joined by comma (RFC 6265). Use Headers.append() to send each cookie
in its own Set-Cookie header. Fixes state/verifier cookie mismatch.
- Add back-to-generators link on EN and RU blog index pages
- Update all 16 blog post dates to 2026-05-14 with staggered times
- Sync EN and RU post dates so matching topics have identical timestamps
- Delete extra test-post.md (scope creep from F4)
- Fix EN blog index: strip 'en/' prefix from post.id in links
- Fix RU blog index: strip 'ru/' prefix from post.id in links
- Fix schema URLs in both blog indices to use clean slugs