Files
CapaKraken/samples/Dispov2/plan-utilization-categories.md
T

6.0 KiB

Plan: Utilization Categories on Projects

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

Problem

The chargeability report categorizes all work into utilization buckets. Currently CapaKraken projects have no utilization classification. Every project needs a utilization category so that hours booked against it flow into the correct reporting bucket.

Utilization Categories

From the Dispo Categories file (adapted to ACN naming):

Short Name Description
Chg Chargeable Billable client project work
BD Business Development Sales, proposals, presales activities
MD&I Market Development and Initiative R&D, innovation, market development
M&O Management and Operations Internal admin, management overhead
PD&R Personal Development and Recruitment Training, hiring, onboarding
Absence Absence & Non Standard Reduces Standard Available Hours: vacation, illness, non-standard leave

Notes from the Dispo file:

  • "Absent" and "Not available" are merged into "Absence & Non Standard"
  • "Unassigned" hours are calculated automatically (SAH minus all categorized hours)
  • Categories follow ACN naming convention

Schema

New: UtilizationCategory model

model UtilizationCategory {
  id          String    @id @default(cuid())
  code        String    @unique              // "Chg", "BD", "MD&I", etc.
  name        String                         // Full display name
  description String?                        // Editable explanation
  sortOrder   Int       @default(0)
  isActive    Boolean   @default(true)
  isDefault   Boolean   @default(false)      // One category can be the default for new projects
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt

  projects    Project[]
}

Project model extension

model Project {
  // ... existing fields ...

  utilizationCategoryId  String?
  utilizationCategory    UtilizationCategory? @relation(fields: [utilizationCategoryId], references: [id])
}

Why on Project (not on Allocation/Assignment):

  • The Dispo model maps categories to projects, not to individual time entries
  • A project is either "Chargeable" or "Business Development" — the category is a project-level attribute
  • Hours assigned to a project inherit the project's utilization category for reporting

Shared Types

// packages/shared/src/types/utilization-category.ts

interface UtilizationCategory {
  id: string;
  code: string;      // "Chg", "BD", "MD&I", "M&O", "PD&R", "Absence"
  name: string;
  description?: string;
  sortOrder: number;
  isActive: boolean;
  isDefault: boolean;
}

API

Location: packages/api/src/router/utilization-category.ts

Procedure Access Description
list protected Returns all active categories (sorted)
getById protected Single category
create admin Create new category
update admin Edit code, name, description, sort order
deactivate admin Soft-delete

UI

Admin: Utilization Category Management (/admin/utilization-categories)

  • Table listing all categories with code, name, description
  • Inline editing of name and description
  • Add new categories (for future extensibility)
  • Reorder via sort order
  • Mark one as default for new projects

Project: Category Assignment

  • ProjectModal.tsx gets a UtilizationCategory dropdown (required or defaults to "Chg")
  • ProjectWizard.tsx Step 1 includes category selection
  • Project list shows category badge

Chargeability Report

Hours are bucketed by looking up project.utilizationCategory.code:

  • Chg hours → chargeability numerator
  • BD hours → business development column
  • MD&I hours → market development column
  • M&O hours → management overhead column
  • PD&R hours → personal development column
  • Absence hours → reduce SAH (already handled by vacation system, this is the project-side booking)

Unassigned hours = SAH - sum of all categorized hours (calculated, not stored)

Absence Category and Vacation System

The "Absence & Non Standard" category overlaps with Phase 9 Vacation Pro. Relationship:

  • Vacation/illness from the vacation system reduces SAH directly (date-based)
  • An "Absence" project may additionally exist for booking non-standard absence hours
  • The chargeability calculator deducts both: vacation days (from vacation system) and hours booked to Absence-category projects

This avoids double-counting: vacation days reduce available days in SAH, while Absence-project hours capture remaining non-standard time.

Seed Data

INSERT INTO "UtilizationCategory" (code, name, description, "sortOrder", "isDefault") VALUES
('Chg',     'Chargeable',                       'Billable client project work',                    1, true),
('BD',      'Business Development',              'Sales, proposals, presales activities',            2, false),
('MD&I',    'Market Development and Initiative',  'R&D, innovation, market development',             3, false),
('M&O',     'Management and Operations',          'Internal admin, management overhead',              4, false),
('PD&R',    'Personal Development and Recruitment','Training, hiring, onboarding',                   5, false),
('Absence', 'Absence & Non Standard',             'Vacation, illness, non-standard leave (reduces SAH)', 6, false);

Migration

  1. Create UtilizationCategory table with seed data
  2. Add utilizationCategoryId to Project (nullable initially)
  3. Default all existing projects to "Chg" (or let admin assign manually)
  4. Make required once all projects are assigned

Acceptance Criteria

  • UtilizationCategory model with code, name, description
  • Project linked to UtilizationCategory
  • Admin UI for category CRUD (code, name, description editable)
  • Project modal/wizard includes category dropdown
  • Seed data for all 6 categories
  • Chargeability report buckets hours by project category
  • Unassigned hours computed as SAH minus all categorized hours