chore(repo): initialize planarchy workspace

This commit is contained in:
2026-03-14 14:31:09 +01:00
commit dd55d0e78b
769 changed files with 166461 additions and 0 deletions
+206
View File
@@ -0,0 +1,206 @@
# Plan: Resource Model Extensions (EID Attributes)
**Date:** 2026-03-13
**Status:** Draft
**Depends on:** Country/SAH, OrgUnit hierarchy
## Problem
The Dispo Categories file defines a rich set of EID (employee) attributes that Planarchy's Resource model currently does not cover. These attributes are needed for chargeability reporting, resource filtering, and organizational grouping.
## Current Resource Model (relevant fields)
```
Resource {
id, name, email, skills (JSONB), isActive, postalCode, federalState,
portfolioUrl, roleId, aiSummary, fte, userId, ...
}
```
## Required New Attributes
### Attributes that need DB storage
| Attribute | Type | Source | Notes |
|---|---|---|---|
| Enterprise ID | String | manual/import | ACN-style username (e.g. "a.kasperovich") |
| Country | FK → Country | manual | See plan-country-sah-fte.md |
| Metro City | FK → MetroCity | manual | See plan-country-sah-fte.md |
| Org Unit (L7) | FK → OrgUnit | manual | See plan-org-unit-hierarchy.md |
| Management Level Group | FK → ManagementLevel | manual | See below |
| Management Level | derived from group | - | Sub-level within group |
| FTE | Float | manual | Already exists, ensure 2+ decimal precision |
| Resource Type | Enum | manual | Apprentice, Employee, Freelancer, Intern, Student |
| Chg Responsibility | Boolean | manual | Default: true. Drives "Accenture" resource type derivation |
| Rolled Off | Boolean | manual | Status flag, default: false |
| Departed | Boolean | manual | Status flag, default: false |
| Client Unit | FK → Client? or String | manual | Primary client assignment for reporting |
### Attributes that are derived (no DB input)
| Attribute | Derivation Rule |
|---|---|
| Long-term absence | Derived from vacation/absence system (extended leave) |
| Chapter | Derived from OrgUnit L7 → name |
| Department | Derived from OrgUnit L6 → name |
| MV Ressource Type (reporting) | Derived: see resource type derivation rules |
### Resource Type Derivation for Reporting
The chargeability report uses a "MV Ressource Type" that differs from the stored Resource Type:
| Reporting Type | Derivation Rule |
|---|---|
| Production Studios | `chgResponsibility = true` AND country is Germany |
| Near&Offshore | Country is NOT Germany AND resource type is Employee/Freelancer |
| Accenture | `chgResponsibility = false` (regardless of country) |
| Long-term absence | Has active long-term absence flag |
These are computed at query time, not stored. An admin UI can make the country→reporting-type mapping configurable.
## Management Level Model
### New: `ManagementLevelGroup` model
```prisma
model ManagementLevelGroup {
id String @id @default(cuid())
name String @unique // "Analyst", "Consultant", "Manager", etc.
targetPercentage Float // Official chargeability target (e.g. 0.805)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
levels ManagementLevel[]
resources Resource[]
}
```
### New: `ManagementLevel` model
```prisma
model ManagementLevel {
id String @id @default(cuid())
name String @unique // "10-Senior Analyst", "11-Analyst", etc.
groupId String
group ManagementLevelGroup @relation(fields: [groupId], references: [id])
resources Resource[]
}
```
### Seed Data
| Group | Target % | Levels |
|---|---|---|
| Accenture Leadership | 36.5% | *(levels 1-4, names TBD)* |
| Senior Manager | 54.6% | 5-Associate Director, 6-Senior Manager |
| Manager | 74.7% | 7-Manager |
| Consultant | 80.8% | 8-Associate Manager, 9-Team Lead/Consultant |
| Analyst | 80.5% | 10-Senior Analyst, 11-Analyst |
| Associate | 77.0% | 12-Associate, 13-New Associate |
## Schema Changes on Resource
```prisma
model Resource {
// ... existing fields ...
enterpriseId String? @unique // ACN enterprise ID
countryId String? // FK → Country
country Country? @relation(...)
metroCityId String? // FK → MetroCity
metroCity MetroCity? @relation(...)
orgUnitId String? // FK → OrgUnit (L7)
orgUnit OrgUnit? @relation(...)
managementLevelGroupId String? // FK → ManagementLevelGroup
managementLevelGroup ManagementLevelGroup? @relation(...)
managementLevelId String? // FK → ManagementLevel
managementLevel ManagementLevel? @relation(...)
resourceType ResourceType @default(EMPLOYEE)
chgResponsibility Boolean @default(true)
rolledOff Boolean @default(false)
departed Boolean @default(false)
clientUnitId String? // Primary client for reporting
clientUnit Client? @relation("ResourceClientUnit", fields: [clientUnitId], references: [id])
}
enum ResourceType {
EMPLOYEE
FREELANCER
APPRENTICE
INTERN
STUDENT
}
```
## UI Changes
### Resource Modal Extensions
Add to `ResourceModal.tsx`:
| Field | UI Element | Notes |
|---|---|---|
| Enterprise ID | Text input | Optional, unique |
| Country | Dropdown | Required for SAH |
| Metro City | Dropdown (filtered by country) | Optional |
| Org Unit | Cascading L5→L6→L7 picker | Stores L7 |
| Management Level Group | Dropdown | Drives target % |
| Management Level | Dropdown (filtered by group) | Specific level |
| Resource Type | Dropdown (5 values) | Default: Employee |
| Chg Responsibility | Toggle | Default: on |
| Client Unit | Client picker | Primary client for reporting |
| Rolled Off | Toggle | Status |
| Departed | Toggle | Status |
### Admin: Management Level Management (`/admin/management-levels`)
- Table of management level groups with target percentages
- Nested levels within each group
- Editable target % (changes over time)
- Add/edit levels
### Resource List Enhancements
- New columns: Enterprise ID, Country, Org Unit, Management Level, Client Unit
- Filters for: Country, Org Unit (L6/L7), Management Level Group, Resource Type, Client Unit
- Status filter: active / rolled off / departed
## LCR and UCR
The Dispo file mentions LCR (Local Cost Rate) and UCR (Unit Cost Rate) but has no defined values yet. These are likely cost rates per resource used in budget calculations.
Recommendation: Add placeholder fields now, define schema when values become available.
```prisma
model Resource {
// ...
lcrCents Int? // Local Cost Rate in cents per hour
ucrCents Int? // Unit Cost Rate in cents per hour
}
```
Follows the integer-cents pattern from CLAUDE.md.
## Migration
1. Add new columns to Resource (all nullable initially)
2. Create ManagementLevelGroup + ManagementLevel tables with seed data
3. Add ResourceType enum
4. Admin populates existing resources via batch import or manual assignment
## Acceptance Criteria
- [ ] Enterprise ID field on Resource (unique, optional)
- [ ] Resource linked to Country, MetroCity, OrgUnit, ManagementLevel
- [ ] ResourceType enum with 5 values
- [ ] chgResponsibility, rolledOff, departed boolean flags
- [ ] Client Unit FK for primary client assignment
- [ ] ManagementLevelGroup with target percentages
- [ ] ManagementLevel with group membership
- [ ] Resource modal with all new fields
- [ ] Resource list with new columns and filters
- [ ] Management level admin UI
- [ ] LCR/UCR placeholder fields (integer cents)
- [ ] Reporting resource type derivation logic