Schema cleanup, publishable awards, event scopes, and a consolidated baseline #10

Merged
ngu-git-admin merged 4 commits from cleanup into main 2026-09-26 23:44:12 +01:00

Cleans up the database schema against what the code actually uses, then consolidates all migrations into one baseline file.

⚠ Deploy in two steps

Production is at v19. The branch tip replaces migrations 001–023 with a single baseline, and the runner refuses to run it over a database between v1 and v22. Deploying the tip straight onto v19 leaves the service unable to boot.

  1. Back up /var/lib/ngu/ngu.db.
  2. Deploy 7bc71ce and restart: migrations 020–023 run and production reaches v23.
  3. Deploy 625329f (the tip): v23 skips the baseline, nothing runs.

Commits

8790f86 Front page subnav: points the / subnav at the new home sections (#hero, #connect, #retreats, #calendar, #numbers).

25e592b Schema cleanup (migrations 020–023):

  • Drops people_lists, people_list_members, v_chapters, v_person_affiliations, which nothing read, and the stray src/App.tsx.save.
  • Renames event_sections → event_scopes and events.section_id → scope_id. The API sends scopes/scope_id; useEvents, EventListCards and EventCalendar take scope. Also inserts national/regional/partner, which only the retired seed created.
  • Drops events.sort_order (events sort by date now) and people.sort_order (never read by the site). Every other sort_order stays.
  • Rebuilds teams with created_at/updated_at and a touch trigger, so the teams editor gets optimistic concurrency.
  • Awards can be drafted: is_published is on the admin form, and the award list, award page, org awards and event awards leave drafts out.
  • The migration runner now turns foreign keys off around the per-file transactions and runs foreign_key_check before each commit (PRAGMA foreign_keys is a no-op inside a transaction).

7bc71ce Event order: /events and org events go oldest first, undated last, so the carousel's past events sit before the first upcoming one again.

625329f Consolidated baseline: 023_schema.sql is the whole schema as 001–023 left it, with the rationale kept beside each table. migrate() treats the first file as the baseline and refuses v1–v22 with a clear message. New migrations start at 024_.

Verification

  • A database built from the old 23 migrations and one built from 023_schema.sql compare identical: 85 schema objects (columns, types, defaults, keys, foreign-key actions, CHECKs, indexes, view and trigger SQL) and all seed rows. The comparator was checked to catch a deliberate one-constraint change.
  • 020–023 upgrade a seeded v19 database with rows, foreign keys, triggers and views intact; foreign_key_check is clean.
  • Runner guard: a v23 database is left alone; a v19 one is refused and untouched.
  • Against the real admin API on a fresh database: award draft → hidden and 404, publish → listed; team save with no or stale updated_at refused, current accepted; event order correct.
  • pnpm exec tsc clean, pnpm build passes.
  • Verified and tested - Aidan

🤖 Generated with Claude Code

Cleans up the database schema against what the code actually uses, then consolidates all migrations into one baseline file. ## ⚠ Deploy in two steps Production is at v19. The branch tip replaces migrations 001–023 with a single baseline, and the runner refuses to run it over a database between v1 and v22. Deploying the tip straight onto v19 leaves the service unable to boot. 1. Back up `/var/lib/ngu/ngu.db`. 2. Deploy **`7bc71ce`** and restart: migrations 020–023 run and production reaches v23. 3. Deploy **`625329f`** (the tip): v23 skips the baseline, nothing runs. ## Commits **8790f86 Front page subnav:** points the `/` subnav at the new home sections (#hero, #connect, #retreats, #calendar, #numbers). **25e592b Schema cleanup** (migrations 020–023): - Drops `people_lists`, `people_list_members`, `v_chapters`, `v_person_affiliations`, which nothing read, and the stray `src/App.tsx.save`. - Renames `event_sections` → `event_scopes` and `events.section_id` → `scope_id`. The API sends `scopes`/`scope_id`; `useEvents`, `EventListCards` and `EventCalendar` take `scope`. Also inserts national/regional/partner, which only the retired seed created. - Drops `events.sort_order` (events sort by date now) and `people.sort_order` (never read by the site). Every other sort_order stays. - Rebuilds `teams` with `created_at`/`updated_at` and a touch trigger, so the teams editor gets optimistic concurrency. - Awards can be drafted: `is_published` is on the admin form, and the award list, award page, org awards and event awards leave drafts out. - The migration runner now turns foreign keys off around the per-file transactions and runs `foreign_key_check` before each commit (PRAGMA foreign_keys is a no-op inside a transaction). **7bc71ce Event order:** `/events` and org events go oldest first, undated last, so the carousel's past events sit before the first upcoming one again. **625329f Consolidated baseline:** `023_schema.sql` is the whole schema as 001–023 left it, with the rationale kept beside each table. `migrate()` treats the first file as the baseline and refuses v1–v22 with a clear message. New migrations start at `024_`. ## Verification - A database built from the old 23 migrations and one built from `023_schema.sql` compare identical: 85 schema objects (columns, types, defaults, keys, foreign-key actions, CHECKs, indexes, view and trigger SQL) and all seed rows. The comparator was checked to catch a deliberate one-constraint change. - 020–023 upgrade a seeded v19 database with rows, foreign keys, triggers and views intact; `foreign_key_check` is clean. - Runner guard: a v23 database is left alone; a v19 one is refused and untouched. - Against the real admin API on a fresh database: award draft → hidden and 404, publish → listed; team save with no or stale `updated_at` refused, current accepted; event order correct. - `pnpm exec tsc` clean, `pnpm build` passes. - Verified and tested - Aidan 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ngu-git-admin added 4 commits 2026-09-26 23:42:31 +01:00
The admin-driven home dropped the #about and #events sections. The
subnav now links to what the page has: the hero, connect, retreats,
calendar and the numbers band (labelled About).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migrations 020–023, with the code that reads each:

- 020 drops people_lists, people_list_members, v_chapters and
  v_person_affiliations. Nothing queried any of them.
- 021 renames event_sections to event_scopes and events.section_id
  to scope_id, finishing what 015 described. The API sends `scopes`
  and `scope_id`, and useEvents, EventListCards and EventCalendar
  take `scope`. It also inserts national/regional/partner, which only
  the retired seed ever created: a database built from migrations
  alone had no scope for the Retreats bands.
- 022 drops events.sort_order and people.sort_order. Events now sort
  by date (upcoming soonest first, past latest first, undated last)
  on /events, org pages and the countdown. People were only ever
  sorted by sort_name on the site. Every other sort_order stays.
- 023 rebuilds teams with created_at and updated_at plus a touch
  trigger, so the teams editor gets the same optimistic concurrency
  as the other entities.

Awards can be drafted: is_published (added in 011) is on both
descriptor halves with a Publishing group, and the award list, award
page, org awards and event awards leave drafts out.

The migration runner now turns foreign keys off around the per-file
transactions and runs foreign_key_check before each commit. PRAGMA
foreign_keys is a no-op inside a transaction, so 009's warning was
right and a rebuild of a referenced table (023) couldn't be written
otherwise. CLAUDE.md is updated to match.

Also removes the stray src/App.tsx.save.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25e592b ordered /events upcoming-first, then past latest-first.
The carousel shows the list as it arrives and opens on the first
upcoming event, so past events landed after the upcoming ones and
"previous" no longer went back in time. Plain chronological order
(undated last) puts them before it again; the grid splits upcoming
from past itself, so it reads the same either way. Org pages share
the order and the carousel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
023_schema.sql is the whole database as the 23 migrations left it:
every table in its final shape (columns added by ALTER folded into
their CREATE), its indexes, the five views, the seed rows (event
scopes, the shipped front page) and the triggers, last. The reasoning
from the old files that still applies sits next to what it explains;
the rest is in git history.

A fresh database runs it and lands at v23; one already at v23 skips
it. migrate() now treats the first file as a baseline and refuses a
database between v1 and v22 with a message saying to upgrade it on
an older release first, rather than failing halfway on CREATE TABLE.
Production is at v19, so the previous commits on this branch
(020–023) have to be deployed before this one.

Checked by building a database from the old files and one from this
file and comparing them: strictness, columns, types, defaults,
nullability, keys, foreign keys and their actions, CHECK constraints,
index definitions, view and trigger SQL, and seed rows all match.

Comments that cited migration numbers now point at the schema, and
CLAUDE.md describes the baseline and where new migrations go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ngu-git-admin merged commit b10a263a90 into main 2026-09-26 23:44:12 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ngu-git-admin/NGU-Web#10
No description provided.