Compare commits

79 Commits
Author SHA1 Message Date
emilandClaude Opus 4.7 4f3e641458 feat(home): mark DM Dashboard promo with Work in Progress badge
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 09:47:35 +03:00
emilandClaude Opus 4.7 815c5c7b04 fix(home): move prerender export inside frontmatter so it stops rendering as text
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 09:30:33 +03:00
emilandClaude Opus 4.7 79e1dc4144 fix(deploy): lock down postgres — no public port + password via .env
Yesterday's prod incident exposed postgres on 0.0.0.0:5432 with the
default 'postgres:postgres' credentials. A scanner ransomware bot
brute-forced it and dropped the database (left a readme_to_recover
note). We restored from a pre-incident dump and the user data is back,
but the underlying weakness was in this docker-compose.yml.

Changes:
- Remove `ports: "5432:5432"` from the postgres service entirely.
  Postgres is reachable only via the internal docker network. For
  ad-hoc admin access, use an SSH tunnel:
  `ssh -L 5432:localhost:5432 deploy@<host>`
- POSTGRES_PASSWORD now reads from `${POSTGRES_PASSWORD:-postgres}`
  via env interpolation. Prod `.env` (not in repo) provides the real
  value; local dev gets the `postgres` fallback so `docker compose up`
  still works without setup.
- Remove the no-longer-needed DATABASE_URL override in the app service
  `environment:` — `env_file: .env` already supplies it.

After this lands, the deploy pipeline will rsync the new compose.yml,
recreate containers with no exposed pg port, and substitute the strong
password from .env at container start. Volumes persist, data intact.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 02:56:53 +03:00
emilandClaude Opus 4.7 cce582df6c feat(dm-dashboard): Wave 8 — spell generator + Open5e equipment/magicitems + UX polish
Wave 8 closes the high-value gaps from the original spec while staying
inside MVP scope (encounters/weapons/items still future work).

Spell generator (mirrors the NPC pattern end-to-end)
- src/lib/ai/types.ts: spellParamsSchema, spellResultSchema, Open5eSpell
- src/lib/ai/openrouter.ts: generateSpell using llama-3.3-70b:free for FREE
- src/lib/ai/kimi.ts: generateSpell using moonshot-v1-8k with json_schema
  response_format for PRO
- src/pages/api/dm/ai/generate-spell.ts: auth → rate-limit → optional
  /spells/ Open5e reference for balance → AI generate → Zod validate →
  increment counter. Spells are returned to client and not persisted
  (spec only requires NPC persistence for PRO).
- src/components/dm/AiSpellForm.astro: form (level, school, classes,
  tone, suggested name) + inline result card rendering with copy-JSON
- src/components/dm/AiKindSwitcher.astro: segmented NPC | Spell control
  wrapping both forms; default tab is NPC

Open5e Reference: equipment + magic items tabs
- src/lib/open5e/client.ts: searchEquipment, getEquipmentItem,
  searchMagicItems, getMagicItem (plus EquipmentItem / MagicItem types)
- src/lib/client/open5e-ui.ts: Tab type extended to four, search() and
  selectItem() dispatch all four
- src/components/dm/Open5eReference.astro: two more tab buttons; new
  renderEquipmentCard/Detail and renderMagicItemCard/Detail; filter
  dropdown hidden for new tabs (search-by-name only)
- src/lib/client/translation.ts: TranslationType union now includes
  "equipment" | "magicitem"
- src/lib/ai/openrouter.ts: translateOpen5eContent type widened (export
  Open5eContentType)
- src/pages/api/dm/translate.ts: ALLOWED_TYPES adds equipment/magicitem
  and dispatches to the right Open5e fetcher

UX polish
- src/components/dm/AiQuotaExhausted.astro: dedicated state shown to
  authenticated FREE users with remaining=0 — replaces the form with
  reset-time message and Boosty upgrade hint
- src/pages/{dm,ru/dm}/index.astro: render AiQuotaExhausted when the
  guard passes; otherwise render the kind switcher
- src/middleware/index.ts: remove [Middleware] debug console.logs that
  were noisy in prod logs (one line per request)

Verified locally: tsc 0 errors, lint 0 errors, vitest 339/339 passing,
npm run build succeeds without auth env vars.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 02:47:41 +03:00
emilandClaude Opus 4.7 e6dec1eb95 fix(deploy): apply drizzle migrations to prod on container startup
The deploy pipeline was building the app image with only `dist/` inside
and rsync'ing only `dist package*.json docker-compose.yml Dockerfile`
to the server. The drizzle migrations folder never reached prod, so
new schema changes (Wave 1 added `tier`, `boosty_verified_at`, and 5
tables) silently went missing. App requests then failed with
"column does not exist" errors at runtime.

Wave-1 CI step `npm run db:migrate` ran against the in-job postgres
service, not against prod — so it never helped.

Changes:
- src/db/migrate.ts -> src/db/migrate.mjs: plain JS so the prod image
  can run it via `node` without devDependencies (no tsx needed).
- Dockerfile: COPY drizzle and src/db/migrate.mjs into the image,
  prepend `node ./src/db/migrate.mjs &&` to the CMD. Container fails
  to start if migrations fail — better than serving with stale schema.
- .github/workflows/deploy.yml: rsync now also sends `drizzle` and
  `src` so the build context on the server has what the Dockerfile
  COPYs reference.
- package.json: `db:migrate` script switched to `node src/db/migrate.mjs`.
- eslint.config.mjs: enable node globals for the migrator script.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 00:29:32 +03:00
emilandClaude Opus 4.7 4b78e9edad fix(auth): defer env validation to first access so build works without secrets
`validateAuthEnv()` was running at module-load time, which fired during
`astro build` while constructing the route manifest — before any actual
request needed the secrets. CI build failed even though build-time code
doesn't use JWT_SECRET / OAuth secrets.

- src/lib/auth/env.ts: wrap authEnv in a Proxy that runs validation
  on first property read; cache the validated object after.
- src/lib/auth/jwt.ts: defer `new TextEncoder().encode(...)` of the
  secret behind a memoised getSecret() helper.
- src/lib/auth/oauth.ts: same for the JWT secret; vkOAuthConfig and
  yandexOAuthConfig switched to getter-based properties so credential
  access is also lazy.
- src/lib/auth/auth.test.ts: 3 tests previously asserted "throws at
  module load"; updated to assert "throws on first access" — semantic
  guarantee (invalid env throws) is preserved.

Runtime fail-fast is intact: any auth route reading authEnv.X will
throw with the same descriptive Zod error if a var is missing. Build
just no longer crashes when secrets aren't in env (e.g. CI deploy
pipeline running tsc/lint/build without secrets).

Verified: npm run build succeeds with no auth env vars set; tsc 0,
lint 0, vitest 339/339.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 23:45:03 +03:00
emilandClaude Opus 4.7 f2afaf60a3 fix(lint): unblock CI — add scoped eslint-disable for APIContext mocks
The 6 API/CORS test files mock the Astro APIContext by spreading
`{} as any` to satisfy fields not under test (cookies, redirect,
clientAddress, etc.). Replacing each cast individually would require
either full typed contexts (obscures tests) or 70+ inline disables.

Add one file-level `eslint-disable @typescript-eslint/no-explicit-any`
with a comment explaining the rationale to each affected file.

Production code remains lint-clean. Verified: tsc 0, lint 0,
vitest 339/339.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 23:39:50 +03:00
emilandClaude Opus 4.7 2f7453e571 chore(qa): Final Wave cleanup — resolve lint findings from F2 review
Production code (all findings cleared):
- GenerationHistory: drop unused fetchProHistory(userId) param,
  change let activeId to const
- InitiativeTracker: remove write-only currentSessionName state
- NotesPanel: remove unused isLoading flag
- Open5eReference: drop unused getCachedTranslation/setCachedTranslation
  imports; use fetchTranslation result directly instead of re-lookup
- ai/openrouter.ts: drop unused z + Monster imports; attach cause to
  rethrown AbortError
- ai/kimi.ts: drop unused z import
- api/dm/ai/generate.ts: annotate best-effort counter increment catch
- api/dm/ai/history.ts: drop unused sql import

Test files (trivial fixes; ~70 mock-related `as any` errors remain as
pre-existing tech debt across api test mocks):
- translation-client: drop unused MockBroadcastChannel _name param and
  unused getCachedTranslation destructure
- open5e-types: eslint-disable for the intentional type-test aliases
- {notes,initiative}-api: remove unused mockUser2 placeholder
- {notes,initiative,translate,history}-api: let mockDb -> const mockDb
- ai-generate-api: wrap deliberate `var` mock decls in eslint-disable
  with comment explaining vi.mock hoisting requirement

Verification: tsc 0 errors, vitest 339/339, lint 81 -> 70 errors
(production code fully clean; remaining errors are test-mock as-any
patterns from Waves 5-6).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 23:33:57 +03:00
emilandClaude Opus 4.7 701398f627 feat(dm-dashboard): Wave 7 — FREE→PRO data import flow (Task 22)
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>
2026-05-15 23:33:39 +03:00
emil 09e947f430 feat(dm-dashboard): Wave 6 — NPC form, result card, history panel, notes/initiative DB migration, translation service 2026-05-15 23:09:06 +03:00
emil 75f2dc6972 feat(dm-dashboard): Wave 5 — NPC generation API, history API, quota/tier badges, translate button 2026-05-15 22:45:26 +03:00
emil 2921e45237 feat(dm-dashboard): Wave 4 — rate limiting, translation API, AI tab navigation 2026-05-15 22:26:41 +03:00
emil 5aec915034 feat(dm-dashboard): Wave 3 — Boosty verification, notes/initiative API routes 2026-05-15 22:00:19 +03:00
emil 0bbaa6e3d8 feat(dm-dashboard): Wave 2 — Drizzle migration, DmSidebar fix, CORS config 2026-05-15 21:48:09 +03:00
emil 25f43ec4e2 feat(dm-dashboard): Wave 1 — auth fixes, DB schema, Open5e interfaces, AI clients
- 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
2026-05-15 21:28:42 +03:00
emilandClaude Opus 4.7 1f09270329 fix(dm): polish hardcoded strings, typo, and aria-labels
- 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>
2026-05-15 18:31:21 +03:00
emilandClaude Opus 4.7 c01c34d3e0 style(dm): widen desktop dashboard at xl/2xl breakpoints
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>
2026-05-15 18:23:35 +03:00
emilandSisyphus 659b042de5 fix(lint): resolve explicit any and empty catch in DM test scripts
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-15 18:10:36 +03:00
emilandSisyphus 8eafd504b2 fix(lint): resolve explicit any and useless assignment in DM components
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-15 18:10:28 +03:00
emilandSisyphus 3388d70d96 chore(lint): add debug-open5e.mjs to ESLint ignores
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-15 18:10:19 +03:00
emilandSisyphus fddc40e967 docs: note boulder tracking sync issue in DM dashboard redesign
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-15 18:02:00 +03:00
emil 1c38df7e74 style(dm): redesign dashboard with purple-gold theme
Redesign DM Dashboard (/dm/, /ru/dm/) with purple-gold theme (#534AB7 + #c8a84b):

Design System:
- Update dm-theme.css with 49 purple-gold tokens (transitions, shadows, hover states)
- Create DmTabs.astro with ARIA, keyboard nav, URL hash sync, localStorage persistence
- Create DmSidebar.astro for desktop navigation
- Redesign DmHeader with gold accent
- Update DmButton, DmCard, DmInput primitives
- Expand i18n to 47 strings

Layout:
- Redesign DmLayout with 3-column dashboard grid (sidebar|main|context)
- Update /dm/index.astro and /ru/dm/index.astro with named slots

Feature Components:
- DiceRoller: empty state, ARIA live, color-coded history, storage key fallback
- InitiativeTracker: HP editing, active highlighting, storage key fallback
- Open5eReference: skeletons, debounce, error retry, gold tabs
- NotesPanel: cross-tab sync, copy-to-clipboard, auto-save
- AuthPanel: VK/Yandex brand colors, pill buttons

Tests:
- Add 50 Playwright E2E tests (smoke, dice, initiative, reference, notes, data-migration)

Fixes:
- Document Open5e client.ts URL bugfix
- Add backward-compatible storage key fallback for dice/initiative
- Preserve legacy sessionStorage data on load
2026-05-15 17:49:32 +03:00
emil 11da171bfb docs: add AGENTS.md knowledge base (root + generators + dm) 2026-05-15 04:35:00 +03:00
emil 592fa4cc3e chore(vk): remove debug logging from callback 2026-05-15 04:21:34 +03:00
emil 5815b52c4e fix(vk): add client_id to user_info request, use query params for device_id 2026-05-15 04:18:19 +03:00
emil 57d56c7f29 debug(vk): log full callback URL and all query params 2026-05-15 04:15:07 +03:00
emil 258f062115 fix(lint): remove unused refreshToken variable 2026-05-15 04:11:07 +03:00
emil fbc011f55e fix(vk): use id.vk.ru domain, handle payload param, add device_id to token exchange 2026-05-15 04:09:02 +03:00
emil 5b6247ff7c style(auth): remove debug border from AuthPanel, clean up console.log 2026-05-15 03:55:51 +03:00
emil 6f2d9aff5d fix(auth): make DM pages server-rendered so middleware can set Astro.locals.user
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.
2026-05-15 03:50:41 +03:00
emil 38a778f3de debug(auth): add visible debug border and user state to AuthPanel 2026-05-15 03:40:01 +03:00
emil 08161dcdd1 fix(auth): unify cookie name to auth_token for OAuth and middleware compatibility
- 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'
2026-05-15 02:22:19 +03:00
emil de81e54ae1 fix(oauth): use SameSite=Lax for session cookie to survive cross-site redirect 2026-05-15 02:14:21 +03:00
emil b762e2eb66 fix(health): check DB connectivity in health endpoint 2026-05-15 02:05:40 +03:00
emil b71902b686 fix(oauth): use separate Set-Cookie headers for multiple cookies
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.
2026-05-15 01:59:56 +03:00
emil da6208de50 fix(oauth): fix VK token URL (.ru -> .com), add error logging to callbacks 2026-05-15 01:50:45 +03:00
emil da0ee46bc0 fix(dm): scope DM theme CSS to .dm-theme class to override BaseLayout purple accent 2026-05-15 01:46:01 +03:00
emil aaf596a7bc fix(dm): OAuth redirect_uri, orange buttons, denser layout, hide lang switcher
- Fix OAuth redirect_uri mismatch in VK/Yandex callbacks (use PUBLIC_APP_URL)
- Make quick dice buttons and anchor nav links orange by default
- Densify DM Dashboard layout (smaller gaps, tighter spacing)
- Hide LanguageSwitcher/Blog/About/Privacy links on DM pages
- Increase notes textarea height for better usability
2026-05-15 01:42:09 +03:00
emil 5273518908 fix: SameSite=Lax for OAuth cookies to allow cross-site redirects 2026-05-15 01:28:24 +03:00
emil 2b57cba3bb fix: use process.env for runtime OAuth secrets 2026-05-15 01:25:27 +03:00
emil 4a13ba3272 fix deploy: copy dist directory instead of contents 2026-05-15 01:01:55 +03:00
emil d24f978d7e trigger deploy 2026-05-15 00:54:45 +03:00
emil 1a092e05c1 feat(dm): add dashboard with oauth, dice, initiative, open5e, notes 2026-05-14 23:48:36 +03:00
emil 7efe188a9a feat(ads): restore custom AdBanner with Admitad link 2026-05-14 16:21:50 +03:00
emil 87b35ba067 fix(ads): remove Admitad and Chitai-gorod banners completely 2026-05-14 15:55:37 +03:00
emil dfca40bb34 fix(lint): remove unused Props and eslint-disable directive 2026-05-14 15:38:04 +03:00
emil b22a68bf12 feat(ads): replace custom banner with Admitad leaderboard 2026-05-14 15:33:48 +03:00
emil 375455aac9 fix(ads): remove Yandex branding from banner, use neutral accent styling 2026-05-14 15:11:50 +03:00
emil 7c4241fd0e feat(ads): remove Yandex ads, move banner above generators 2026-05-14 15:07:17 +03:00
emil ae809cd119 feat(ads): replace Yandex Market with Admitad Читай-город affiliate link 2026-05-14 15:00:54 +03:00
emil f6f1ca05c9 feat(seo): add Admitad verification file 2026-05-14 14:48:07 +03:00
emil 2225044795 feat(seo): add Admitad verification meta tag 2026-05-14 14:43:06 +03:00
emil f3993a8315 feat(ads): replace YandexRTB placeholder with AdBanner referral banners 2026-05-14 14:10:22 +03:00
emil 11e7c9578a feat(ads): add Yandex Market referral link to banner rotation 2026-05-14 14:05:49 +03:00
emil 3917934d45 fix(blog): register @tailwindcss/typography for prose styling 2026-05-14 13:24:43 +03:00
emil 36a714d7e2 content(blog): add real articles to all 16 posts 2026-05-14 13:12:39 +03:00
emil db09f493e9 fix(blog): add generator links, sync dates to 2026-05-14
- 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
2026-05-14 10:32:53 +03:00
emil ea77828094 fix(blog): remove test-post.md, fix blog index slug links
- 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
2026-05-14 03:28:08 +03:00
emil 25fd24d236 feat(blog+categories): Wave 3-5 — blog infrastructure, categories, content, navigation
- Install @astrojs/rss and setup content collections (blog + generators)
- Create BlogLayout with BlogPosting schema, article OG tags, prev/next nav
- Create blog post pages EN/RU ([slug].astro) with dynamic routing
- Create blog index pages EN/RU with post cards and filtering
- Create RSS feeds EN/RU with auto-discovery links
- Create generator category pages EN/RU (5 categories each)
- Add category navigation pills to homepage
- Create Breadcrumbs, RelatedGenerators, RelatedPosts components
- Add breadcrumbs to GeneratorLayout and BlogLayout
- Wire RelatedGenerators into GeneratorLayout
- Wire RelatedPosts into blog post pages
- Create 8 EN + 8 RU blog post templates with placeholder content
- Add blog link to LanguageSwitcher navigation
- Add category and blog translation keys
2026-05-14 03:19:06 +03:00
emil 23cf7058f0 feat(schema): Wave 2 — add generator categories, Organization schema, 404 pages
- Add category field to generatorSchema (required, 5 values)
- Assign categories to all 28 generators
- Add Organization JSON-LD schema to BaseLayout
- Create custom 404 pages (EN + RU)
- Add not-found and blog translation keys
2026-05-14 02:48:05 +03:00
emil 43ea9bc8f3 fix(seo): Wave 1 — fix critical SEO gaps
- Fix duplicate faq/ruFaq keys in dice.json, list.json, colors.json
- Add <main> landmarks to about/privacy pages (EN + RU)
- Move YandexRTB after <main> on homepage
- Add x-default hreflang to BaseLayout
- Configure sitemap i18n with hreflang alternates
- Add Open Graph + Twitter Card meta tags
- Create default OG image (1200x630)
2026-05-14 02:39:56 +03:00
emil 75038780d5 fix(lint): fix pre-existing unused vars in 5 generators
- EmojiGenerator: remove unused clickToCopyLabel, CopyFeedback import, forEach i
- FontPairGenerator: prefer-const loadedFonts, remove unused headingFamily, bodyFamily, copyIconSvg
- HashGenerator: remove unused copyIcon, checkIcon, copyLabel
- Magic8BallGenerator: remove unused getTypeLabel
- TeamsGenerator: remove unused teamPrefix, errAddTwo, errTeamsMin, errTeamsMax, errMorePlayers
2026-05-13 21:29:57 +03:00
emil 8a0e2b5e0f fix(lint): remove unused vars in refactored generators
- Fix 11 lint errors introduced during refactoring
- All remaining 16 errors are pre-existing in unrefactored files
2026-05-13 20:59:01 +03:00
emil 0081510914 Wave 6: refactor generators batch 4 to crypto random
- refactor(generators): migrate Teams, Time, Uuid, Weighted to crypto random
- refactor(generators): migrate WheelSpinner, YesNo to crypto random

All 28 generators now use cryptographically secure random via src/lib/client/random.ts
2026-05-13 20:41:27 +03:00
emil 8e0485c215 Wave 5: refactor generators batch 3 to crypto random
- refactor(generators): migrate Meal, Names, Number, Palette to crypto random
- refactor(generators): migrate Password, Rps, Shuffler to crypto random
2026-05-13 20:34:16 +03:00
emil 49269f209d Wave 4: refactor generators batch 2 to crypto random
- refactor(generators): migrate Gradient, Hash, Letter, List to crypto random
- refactor(generators): migrate Lorem, Lottery, Magic8Ball to crypto random
2026-05-13 20:25:39 +03:00
emil 3d94c99ff9 Wave 3: refactor generators batch 1 to crypto random
- refactor(generators): migrate Card, Coin, Color, Country to crypto random
- refactor(generators): migrate Date, Emoji, FontPair to crypto random
- refactor(dice): deduplicate DiceGenerator by importing from dice-engine.ts
2026-05-13 20:16:40 +03:00
emil e24a8b744d Wave 2: shared components + dice engine crypto migration
- feat(components): add ResultBox and CopyButton shared components
- refactor(dice): migrate dice engine to cryptographically secure random
2026-05-13 19:42:28 +03:00
emil 515c4a6168 Wave 1: add deps, crypto random utility, i18n helper, privacy fix, CI gates
- fix(deps): add zod and typescript to package.json
- feat(lib): add cryptographically secure random utility with TDD
- feat(lib): add client i18n helper with TDD
- fix(i18n): update privacy policy for crypto accuracy
- ci(deploy): add test and lint gates, fix SSH security
2026-05-13 19:34:42 +03:00
emil 2c400abb0a fix(magic8ball): enlarge triangle, shrink text further for long answers 2026-05-13 00:50:55 +03:00
emil 074adaa5e4 fix(magic8ball): lower text further and widen triangle for long answers 2026-05-13 00:45:27 +03:00
emil 40bf7dbacf fix(magic8ball): shrink text and widen triangle viewport for long answers
- Reduce font size: 8px mobile / 10px desktop
- Tighten padding and max-width for earlier line breaks
- Lower text with mt-5 for wider triangle area
- Widen triangle clip-path: 50% 12%, 94% 92%, 6% 92%
2026-05-13 00:43:18 +03:00
emil 87e11655f6 fix(magic8ball): shift answer text down with mt-3 instead of pt-2
- Replace padding-top with margin-top so text actually shifts down
  inside the flex-centered triangle viewport
2026-05-13 00:35:50 +03:00
emil 1b02227cdd Merge remote main: resolve conflicts, keep local icons and gitignore 2026-05-13 00:31:07 +03:00
emil 8f11c5af43 feat: add favorites panel to meal generator, remove redundant Another one button
- Add clickable favorites counter with expandable panel
- Render saved recipes list with remove button
- Remove duplicate 'Another one' button (Generate already covers it)
- Sync favorite button state when removing from panel
2026-05-13 00:25:09 +03:00
emil28092005 a1cc10d0a2 feat: add 4 new generators (Palette, Lorem, Country, Weighted)
- Color Palette: 7 harmony modes (Random, Analogous, Complementary,
  Triadic, Monochromatic, Split-Complementary, Tetradic), 3-8 colors,
  individual swatch copy + copy all
- Lorem Ipsum: 1-20 paragraphs, Short/Medium/Long length,
  optional classic start, full a11y support
- Random Country: 40 countries, region filter, flag emoji + capital
  + population, bilingual data
- Weighted Random: dynamic item-weight rows, validation,
  single pick + N-trials with statistics bars

All generators include EN/RU i18n, SEO metadata, FAQ, and follow
project patterns.
2026-05-12 16:22:26 +03:00
emil 02f9ada193 feat: add 6 new generators + Privacy Policy
New generators:
- Yes or No — random Yes/No/Maybe with confidence bar
- Random Name — male/female/any names (EN + RU databases)
- Team Splitter — split list into random teams
- Random Letter — A-Z / А-Я alphabet picker
- Random Date — date between two dates
- Rock Paper Scissors — play against random bot

Also added:
- Privacy Policy page (/privacy, /ru/privacy)
- FAQ blocks on all 16 generators (3 Q&A each, EN+RU)
- About page (/about, /ru/about)
- Improved Yandex RTB ad placement with min-height placeholder
- Navigation: About + Privacy links in LanguageSwitcher

Build: 38 pages, all passing
2026-05-11 23:34:31 +03:00
emil 6f8264a0fb fix: add PNG favicon for search engine snippets 2026-05-11 22:26:17 +03:00
emil cbc0a3b545 feat: prepare site for Yandex Ads (RSYA) moderation
- Add About page (/about, /ru/about) with mission, history, contacts
- Add FaqBlock component for generator FAQ sections
- Add FAQ to all 10 generators (3 Q&A each, EN+RU)
- Expand howTo/whenTo content on numbers, password, coin generators
- Add About link to LanguageSwitcher navigation
- Improve Yandex RTB ad block: min-height placeholder, no layout shift
- Extend generator schema with optional faq/ruFaq fields
- Update translations.ts with about and faq i18n keys
2026-05-11 21:59:37 +03:00
451 changed files with 43398 additions and 437 deletions
-1
View File
@@ -1,5 +1,4 @@
node_modules node_modules
dist
.git .git
.env .env
*.log *.log
+15
View File
@@ -0,0 +1,15 @@
# OAuth - VK ID
# Register at https://id.vk.com/about/business/go/
VK_CLIENT_ID=
VK_CLIENT_SECRET=
# OAuth - Yandex
# Register at https://oauth.yandex.com/
YANDEX_CLIENT_ID=
YANDEX_CLIENT_SECRET=
# Database
DATABASE_URL=postgresql://dmuser:dmpass@localhost:5432/dmdashboard
# JWT
JWT_SECRET=your-jwt-secret-min-32-chars
+33 -3
View File
@@ -7,6 +7,24 @@ on:
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/randify
NODE_ENV: test
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: randify
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -16,8 +34,13 @@ jobs:
cache: npm cache: npm
- run: npm ci - run: npm ci
- run: npm run lint
- run: npm run test
- run: npm run build - run: npm run build
- name: Run database migrations
run: npm run db:migrate
- name: Setup SSH key - name: Setup SSH key
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
@@ -25,9 +48,16 @@ jobs:
chmod 600 ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Deploy via rsync - name: Deploy Node.js app
run: | run: |
# drizzle/ and src/db/migrate.mjs are needed inside the Docker
# build context so the image can apply pending migrations on startup.
rsync -avz --delete \ rsync -avz --delete \
-e "ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no" \ -e "ssh -i ~/.ssh/deploy_key" \
dist/ \ dist drizzle src package*.json docker-compose.yml Dockerfile \
${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:~/www/randify.pro/ ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:~/www/randify.pro/
- name: Restart app
run: |
ssh -i ~/.ssh/deploy_key ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \
"cd ~/www/randify.pro && docker compose down && docker compose up -d --build && sleep 5 && curl -sf http://localhost:4321/api/health || echo 'Health check skipped'"
+4
View File
@@ -3,3 +3,7 @@ dist/
.env .env
*.log *.log
.astro/ .astro/
.kimi/
node_modules_old/
package-lock.json
plan.md
+445
View File
@@ -0,0 +1,445 @@
{
"schema_version": 2,
"active_work_id": "dm-dashboard-ai-c738b11e",
"works": {
"critical-refactor-f063daf0": {
"work_id": "critical-refactor-f063daf0",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/critical-refactor.md",
"plan_name": "critical-refactor",
"status": "completed",
"started_at": "2026-05-13T16:25:19.266Z",
"updated_at": "2026-05-13T18:03:08.059Z",
"session_ids": [
"ses_1de6ede59ffexUwt5C0sddEWwR"
],
"session_origins": {
"ses_1de6ede59ffexUwt5C0sddEWwR": "direct"
},
"agent": "atlas",
"task_sessions": {
"todo:1": {
"task_key": "todo:1",
"task_label": "1",
"task_title": "Add missing dependencies to package.json",
"session_id": "ses_1ddd57501ffeO4NlJDKb2pwLz2",
"agent": "Sisyphus-Junior",
"category": "writing",
"started_at": "2026-05-13T16:27:48.876Z",
"status": "completed",
"updated_at": "2026-05-13T16:33:52.668Z",
"ended_at": "2026-05-13T16:33:52.668Z",
"elapsed_ms": 363792
},
"todo:4": {
"task_key": "todo:4",
"task_label": "4",
"task_title": "Create ResultBox.astro shared component",
"session_id": "ses_1ddce8961ffeoaXaB2Rxgt684X",
"agent": "Sisyphus-Junior",
"category": "visual-engineering",
"updated_at": "2026-05-13T16:42:05.595Z",
"started_at": "2026-05-13T16:40:57.448Z",
"status": "completed",
"ended_at": "2026-05-13T16:42:05.595Z",
"elapsed_ms": 68147
},
"todo:6": {
"task_key": "todo:6",
"task_label": "6",
"task_title": "Refactor CardGenerator.astro",
"session_id": "ses_1ddc76889ffe240ehScl9taAza",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T16:47:10.433Z",
"started_at": "2026-05-13T16:44:57.812Z",
"status": "completed",
"ended_at": "2026-05-13T16:47:10.433Z",
"elapsed_ms": 132621
},
"todo:10": {
"task_key": "todo:10",
"task_label": "10",
"task_title": "Refactor DateGenerator.astro",
"session_id": "ses_1ddc380cbffe0YA1da3ew6QlNf",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T17:16:10.363Z",
"started_at": "2026-05-13T16:49:43.859Z",
"status": "completed",
"ended_at": "2026-05-13T17:16:10.363Z",
"elapsed_ms": 1586504
},
"todo:13": {
"task_key": "todo:13",
"task_label": "13",
"task_title": "Refactor GradientGenerator.astro",
"session_id": "ses_1dda85f21ffeEGeOWrbqmWAk02",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T17:22:16.123Z",
"started_at": "2026-05-13T17:19:45.020Z",
"status": "completed",
"ended_at": "2026-05-13T17:22:16.123Z",
"elapsed_ms": 151103
},
"todo:17": {
"task_key": "todo:17",
"task_label": "17",
"task_title": "Refactor LoremGenerator.astro",
"session_id": "ses_1dda37bf2ffexATCZ3W4Z6EDu1",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T17:25:32.173Z",
"started_at": "2026-05-13T17:25:11.269Z",
"status": "completed",
"ended_at": "2026-05-13T17:25:32.173Z",
"elapsed_ms": 20904
},
"todo:20": {
"task_key": "todo:20",
"task_label": "20",
"task_title": "Refactor MealGenerator.astro",
"session_id": "ses_1dda01e38ffeVc6AUwAlt7lQXl",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T17:31:02.031Z",
"started_at": "2026-05-13T17:30:26.005Z",
"status": "completed",
"ended_at": "2026-05-13T17:31:02.031Z",
"elapsed_ms": 36026
},
"todo:24": {
"task_key": "todo:24",
"task_label": "24",
"task_title": "Refactor PasswordGenerator.astro",
"session_id": "ses_1dd9b7bb1ffez3Q0aayg7PZUIF",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-05-13T17:34:08.166Z",
"started_at": "2026-05-13T17:32:34.652Z",
"status": "completed",
"ended_at": "2026-05-13T17:34:08.166Z",
"elapsed_ms": 93514
},
"todo:27": {
"task_key": "todo:27",
"task_label": "27",
"task_title": "Refactor TeamsGenerator.astro",
"session_id": "ses_1dd94b493ffemX2z2dEFdh8W7R",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"started_at": "2026-05-13T17:37:23.881Z",
"status": "completed",
"updated_at": "2026-05-13T17:41:13.262Z",
"ended_at": "2026-05-13T17:41:13.262Z",
"elapsed_ms": 229381
},
"final-wave:f1": {
"task_key": "final-wave:f1",
"task_label": "F1",
"task_title": "**Plan Compliance Audit** — `oracle`",
"session_id": "ses_1dd81d9e1ffeclA0rP510AXfNB",
"agent": "Sisyphus-Junior",
"category": "deep",
"started_at": "2026-05-13T17:47:58.486Z",
"status": "completed",
"updated_at": "2026-05-13T18:02:13.341Z",
"ended_at": "2026-05-13T18:02:13.341Z",
"elapsed_ms": 854855
}
},
"ended_at": "2026-05-13T18:03:08.059Z",
"elapsed_ms": 5868793
},
"seo-blog-categories-9c7476b9": {
"work_id": "seo-blog-categories-9c7476b9",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/seo-blog-categories.md",
"plan_name": "seo-blog-categories",
"status": "completed",
"started_at": "2026-05-13T23:32:06.345Z",
"updated_at": "2026-05-14T00:35:49.637Z",
"session_ids": [
"ses_1de6ede59ffexUwt5C0sddEWwR"
],
"session_origins": {
"ses_1de6ede59ffexUwt5C0sddEWwR": "direct"
},
"agent": "atlas",
"task_sessions": {
"todo:1": {
"task_key": "todo:1",
"task_label": "1",
"task_title": "test-post.md — extra 9th EN blog post (scope creep)",
"session_id": "ses_1dc1d5043ffeFR7r3vy15aTFmv",
"agent": "Sisyphus-Junior",
"category": "deep",
"started_at": "2026-05-13T23:36:41.704Z",
"ended_at": "2026-05-14T00:33:08.868Z",
"elapsed_ms": 3387164,
"status": "completed",
"updated_at": "2026-05-14T00:33:08.868Z"
},
"todo:7": {
"task_key": "todo:7",
"task_label": "7",
"task_title": "Update generatorSchema.ts with category field",
"session_id": "ses_1dc1d7618ffeRpk0nnIfvvISQH",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"started_at": "2026-05-13T23:42:40.563Z",
"status": "completed",
"updated_at": "2026-05-14T00:34:58.498Z",
"ended_at": "2026-05-14T00:34:58.498Z",
"elapsed_ms": 3137935
}
},
"ended_at": "2026-05-14T00:35:49.637Z",
"elapsed_ms": 3823292
},
"fill-blog-content-fb2229ab": {
"work_id": "fill-blog-content-fb2229ab",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/fill-blog-content.md",
"plan_name": "fill-blog-content",
"status": "completed",
"started_at": "2026-05-14T09:06:01.254Z",
"updated_at": "2026-05-14T10:11:10.838Z",
"ended_at": "2026-05-14T10:11:10.838Z",
"elapsed_ms": 7509549,
"session_ids": [
"ses_1de6ede59ffexUwt5C0sddEWwR",
"ses_1da346c55ffe2yhgC2v7zqrilE"
],
"session_origins": {
"ses_1de6ede59ffexUwt5C0sddEWwR": "direct",
"ses_1da346c55ffe2yhgC2v7zqrilE": "direct"
},
"agent": "atlas",
"task_sessions": {
"todo:1": {
"task_key": "todo:1",
"task_label": "1",
"task_title": "EN — What is Cryptographically Secure Randomness",
"session_id": "ses_1da41fec6ffeNQIbWZFz8CVyWF",
"agent": "Sisyphus-Junior",
"category": "writing",
"updated_at": "2026-05-14T09:14:45.203Z",
"started_at": "2026-05-14T09:12:23.181Z",
"status": "completed",
"ended_at": "2026-05-14T09:14:45.203Z",
"elapsed_ms": 142022
},
"todo:5": {
"task_key": "todo:5",
"task_label": "5",
"task_title": "EN — RNG in Gaming",
"session_id": "ses_1da24e0f5ffeOF5lOCH6y7ITTz",
"agent": "Sisyphus-Junior",
"category": "writing",
"started_at": "2026-05-14T09:21:18.403Z",
"status": "completed",
"updated_at": "2026-05-14T09:41:37.697Z",
"ended_at": "2026-05-14T09:41:37.696Z",
"elapsed_ms": 1219293
},
"todo:9": {
"task_key": "todo:9",
"task_label": "9",
"task_title": "RU — Криптографически стойкая случайность",
"session_id": "ses_1da21f28fffeAnOJVgAFQWldSb",
"agent": "Sisyphus-Junior",
"category": "writing",
"updated_at": "2026-05-14T09:53:48.978Z",
"started_at": "2026-05-14T09:52:28.114Z",
"status": "completed",
"ended_at": "2026-05-14T09:53:48.978Z",
"elapsed_ms": 80864
},
"todo:13": {
"task_key": "todo:13",
"task_label": "13",
"task_title": "RU — RNG в играх",
"session_id": "ses_1da16a3cdffe5O9FyZDLUu2SUM",
"agent": "Sisyphus-Junior",
"category": "writing",
"updated_at": "2026-05-14T10:11:10.838Z",
"started_at": "2026-05-14T10:09:51.259Z",
"status": "completed",
"ended_at": "2026-05-14T10:11:10.838Z",
"elapsed_ms": 79579
}
}
},
"blog-typography-fix-c9cf9be1": {
"work_id": "blog-typography-fix-c9cf9be1",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/blog-typography-fix.md",
"plan_name": "blog-typography-fix",
"status": "completed",
"started_at": "2026-05-14T10:23:17.171Z",
"updated_at": "2026-05-14T10:25:36.103Z",
"ended_at": "2026-05-14T10:25:36.103Z",
"elapsed_ms": 127932,
"session_ids": [
"ses_1da346c55ffe2yhgC2v7zqrilE"
],
"session_origins": {
"ses_1da346c55ffe2yhgC2v7zqrilE": "direct"
},
"agent": "atlas",
"task_sessions": {
"final-wave:f1": {
"task_key": "final-wave:f1",
"task_label": "F1",
"task_title": "Build + Visual Check",
"session_id": "ses_1d9fc2935ffesVSRCGlGP4wnCU",
"agent": "Sisyphus-Junior",
"category": "quick",
"updated_at": "2026-05-14T10:25:36.103Z",
"started_at": "2026-05-14T10:24:51.820Z",
"status": "completed",
"ended_at": "2026-05-14T10:25:36.103Z",
"elapsed_ms": 44283
}
}
},
"dm-dashboard-c3118dfa": {
"work_id": "dm-dashboard-c3118dfa",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/dm-dashboard.md",
"plan_name": "dm-dashboard",
"status": "completed",
"started_at": "2026-05-14T17:56:40.328Z",
"updated_at": "2026-05-14T20:09:11.770Z",
"session_ids": [
"ses_1d89ad89affe987QEXPgCGcx4S"
],
"session_origins": {
"ses_1d89ad89affe987QEXPgCGcx4S": "direct"
},
"agent": "atlas",
"task_sessions": {
"final-wave:f1": {
"task_key": "final-wave:f1",
"task_label": "F1",
"task_title": "**Plan Compliance Audit** — `oracle`",
"session_id": "ses_1d7f26069ffeYjfNhmNuooCc3p",
"agent": "Sisyphus-Junior",
"category": "quick",
"started_at": "2026-05-14T18:05:29.120Z",
"status": "completed",
"updated_at": "2026-05-14T20:01:43.840Z",
"ended_at": "2026-05-14T20:01:43.840Z",
"elapsed_ms": 6974720
},
"final-wave:f2": {
"task_key": "final-wave:f2",
"task_label": "F2",
"task_title": "Code Quality Review (re-run after fixes)",
"session_id": "ses_1d7eaed87ffen4vuG6WyFcGh7b",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"started_at": "2026-05-14T19:44:00.709Z",
"status": "completed",
"updated_at": "2026-05-14T20:07:46.967Z",
"ended_at": "2026-05-14T20:07:46.967Z",
"elapsed_ms": 1426258
},
"final-wave:f3": {
"task_key": "final-wave:f3",
"task_label": "F3",
"task_title": "Real Manual QA (re-run after fixes)",
"session_id": "ses_1d7eab36dffeC7MQ1w6VXEOAnr",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"started_at": "2026-05-14T19:46:49.796Z",
"status": "completed",
"updated_at": "2026-05-14T20:07:53.184Z",
"ended_at": "2026-05-14T20:07:53.184Z",
"elapsed_ms": 1263388
},
"final-wave:f4": {
"task_key": "final-wave:f4",
"task_label": "F4",
"task_title": "Scope Fidelity Check",
"session_id": "ses_1d7fd7992ffe3wLZZY1Zj6CrLD",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-05-14T20:01:50.576Z",
"started_at": "2026-05-14T19:50:33.428Z",
"status": "completed",
"ended_at": "2026-05-14T20:01:50.576Z",
"elapsed_ms": 677148
}
},
"ended_at": "2026-05-14T20:09:11.770Z",
"elapsed_ms": 7951442
},
"dm-dashboard-redesign-a1bfaddc": {
"work_id": "dm-dashboard-redesign-a1bfaddc",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/dm-dashboard-redesign.md",
"plan_name": "dm-dashboard-redesign",
"status": "active",
"started_at": "2026-05-15T12:32:10.008Z",
"updated_at": "2026-05-15T12:32:10.008Z",
"session_ids": [
"ses_1d6b615cbffe5pqd0AObdil6OK"
],
"session_origins": {
"ses_1d6b615cbffe5pqd0AObdil6OK": "direct"
},
"agent": "atlas",
"task_sessions": {}
},
"dm-dashboard-ai-c738b11e": {
"work_id": "dm-dashboard-ai-c738b11e",
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/dm-dashboard-ai.md",
"plan_name": "dm-dashboard-ai",
"status": "active",
"started_at": "2026-05-15T17:58:09.859Z",
"updated_at": "2026-05-15T19:37:40.096Z",
"session_ids": [
"ses_1d3921469ffeQox08ZjNWWJq7u"
],
"session_origins": {
"ses_1d3921469ffeQox08ZjNWWJq7u": "direct"
},
"agent": "atlas",
"task_sessions": {
"final-wave:f1": {
"task_key": "final-wave:f1",
"task_label": "F1",
"task_title": "**Plan Compliance Audit** — `oracle`",
"session_id": "ses_1d2e49248ffelY8jx06oXxpWMG",
"agent": "Sisyphus-Junior",
"category": "deep",
"started_at": "2026-05-15T18:24:29.818Z",
"status": "running",
"updated_at": "2026-05-15T19:37:40.097Z"
}
}
}
},
"active_plan": "/home/emil/Desktop/Coding/AI/Randify.pro/.sisyphus/plans/dm-dashboard-ai.md",
"started_at": "2026-05-15T17:58:09.859Z",
"status": "active",
"updated_at": "2026-05-15T19:37:40.096Z",
"session_ids": [
"ses_1d3921469ffeQox08ZjNWWJq7u"
],
"session_origins": {
"ses_1d3921469ffeQox08ZjNWWJq7u": "direct"
},
"plan_name": "dm-dashboard-ai",
"task_sessions": {
"final-wave:f1": {
"task_key": "final-wave:f1",
"task_label": "F1",
"task_title": "**Plan Compliance Audit** — `oracle`",
"session_id": "ses_1d2e49248ffelY8jx06oXxpWMG",
"agent": "Sisyphus-Junior",
"category": "deep",
"started_at": "2026-05-15T18:24:29.818Z",
"status": "running",
"updated_at": "2026-05-15T19:37:40.097Z"
}
},
"agent": "atlas"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

+77
View File
@@ -0,0 +1,77 @@
# F3 Manual QA Report — DM Dashboard Redesign
## Test Environment
- **URL**: http://localhost:4321/dm/
- **Browser**: Chromium + Mobile Chromium (Pixel 5)
- **Dev Server**: Astro dev on localhost:4321
## Automated Test Suite (Playwright CLI)
- **Total tests**: 50
- **Passed**: 50
- **Failed**: 0
- **Projects**: chromium (Desktop Chrome), mobile-chromium (Pixel 5)
- **Test files**: smoke.spec.ts, dice.spec.ts, initiative.spec.ts, reference.spec.ts, notes.spec.ts, data-migration.spec.ts
## Manual QA — Browser Automation Results
### Scenario 1: Dice Roller
- Navigate to `/dm/#dice`
- Click d20 button → result appears
- Enter custom formula `2d6+3` → roll works
- History persists after refresh
- **Status**: PASS | **Console Errors**: none
### Scenario 2: Initiative Tracker
- Navigate to `/dm/#initiative`
- Add combatant "Гоблин" → appears in list
- Add second combatant, click Next Turn → active combatant cycles
- Data persists after refresh
- **Status**: PASS | **Console Errors**: none
### Scenario 3: Open5e Reference
- Navigate to `/dm/#reference`
- Search for "goblin" → results appear
- Click result → detail modal opens
- Click overlay → modal closes
- **Status**: PASS | **Console Errors**: none
### Scenario 4: Notes Panel
- Navigate to `/dm/#notes`
- Type text → auto-save indicator appears
- Refresh page → text persists in localStorage
- **Status**: PASS | **Console Errors**: none
### Scenario 5: Responsive Desktop (1440px)
- Viewport 1440×900
- Dice, Initiative, and Reference sections all visible simultaneously
- 3-column layout confirmed
- **Status**: PASS | **Console Errors**: none
### Scenario 6: Responsive Mobile (375px)
- Viewport 375×812
- Tab navigation visible and functional
- Single-column layout, tab switching works across all 4 sections
- **Status**: PASS | **Console Errors**: none
## Visual Verification
Screenshots captured for all scenarios:
- `.sisyphus/evidence/f3-screenshots/f3-dice-roller.png`
- `.sisyphus/evidence/f3-screenshots/f3-initiative.png`
- `.sisyphus/evidence/f3-screenshots/f3-open5e.png`
- `.sisyphus/evidence/f3-screenshots/f3-notes.png`
- `.sisyphus/evidence/f3-screenshots/f3-responsive-desktop.png`
- `.sisyphus/evidence/f3-screenshots/f3-responsive-mobile.png`
## Console Errors
**None detected** across all manual QA flows and all 50 automated tests.
## Data Persistence
- Dice history: sessionStorage ✅
- Initiative tracker: sessionStorage ✅
- Notes: localStorage ✅
---
## VERDICT: APPROVE
All 4 DM Dashboard sections (Dice Roller, Initiative Tracker, Open5e Reference, Notes Panel) function correctly. Responsive layouts work on both desktop (1440px) and mobile (375px). No console errors, no broken layouts, all interactive elements respond to input, and data persistence works as expected.
Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

+25
View File
@@ -0,0 +1,25 @@
Scenarios [10/11 pass] | Integration [5/6] | Edge Cases [5 tested] | VERDICT: REJECT
Details:
PASS: T2: Tab switching and URL hash — hash=true, keyboardFocused=initiative
PASS: T2: Mobile scrollable tabs — allInRow=true, minHeightOk=true, tabCount=4
PASS: T2: Initial tab state — aria-selected=true
PASS: T9: Dice rolling and history — d20=11(valid=true), 2d6+3=6(valid=true), history=2, empty=true
PASS: T9: Critical hit/fail colors — foundCrit=false, foundFail=false, colorClasses=true
PASS: T9: Hover and active states — hoverClass=true, activeClass=true
PASS: T10: Initiative tracking flow — goblin=true, sorted=true, turnChanged=true, afterDelete=1
PASS: T11: Open5e search and detail — results=true, empty=false, searchResults=10, modalOpened=true, modalClosed=true
PASS: T11: Empty search state — emptyVisible=true, noResults=true
FAIL: T12: Notes auto-save and cross-tab sync — savedVisible=true, savedOpacity=1, chars=16, sync=false, cleared=true
PASS: T6: All sections accessible — allAccessible=true
PASS: INT-1: Switch between all tabs — urlHashOk=true
PASS: INT-2: Roll dice, check history, clear — history=2, empty=true
PASS: INT-3: Initiative flow — sorted=true, turnChanged=true, afterDelete=1
PASS: INT-4: Open5e search and modal — cards=10, modalOpened=true, modalClosed=true
PASS: INT-5: Notes persistence — value="Persistent note test"
FAIL: INT-6: Responsive layout — desktop=false, mobile=true, back=false
PASS: EDGE-1: Empty states — dice=true, init=true, notes=true
PASS: EDGE-2: Rapid tab switching — url=http://localhost:4322/dm/#initiative
PASS: EDGE-3: Invalid dice notation — result="?", details="Invalid notation"
PASS: EDGE-4: Empty search in Open5e — results=true, empty=false, noError=true
PASS: EDGE-5: Clear notes after typing — value="", chars=0
Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

+69
View File
@@ -0,0 +1,69 @@
# Final QA Verdict — Wave F3
## Build Status
- 93 pages built, 0 errors
- No Zod validation errors
## Per-Task QA Results
| Task | Description | Status |
|------|-------------|--------|
| 1 | Build passes, no Zod errors | PASS |
| 2 | `<main>` in about/privacy | PASS |
| 3 | Ad block after `<main>` | PASS |
| 4 | `hreflang="x-default"` | PASS |
| 5 | `<xhtml:link>` in sitemap | PASS |
| 6 | OG tags on index + dice | PASS |
| 7 | category field in schema | PASS |
| 8 | All 28 JSONs have category | PASS |
| 9 | Organization schema | PASS |
| 10 | dist/404.html exists | PASS |
| 11 | @astrojs/rss in package.json | PASS |
| 12 | BlogPosting schema in posts | PASS |
| 13 | dist/blog/*/index.html exists (9 EN) | PASS |
| 14 | dist/ru/blog/*/index.html exists (8 RU) | PASS |
| 15 | Blog index pages exist | PASS |
| 16 | RSS feeds exist | PASS |
| 17 | Gaming category has dice content | PASS |
| 18 | Category links on homepage | PASS |
| 19 | `aria-label="Breadcrumb"` | PASS |
| 20 | Related generators on dice | PASS |
| 21 | RelatedPosts on blog pages | PASS |
| 22-23 | 9 EN + 8 RU blog posts | PASS |
| 24 | Blog link in homepage | PASS |
| 25-26 | Breadcrumbs on generator/blog | PASS |
## Integration Tests
| Test | Status |
|------|--------|
| Homepage loads with category pills + generator grid | PASS |
| Category page filters correctly (gaming has dice, no password) | PASS |
| Blog index lists posts | PASS (but links broken — see bugs) |
| Blog post renders with BlogPosting schema | PASS |
| RSS feed contains posts | PASS |
| Prev/next navigation on blog posts | PASS |
| Related posts show on blog pages | PASS |
| Related generators show on generator pages | PASS |
| 404 page renders | PASS |
## Edge Cases
| Test | Status |
|------|--------|
| RU locale on all pages | PASS |
| Empty blog collection | N/A (collection has posts) |
| Category with excluded generators | PASS (gaming=6, security=3, etc.) |
## Bugs Found
### CRITICAL: Blog Index Broken Links
- **EN blog index** links to `/blog/en/<slug>/` but posts exist at `/blog/<slug>/`
- **RU blog index** links to `/ru/blog/ru/<slug>/` but posts exist at `/ru/blog/<slug>/`
- **Impact**: All blog index links are 404s
- **Root cause**: `post.slug` includes locale prefix (e.g. `en/color-theory-palettes`) in the blog collection
- **Isolated to**: Blog index pages only. Individual post prev/next and RelatedPosts links are correct.
## Score
Scenarios 26/26 pass | Integration 8/9 pass | Edge Cases 2/2 tested | VERDICT: CONDITIONAL PASS
+42
View File
@@ -0,0 +1,42 @@
=== Playwright E2E Infrastructure Verification ===
Date: 2026-05-15
Task: T0 - Verify and configure Playwright E2E test infrastructure
---
1. npx playwright test --list
---
Listing tests:
[chromium] › dm/smoke.spec.ts:4:3 › DM Dashboard Smoke Tests › /dm/ loads without errors
[chromium] › dm/smoke.spec.ts:11:3 › DM Dashboard Smoke Tests › /ru/dm/ loads without errors
[mobile-chromium] › dm/smoke.spec.ts:4:3 › DM Dashboard Smoke Tests › /dm/ loads without errors
[mobile-chromium] › dm/smoke.spec.ts:11:3 › DM Dashboard Smoke Tests › /ru/dm/ loads without errors
Total: 4 tests in 1 file
---
2. npx playwright test tests/dm/smoke.spec.ts
---
Running 4 tests using 4 workers
✓ 3 [chromium] › tests/dm/smoke.spec.ts:11:3 › DM Dashboard Smoke Tests › /ru/dm/ loads without errors (2.9s)
✓ 4 [mobile-chromium] › tests/dm/smoke.spec.ts:11:3 › DM Dashboard Smoke Tests › /ru/dm/ loads without errors (3.1s)
✓ 1 [mobile-chromium] › tests/dm/smoke.spec.ts:4:3 › DM Dashboard Smoke Tests › /dm/ loads without errors (3.1s)
✓ 2 [chromium] › tests/dm/smoke.spec.ts:4:3 › DM Dashboard Smoke Tests › /dm/ loads without errors (3.2s)
4 passed (8.4s)
---
Summary
---
- playwright.config.ts: EXISTING, VALID
- testDir: ./tests
- baseURL: http://localhost:4321
- fullyParallel: true
- projects: chromium, mobile-chromium
- webServer: npm run dev, reuseExistingServer: !CI
- package.json scripts:
- test:e2e: playwright test (ADDED)
- test:ui: playwright test (PRESERVED)
- Smoke test created: tests/dm/smoke.spec.ts
- /dm/ loads without errors (title contains "DM Dashboard")
- /ru/dm/ loads without errors (title contains "DM Dashboard")
- Result: ALL TESTS PASS (4/4)
+1
View File
@@ -0,0 +1 @@
{"status":"ok"}
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

+605
View File
@@ -0,0 +1,605 @@
> randify@0.0.1 build
> astro build
16:06:25 [types] Generated 474ms
16:06:25 [build] output: "hybrid"
16:06:25 [build] directory: /home/emil/Desktop/Coding/AI/Randify.pro/dist/
16:06:25 [build] adapter: @astrojs/node
16:06:25 [build] Collecting build info...
16:06:25 [build] ✓ Completed in 521ms.
16:06:25 [build] Building hybrid entrypoints...
16:06:29 [vite] ✓ built in 4.38s
16:06:29 [build] ✓ Completed in 4.43s.
building client (vite)
16:06:29 [vite] transforming...
16:06:29 [vite] ✓ 83 modules transformed.
16:06:29 [vite] rendering chunks...
16:06:29 [vite] computing gzip size...
16:06:29 [vite] dist/client/_astro/animations.JKmio82t.js 0.19 kB │ gzip: 0.13 kB
16:06:29 [vite] dist/client/_astro/validation.plcuGzaj.js 0.20 kB │ gzip: 0.16 kB
16:06:29 [vite] dist/client/_astro/clipboard.v9BZgIeL.js 0.43 kB │ gzip: 0.22 kB
16:06:29 [vite] dist/client/_astro/random.PhfdigkC.js 0.50 kB │ gzip: 0.31 kB
16:06:29 [vite] dist/client/_astro/hoisted.CFrvq8IZ.js 0.87 kB │ gzip: 0.55 kB
16:06:29 [vite] dist/client/_astro/hoisted.DeuEhRu-.js 1.20 kB │ gzip: 0.60 kB
16:06:29 [vite] dist/client/_astro/hoisted.CDqNCJbh.js 1.35 kB │ gzip: 0.70 kB
16:06:29 [vite] dist/client/_astro/hoisted.PmXvumdK.js 1.45 kB │ gzip: 0.82 kB
16:06:29 [vite] dist/client/_astro/hoisted.D82rtlIG.js 1.54 kB │ gzip: 0.84 kB
16:06:29 [vite] dist/client/_astro/hoisted.CBL-zfRu.js 1.60 kB │ gzip: 0.80 kB
16:06:29 [vite] dist/client/_astro/hoisted.ChTmcvxE.js 1.61 kB │ gzip: 0.72 kB
16:06:29 [vite] dist/client/_astro/hoisted.B3IGpv9b.js 1.62 kB │ gzip: 0.80 kB
16:06:29 [vite] dist/client/_astro/hoisted.CcnzwbSI.js 1.70 kB │ gzip: 0.90 kB
16:06:29 [vite] dist/client/_astro/hoisted.Ctqpdo5m.js 1.71 kB │ gzip: 0.85 kB
16:06:29 [vite] dist/client/_astro/hoisted.Dk2zSKc8.js 1.73 kB │ gzip: 0.98 kB
16:06:29 [vite] dist/client/_astro/hoisted.C2xv_bfE.js 1.86 kB │ gzip: 1.04 kB
16:06:29 [vite] dist/client/_astro/hoisted.DEA5quja.js 1.96 kB │ gzip: 0.94 kB
16:06:29 [vite] dist/client/_astro/hoisted.BFWROTcs.js 2.16 kB │ gzip: 1.06 kB
16:06:29 [vite] dist/client/_astro/hoisted.D3o68Cb5.js 2.30 kB │ gzip: 1.14 kB
16:06:29 [vite] dist/client/_astro/hoisted.C2hEIf7W.js 2.85 kB │ gzip: 1.69 kB
16:06:29 [vite] dist/client/_astro/hoisted.BPWMU8Hf.js 2.88 kB │ gzip: 1.40 kB
16:06:29 [vite] dist/client/_astro/hoisted.D0K3hqdU.js 3.91 kB │ gzip: 1.94 kB
16:06:29 [vite] dist/client/_astro/hoisted.BYkrZFZ1.js 4.07 kB │ gzip: 1.69 kB
16:06:29 [vite] dist/client/_astro/hoisted.Ccfod4c9.js 4.27 kB │ gzip: 1.95 kB
16:06:29 [vite] dist/client/_astro/hoisted.C3FdK1i-.js 4.50 kB │ gzip: 1.96 kB
16:06:29 [vite] dist/client/_astro/hoisted.BIopzZUx.js 4.76 kB │ gzip: 1.96 kB
16:06:29 [vite] dist/client/_astro/hoisted.C4XJaAq2.js 5.24 kB │ gzip: 2.18 kB
16:06:29 [vite] dist/client/_astro/hoisted.BjwopM0U.js 7.16 kB │ gzip: 2.53 kB
16:06:29 [vite] dist/client/_astro/hoisted.v_hq36aE.js 9.68 kB │ gzip: 3.83 kB
16:06:29 [vite] dist/client/_astro/hoisted.iGyTjoKm.js 10.89 kB │ gzip: 3.88 kB
16:06:29 [vite] dist/client/_astro/hoisted.C_iAN1Og.js 11.80 kB │ gzip: 2.75 kB
16:06:29 [vite] dist/client/_astro/i18n.ByZTyuwN.js 12.13 kB │ gzip: 6.14 kB
16:06:29 [vite] dist/client/_astro/hoisted.BI9nWQCa.js 26.98 kB │ gzip: 7.71 kB
16:06:29 [vite] dist/client/_astro/hoisted.DlpuYXZt.js 35.52 kB │ gzip: 17.44 kB
16:06:29 [vite] dist/client/_astro/hoisted.DDZr0hhq.js 45.23 kB │ gzip: 14.57 kB
16:06:29 [vite] ✓ built in 509ms
prerendering static routes
16:06:31 ▶ src/pages/404.astro
16:06:31 └─ /404.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+21ms)
16:06:31 ▶ src/pages/about.astro
16:06:31 └─ /about/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/blog/[slug].astro
16:06:31 ├─ /blog/uuid-vs-sequential-ids/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+13ms)
16:06:31 ├─ /blog/color-theory-palettes/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+9ms)
16:06:31 ├─ /blog/random-team-picker/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+9ms)
16:06:31 ├─ /blog/rng-in-gaming/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+8ms)
16:06:31 ├─ /blog/psychology-of-randomness/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+9ms)
16:06:31 ├─ /blog/dice-notation-explained/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+12ms)
16:06:31 ├─ /blog/how-to-create-strong-passwords/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+12ms)
16:06:31 └─ /blog/what-is-cryptographically-secure-randomness/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+8ms)
16:06:31 ▶ src/pages/blog/index.astro
16:06:31 └─ /blog/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ▶ src/pages/generators/cards.astro
16:06:31 └─ /generators/cards/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ▶ src/pages/generators/category/[category].astro
16:06:31 ├─ /generators/category/gaming/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ├─ /generators/category/security/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ├─ /generators/category/decision-making/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ├─ /generators/category/creative/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 └─ /generators/category/utility/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/coin.astro
16:06:31 └─ /generators/coin/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/colors.astro
16:06:31 └─ /generators/colors/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/country.astro
16:06:31 └─ /generators/country/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/date.astro
16:06:31 └─ /generators/date/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/dice.astro
16:06:31 └─ /generators/dice/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/emoji.astro
16:06:31 └─ /generators/emoji/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/fontpair.astro
16:06:31 └─ /generators/fontpair/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/gradient.astro
16:06:31 └─ /generators/gradient/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/hash.astro
16:06:31 └─ /generators/hash/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/letter.astro
16:06:31 └─ /generators/letter/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/list.astro
16:06:31 └─ /generators/list/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/lorem.astro
16:06:31 └─ /generators/lorem/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/lottery.astro
16:06:31 └─ /generators/lottery/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ▶ src/pages/generators/magic8ball.astro
16:06:31 └─ /generators/magic8ball/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/meal.astro
16:06:31 └─ /generators/meal/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/names.astro
16:06:31 └─ /generators/names/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/numbers.astro
16:06:31 └─ /generators/numbers/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/palette.astro
16:06:31 └─ /generators/palette/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/password.astro
16:06:31 └─ /generators/password/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/rps.astro
16:06:31 └─ /generators/rps/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/shuffler.astro
16:06:31 └─ /generators/shuffler/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/teams.astro
16:06:31 └─ /generators/teams/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/time.astro
16:06:31 └─ /generators/time/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/generators/uuid.astro
16:06:31 └─ /generators/uuid/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/weighted.astro
16:06:31 └─ /generators/weighted/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/generators/wheel.astro
16:06:31 └─ /generators/wheel/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/generators/yesno.astro
16:06:31 └─ /generators/yesno/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/privacy.astro
16:06:31 └─ /privacy/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 λ src/pages/rss.xml.ts
16:06:31 └─ /rss.xml16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+12ms)
16:06:31 ▶ src/pages/ru/404.astro
16:06:31 └─ /ru/404/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/about.astro
16:06:31 └─ /ru/about/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/blog/[slug].astro
16:06:31 ├─ /ru/blog/uuid-vs-sequential-ids/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+7ms)
16:06:31 ├─ /ru/blog/color-theory-guide/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ├─ /ru/blog/random-team-selection/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+7ms)
16:06:31 ├─ /ru/blog/rng-in-gaming/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+7ms)
16:06:31 ├─ /ru/blog/psychology-of-randomness/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ├─ /ru/blog/dice-notation-guide/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ├─ /ru/blog/how-to-create-strong-passwords/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+8ms)
16:06:31 └─ /ru/blog/what-is-cryptographically-secure-randomness/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+7ms)
16:06:31 ▶ src/pages/ru/blog/index.astro
16:06:31 └─ /ru/blog/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/ru/generators/cards.astro
16:06:31 └─ /ru/generators/cards/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/category/[category].astro
16:06:31 ├─ /ru/generators/category/gaming/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ├─ /ru/generators/category/security/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ├─ /ru/generators/category/decision-making/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ├─ /ru/generators/category/creative/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 └─ /ru/generators/category/utility/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/coin.astro
16:06:31 └─ /ru/generators/coin/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/colors.astro
16:06:31 └─ /ru/generators/colors/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/country.astro
16:06:31 └─ /ru/generators/country/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/date.astro
16:06:31 └─ /ru/generators/date/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/generators/dice.astro
16:06:31 └─ /ru/generators/dice/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/generators/emoji.astro
16:06:31 └─ /ru/generators/emoji/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+12ms)
16:06:31 ▶ src/pages/ru/generators/fontpair.astro
16:06:31 └─ /ru/generators/fontpair/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/generators/gradient.astro
16:06:31 └─ /ru/generators/gradient/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/hash.astro
16:06:31 └─ /ru/generators/hash/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/letter.astro
16:06:31 └─ /ru/generators/letter/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/list.astro
16:06:31 └─ /ru/generators/list/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/generators/lorem.astro
16:06:31 └─ /ru/generators/lorem/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/lottery.astro
16:06:31 └─ /ru/generators/lottery/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/magic8ball.astro
16:06:31 └─ /ru/generators/magic8ball/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/meal.astro
16:06:31 └─ /ru/generators/meal/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/names.astro
16:06:31 └─ /ru/generators/names/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/generators/numbers.astro
16:06:31 └─ /ru/generators/numbers/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/palette.astro
16:06:31 └─ /ru/generators/palette/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/password.astro
16:06:31 └─ /ru/generators/password/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/rps.astro
16:06:31 └─ /ru/generators/rps/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/shuffler.astro
16:06:31 └─ /ru/generators/shuffler/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/teams.astro
16:06:31 └─ /ru/generators/teams/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/time.astro
16:06:31 └─ /ru/generators/time/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 ▶ src/pages/ru/generators/uuid.astro
16:06:31 └─ /ru/generators/uuid/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/weighted.astro
16:06:31 └─ /ru/generators/weighted/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/wheel.astro
16:06:31 └─ /ru/generators/wheel/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+3ms)
16:06:31 ▶ src/pages/ru/generators/yesno.astro
16:06:31 └─ /ru/generators/yesno/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ▶ src/pages/ru/privacy.astro
16:06:31 └─ /ru/privacy/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+2ms)
16:06:31 λ src/pages/ru/rss.xml.ts
16:06:31 └─ /ru/rss.xml16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+5ms)
16:06:31 ▶ src/pages/ru/index.astro
16:06:31 └─ /ru/index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+6ms)
16:06:31 ▶ src/pages/index.astro
16:06:31 └─ /index.html16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] Cookie header: none
16:06:31 [WARN] `Astro.request.headers` is unavailable in "static" output mode, and in prerendered pages within "hybrid" and "server" output modes. If you need access to request headers, make sure that `output` is configured as either `"server"` or `output: "hybrid"` in your config file, and that the page accessing the headers is rendered on-demand.
[Middleware] No auth_token cookie found
(+4ms)
16:06:31 ✓ Completed in 1.89s.
16:06:31 [build] Rearranging server assets...
16:06:31 [@astrojs/sitemap] `sitemap-index.xml` created at `dist/client`
16:06:31 [build] Server built in 7.42s
16:06:31 [build] Complete!
+41
View File
@@ -0,0 +1,41 @@
# T18 — Data Migration Verification
## Test Setup
- Pre-populated `sessionStorage` with old-format dice history and initiative data.
- Pre-populated `localStorage` with old-format notes.
- Ran Playwright tests against `/dm/#dice`, `/dm/#initiative`, `/dm/#notes` on both desktop and mobile viewports.
## Results
### Dice History (`dm-dice-history`)
**Status:** INCOMPATIBLE
- Old format uses `result` instead of `total` and omits `rolls`.
- `renderHistory()` calls `entry.rolls.includes(20)`, which throws when `rolls` is undefined.
- The uncaught exception aborts rendering, leaving the history list empty.
- **Evidence:** Playwright test confirms empty state is visible and 0 history items rendered.
### Initiative Tracker (`dm-initiative`)
**Status:** PARTIALLY COMPATIBLE
- Old format stores `name`, `modifier`, `initiative`, `active` but lacks `id` and `hp`.
- The list renders correctly (name and initiative score display).
- **Broken:** Delete button does nothing because `deleteCombatant()` cannot match a missing `id`.
- **Evidence:** Playwright test confirms the combatant renders and survives a delete click.
### Notes (`dm-notes`)
**Status:** FULLY COMPATIBLE
- Old format stores a plain string; new `loadNotes()` reads the same key unchanged.
- Textarea populates correctly from `localStorage`.
- **Evidence:** Playwright test confirms textarea value matches old data.
## Summary
| Feature | Compatibility |
|---------|---------------|
| Dice history | Broken — missing `total`/`rolls` fields cause JS error |
| Initiative | Loads but delete is broken due to missing `id` |
| Notes | Fully compatible |
## Commands Run
```bash
npx playwright test tests/dm/data-migration.spec.ts
```
All 6 tests passed (3 scenarios × 2 viewports).
+11
View File
@@ -0,0 +1,11 @@
Running 6 tests using 6 workers
✓ 3 [chromium] › tests/dm/data-migration.spec.ts:63:3 › Data Migration › notes old data loads correctly (2.9s)
✓ 2 [chromium] › tests/dm/data-migration.spec.ts:38:3 › Data Migration › initiative old data loads with broken delete (3.7s)
✓ 1 [chromium] › tests/dm/data-migration.spec.ts:25:3 › Data Migration › dice history old data is incompatible (3.8s)
✓ 5 [mobile-chromium] › tests/dm/data-migration.spec.ts:63:3 › Data Migration › notes old data loads correctly (4.4s)
✓ 4 [mobile-chromium] › tests/dm/data-migration.spec.ts:38:3 › Data Migration › initiative old data loads with broken delete (4.5s)
✓ 6 [mobile-chromium] › tests/dm/data-migration.spec.ts:25:3 › Data Migration › dice history old data is incompatible (5.2s)
6 passed (6.8s)
+13
View File
@@ -0,0 +1,13 @@
> randify@0.0.1 test
> vitest run
RUN v4.1.5 /home/emil/Desktop/Coding/AI/Randify.pro
Test Files 10 passed (10)
Tests 148 passed (148)
Start at 16:06:50
Duration 1.10s (transform 1.38s, setup 388ms, import 1.57s, tests 283ms, environment 5.30s)
+4
View File
@@ -0,0 +1,4 @@
src/pages/rss.xml.ts(10,6): error TS7006: Parameter 'post' implicitly has an 'any' type.
src/pages/rss.xml.ts(18,25): error TS7006: Parameter 'post' implicitly has an 'any' type.
src/pages/ru/rss.xml.ts(10,6): error TS7006: Parameter 'post' implicitly has an 'any' type.
src/pages/ru/rss.xml.ts(18,25): error TS7006: Parameter 'post' implicitly has an 'any' type.
+185
View File
@@ -0,0 +1,185 @@
> randify@0.0.1 build
> astro build
02:36:15 [types] Generated 342ms
02:36:15 [build] output: "static"
02:36:15 [build] directory: /home/emil/Desktop/Coding/AI/Randify.pro/dist/
02:36:15 [build] Collecting build info...
02:36:15 [build] ✓ Completed in 368ms.
02:36:15 [build] Building static entrypoints...
02:36:17 [vite] ✓ built in 2.10s
02:36:17 [build] ✓ Completed in 2.15s.
building client (vite)
02:36:17 [vite] transforming...
02:36:17 [vite] ✓ 71 modules transformed.
02:36:17 [vite] rendering chunks...
02:36:17 [vite] computing gzip size...
02:36:17 [vite] dist/_astro/hoisted.BKKrxAht.js 0.16 kB │ gzip: 0.15 kB
02:36:17 [vite] dist/_astro/animations.JKmio82t.js 0.19 kB │ gzip: 0.13 kB
02:36:17 [vite] dist/_astro/validation.plcuGzaj.js 0.20 kB │ gzip: 0.16 kB
02:36:17 [vite] dist/_astro/clipboard.v9BZgIeL.js 0.43 kB │ gzip: 0.22 kB
02:36:17 [vite] dist/_astro/random.PhfdigkC.js 0.50 kB │ gzip: 0.31 kB
02:36:17 [vite] dist/_astro/hoisted.B5m2ZYh6.js 0.90 kB │ gzip: 0.56 kB
02:36:17 [vite] dist/_astro/hoisted.CdG8uTdI.js 1.23 kB │ gzip: 0.61 kB
02:36:17 [vite] dist/_astro/hoisted.CT9HX5_Y.js 1.38 kB │ gzip: 0.72 kB
02:36:17 [vite] dist/_astro/hoisted.Cb7Tv2oN.js 1.48 kB │ gzip: 0.83 kB
02:36:17 [vite] dist/_astro/hoisted.D82rtlIG.js 1.54 kB │ gzip: 0.84 kB
02:36:17 [vite] dist/_astro/hoisted.uArMeWBD.js 1.63 kB │ gzip: 0.81 kB
02:36:17 [vite] dist/_astro/hoisted.CwDo-_-Z.js 1.64 kB │ gzip: 0.73 kB
02:36:17 [vite] dist/_astro/hoisted.j6ibv0wb.js 1.65 kB │ gzip: 0.81 kB
02:36:17 [vite] dist/_astro/hoisted.BEwWV8JC.js 1.73 kB │ gzip: 0.90 kB
02:36:17 [vite] dist/_astro/hoisted.6rLeMLDm.js 1.74 kB │ gzip: 0.86 kB
02:36:17 [vite] dist/_astro/hoisted.DOtqogeQ.js 1.76 kB │ gzip: 0.99 kB
02:36:17 [vite] dist/_astro/hoisted.CHG7AXVP.js 1.89 kB │ gzip: 1.05 kB
02:36:17 [vite] dist/_astro/hoisted.DnGtBYme.js 1.99 kB │ gzip: 0.95 kB
02:36:17 [vite] dist/_astro/hoisted.hrxZZFEF.js 2.19 kB │ gzip: 1.07 kB
02:36:17 [vite] dist/_astro/hoisted.CjZD7f2g.js 2.33 kB │ gzip: 1.15 kB
02:36:17 [vite] dist/_astro/hoisted.qLZXl1Do.js 2.88 kB │ gzip: 1.70 kB
02:36:17 [vite] dist/_astro/hoisted.BKosNXxl.js 2.91 kB │ gzip: 1.41 kB
02:36:17 [vite] dist/_astro/hoisted.CpSL7HYx.js 3.94 kB │ gzip: 1.95 kB
02:36:17 [vite] dist/_astro/hoisted.DmqdUAAB.js 4.10 kB │ gzip: 1.70 kB
02:36:17 [vite] dist/_astro/hoisted.COsV1Syq.js 4.30 kB │ gzip: 1.96 kB
02:36:17 [vite] dist/_astro/hoisted.Ftg8tUcf.js 4.53 kB │ gzip: 1.97 kB
02:36:17 [vite] dist/_astro/hoisted.3XDY-7Px.js 4.79 kB │ gzip: 1.97 kB
02:36:17 [vite] dist/_astro/hoisted.mRfAHLMS.js 5.27 kB │ gzip: 2.20 kB
02:36:17 [vite] dist/_astro/hoisted.B7vaoHN9.js 7.19 kB │ gzip: 2.54 kB
02:36:17 [vite] dist/_astro/hoisted.DU8tsC8l.js 9.71 kB │ gzip: 3.84 kB
02:36:17 [vite] dist/_astro/i18n.DYCg5-VL.js 10.76 kB │ gzip: 5.53 kB
02:36:17 [vite] dist/_astro/hoisted.ChvQAxmv.js 10.92 kB │ gzip: 3.89 kB
02:36:17 [vite] dist/_astro/hoisted.DdCnpAKh.js 11.83 kB │ gzip: 2.76 kB
02:36:17 [vite] dist/_astro/hoisted.CvjQ9xHL.js 35.55 kB │ gzip: 17.46 kB
02:36:17 [vite] dist/_astro/hoisted.Bdx021zL.js 45.26 kB │ gzip: 14.58 kB
02:36:17 [vite] ✓ built in 438ms
generating static routes
02:36:18 ▶ src/pages/about.astro
02:36:18 └─ /about/index.html (+11ms)
02:36:18 ▶ src/pages/generators/cards.astro
02:36:18 └─ /generators/cards/index.html (+6ms)
02:36:18 ▶ src/pages/generators/coin.astro
02:36:18 └─ /generators/coin/index.html (+4ms)
02:36:18 ▶ src/pages/generators/colors.astro
02:36:18 └─ /generators/colors/index.html (+3ms)
02:36:18 ▶ src/pages/generators/country.astro
02:36:18 └─ /generators/country/index.html (+4ms)
02:36:18 ▶ src/pages/generators/date.astro
02:36:18 └─ /generators/date/index.html (+2ms)
02:36:18 ▶ src/pages/generators/dice.astro
02:36:18 └─ /generators/dice/index.html (+3ms)
02:36:18 ▶ src/pages/generators/emoji.astro
02:36:18 └─ /generators/emoji/index.html (+3ms)
02:36:18 ▶ src/pages/generators/fontpair.astro
02:36:18 └─ /generators/fontpair/index.html (+3ms)
02:36:18 ▶ src/pages/generators/gradient.astro
02:36:18 └─ /generators/gradient/index.html (+2ms)
02:36:18 ▶ src/pages/generators/hash.astro
02:36:18 └─ /generators/hash/index.html (+2ms)
02:36:18 ▶ src/pages/generators/letter.astro
02:36:18 └─ /generators/letter/index.html (+2ms)
02:36:18 ▶ src/pages/generators/list.astro
02:36:18 └─ /generators/list/index.html (+2ms)
02:36:18 ▶ src/pages/generators/lorem.astro
02:36:18 └─ /generators/lorem/index.html (+2ms)
02:36:18 ▶ src/pages/generators/lottery.astro
02:36:18 └─ /generators/lottery/index.html (+2ms)
02:36:18 ▶ src/pages/generators/magic8ball.astro
02:36:18 └─ /generators/magic8ball/index.html (+2ms)
02:36:18 ▶ src/pages/generators/meal.astro
02:36:18 └─ /generators/meal/index.html (+2ms)
02:36:18 ▶ src/pages/generators/names.astro
02:36:18 └─ /generators/names/index.html (+3ms)
02:36:18 ▶ src/pages/generators/numbers.astro
02:36:18 └─ /generators/numbers/index.html (+2ms)
02:36:18 ▶ src/pages/generators/palette.astro
02:36:18 └─ /generators/palette/index.html (+2ms)
02:36:18 ▶ src/pages/generators/password.astro
02:36:18 └─ /generators/password/index.html (+2ms)
02:36:18 ▶ src/pages/generators/rps.astro
02:36:18 └─ /generators/rps/index.html (+2ms)
02:36:18 ▶ src/pages/generators/shuffler.astro
02:36:18 └─ /generators/shuffler/index.html (+2ms)
02:36:18 ▶ src/pages/generators/teams.astro
02:36:18 └─ /generators/teams/index.html (+2ms)
02:36:18 ▶ src/pages/generators/time.astro
02:36:18 └─ /generators/time/index.html (+2ms)
02:36:18 ▶ src/pages/generators/uuid.astro
02:36:18 └─ /generators/uuid/index.html (+2ms)
02:36:18 ▶ src/pages/generators/weighted.astro
02:36:18 └─ /generators/weighted/index.html (+2ms)
02:36:18 ▶ src/pages/generators/wheel.astro
02:36:18 └─ /generators/wheel/index.html (+2ms)
02:36:18 ▶ src/pages/generators/yesno.astro
02:36:18 └─ /generators/yesno/index.html (+2ms)
02:36:18 ▶ src/pages/privacy.astro
02:36:18 └─ /privacy/index.html (+2ms)
02:36:18 ▶ src/pages/ru/about.astro
02:36:18 └─ /ru/about/index.html (+3ms)
02:36:18 ▶ src/pages/ru/generators/cards.astro
02:36:18 └─ /ru/generators/cards/index.html (+3ms)
02:36:18 ▶ src/pages/ru/generators/coin.astro
02:36:18 └─ /ru/generators/coin/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/colors.astro
02:36:18 └─ /ru/generators/colors/index.html (+3ms)
02:36:18 ▶ src/pages/ru/generators/country.astro
02:36:18 └─ /ru/generators/country/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/date.astro
02:36:18 └─ /ru/generators/date/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/dice.astro
02:36:18 └─ /ru/generators/dice/index.html (+3ms)
02:36:18 ▶ src/pages/ru/generators/emoji.astro
02:36:18 └─ /ru/generators/emoji/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/fontpair.astro
02:36:18 └─ /ru/generators/fontpair/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/gradient.astro
02:36:18 └─ /ru/generators/gradient/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/hash.astro
02:36:18 └─ /ru/generators/hash/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/letter.astro
02:36:18 └─ /ru/generators/letter/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/list.astro
02:36:18 └─ /ru/generators/list/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/lorem.astro
02:36:18 └─ /ru/generators/lorem/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/lottery.astro
02:36:18 └─ /ru/generators/lottery/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/magic8ball.astro
02:36:18 └─ /ru/generators/magic8ball/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/meal.astro
02:36:18 └─ /ru/generators/meal/index.html (+3ms)
02:36:18 ▶ src/pages/ru/generators/names.astro
02:36:18 └─ /ru/generators/names/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/numbers.astro
02:36:18 └─ /ru/generators/numbers/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/palette.astro
02:36:18 └─ /ru/generators/palette/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/password.astro
02:36:18 └─ /ru/generators/password/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/rps.astro
02:36:18 └─ /ru/generators/rps/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/shuffler.astro
02:36:18 └─ /ru/generators/shuffler/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/teams.astro
02:36:18 └─ /ru/generators/teams/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/time.astro
02:36:18 └─ /ru/generators/time/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/uuid.astro
02:36:18 └─ /ru/generators/uuid/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/weighted.astro
02:36:18 └─ /ru/generators/weighted/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/wheel.astro
02:36:18 └─ /ru/generators/wheel/index.html (+2ms)
02:36:18 ▶ src/pages/ru/generators/yesno.astro
02:36:18 └─ /ru/generators/yesno/index.html (+2ms)
02:36:18 ▶ src/pages/ru/privacy.astro
02:36:18 └─ /ru/privacy/index.html (+2ms)
02:36:18 ▶ src/pages/ru/index.astro
02:36:18 └─ /ru/index.html (+4ms)
02:36:18 ▶ src/pages/index.astro
02:36:18 └─ /index.html (+3ms)
02:36:18 ✓ Completed in 381ms.
02:36:18 [@astrojs/sitemap] `sitemap-index.xml` created at `dist`
02:36:18 [build] 62 page(s) built in 3.40s
02:36:18 [build] Complete!
+28
View File
@@ -0,0 +1,28 @@
Task 10: Custom 404 Pages (EN + RU)
Date: 2026-05-14
Status: COMPLETE
Files created:
- src/pages/404.astro
- src/pages/ru/404.astro
Files modified:
- src/i18n/translations.ts (added notFoundTitle, notFoundMessage, backToHome, blog keys)
Build verification:
- npm run build: PASS
- Total pages: 64 (62 existing + 2x 404)
- dist/404.html exists (Astro outputs root 404 as 404.html for static host compatibility)
- dist/ru/404/index.html exists
Content verified:
- EN page contains "Page Not Found"
- RU page contains "Страница не найдена"
- Both pages include breadcrumb back to home, friendly message, and links to home + blog
Key patterns used:
- BaseLayout with title/description props
- Locale detection via Astro.currentLocale
- Translation keys via useT(lang)
- Identical EN/RU template files (locale-aware links computed from lang variable)
- JSON-LD WebPage schema injected via slot="head"
@@ -0,0 +1,10 @@
Task 11: Install @astrojs/rss and set up content collections config
- Package installed: @astrojs/rss (added 9 packages, 511 total)
- File updated: src/content/config.ts
- Imported z from astro:content
- Added blog collection with type: "content"
- Blog schema fields: title (max 120), description (max 160), pubDate, modDate (optional), draft (default false), lang (en/ru), category (tutorial/guide/news/tips), tags (default []), ogImage (optional, image()), relatedGenerators (optional), relatedPosts (optional)
- Preserved existing generators collection (type: "data", schema: generatorSchema)
- Directories created: src/content/blog/en/ and src/content/blog/ru/
- Build verification: npm run build passed with 64 pages, 0 errors
+38
View File
@@ -0,0 +1,38 @@
Task 12: BlogLayout.astro with BlogPosting JSON-LD and Article OG Meta Tags
Verification: npm run build — PASSED (64 pages built)
File: src/layouts/BlogLayout.astro
Features implemented:
1. Wraps BaseLayout, passing title, description, ogImage.
2. Injects BlogPosting JSON-LD schema via slot="head" with:
- @type: BlogPosting
- headline (from title prop)
- author: Organization { name: "Randify" }
- publisher: Organization { name: "Randify", logo: ImageObject }
- datePublished (ISO 8601)
- dateModified (ISO 8601, falls back to datePublished)
- url (canonical)
- description
- inLanguage
3. OG type set to "article" via <meta property="og:type" content="article" /> in slot="head".
4. Article-specific meta tags added:
- article:published_time
- article:modified_time
5. Styled container: max-w-2xl mx-auto, matching GeneratorLayout spacing.
6. Header with title, accent dot, publication date, and conditional "Updated" label.
7. Prev/next post navigation with bilingual labels (EN/RU), arrow icons, and focus rings.
8. Named slot "related" for RelatedPosts component.
Props accepted:
- title: string
- description: string
- pubDate: Date | string
- modDate?: Date | string
- ogImage?: string
- lang?: Lang
- prevPost?: { slug: string; title: string }
- nextPost?: { slug: string; title: string }
Build output: 64 pages, 0 errors.
+7
View File
@@ -0,0 +1,7 @@
Task 13: EN blog post page ([slug].astro)
- Build: PASS (77 pages)
- Generated: dist/blog/test-post/index.html
- Verified: post title present in HTML
- Verified: BlogPosting JSON-LD schema present
- Verified: article:published_time meta tag present
- Slug derived from post.id with en/ prefix and .md extension stripped
+16
View File
@@ -0,0 +1,16 @@
Task 14: Create RU blog post page src/pages/ru/blog/[slug].astro
Build result: PASS
Pages built: 77
RU blog post page: compiled successfully (no RU blog posts yet, so no static pages generated)
EN blog post page: /blog/test-post/index.html generated
Files created/modified:
- src/pages/ru/blog/[slug].astro (created)
- src/layouts/BlogLayout.astro (fixed locale-aware prev/next links)
Verification:
- npm run build exited with code 0
- No TypeScript or Astro errors
- RU [slug].astro correctly filters getCollection("blog") by lang === "ru"
- BlogLayout prev/next navigation updated to use locale-aware paths (/ru/blog/ for RU, /blog/ for EN)
+36
View File
@@ -0,0 +1,36 @@
Task 15: Blog Index Pages — Evidence
======================================
Build Status: PASS (76 pages, exit code 0)
Files Created:
- src/pages/blog/index.astro
- src/pages/ru/blog/index.astro
Files Modified:
- src/i18n/translations.ts (added blogDesc, readMore, noPosts keys for EN + RU)
Build Output Verification:
- dist/blog/index.html (6893 bytes)
- dist/ru/blog/index.html (7342 bytes)
EN Page Features:
- Queries getCollection("blog"), filters lang === "en" and draft !== true
- Sorts by pubDate descending
- Links to /blog/[slug]/
- Date formatting: toLocaleDateString("en-US", ...)
- JSON-LD Blog schema with blogPost array
RU Page Features:
- Queries getCollection("blog"), filters lang === "ru" and draft !== true
- Sorts by pubDate descending
- Links to /ru/blog/[slug]/
- Date formatting: toLocaleDateString("ru-RU", ...)
- JSON-LD Blog schema with blogPost array
Both pages:
- Use BaseLayout with title and description props
- Include OG/Twitter Card meta tags (inherited from BaseLayout)
- Include canonical + hreflang alternates (inherited from BaseLayout)
- Show empty state "No posts yet" / "Пока нет записей." when collection is empty
- Display category badge + tag badges per post card
+20
View File
@@ -0,0 +1,20 @@
Task 16: RSS Feeds
Files created:
- src/pages/rss.xml.ts (EN feed)
- src/pages/ru/rss.xml.ts (RU feed)
File modified:
- src/layouts/BaseLayout.astro (added <link rel="alternate" type="application/rss+xml"> for both EN and RU feeds)
Build: PASS (npm run build exited 0)
Generated feeds:
- dist/rss.xml exists (287 bytes)
- dist/ru/rss.xml exists (404 bytes)
Feed content verified:
- EN: title="Randify Blog", language="en", description present, link=https://randify.pro/
- RU: title="Блог Randify", language="ru", description present, link=https://randify.pro/
Note: Feeds are currently empty because no blog posts exist in src/content/blog/ yet. When posts are added with lang="en"/"ru" and draft !== true, they will appear automatically.
+26
View File
@@ -0,0 +1,26 @@
Task 17: Category Pages for Generators
======================================
Build Result: PASS
Pages built: 76
EN Category Pages Created:
- dist/generators/category/gaming/index.html
- dist/generators/category/security/index.html
- dist/generators/category/decision-making/index.html
- dist/generators/category/creative/index.html
- dist/generators/category/utility/index.html
RU Category Pages Created:
- dist/ru/generators/category/gaming/index.html
- dist/ru/generators/category/security/index.html
- dist/ru/generators/category/decision-making/index.html
- dist/ru/generators/category/creative/index.html
- dist/ru/generators/category/utility/index.html
Verification:
- EN gaming page contains: "Gaming generators for tabletop RPGs" and generator titles (Lottery, Rock Paper Scissors, etc.)
- RU gaming page contains: "Игровые генераторы для настольных RPG" and generator titles (Колесо фортуны, Лотерея, etc.)
- All 5 categories render correctly with getStaticPaths
- Breadcrumb JSON-LD schema included on each page
- Generators filtered dynamically by category field from src/data/generators.ts
+16
View File
@@ -0,0 +1,16 @@
Task 18: Category Navigation Pills on Homepage
Files modified:
- src/pages/index.astro
- src/pages/ru/index.astro
- src/i18n/translations.ts
Build result: PASS (85 pages, 0 errors)
Verification:
- dist/index.html contains category navigation pills
- dist/ru/index.html contains localized category navigation pills
- All 5 categories present: Gaming (6), Security (3), Decision Making (4), Creative (5), Utility (10)
- Links point to /generators/category/[category]/ (EN) and /ru/generators/category/[category]/ (RU)
- Pills styled with Tailwind: rounded-full, bg-zinc-800/60, border-zinc-700/50, hover:bg-accent/20, hover:text-accent
- Responsive flex-wrap layout
@@ -0,0 +1,28 @@
Task 19: Create Breadcrumbs.astro Component — Evidence
=====================================================
1. File Created
---------------
Path: src/components/Breadcrumbs.astro
2. Component Specification
--------------------------
- Props interface: { items: Array<{ label: string, href?: string }> }
- Renders <nav aria-label="Breadcrumb"> containing <ol>
- Each item rendered as <li> with "/" separator between items
- Last item (no href or end of array): <span aria-current="page"> with text-zinc-400
- Items with href: <a> with text-zinc-500 hover:text-accent transition-colors and focus ring
- Tailwind styling: text-sm, muted zinc colors, accent hover state
3. Build Verification
---------------------
Command: npm run build
Result: PASS (64 pages built, 0 errors)
4. Example Usage
----------------
<Breadcrumbs items={[
{ label: "Home", href: "/" },
{ label: "Gaming", href: "/generators/category/gaming/" },
{ label: "Dice Roller" }
]} />
+16
View File
@@ -0,0 +1,16 @@
Task: Fix <main> landmarks on about/privacy pages
Files modified:
- src/pages/about.astro
- src/pages/ru/about.astro
- src/pages/privacy.astro
- src/pages/ru/privacy.astro
Verification:
- npm run lint: 0 errors
- npm run build: success
- grep dist for <main> on about/privacy pages: all 4 files contain <main> tag
Pattern applied:
- Breadcrumb nav and page header remain outside <main>
- Content sections wrapped in <main> following GeneratorLayout.astro pattern
+19
View File
@@ -0,0 +1,19 @@
Task 20: RelatedGenerators.astro
Files changed:
- src/components/RelatedGenerators.astro (created)
- src/layouts/GeneratorLayout.astro (updated — integrated RelatedGenerators)
- src/i18n/translations.ts (updated — added relatedGenerators key EN+RU)
Build result:
- npm run build: PASSED
- 76 pages built, 0 errors
Component behavior:
- Accepts props: currentSlug, category, optional lang
- Filters generators by category, excludes current slug, limits to 4
- Returns null (renders nothing) if no related generators exist
- Locale-aware titles and links (EN / RU)
- Compact card layout: icon + title in a responsive 2-column grid
- Uses Tailwind with existing design tokens (accent color, zinc palette)
- Includes focus-visible ring for accessibility
@@ -0,0 +1,24 @@
Task 21: RelatedPosts Component
================================
Files created:
- src/components/RelatedPosts.astro
Files modified:
- src/i18n/translations.ts (added relatedPosts key: en="Related posts", ru="Похожие статьи")
- src/pages/blog/[slug].astro (imported RelatedPosts, wired into "related" slot)
- src/pages/ru/blog/[slug].astro (imported RelatedPosts, wired into "related" slot)
Build result: PASS
- 83 pages built successfully
- No errors or warnings
Implementation details:
- Accepts post: CollectionEntry<"blog">
- Uses getCollection to fetch non-draft posts in same language
- Scores related posts by tag overlap count
- Shows top 3 posts with score > 0
- Hides section entirely if no related posts found
- Renders title, date, and description snippet for each related post
- Links use correct /blog/ or /ru/blog/ base path
- Styled with Tailwind matching existing dark theme (zinc palette, accent color)
+25
View File
@@ -0,0 +1,25 @@
Task 22: Create 8 English blog post templates
Date: 2026-05-14
Build result: PASS
Pages built: 85
Files created:
- src/content/blog/en/what-is-cryptographically-secure-randomness.md
- src/content/blog/en/how-to-create-strong-passwords.md
- src/content/blog/en/dice-notation-explained.md
- src/content/blog/en/psychology-of-randomness.md
- src/content/blog/en/rng-in-gaming.md
- src/content/blog/en/random-team-picker.md
- src/content/blog/en/color-theory-palettes.md
- src/content/blog/en/uuid-vs-sequential-ids.md
Build output confirms all 8 posts were generated alongside the existing test-post:
/blog/what-is-cryptographically-secure-randomness/index.html
/blog/how-to-create-strong-passwords/index.html
/blog/dice-notation-explained/index.html
/blog/psychology-of-randomness/index.html
/blog/rng-in-gaming/index.html
/blog/random-team-picker/index.html
/blog/color-theory-palettes/index.html
/blog/uuid-vs-sequential-ids/index.html
/blog/test-post/index.html
+20
View File
@@ -0,0 +1,20 @@
Build completed: 93 pages
RU blog posts generated (8):
- /ru/blog/what-is-cryptographically-secure-randomness/index.html
- /ru/blog/how-to-create-strong-passwords/index.html
- /ru/blog/dice-notation-guide/index.html
- /ru/blog/psychology-of-randomness/index.html
- /ru/blog/rng-in-gaming/index.html
- /ru/blog/random-team-selection/index.html
- /ru/blog/color-theory-guide/index.html
- /ru/blog/uuid-vs-sequential-ids/index.html
Files created:
- src/content/blog/ru/what-is-cryptographically-secure-randomness.md
- src/content/blog/ru/how-to-create-strong-passwords.md
- src/content/blog/ru/dice-notation-guide.md
- src/content/blog/ru/psychology-of-randomness.md
- src/content/blog/ru/rng-in-gaming.md
- src/content/blog/ru/random-team-selection.md
- src/content/blog/ru/color-theory-guide.md
- src/content/blog/ru/uuid-vs-sequential-ids.md
Build timestamp: 2026-05-14T03:08:00+03:00
+16
View File
@@ -0,0 +1,16 @@
Task 24 Evidence: Blog Navigation Link
=======================================
Build: PASS
- npm run build completed successfully (84 pages built)
Verification:
- EN blog link (/blog/) found in dist/index.html
- RU blog link (/ru/blog/) found in 38 RU pages including dist/ru/index.html
Changes made:
- Modified src/components/LanguageSwitcher.astro
- Added Blog / Блог link between language toggle and About link
- Link points to /blog/ on EN pages and /ru/blog/ on RU pages
- Used existing translation keys (blog: "Blog", blog: "Блог") from src/i18n/translations.ts
- Styled consistently with existing About/Privacy links
@@ -0,0 +1,17 @@
Task: Add Breadcrumbs component to generator and blog layouts
Date: 2026-05-14
1. npm run build
Result: PASS (93 pages built, exit code 0)
2. Grep dist/generators/dice/index.html for breadcrumb items:
- Found: Home, Gaming, Dice
- Command: grep -o 'Home\|Gaming\|Dice' dist/generators/dice/index.html
3. Grep dist/blog/test-post/index.html for breadcrumb items:
- Found: Home, Blog, Test Post
- Command: grep -o 'Home\|Blog\|Test Post' dist/blog/test-post/index.html
Files modified:
- src/layouts/GeneratorLayout.astro
- src/layouts/BlogLayout.astro
+8
View File
@@ -0,0 +1,8 @@
TASK: Fix ad placement on homepage
FILE: src/pages/index.astro
CHANGE: Moved <YandexRTB /> from before <main> to after </main>
BUILD: PASS (npm run build exited 0)
VERIFICATION:
- dist/index.html: </main> at byte 43284
- dist/index.html: yandex_rtb at byte 43335
- Order correct: True (main content before ad block)
+11
View File
@@ -0,0 +1,11 @@
Task: Add x-default hreflang to BaseLayout
Date: 2026-05-14
Verification:
- npm run build: PASS (62 pages built)
- grep dist/index.html for x-default: FOUND
<link rel="alternate" hreflang="x-default" href="https://randify.pro/">
- grep dist/generators/dice/index.html for x-default: FOUND
- grep all dist/*.html for x-default: 62 matches across 62 files
All pages now include x-default hreflang fallback pointing to the English version.
+13
View File
@@ -0,0 +1,13 @@
# Task 5 Evidence: Sitemap i18n Config
## Build Status
PASS
## Verification
File: dist/sitemap-0.xml
Contains <xhtml:link rel="alternate" hreflang="en-US"> and <xhtml:link rel="alternate" hreflang="ru-RU"> entries for all bilingual pages.
## Sample Entries
- https://randify.pro/ -> en-US + ru-RU
- https://randify.pro/about/ -> en-US + ru-RU
- https://randify.pro/generators/coin/ -> en-US + ru-RU
+31
View File
@@ -0,0 +1,31 @@
Evidence: Open Graph and Twitter Card meta tags added successfully.
Build status: PASS (npm run build completed with exit 0)
--- dist/index.html ---
<meta property="og:site_name" content="Randify">
<meta property="og:locale" content="en_US">
<meta property="og:type" content="website">
<meta property="og:title" content="Randify — Random Value Generators">
<meta property="og:description" content="Simple tools for raffles, games, and everything that needs randomness.">
<meta property="og:url" content="https://randify.pro/">
<meta property="og:image" content="https://randify.pro/og-default.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Randify — Random Value Generators">
<meta name="twitter:description" content="Simple tools for raffles, games, and everything that needs randomness.">
<meta name="twitter:image" content="https://randify.pro/og-default.jpg">
--- dist/generators/dice/index.html ---
<meta property="og:site_name" content="Randify">
<meta property="og:locale" content="en_US">
<meta property="og:type" content="website">
<meta property="og:title" content="Dice Roller — d4 d6 d20 + Full Notation | D&D Dice | Randify">
<meta property="og:description" content="Free online dice roller with full XdY+Z notation, keep/drop (4d6dl1), exploding dice (3d6!), reroll, advantage/disadvantage, and roll history. Perfect for D&D, Pathfinder, and Savage Worlds.">
<meta property="og:url" content="https://randify.pro/generators/dice/">
<meta property="og:image" content="https://randify.pro/og-default.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Dice Roller — d4 d6 d20 + Full Notation | D&D Dice | Randify">
<meta name="twitter:description" content="Free online dice roller with full XdY+Z notation, keep/drop (4d6dl1), exploding dice (3d6!), reroll, advantage/disadvantage, and roll history. Perfect for D&D, Pathfinder, and Savage Worlds.">
<meta name="twitter:image" content="https://randify.pro/og-default.jpg">
All required tags present on both pages.
+12
View File
@@ -0,0 +1,12 @@
Build output for Task 8 (Add category field to all generators + make required in schema)
Command: npm run build
Result: PASS
Key metrics:
- 64 pages built
- 0 Zod validation errors
- 0 build errors
- All 28 generator JSON files validated successfully with required category field
Timestamp: 2026-05-14
+16
View File
@@ -0,0 +1,16 @@
Organization Schema Verification
================================
Build: PASS
File modified: src/layouts/BaseLayout.astro
Organization schema found in dist/index.html:
{"@context":"https://schema.org","@type":"Organization","name":"Randify","url":"https://randify.pro","logo":"https://randify.pro/favicon.png"}
Presence verified across built pages:
- dist/index.html
- dist/ru/index.html
- dist/ru/privacy/index.html
- dist/ru/generators/yesno/index.html
- dist/ru/generators/wheel/index.html
(and all other 63 built pages)
@@ -0,0 +1,24 @@
# Color Contrast Report
## Method
Evaluated all visible text elements on mobile viewport (375x812) at /dm/. Checked computed color and background-color for contrast ratio against WCAG 2.1 AA thresholds (4.5:1 for normal text, 3:1 for large/bold text ≥18px or 14px bold).
- **PASS** | Ratio: 16.95:1 | rgb(244, 244, 245) on rgb(22, 18, 14) | font-size: 16px
- **PASS** | Ratio: 4.79:1 | rgb(255, 255, 255) on rgb(76, 117, 163) | font-size: 14px
- **FAIL** | Ratio: 3.58:1 | rgb(255, 255, 255) on rgb(252, 63, 29) | font-size: 14px
- **PASS** | Ratio: 6.93:1 | rgb(255, 255, 255) on rgb(83, 74, 183) | font-size: 14px
- **PASS** | Ratio: 6.47:1 | rgb(161, 161, 170) on rgb(34, 30, 24) | font-size: 14px
- **FAIL** | Ratio: 1.12:1 | rgb(161, 161, 170) on rgb(200, 168, 75) | font-size: 14px
- **PASS** | Ratio: 6.30:1 | rgb(244, 244, 245) on rgb(83, 74, 183) | font-size: 16px
- **PASS** | Ratio: 15.08:1 | rgb(244, 244, 245) on rgb(34, 30, 24) | font-size: 16px
- **PASS** | Ratio: 7.61:1 | rgb(200, 168, 75) on rgb(30, 25, 18) | font-size: 14px
- **PASS** | Ratio: 16.38:1 | rgb(244, 244, 245) on rgb(26, 22, 16) | font-size: 16px
- **PASS** | Ratio: 6.93:1 | rgb(255, 255, 255) on rgb(83, 74, 183) | font-size: 16px
- **PASS** | Ratio: 15.88:1 | rgb(244, 244, 245) on rgb(30, 25, 18) | font-size: 16px
- **PASS** | Ratio: 15.08:1 | rgb(244, 244, 245) on rgb(34, 30, 24) | font-size: 14px
- **FAIL** | Ratio: 2.09:1 | rgb(244, 244, 245) on rgb(200, 168, 75) | font-size: 16px
## Summary
- Total unique color combinations checked: 14
- Failures: 3
- Status: 3 contrast issues detected
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

@@ -0,0 +1,190 @@
# Keyboard Navigation Report
Tested on desktop viewport (1440x900) by pressing Tab repeatedly and capturing focus state.
## Focus 1: `A` " ← Назад к Randify " (/)
- Position: 826,18 | Size: 142x28px | Visible: true
- Outline: `1px none rgb(17, 17, 17)` (offset: 1px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgb(22, 18, 14) 0px 0px 0px 2px, rgb(83, 74, 183) 0px 0px 0px 4px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 2: `A` "VKВойти через VK" (/api/auth/login/vk)
- Position: 977,14 | Size: 158x36px | Visible: true
- Outline: `1px none rgb(46, 46, 46)` (offset: 1px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50387px, oklab(0 0 0 / 0.2) 0px 4px 6px -1px, oklab(0 0 0 / 0.2) 0px 2px 4px -2px`
- **Focus visible:** YES
## Focus 3: `A` "YВойти через Яндекс" (/api/auth/login/yandex)
- Position: 1142,14 | Size: 178x36px | Visible: true
- Outline: `1px none rgb(60, 60, 60)` (offset: 1px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.816) 0px 0px 0px 1.62858px, rgba(83, 74, 183, 0.816) 0px 0px 0px 3.25715px, oklab(0 0 0 / 0.2) 0px 4px 6px -1px, oklab(0 0 0 / 0.2) 0px 2px 4px -2px`
- **Focus visible:** YES
## Focus 4: `A` " 🎲 Кубики " (#dice)
- Position: 105,113 | Size: 260x40px | Visible: true
- Outline: `1px auto rgb(34, 34, 35)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 5: `A` " ⚔️ Инициатива " (#initiative)
- Position: 105,157 | Size: 260x40px | Visible: true
- Outline: `1px auto rgb(34, 34, 35)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 6: `A` " 📖 Справочник " (#reference)
- Position: 105,201 | Size: 260x40px | Visible: true
- Outline: `1px auto rgb(34, 34, 35)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 7: `A` " 📝 Заметки " (#notes)
- Position: 105,245 | Size: 260x40px | Visible: true
- Outline: `1px auto rgb(34, 34, 35)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 8: `A` " Монстры " (#reference)
- Position: 105,333 | Size: 260x36px | Visible: true
- Outline: `1px auto rgb(43, 43, 45)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 9: `A` " Заклинания " (#reference)
- Position: 105,373 | Size: 260x36px | Visible: true
- Outline: `1px auto rgb(43, 43, 45)` (offset: 1px)
- Ring width: ``
- Box shadow: `none`
- **Focus visible:** YES
## Focus 10: `BUTTON` " d4 "
- Position: 402,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(25, 23, 19)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.953) 0px 0px 0px 1.9058px, rgba(83, 74, 183, 0.953) 0px 0px 0px 3.81159px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 11: `BUTTON` " d6 "
- Position: 486,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(50, 44, 27)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.816) 0px 0px 0px 1.62858px, rgba(83, 74, 183, 0.816) 0px 0px 0px 3.25715px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 12: `BUTTON` " d8 "
- Position: 570,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(39, 35, 23)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50387px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 13: `BUTTON` " d10 "
- Position: 654,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(39, 35, 23)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50387px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 14: `BUTTON` " d12 "
- Position: 739,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(50, 44, 27)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.816) 0px 0px 0px 1.62944px, rgba(83, 74, 183, 0.816) 0px 0px 0px 3.25887px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 15: `BUTTON` " d20 "
- Position: 823,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(39, 35, 23)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50387px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 16: `BUTTON` " d100 "
- Position: 907,198 | Size: 76x38px | Visible: true
- Outline: `1px none rgb(39, 35, 23)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75256px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50513px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 17: `INPUT` ""
- Position: 402,280 | Size: 459x42px | Visible: true
- Outline: `1px none rgb(44, 44, 44)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(200, 168, 75, 0.875) 0px 0px 0px 3.50387px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 18: `BUTTON` "Бросить"
- Position: 868,278 | Size: 115x44px | Visible: true
- Outline: `1px none rgb(81, 81, 81)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.73) 0px 0px 0px 1.45914px, rgba(83, 74, 183, 0.73) 0px 0px 0px 2.91829px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px`
- **Focus visible:** YES
## Focus 19: `BUTTON` "Очистить"
- Position: 883,342 | Size: 100x34px | Visible: true
- Outline: `1px none rgb(44, 44, 44)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75131px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50261px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 20: `BUTTON` "
d20
"
- Position: 790,630 | Size: 79x34px | Visible: true
- Outline: `1px none rgb(58, 58, 59)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.816) 0px 0px 0px 1.62858px, rgba(83, 74, 183, 0.816) 0px 0px 0px 3.25715px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 21: `BUTTON` "+ Добавить"
- Position: 881,612 | Size: 79x52px | Visible: true
- Outline: `1px none rgb(46, 46, 46)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.875) 0px 0px 0px 1.75194px, rgba(83, 74, 183, 0.875) 0px 0px 0px 3.50387px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px`
- **Focus visible:** YES
## Focus 22: `BUTTON` "
Монстры
"
- Position: 1042,150 | Size: 129x32px | Visible: true
- Outline: `1px none rgb(17, 17, 16)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgb(22, 18, 14) 0px 0px 0px 2px, rgb(83, 74, 183) 0px 0px 0px 4px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 23: `BUTTON` "
Заклинания
"
- Position: 1171,150 | Size: 129x32px | Visible: true
- Outline: `1px none rgb(16, 16, 16)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgb(22, 18, 14) 0px 0px 0px 2px, rgb(83, 74, 183) 0px 0px 0px 4px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 24: `SELECT` " Все "
- Position: 1125,220 | Size: 154x41px | Visible: true
- Outline: `1px none rgb(58, 58, 59)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(22, 18, 14, 0.816) 0px 0px 0px 1.62858px, rgba(200, 168, 75, 0.816) 0px 0px 0px 3.25715px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Focus 25: `TEXTAREA` ""
- Position: 1063,442 | Size: 216x256px | Visible: true
- Outline: `1px auto rgb(16, 16, 16)` (offset: 0px)
- Ring width: ``
- Box shadow: `rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgb(200, 168, 75) 0px 0px 0px 1px, rgba(0, 0, 0, 0) 0px 0px 0px 0px`
- **Focus visible:** YES
## Summary
- Total unique focusable elements reached: 25
- Elements with visible focus indicator: 25
- Elements without visible focus indicator: 0
- Focus screenshots saved: 25
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Some files were not shown because too many files have changed in this diff Show More