2 Commits

Author SHA1 Message Date
m
2247c0707d docs(t-paliad-139): design lock — m signed off on all 19 §6 recommendations
m's go/no-go pass at 2026-05-06 15:58: "I agree with all your recommendations
- go." All 19 questions in §6 lock as the recommended answers verbatim.

§0 status flipped from READY-FOR-REVIEW to LOCKED. New "Locked m decisions
on §6" subsection captures the highlights inline so future readers don't
have to scan the whole table to know what's pinned.

§13 end-of-design line updated to reflect the lock.

Implementation phasing (§7) unchanged:
- Phase 1: bug fix on the 3 narrow service methods (no schema, ~400 LoC,
  ships standalone, closes the user-visible /projects/{id} "Keine Fristen"
  bug).
- Phase 2: migration 055 (partner_unit_members.unit_role,
  project_partner_units, extended can_see_project()) + DerivationService +
  frontend Team-tab subsections + /admin/partner-units unit_role tagging
  + project /settings/team Partner Units section. Independent of t-138.
- Phase 3: approval extension — canApprove + inbox SQL widening for
  derived_peer decision_kind. Gates on cronus's t-138 (currently on
  mai/cronus/inventor-dual-control @ b3401ec) landing on main.

Inventor parked. Awaiting head's coder-shift assignment.
2026-05-06 15:59:37 +02:00
m
6c41550945 docs(t-paliad-139): inventor design — hierarchy aggregation + effective team + PA derivation
Three coordinated sub-designs in one doc, scoped to m's locked constraints
(2026-05-06):

1. Surface-by-surface aggregation policy. Bug surface fix:
   /projects/{client_id} renders "Keine Fristen" because
   DeadlineService.ListForProject + AppointmentService.ListForProject +
   ProjectService.ListProjectEvents all WHERE project_id=$1 exact-match
   instead of walking paliad.projects.path descendants. The shipped t-124
   contract (projectDescendantPredicate, deadline_service.go:133 etc.)
   already aggregates correctly on the union endpoints — three legacy
   narrow paths just bypass it. Per-surface decision table for events /
   deadlines / termine / Verlauf / project tree counts / dashboard /
   CalDAV / email / search.

2. Effective-team semantics. Three structural gaps in the issue's
   premise (verified against schema):
   - No project↔unit junction (partner_unit involvement on a project).
   - No PA/lawyer distinction in partner_unit_members (no role column).
   - No lawyer↔PA pairing anywhere — Q11's "where is it stored" → nowhere.
   Proposes:
   - paliad.partner_unit_members.unit_role (lead|attorney|senior_pa|pa|paralegal),
     unit-scoped not firm-wide so 3-axis principle holds.
   - paliad.project_partner_units junction with derive_unit_roles[]
     (default {pa, senior_pa}) + derive_grants_authority bool.
   - Compute-on-read derivation via extended can_see_project() — no
     materialised state, no drift.
   - Display-effective vs visibility-effective team are different sets;
     rename ListEffectiveMembers to ListVisibilityEffectiveMembers + add
     ListSubtreeMembers.

3. Approval policy × hierarchy × derivation. Coordinates with t-138
   (cronus, mai/cronus/inventor-dual-control @ 7d1ddb9):
   - Q10: keep cronus's no-auto-inheritance, harden UX with a "Eltern-
     Politik (zur Information)" panel showing parent rules without
     applying.
   - Q12: derived members visibility-only by default; per-(project, unit)
     opt-in flag derive_grants_authority. When opted in, decision_kind
     extends with derived_peer for honest audit chronology.
   - canApprove + inbox SQL extension shape spec'd; coordinates with
     cronus's t-138 §3.4 / §7.4.

Locked m decisions surfaced in §0:
- Behaviour is surface-specific.
- Effective Team of a Client = direct ∪ descendants ∪ partner-unit-derived.
- PA derivation = unit-on-project trigger.
- Derivation honesty: annotated everywhere.
- paliad-only scope.

19 design questions with proposed answers in §6 for m to lock. Migration
055 specced (§5). Implementation phased into 3 PRs (§7) — Phase 1 bug fix
ships standalone if m wants quick win.

Inventor parked. Awaiting m go/no-go before coder shift.
2026-05-06 15:38:41 +02:00