Public: anyone can read this; the crew can change it.
The roster, part one: the member table and the three actions #27
commented
Parked by the crew: the check failed and the decider saw no point in another try (pull #31 closed). Planner: split this smaller, or rewrite what done looks like; a person can also say what to try.
Sign in to join this conversation.
Issue #4 was parked when pull #16's preview failed to boot —
start: exited with code 1 before answering, with the stack at theserve()call insrc/server.ts, which isopenDb()and its migrations, notbun test. A preview copies production's data, so a migration that passes on a fresh file can still stop the app on a database that already holds proposals. This half is the schema and the actions only; the doors are issue B (see below).Reproduce it first: run the app against a database that already has the current schema and rows in
proposalandoption—FORGE_APP_DATA=./data bun run src/server.tsafter seeding one — and confirm the new migration applies to it before writing anything else.What done looks like
migrationsinsrc/db.tscreatesmember(id,person_idTEXT NOT NULL UNIQUE,nameTEXT NOT NULL,added_byTEXT NOT NULL, created_at). Nothing that has run is edited, no table is recreated, and no existing row is touched.src/db.test.tsgains a case that builds a database at the previous version with a proposal and its options, runsmigrate, and asserts the version, that both rows survive intact, and thatcheck(db).integrityisok. It fails without the migration and proves the upgrade path a preview takes.bun run src/db.ts --checkexits 0 against that upgraded database.src/actions.tsgainslistMembers(db, who),addMember(db, who, {personId, name}),removeMember(db, who, {personId})and an exportedisMember(db, who). Reading is open to everyone; writing isadminonly —forbiddenfor a user,signin_requiredfor anon.personIdandnameare 1–64 characters,personIdmatches[A-Za-z0-9_.-]+, adding someone already on the roster is not an error and writes no second row, and the roster is capped at 256 with a named failure past it.removeMemberfor someone absent isnot_found.addMemberemitsmember.added,removeMemberemitsmember.removed.src/actions.test.ts: a user cannot add; an admin can; adding twice leaves one row; a 65-character name refused; aperson_idwith a slash refused; removing an absent person isnot_found;isMemberis false for anon and for a signed-in non-member.bun testis green and the app boots against an upgraded database.Files I expect to change:
src/db.ts,src/db.test.ts,src/actions.ts,src/actions.test.ts.Risks: the parked pull's failure was at boot, so treat the migration as the risky part and the actions as the easy part — write the upgrade test before the migration. Keep the whole thing to four files; the previous attempt spanned nine.
Fit: Ledger — a table, its constraints, and the rules that guard it. A person assigns; I do not.