Project hierarchy aggregation — child rollup, parent inheritance, per-surface policy #4
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
paliad's project model is hierarchical (Client → Litigation → Patent → Case), but most read surfaces only show direct-project rows — they don't aggregate descendants. Concrete bug m hit today: a Client project with multiple Case-level deadlines renders "Keine Fristen" on its
/projects/{client_id}page because the deadlines live on descendant Case rows, not on the Client itself.The fix is conceptually obvious — "include children" — but the right answer is surface-specific:
This issue scopes a unified inventor design covering all three axes.
Goals
/projects/{client_id}(and similar parent-level views) show aggregated child deadlines, termine, and activity — not "Keine Einträge".paliad.projects.path(ltree-style materialised path) for "all descendants of X" — no new schema axis needed if avoidable.Out of scope (v1)
Locked design constraints (m, 2026-05-06)
Open design questions (for inventor — m will answer in design pass)
Surface-by-surface aggregation policy
/projects/{id}detail page sections — Fristen / Termine / Aktivität / Verlauf — each aggregate descendants by default? Per-section toggle to narrow?/eventslist (merged Fristen + Termine) — when filtered by a project, include descendants? (Today's bug surface.)/deadlinesand/appointmentslist pages — same question. Likely answer: aggregate by default, narrow toggle.Team / membership semantics
can_see_project()already gives Client team members visibility of descendants — so (a) is the obvious read. Is that all m wants, or does (b) also apply?docs/design-approvals-2026-05-06.md) usesproject_teams.roleon the specific project carrying the deadline / termin. If a deadline lives on a Case but the policy is authored on the Client, does the policy inherit down the path? First place where hierarchy aggregation interacts with the new approval system. Inventor proposes resolution.Partner-unit-derived membership
paliad.partner_units/paliad.partner_unit_eventsmigration 027 lives in the codebase — inventor should map this.)paonly, or can it carry richer authority?associateand can be lowered topa. If a derived PA is on a project at level=pa, can they approve? The integrity question: does derivation carry the same authority as direct staffing, or is derived membership "visibility-only" while authority requires explicit roster?can_see_projectwalks down)? Or do we need to recompute derivation per descendant? (The simpler answer is yes — derivation makes you a team member at the level it derives, and visibility walks down from there.)Architecture / performance
paliad.projects.pathis ltree-shaped. The aggregation pattern isWHERE p.path <@ $ancestor_path. Inventor: confirm this scales for deadline aggregation; propose materialised counts where it doesn't.References
paliad.projects— schema withpath ltree(materialised path)paliad.can_see_project()— visibility predicate (path-walks ancestors-of)paliad.partner_units/paliad.partner_unit_events— migration 027, partner-unit infrastructure (the inventor must map this for derivation Q11)internal/services/project_service.go— current narrow queriesinternal/services/event_deadline_service.go— events read path (the surface m noticed the bug on)internal/services/visibility_predicate.go— Go mirror ofcan_see_projectdocs/design-approvals-2026-05-06.md) — interacts via Q10 + Q12Inventor brief
mai/<inventor>/inventor-hierarchy-aggregationdocs/design-hierarchy-aggregation-2026-05-06.md. Three coordinated sub-designs in one doc:/mai-coderself-load. Awaits m's explicit go on the design before any coder shift.