Files
CapaKraken/docs/estimating-extension-design.md

14 KiB

Estimating Extension Design

Date: 2026-03-13 Related workbook: samples/CGIBreakdown_Template/Template_CGI-Breakdown+Calc_25Dez_V0.976_251212_beta_LCR-Update.xlsx Purpose: Canonical design, field mapping, and implementation plan for a browser-based estimating system in CapaKraken.

Executive Summary

The workbook is not a simple calculator. It is a full estimating and pricing system with:

  • project and commercial assumptions
  • scope breakdown for shots and assets
  • roster and rate lookups
  • phased effort and cost calculations
  • management summaries
  • downstream export sheets

CapaKraken can support this, but not by copying Excel cell logic into the browser. The right implementation is a dedicated estimating bounded context with:

  • a wizard for first-pass estimate creation
  • a workspace for iterative revisions
  • a typed calculation pipeline
  • live linkage to CapaKraken resources and roles
  • immutable snapshots for auditability

Design Principles

1. Do not emulate Excel

The workbook contains very large formula surfaces, including roughly 823k formula cells in CALC_AUX alone. Rebuilding that as browser spreadsheet emulation would preserve the current maintenance problem instead of solving it.

The replacement should be:

  • typed
  • stage-based
  • versioned
  • testable
  • explainable

2. Reuse the current platform where it already fits

Useful existing CapaKraken primitives:

  • Resource for roster, rates, skills, availability, and dynamic metadata
  • Project for schedule, budget, and project linkage
  • Role for assignment and capability alignment
  • blueprint-driven fields for temporary bridge data where first-class models do not yet exist

3. Keep estimating separate from operational staffing

Estimating answers:

  • what work is assumed
  • what rates and policies apply
  • what cost, price, and margin result

Operational planning answers:

  • who is actually assigned
  • when capacity is consumed
  • how delivery is staffed in reality

DemandRequirement and Assignment are downstream execution data, not the primary estimating store.

Product Shape

Estimate Wizard

The wizard should generate the first complete draft through structured steps:

  1. Opportunity and project shell
  2. Scope breakdown
  3. Commercial assumptions
  4. Staffing strategy
  5. Rate and resource matching
  6. Financial review
  7. Export and approval

Estimate Workspace

After the wizard, the user should move into a workspace with tabs:

  • Overview
  • Scope Breakdown
  • Assumptions
  • Rates & Resources
  • Staffing / Phasing
  • Financials
  • Exports
  • Version Compare

This replaces the giant spreadsheet with a clearer domain-oriented UI.

Workbook Domains

The analyzed workbook combines several distinct domains:

  • input and assumption sheets such as ProjectInfo, Shots&Assets_Breakdown, ratesBreakdown, and Ressource Roster MASTER
  • reference catalogs such as ExperienceAdjust, Packages, IT Rate card, machine_rates, FX, and Rates ACN
  • derived engine sheets such as Calculation, CALC_AUX, 4Dispo, SAP Phasing, and MMP Import
  • management and reporting views such as Overview_*, Cockpit, Analytics, and Per Year

That mix is exactly why the app needs separated models for assumptions, scope, demand, rates, snapshots, outputs, and exports.

Proposed Domain Model

New bounded context: Estimating

Model Purpose
Estimate Top-level estimate container tied to a project or opportunity
EstimateVersion Versioning, options, baselines, approvals, and locked commercial states
EstimateAssumption Structured commercial, tax, pricing, and scenario inputs
ScopeItem Scope rows imported or authored from the breakdown sheet
ScopeEffortRule Rules that turn scope into discipline effort
EstimateDemandLine Normalized effort lines with phasing and pricing attributes
RateCard Versioned pricing and cost catalog
RateCardLine Attribute-based rate resolution entries
ResourceCostSnapshot Immutable copy of roster/rate facts used by one estimate version
EstimateMetric Persisted derived totals for fast reads and auditability
EstimateExport Stored export artifacts and serializer metadata

Reuse strategy

Existing model Reuse level How it fits
Project Direct Parent linkage, timeline context, budget bridge
Resource Direct Roster, chapter, role, LCR/UCR, skill and availability context
Role Direct Demand-line role alignment and staffing suggestions
DemandRequirement / Assignment Downstream Planning handoff target after estimate approval
dynamicFields / blueprints Bridge only Short-term bridge for unmigrated metadata, not core estimate storage

Mapping Strategy

Mapping legend

  • Direct: already maps to an existing first-class CapaKraken field
  • Bridge: can be bridged short-term, but should move to estimating models
  • Derived: calculate it, do not persist it as manual source data
  • New Model: requires estimating schema

Project and commercial inputs

Workbook field Current target Status Recommended target
Project Name Project.name Direct keep on Project, mirror into Estimate.name
Opportunity ID project dynamic field Bridge Estimate.opportunityId
Timeframe From / To Project.startDate / Project.endDate Direct default estimate context from project
Currency project/resource bridge only Bridge Estimate.baseCurrency
Contract Owner / Business Unit / Service Group none New Model EstimateAssumption.*
Pricing Structure partly Project.orderType Bridge EstimateAssumption.pricingStructure
Revenue Timing / Recognition none New Model EstimateAssumption.*
Sales Tax / Billing Arrears / Payment Terms none New Model EstimateAssumption.*
Contingency / Capital Charge / Mgmt Fee policies none New Model EstimateAssumption.*

Scope breakdown inputs

Workbook field Current target Status Recommended target
Row sequence, type, package none New Model ScopeItem.sequenceNo, scopeType, packageCode
Description, scene, page, location coarse project notes only New Model ScopeItem.*
Assumptions / comments none New Model ScopeItem.assumptionCategory, internalComments
Resolution / FPS / aspect / shot length project dynamic fields only Bridge ScopeItem.technicalSpec JSON
Frame count / count / unit mode limited bridge only Bridge ScopeItem.frameCount, count, unitMode
Discipline effort columns none New Model generated EstimateDemandLine rows
Total costs on the breakdown sheet none Derived EstimateMetric

Resource, rate, and lookup data

Workbook field Current target Status Recommended target
Roster employee/name Resource.displayName / eid Bridge link to Resource plus snapshot source text
UCR / LCR Resource.ucrCents / lcrCents Direct direct reuse plus snapshot
FTE indirect only Bridge ResourceCostSnapshot.fte
Level / work type / area dynamic fields only Bridge normalize later, snapshot now
Location / country dynamic bridge only Bridge snapshot + demand-line attributes
Rates ACN / rate breakdown / machine / FX none New Model RateCard, RateCardLine, FX/rule tables
Experience adjustments none New Model rate adjustment rules

Calculation, phasing, and exports

Workbook field group Current target Status Recommended target
Calculation line items none New Model EstimateDemandLine
Named resource references Assignment.resourceId via planning handoff Direct linked demand line + resource snapshot
Dates, hours, bill code, org unit, economic profile none New Model EstimateDemandLine.*
Monthly spread none New Model EstimateDemandLine.monthlySpread
Weekly phasing (4Dispo) none Derived generated projection view
CALC_AUX transformed outputs none Derived derived from demand lines and snapshots
MMP Import / external export sheets none New Model serializer output + EstimateExport
Cockpit / analytics totals none Derived persisted EstimateMetric rows

Browser Architecture

Calculation engine

Implement a typed calculation pipeline in packages/engine:

  1. validate assumptions and scope
  2. resolve effort rules into demand lines
  3. resolve roster/rate snapshots
  4. calculate phased costs, prices, and metrics
  5. materialize outputs for UI and export

This should be deterministic and test-first. Manual overrides must be explicit and traceable.

Resource-connected behavior

The browser system can stay dynamic and resource-connected if it uses two data modes at once:

  • live links to Resource and Role for current matching and suggestion UX
  • immutable snapshots on EstimateVersion for pricing, auditability, and approval history

That prevents old approved estimates from changing when roster rates or metadata are edited later.

Implementation Plan

Phase 1. Schema and contracts

  • add Estimate, EstimateVersion, EstimateAssumption, ScopeItem, EstimateDemandLine, RateCard, RateCardLine, ResourceCostSnapshot, EstimateMetric, and EstimateExport
  • define DTOs and use cases in packages/application
  • create engine contracts and test fixtures

Phase 2. Wizard and workspace

  • build the estimate wizard
  • add estimate workspace routes and tabs
  • support import from workbook-derived source data where useful

Phase 3. Calculation and pricing

  • implement rule engine for scope-to-effort conversion
  • add rate resolution and cost/price calculations
  • persist metrics and audit trail

Phase 4. Resource linkage and planning handoff

  • connect demand lines to resources, roles, and availability
  • add staffing suggestions from current CapaKraken data
  • support conversion from approved estimate demand into downstream planning entities

Phase 5. Exports and approvals

  • generate external export formats
  • add version compare, lock, approval, and audit views

Current Status

This is no longer design-only.

Implemented baseline in the current codebase:

  • estimating Prisma schema and enums
  • shared estimate types and validation schemas
  • engine-level summary metric helper
  • application-layer estimate creation and retrieval use-cases
  • estimate API router registration
  • estimates list route and first estimate creation wizard
  • estimate workspace detail route with overview, assumptions, scope, staffing, versions, and exports tabs
  • working-draft editor for overview, assumptions, scope, and staffing
  • version submit, approve, and locked revision-cloning actions
  • export artifact scaffolding with stored serializer metadata records
  • format-specific export generation with stored payloads for JSON, CSV, XLSX, SAP, and MMP
  • live resource-linked staffing rows that can sync current CapaKraken rates and persist estimate-version snapshots
  • explicit live-vs-manual rate mode metadata on demand lines, with server-side recalculation before metrics are persisted
  • read-only and draft workspace visibility for manual overrides versus live resource snapshots
  • project snapshot persistence on estimate versions
  • approved-version planning handoff into downstream DemandRequirement and Assignment records, with estimate lineage metadata
  • scope import from XLSX in the estimate wizard
  • financials tab in the estimate workspace with summary cards, cost-to-price bridge, chapter breakdown, and monthly phasing
  • rate cards with per-client association and client filter in the admin UI

Still open:

  • estimate templates and cloning for recurring project types
  • richer version comparison (side-by-side diff of demand lines and metrics)
  • approval email notifications
  • scope-to-effort rule engine (currently manual demand lines only)
  • rate adjustment rules and experience multipliers

Planning Handoff Model

The demand/assignment persistence split is complete. The legacy Allocation table has been dropped.

Current behavior

Approved estimate versions hand off like this:

  1. one DemandRequirement is created per normalized estimate demand line
  2. if a linked resource is valid, an Assignment is created linked to that demand
  3. if no valid resource is available, the demand stays open with the suggested resource stored in metadata
  4. estimate provenance is preserved on both records through estimateHandoff metadata

Estimate-to-planning mapping

Estimate source DemandRequirement target Assignment target Notes
Estimate.projectId + approved version projectId projectId direct
EstimateDemandLine.id metadata.estimateHandoff.estimateDemandLineId same provenance
EstimateDemandLine.name role or demand title copied display metadata readable context
EstimateDemandLine.roleId roleId optional copied roleId direct when present
EstimateDemandLine.resourceId metadata.suggestedResourceId when open resourceId when assigned demand vs assignment split eliminates nullable-resource ambiguity
EstimateDemandLine.hours + project window hoursPerDay, percentage, headcount hoursPerDay, percentage reused derivation logic
EstimateDemandLine.fte headcount not needed demand owns quantity
rate and price totals metadata snapshot metadata snapshot preserve auditability
staffing attributes / monthly spread metadata metadata direct carry-over

The workbook mapping is feasible. The estimating product covers wizard creation, workspace editing, version management, export generation, and planning handoff. Remaining work focuses on templates, richer comparison, and the scope-to-effort rule engine.