Give every Bookmark an owner (Reader table) #30
Reference in New Issue
Block a user
Delete Branch "feat/reader-ownership"
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?
Closes #22
What
A
readerstable appears; every Bookmark belongs to one. The owner is seeded as the first and only Reader, and all existing rows are attached to them.readers(discord_id UNIQUE, token_sha256 UNIQUE, created_at).keycolumn, composite PK(reader_id, site, series_id), FK to readersON DELETE CASCADE— a duplicate Bookmark for one Reader and Series is impossible at the database level.Store.Openruns schema to 0003, seeds exactly one owner row fromOWNER_DISCORD_ID(hash = SHA-256 ofAPI_TOKEN, refreshed on every start so rotation stays current), then migrates the rest.List/Get/Upsert/DeletetakereaderID; the wirekeyis derived assite:series_idon read. Handlers act asStore.OwnerID()while the global token remains the only credential.OWNER_DISCORD_ID(required): compose, .env.example, DEPLOY.md, README.md, backend/AGENTS.md updated.Series-level methods (due queue, mark-checked, set-latest-chapter) stay unscoped deliberately: series are shared rows polled once per due cycle, and the reader_count ordering requires cross-reader visibility (ADR-0003).
Verification
go test ./...green, including new tests: seed idempotency + hash refresh, 0004 attach migration, DB-level duplicate impossibility, per-reader scoping, reader-delete cascade.Deploy note
OWNER_DISCORD_IDis required after this lands — the backend refuses to start without it. Set it to the owner's Discord snowflake (Settings → Advanced → Developer Mode → right-click name → Copy User ID).