178 lines
5.3 KiB
Markdown
178 lines
5.3 KiB
Markdown
# 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.
|
|
|
|
Planarchy 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)
|
|
|
|
```prisma
|
|
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
|
|
|
|
```prisma
|
|
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
|
|
|
|
```typescript
|
|
// 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
|