Files
CapaKraken/samples/Dispov2/plan-org-unit-hierarchy.md

5.3 KiB

Plan: Org Unit Hierarchy (Level 5 / 6 / 7)

Date: 2026-03-13 Status: Draft Depends on: -

Problem

The chargeability report groups resources by a 3-level organizational hierarchy:

Level 5: Content Production (department)
  Level 6: CGI Content | CGI Technology | Creative Content Production | VFX (division)
    Level 7: Art Direction | CGI Production | 3D | IT Development | ... (chapter/team)

Every resource must be mapped to an Org Unit Level 7. Level 7 rolls up to Level 6, which rolls up to Level 5. The names of org units can change over time, so they must be editable.

CapaKraken already has a Role model, but roles represent skills/functions (e.g. "3D Artist"), not organizational placement. A person's org unit and their role are different dimensions.

Current Data

Level 5 → Level 6

Level 5 Level 6
Content Production CGI Content
Content Production CGI Technology
Content Production Creative Content Production
Content Production VFX

Level 6 → Level 7

Level 6 Level 7
CGI Content Art Direction
CGI Content Capability Development
CGI Content CGI Production
CGI Content Product Data Management
CGI Content Program/Delivery Mgmt
CGI Technology CGI Development
CGI Technology IT Development
Creative Content Production (direct, no sub-teams)
VFX 2D & Art Direction
VFX 3D
VFX Program/Delivery Mgmt & Other

Schema

New: OrgUnit model (self-referencing tree)

model OrgUnit {
  id        String    @id @default(cuid())
  name      String
  shortName String?                          // optional abbreviation
  level     Int                               // 5, 6, or 7
  parentId  String?
  parent    OrgUnit?  @relation("OrgUnitTree", fields: [parentId], references: [id])
  children  OrgUnit[] @relation("OrgUnitTree")
  sortOrder Int       @default(0)
  isActive  Boolean   @default(true)         // soft-delete for renamed/retired units
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt

  resources Resource[]                        // resources assigned to this org unit (level 7)

  @@unique([parentId, name])
}

Resource model extension

model Resource {
  // ... existing fields ...

  orgUnitId  String?
  orgUnit    OrgUnit?  @relation(fields: [orgUnitId], references: [id])
}

Constraint: A resource should only be assigned to a Level 7 org unit. The UI enforces this; the schema allows any level for flexibility.

Shared Types

// packages/shared/src/types/org-unit.ts

interface OrgUnit {
  id: string;
  name: string;
  shortName?: string;
  level: number;        // 5, 6, or 7
  parentId?: string;
  sortOrder: number;
  isActive: boolean;
}

interface OrgUnitTree extends OrgUnit {
  children: OrgUnitTree[];
}

API

Location: packages/api/src/router/org-unit.ts

Procedure Access Description
list protected Returns flat list, optionally filtered by level or parentId
getTree protected Returns nested tree structure for UI rendering
create admin Create org unit with parent reference
update admin Rename, re-parent, change sort order
deactivate admin Soft-delete (sets isActive = false)

UI

Admin: Org Unit Management (/admin/org-units)

  • Tree view showing L5 → L6 → L7 hierarchy
  • Inline editing of names (since names can change)
  • Add/remove units at each level
  • Drag-and-drop reordering within a level
  • Deactivate (not hard delete) to preserve historical data

Resource: Org Unit Assignment

  • ResourceModal.tsx gets cascading dropdowns:
    1. Level 5 (pre-filtered or single value)
    2. Level 6 (filtered by selected L5)
    3. Level 7 (filtered by selected L6) — this is what gets stored on the resource
  • Alternative: single tree picker showing full path

Chargeability Report

The report groups by L6 → L7 (see plan-chargeability-report.md). The OrgUnit tree drives the row structure of the report.

Seed Data

Seed the initial hierarchy from the Dispo Categories file:

Content Production (L5)
├── CGI Content (L6)
│   ├── Art Direction (L7)
│   ├── Capability Development (L7)
│   ├── CGI Production (L7)
│   ├── Product Data Management (L7)
│   └── Program/Delivery Mgmt (L7)
├── CGI Technology (L6)
│   ├── CGI Development (L7)
│   └── IT Development (L7)
├── Creative Content Production (L6)
│   └── Creative Content Production (L7)
└── VFX (L6)
    ├── 2D & Art Direction (L7)
    ├── 3D (L7)
    └── Program/Delivery Mgmt & Other (L7)

Migration

  1. Create OrgUnit table and seed data
  2. Add orgUnitId to Resource (nullable)
  3. Admin assigns org units to existing resources
  4. No automated backfill possible — org unit assignment is business knowledge

Acceptance Criteria

  • OrgUnit model with self-referencing parent/child tree
  • Resource linked to OrgUnit (level 7)
  • Admin UI: tree view with CRUD for all levels
  • Resource modal: cascading L5 → L6 → L7 dropdowns
  • Org unit names are editable without breaking historical references
  • Seed data for the known hierarchy
  • getTree API returns nested structure for UI