feat(field-guide): record-on-read wiring for the card album (FG-4) #97
No reviewers
Labels
No labels
area: arcade
area: art-studio
area: calendar
area: chapel
area: content
area: design
area: field-guide
area: infra
area: library
area: os
area: portal
area: sync
area: typing
blocked
breaking
bug
content: approved
content: changes-requested
content: drafting
content: needs-doctrinal-review
content: needs-review
dependencies
documentation
duplicate
enhancement
epic
github_actions
good first issue
help wanted
invalid
javascript
needs-triage
priority: high
priority: low
priority: medium
question
type: enhancement
type: feature
type: fix
type: perf
type: security
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Bosco/bosco!97
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/field-guide-record-on-read"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
FG-4 — Record-on-read wiring
The card album's write path. Reading a creature's Library article now quietly records a card for the active child — the first half of the album feature (the album view is FG-5).
What changed
src/lib/fieldguide/RecordOnRead.svelte— a DOM-less component that records a card once, on mount. It is:topic.category === 'creatures');onMount, not$effect, soactiveProfileis not a reactive dependency; switching profiles while an article stays open records nothing new;recordOnceis insert-if-absent — no re-timestamp);<ArticleView>at the three article hosts — the standalone routelibrary/[category]/[topic],LibraryBody, andFieldGuideBody, each inside the{#key topic.path}block.ArticleViewstays pure and state-free — the write is a host concern, not the view's.Records, not rewards
A card stores only
{ v: 1 }keyed by slug. No count, streak, percentage, or score — title/art join from live gated frontmatter at view time, so an un-approved creature can never leak a title through the album.Tests
RecordOnReadinside{#key topic.path};ArticleViewimports no state; the recorder usesonMount, never$effect.tests/e2e/album.spec.ts, reads IndexedDB directly since there's no view yet) — records one card on read; idempotent re-read keeps one card with a frozen timestamp; switching profiles without navigating writes nothing (with a positive control that a subsequent open under the new profile does record); a profileless standalone article records nothing and never crashes.Verification
Full local gauntlet green:
check(430 files, 0 errors) · lint · 168 unit · build (search index unchanged at 2) · all 5 guards (colour/external/content/provenance/offline) · 34 e2e. Hardened after a 6-lens adversarial review (0 findings survived per-finding refutation; three refuted findings were still adopted as cheap defense-in-depth: swallow best-effort write failures, lock the{#key}placement in the wiring test, guard the e2e helper against DB poisoning).Part of the v0.4.0 Field Guide epic (#92).