Files
paliad/internal/db
m f7908f03ad feat(t-paliad-154) commit 1/5: migration 062 — approval_policies unit-defaults + 'none' sentinel + resolver + seed
Schema:
- ALTER paliad.approval_policies: project_id nullable, ADD partner_unit_id
  uuid REFERENCES paliad.partner_units(id) ON DELETE CASCADE.
- XOR check: exactly one of (project_id, partner_unit_id) is set.
- Replace UNIQUE composite with two partial unique indexes (one per scope).
- Extend required_role CHECK with 'none' sentinel.
- approval_role_level('none') already returns 0 via existing ELSE branch
  in 059_profession_vs_responsibility.up.sql:218 — no function update.

Resolver paliad.approval_policy_effective(project, entity_type, lifecycle):
- Step 1: project-specific row wins outright (any value, including 'none').
- Step 2: MAX(approval_role_level) across ancestor rows on project's path
  + unit-default rows for partner units attached to project. Tied levels
  break alphabetically ('ancestor' beats 'unit_default') for stable
  attribution.
- Step 3: zero rows (no candidates) — caller treats as 'no policy applies'.

Returns (required_role, source, source_id) — source ∈ {project, ancestor,
unit_default}; source_id is project_id or partner_unit_id depending.

Seed:
- 8 rows × every existing partner_unit (currently 11): deadline+appointment
  × create/update/delete = associate; complete = none.
- ON CONFLICT (partner_unit_id, entity_type, lifecycle_event)
  WHERE partner_unit_id IS NOT NULL DO NOTHING — idempotent on re-run
  (verified live: 11 units → 88 seed rows, second run is no-op).
- Safe on a DB with 0 partner_units (SELECT returns no rows).

Down migration: reverse-order. Coerces 'none' rows to 'associate' before
restoring CHECK so rollback works without data loss. Drops seeded unit
rows; preserves project rows that pre-date 062.

Validated end-to-end against the live DB inside BEGIN ... ROLLBACK; the
existing project policy (deadline:create=partner) is preserved by the
DO NOTHING clause and the partial-index scope.

Design: docs/design-approval-policy-ui-2026-05-07.md §3.1.

No RAISE EXCEPTION. No bare CSS tokens (no CSS in this commit).
2026-05-08 02:11:23 +02:00
..