feat(seed): sample feed, catalogue, crews and dev persons #73

Merged
bart merged 1 commit from feature/db-seed into main 2026-09-11 12:31:25 +00:00
Owner

Description

Adds polaris seed: one command that loads a fully demoable Polaris database. It fills in the full catalogue planners and admins work against (service types, the skills they require, and reason codes covering every hold/cancel/unplan/failure/rejection kind), stands up three crews with their people, home bases and a complete week of shifts, links a technician account (and the other four LDAP dev logins) to real person rows by username, and loads the sample telematics feed document from the design doc so there's something to look at before the real ingest pipeline exists. Running the command again is a no-op — nothing gets duplicated, so it's safe to include in any dev/demo bootstrap.

Closes #14. Row PH1.6 in docs/12-implementation-plan.md.

Type of Change

  • New feature
  • Bug fix
  • Refactor / cleanup (no behaviour change)
  • Documentation
  • Chore / build / CI
  • Breaking change

Breaking Changes

None.

Test Plan

Tests green (unit + integration against a real Postgres+PostGIS via testcontainers). Also verified manually end to end outside pytest: ran the Alembic migrations against a fresh Postgres+PostGIS container, then ran polaris seed twice — the second run reported the same four applied modules and left every table's row count unchanged (3 crews, 7 crew members, 7 crew-skill links, 21 shifts, 11 persons, 4 skills, 5 service types, 6 service-type-skill links, 9 reason codes, 1 vehicle, 1 ingest record), and every audit row was written in the same transaction as its row.

Checklist

  • Conventional commit(s), one logical change per commit
  • Tests added/updated and passing
  • docs/ updated for any behavioural change (ADR added if a prior decision was reversed)
  • No hard deletes; no direct status updates outside polaris.domain
  • No business logic in routers/components
  • Migration included if the schema changed (one per PR max, reversible downgrade)
  • No new dependency without a reason in the commit body

Additional Context

This row's owned-paths list only names backend/src/polaris/seed/** and backend/tests/fixtures/feed/**, but delivering a runnable polaris seed command needs one small additive file outside that glob: backend/src/polaris/cli/seed.py (plus its test, backend/tests/unit/cli/test_seed_command.py), dropped into the existing CLI-discovery seam exactly the way PH1.4 added cli/replay_run.py — no edit to cli/__init__.py, so it can't conflict with any other branch's own new cli/*.py file. Also added new (nobody else's) test directories backend/tests/unit/seed/** and backend/tests/integration/seed/** for discovery and idempotency coverage. Posted this as a comment on #14 before opening this PR.

No schema change — this PR only inserts through the existing typed mapped classes from PH1.1/PH1.2.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LoNrSy7Reyp7evkfcdHeLX

## Description Adds `polaris seed`: one command that loads a fully demoable Polaris database. It fills in the full catalogue planners and admins work against (service types, the skills they require, and reason codes covering every hold/cancel/unplan/failure/rejection kind), stands up three crews with their people, home bases and a complete week of shifts, links a technician account (and the other four LDAP dev logins) to real `person` rows by username, and loads the sample telematics feed document from the design doc so there's something to look at before the real ingest pipeline exists. Running the command again is a no-op — nothing gets duplicated, so it's safe to include in any dev/demo bootstrap. ## Related Issues Closes #14. Row **PH1.6** in `docs/12-implementation-plan.md`. ## Type of Change - [x] New feature - [ ] Bug fix - [ ] Refactor / cleanup (no behaviour change) - [ ] Documentation - [ ] Chore / build / CI - [ ] Breaking change ## Breaking Changes None. ## Test Plan Tests green (unit + integration against a real Postgres+PostGIS via testcontainers). Also verified manually end to end outside pytest: ran the Alembic migrations against a fresh Postgres+PostGIS container, then ran `polaris seed` twice — the second run reported the same four applied modules and left every table's row count unchanged (3 crews, 7 crew members, 7 crew-skill links, 21 shifts, 11 persons, 4 skills, 5 service types, 6 service-type-skill links, 9 reason codes, 1 vehicle, 1 ingest record), and every audit row was written in the same transaction as its row. ## Checklist - [x] Conventional commit(s), one logical change per commit - [x] Tests added/updated and passing - [x] `docs/` updated for any behavioural change (ADR added if a prior decision was reversed) - [x] No hard deletes; no direct status updates outside `polaris.domain` - [x] No business logic in routers/components - [x] Migration included if the schema changed (one per PR max, reversible downgrade) - [x] No new dependency without a reason in the commit body ## Additional Context This row's owned-paths list only names `backend/src/polaris/seed/**` and `backend/tests/fixtures/feed/**`, but delivering a runnable `polaris seed` command needs one small additive file outside that glob: `backend/src/polaris/cli/seed.py` (plus its test, `backend/tests/unit/cli/test_seed_command.py`), dropped into the existing CLI-discovery seam exactly the way PH1.4 added `cli/replay_run.py` — no edit to `cli/__init__.py`, so it can't conflict with any other branch's own new `cli/*.py` file. Also added new (nobody else's) test directories `backend/tests/unit/seed/**` and `backend/tests/integration/seed/**` for discovery and idempotency coverage. Posted this as a comment on #14 before opening this PR. No schema change — this PR only inserts through the existing typed mapped classes from PH1.1/PH1.2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LoNrSy7Reyp7evkfcdHeLX
Add `polaris seed`: a demoable dataset in one idempotent command.

- `polaris/seed/<aggregate>.py` modules discovered per aggregate and applied
  in ascending `order` (`runner.py`), the same drop-in seam used by task
  handlers and scheduled jobs — adding a new aggregate needs no edit to a
  shared file.
- `catalogue.py`: skills, service types with required skills, and reason
  codes covering all five `ReasonCodeKind`s. No tooling catalogue, per ADR
  0001.
- `feed.py`: the sample FleetPulse feed document from `docs/design_document.md`
  (also checked in at `tests/fixtures/feed/fleetpulse_sample.json` for the
  future ingest pipeline's own tests), loaded as package data so `polaris
  seed` also works from the `api`/`worker` Docker image, which never gets
  `backend/tests/`.
- `crews.py`: three crews with home bases, crew-level skills, rostered
  people and a full week of shifts starting tomorrow (the default horizon).
- `dev_persons.py`: a `person` row per LDAP dev user (admin, planner,
  technician, viewer, ingest), linked by `preferred_username`; the
  technician also joins Crew Noord's roster.
- Every module looks its rows up by natural key before inserting
  (`_util.get_or_create`), so a second `polaris seed` run is a no-op.

Also adds `cli/seed.py` (the `polaris seed` subcommand, discovered the same
way `cli/replay_run.py` was by PH1.4) and tests under `tests/unit/seed/`,
`tests/integration/seed/` and `tests/unit/cli/test_seed_command.py`.

Verified end to end against a real Postgres+PostGIS: migrated database,
`polaris seed` run twice, row counts identical after the second run.

Closes #14

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoNrSy7Reyp7evkfcdHeLX
bart merged commit e62c0d7fa3 into main 2026-09-11 12:31:25 +00:00
bart deleted branch feature/db-seed 2026-09-11 12:31:25 +00:00
Sign in to join this conversation.
No reviewers
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
patrick/Polaris!73
No description provided.