docs: record the domain model and the Postgres/OAuth ADRs
Written while scoping #18. CONTEXT.md pins the ubiquitous language (Series, Reader, Bookmark, Progress, Latest Chapter, Poll) that the schema split and the ordering rule are argued in; the four ADRs record the decisions that follow from it, starting with Postgres over SQLite. Refs #18
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# The wire format stays flat and deliberately does not mirror the schema
|
||||
|
||||
Status: accepted
|
||||
|
||||
Storage splits a tracked series across two tables (ADR-0003), but `GET /bookmarks` and
|
||||
`PUT /bookmarks/{key}` keep emitting and accepting one **flat** JSON object with `title`,
|
||||
`cover`, `last_chapter` and `latest_chapter` as siblings — exactly the shape they had
|
||||
when there was one table. The server joins on the way out and decomposes on the way in.
|
||||
|
||||
## Why a future reader will find this surprising
|
||||
|
||||
The obvious move after splitting a table is to nest the JSON to match. Don't "fix" this.
|
||||
|
||||
**A nested payload would have broken every installed userscript instantly.** Scripts read
|
||||
`b.title` directly; moving it to `b.series.title` yields `undefined` — no error, just
|
||||
blank rows and a New Chapter signal that silently reports nothing forever. Because
|
||||
Violentmonkey updates roughly once a day per device, the migration relies on old scripts
|
||||
continuing to work during a 14-day grace window. A nested format and that grace window
|
||||
are mutually exclusive.
|
||||
|
||||
**It is also the better contract independently of compatibility.** A client rendering one
|
||||
row needs the title and the reading position together; nesting exports the re-stitching
|
||||
to every browser to mirror a decision about disk layout it should not know about. Keeping
|
||||
them separate lets storage change again later without a client release — which is the
|
||||
whole reason this ADR is worth the paragraph.
|
||||
|
||||
## Consequence
|
||||
|
||||
The flat shape is a contract, not an implementation detail. Changing the storage schema
|
||||
must not change it. It follows the rule already in force for `updated_at`: the server
|
||||
owns the truth and returns the row **as stored**, and clients adopt the response rather
|
||||
than their own payload.
|
||||
Reference in New Issue
Block a user