Files
CapaKraken/samples/Dispov2/plan-resource-extensions.md
T

7.5 KiB

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 CapaKraken'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

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

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

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.

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