Files
CapaKraken/samples/Dispov2/plan-client-wbs-model.md
T

150 lines
4.7 KiB
Markdown

# Plan: Client Model with WBS Hierarchy
**Date:** 2026-03-13
**Status:** Draft
**Depends on:** -
## Problem
Projects need to be linked to clients for chargeability reporting, budget tracking, and organizational grouping. The Dispo Categories file defines a two-level client hierarchy:
- **WBS Master Client** — the parent organization (e.g. "BMW", "VOLKSWAGEN")
- **WBS Client Name** — the legal entity (e.g. "BMW AG", "Dr. Ing. h.c. F. Porsche AG")
Currently CapaKraken has no Client model. Projects exist independently without client attribution.
## Data
35 WBS Master Clients with their legal sub-entities. Examples:
| WBS Master Client | WBS Client Names |
|---|---|
| BMW | BMW AG |
| VOLKSWAGEN | Audi Business Innovation GmbH, Dr. Ing. h.c. F. Porsche AG, MAN Truck & Bus SE, Volkswagen AG |
| DAIMLER | antoni garage GmbH & Co. KG, Mercedes-Benz AG |
| EXOR-STELLANTIS | AUTOMOBILES PEUGEOT, FCA Italy S.p.A., Ferrari S.p.A, MASERATI SPA A SOCIO UNICO |
## Schema
### New: `Client` model (self-referencing for parent/child)
```prisma
model Client {
id String @id @default(cuid())
name String // Display name
code String? @unique // Optional short code (e.g. "BMW", "VW")
parentId String?
parent Client? @relation("ClientTree", fields: [parentId], references: [id])
children Client[] @relation("ClientTree")
isActive Boolean @default(true)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
projects Project[]
@@unique([parentId, name])
}
```
Design choice: self-referencing tree instead of separate `MasterClient` + `ClientEntity` tables. This supports:
- Two levels today (Master → Entity)
- Potential deeper nesting in the future
- Simple queries via `parentId IS NULL` for top-level clients
### Project model extension
```prisma
model Project {
// ... existing fields ...
clientId String?
client Client? @relation(fields: [clientId], references: [id])
}
```
A project links to a WBS Client Name (child level). The master client is derived via `client.parent`.
## Shared Types
```typescript
// packages/shared/src/types/client.ts
interface Client {
id: string;
name: string;
code?: string;
parentId?: string;
isActive: boolean;
sortOrder: number;
}
interface ClientWithChildren extends Client {
children: Client[];
}
interface ClientTree extends Client {
children: ClientTree[];
}
```
## API
Location: `packages/api/src/router/client.ts`
| Procedure | Access | Description |
|---|---|---|
| `list` | protected | Flat list, optionally filtered by parentId |
| `getTree` | protected | Nested tree for UI |
| `getById` | protected | Single client with parent/children |
| `create` | manager | Create client (top-level or child) |
| `update` | manager | Edit name, code, re-parent |
| `deactivate` | manager | Soft-delete |
Manager-level access (not just admin) since project managers typically need to manage client relationships.
## UI
### Client Management (`/clients` or `/admin/clients`)
- Tree view showing Master Clients → WBS Client Names
- CRUD at both levels
- Search/filter for quick lookup
- Badge showing number of linked projects per client
### Project: Client Assignment
- `ProjectModal.tsx` gets a cascading or searchable client picker:
1. Select or search Master Client
2. Select WBS Client Name under that master
- `ProjectWizard.tsx` Step 1 includes client selection
- Project list shows client name column
### Client Unit (Resource Attribute)
The chargeability report also has a "Client Unit" dimension on resources (BMW, Daimler, Porsche, etc.). This represents which client a resource is primarily assigned to. This is separate from project-client linking:
- **Project.clientId** → which client owns this project (WBS billing entity)
- **Resource client unit** → which client group the resource primarily serves (for reporting)
Resource client unit can be derived from the resource's primary assignments or set manually. This is covered in the resource extensions plan, not here.
## Seed Data
Seed the 35 master clients and their sub-entities from the Dispo Categories file. See `MandatoryDispoCategories_V3.xlsx``Project-Attr` sheet, rows 5-40.
## Migration
1. Create `Client` table with seed data (35 masters + ~50 sub-entities)
2. Add `clientId` to Project (nullable)
3. Admin links existing projects to clients
## Acceptance Criteria
- [ ] `Client` model with self-referencing parent/child tree
- [ ] Project linked to Client (WBS Client Name level)
- [ ] Client management UI with tree view
- [ ] Project modal/wizard includes client picker
- [ ] Seed data for all 35 master clients and sub-entities
- [ ] `getTree` API returns nested structure