component-dfaas
Component: DFAAS - Demand Forecasting as a Service
Type: Next.js 14 Application
Category: Business Intelligence / Forecasting
Status: Reference Implementation
Repository:amjad-ai-projects/DFAAS
Case: task-afcd480a-d6c8-4c76-8104-9d8d75323777
What It Does
DFAAS is an enterprise demand planning platform for high-tech electronics distribution. It provides:
- Statistical Forecasting: Multi-method forecast generation with confidence intervals
- Scenario Planning: What-if analysis with baseline/optimistic/pessimistic scenarios
- Consensus Workflow: Collaborative forecast adjustment and locking
- Exception Management: Auto-detection and triage of forecast anomalies
- Conversational AI: Claude-powered assistant with live system state context
Design Philosophy: "Autopilot First" - system runs automatically, humans manage exceptions not routine.
Why It Exists
Demand forecasting is a complex domain requiring:
- Statistical rigor (algorithms, confidence intervals, accuracy metrics)
- Human judgment (market knowledge, promotional intelligence)
- Collaboration (consensus across stakeholders)
- Exception handling (anomalies that break the model)
DFAAS demonstrates how to build an AI-augmented forecasting platform where the conversational interface has live awareness of system state.
Technology Stack
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS |
| AI | Claude API (claude-sonnet-4-20250514) |
| State | React useState (session-scoped) |
| Data | In-memory generated (demo mode) |
| Deployment | Vercel / Docker |
Key Dependencies
{
"@anthropic-ai/sdk": "latest",
"next": "14.x",
"react": "18.x",
"tailwindcss": "3.x",
"lucide-react": "icons",
"zod": "schema validation"
}Architecture
Application Structure
apps/web/
├── app/ # Next.js App Router
│ ├── api/chat/route.ts # Claude API endpoint
│ ├── dashboard/ # KPI overview
│ ├── forecast/ # Forecasting tools
│ │ ├── page.tsx # Statistical forecast
│ │ ├── scenarios/ # Scenario planning
│ │ └── consensus/ # Lock workflow
│ ├── exceptions/ # Exception workbench
│ ├── data/ # Master data management
│ ├── config/ # Hierarchies, policies
│ ├── admin/ # User management
│ ├── chat/page.tsx # Conversational UI
│ └── setup/page.tsx # Onboarding wizard
├── lib/
│ ├── data/ # Data layer
│ │ ├── schema.ts # Entity schemas + UDFs
│ │ ├── master-data.ts # Items, locations
│ │ ├── demand-history.ts # Historical + anomalies
│ │ ├── forecasts.ts # Forecast generation
│ │ ├── notifications.ts # Proactive alerts
│ │ ├── change-tracking.ts # Delta detection
│ │ └── documentation.ts # Platform docs
│ └── instrumentation/ # Logging, health
└── components/ # Reusable UICore Algorithms
Forecasting Formula
The statistical forecast is computed as:
StatisticalForecast = BaseQuantity
× SeasonalFactor
× RegionalFactor
× ChannelFactor
× YoYGrowth
× (0.9 + Random × 0.2) // ±10% noiseFactor Tables
Velocity Class → Base Quantity
| Class | Range | Description |
|---|---|---|
| A | 50-200 | Fast movers |
| B | 20-100 | Medium velocity |
| C | 5-35 | Slow movers |
| D | 1-11 | Long tail |
Region → Multiplier
| Region | Factor | Rationale |
|---|---|---|
| West | 1.25 | Tech hub concentration |
| Northeast | 1.15 | Dense urban markets |
| Southwest | 1.10 | Growth markets |
| Southeast | 1.00 | Baseline |
| Midwest | 0.90 | Stable, lower volume |
Channel → Multiplier
| Channel | Factor | Rationale |
|---|---|---|
| E-commerce | 1.30 | High growth, flash sales |
| Retail | 1.00 | Baseline |
| Wholesale | 0.80 | Bulk, lower margin |
| Enterprise | 0.60 | Contracted, predictable |
Seasonality Patterns
52-week multiplier arrays per category capturing:
- Holiday Peak (W44-52): 2x-3.5x lift
- Back-to-School (W26-35): 1.5x-2x for laptops/tablets
- Post-Holiday Slump (W1-8): 0.6x-0.8x
- Tech Launch Season (W36-44): Category-specific spikes
// Example: Gaming category (highest holiday volatility)
const gaming = [
0.9, 0.85, 0.8, 0.85, 0.9, 0.9, 0.95, 0.95, // W1-8
1.0, 1.0, 1.0, 1.0, 0.95, 0.95, 0.95, 0.95, // W9-16
1.0, 1.0, 1.0, 1.05, 1.1, 1.1, 1.05, 1.0, // W17-24
1.0, 1.0, 1.05, 1.1, 1.1, 1.05, 1.0, 1.0, // W25-32
1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, // W33-40
2.0, 2.3, 2.6, 3.0, 3.5, 3.2, 2.5, 1.8, // W41-48 (BLACK FRIDAY)
1.4, 1.2, 1.0, 0.95 // W49-52
]Confidence Intervals
// Confidence decays over forecast horizon
confidence = BaseMethodAccuracy - (weekOffset × 0.008) ± random(0.1)
// Bounds calculation
errorMargin = (1 - confidence) × 1.5
lowerBound = forecast × (1 - errorMargin)
upperBound = forecast × (1 + errorMargin)Forecast Methods
| Method | Accuracy | Suitable For |
|---|---|---|
| ml-ensemble | 82% | Year-round stable |
| prophet | 80% | Holiday, seasonal |
| exponential-smoothing | 78% | General purpose |
| arima | 75% | Trend + seasonal |
| seasonal-naive | 72% | Strong patterns |
| moving-average | 70% | Baseline fallback |
Method selection is automatic based on item's seasonality attribute.
Data Model
Entity Schemas
ItemSchema (Products/SKUs)
interface ItemSchema {
// Identity
id: string
sku: string
name: string
// Hierarchy
categoryId: string
subcategoryId?: string
brandId?: string
divisionId?: string
// Classification
status: 'active' | 'new' | 'discontinued' | 'seasonal' | 'on-hold'
velocityClass: 'A' | 'B' | 'C' | 'D' | 'X'
lifecycleStage: 'introduction' | 'growth' | 'maturity' | 'decline'
// Forecasting
forecastMethod?: 'statistical' | 'ml' | 'manual' | 'hybrid'
seasonalityPattern?: 'none' | 'weekly' | 'monthly' | 'quarterly' | 'annual'
includeInForecast: boolean
// Extensibility
udfValues: UDFValue[] // Unlimited custom fields
}ForecastTransactionSchema
interface ForecastTransactionSchema {
// Keys
itemId: string
locationId: string
forecastDate: string
// Forecast Layers
statisticalForecast: number // Algorithm output
adjustedForecast?: number // Planner modifications
consensusForecast?: number // Team agreement
finalForecast?: number // Locked for planning
// Confidence
confidenceLevel?: number
lowerBound?: number
upperBound?: number
// Workflow
status: 'draft' | 'reviewed' | 'approved' | 'locked' | 'superseded'
lockedAt?: string
lockedBy?: string
// Scenarios
scenarios: {
baseline: number
optimistic: number
pessimistic: number
promotional?: number
}
}UDF System
User Defined Fields allow unlimited extensibility:
type UDFDataType =
| 'string' | 'number' | 'boolean'
| 'date' | 'datetime'
| 'currency' | 'percentage'
| 'email' | 'url' | 'phone'
| 'json' | 'array' | 'enum'
interface UDFDefinition {
id: string
name: string
displayName: string
dataType: UDFDataType
entityType: 'item' | 'location' | 'transaction' | 'forecast'
isRequired: boolean
isSearchable: boolean
isFilterable: boolean
validationRules?: UDFValidationRule[]
enumOptions?: string[] // For dropdowns
}Exception Detection
Exception Types
| Type | Severity | Trigger |
|---|---|---|
stockout-risk |
Critical | Inventory < safety stock |
accuracy-drop |
Critical/High | Accuracy < 65% |
bias-alert |
High | Bias > ±8% |
demand-spike |
High/Medium | Actual > forecast × 1.5 |
demand-drop |
Medium | Actual < forecast × 0.5 |
consensus-needed |
High | Unlocked near horizon |
new-item |
Low | < 8 weeks history |
volatility |
Medium | High CV |
forecast-override |
Low | Manual change detected |
Impact Scoring
Exceptions are scored 0-100 to determine surfacing priority:
function calculateImpactScore(anomaly) {
let score = 0
// 40% weight: Severity
score += { critical: 40, high: 30, medium: 20, low: 10 }[severity]
// 30% weight: Deviation magnitude
score += Math.min(Math.abs(deviation) * 5, 30)
// 15% weight: Type factor
if (type === 'stockout') score += 15
else if (type === 'spike' && deviation > 3) score += 12
// 15% weight: Recency
if (daysSince <= 7) score += 15
else if (daysSince <= 14) score += 10
return Math.min(score, 100)
}Auto-Resolution Rules
function canAutoResolve(anomaly): boolean {
// Low severity + small deviation
if (severity === 'low' && Math.abs(deviation) < 2) return true
// Historical (>4 weeks old, non-critical)
if (daysSince > 28 && severity !== 'critical') return true
// Holiday season spikes (expected)
if (type === 'spike' && weekNumber >= 48 && severity !== 'critical') return true
return false
}Live Context Assembly [fence-candidate:context-builder]
This is the key pattern for conversational AI integration.
The chat API builds a dynamic system prompt at request time:
// api/chat/route.ts
function buildSystemPrompt(): string {
// 1. Pull live metrics
const kpis = getDashboardKPIs()
const accuracyByCategory = getAccuracyByCategory()
const accuracyByRegion = getAccuracyByRegion()
const exceptions = generateExceptions()
// 2. Filter to actionable items
const openExceptions = exceptions.filter(e =>
e.status === 'open' || e.status === 'in-progress'
)
const criticalExceptions = exceptions.filter(e =>
e.severity === 'critical' && e.status === 'open'
)
// 3. Assemble context sections
return `You are an AI assistant for DFAAS...
## Current System State
### Business Overview
- **Total Items**: ${dataSummary.totalItems.toLocaleString()}
- **Total Locations**: ${dataSummary.totalLocations}
- **Categories**: ${categories.map(c => c.name).join(', ')}
### Current KPIs
- **Forecast Accuracy**: ${kpis.forecastAccuracy.value}% (Target: ${kpis.forecastAccuracy.target}%)
- **Forecast Bias**: ${kpis.avgBias.value}%
- **Open Exceptions**: ${openExceptions.length} (${criticalExceptions.length} critical)
### Accuracy by Category
${accuracyByCategory.map(c =>
\`- ${c.category}: ${c.accuracy}% (${c.trend})\`
).join('\n')}
### Top Open Exceptions
${openExceptions.slice(0, 10).map(e =>
\`- [${e.severity.toUpperCase()}] ${e.type}: ${e.entityName}\`
).join('\n')}
## Quick Reference
${quickReference.resolveException}
${quickReference.runForecast}
...
## Role-Specific Guidance
${roleGuidance[userRole]}
## Platform Documentation
${platformDocumentation}
`
}Context Sections Pattern
| Section | Purpose | Update Frequency |
|---|---|---|
| System State | Live KPIs, counts | Every request |
| Accuracy Metrics | By dimension | Every request |
| Open Exceptions | Actionable items | Every request |
| Quick Reference | How-to snippets | Static |
| Role Guidance | Workflow by role | Static |
| Documentation | Full platform docs | Static |
Fence Candidates for MCP
# Proposed fences to replicate this pattern
context-snapshot:
description: "Build live system state summary for AI context"
params:
- include_kpis: boolean
- include_exceptions: boolean
- exception_limit: number
- include_accuracy: boolean
returns: markdown
role-guidance:
description: "Get workflow guidance for a specific role"
params:
- role: enum[planner, analyst, manager, admin]
returns: markdown
quick-reference:
description: "Get how-to snippet for common task"
params:
- task: enum[resolve-exception, run-forecast, lock-forecast, ...]
returns: markdown
exception-summary:
description: "Get prioritized exception list"
params:
- severity: enum[critical, high, medium, low, all]
- limit: number
- include_auto_resolved: boolean
returns: structuredWorkflows
Forecast Lifecycle
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Statistical │ -> │ Adjusted │ -> │ Consensus │ -> │ Locked │
│ Forecast │ │ Forecast │ │ Forecast │ │ Forecast │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
Algorithm Planner Team Review Final for
Generated Judgment Agreement PlanningLock Mechanics
// First 4 weeks: 80% lock probability (near-term)
// Weeks 5-8: 50% lock probability (medium-term)
// Weeks 9+: Unlocked (subject to revision)
if (weekIndex < 4) {
lockProbability = 0.8
} else if (weekIndex < 8) {
lockProbability = 0.5
} else {
lockProbability = 0
}Exception Resolution
Detect → Classify → Score → Route
↓
┌───────────┴───────────┐
↓ ↓
Auto-Resolve Human Review
(low impact) (high impact)
↓ ↓
Archive Action → ResolveUI Components
Chat Interface
interface Message {
id: string
role: 'user' | 'assistant'
content: string
artifacts?: Artifact[] // Structured data panels
proposedActions?: ProposedAction[] // Executable suggestions
timestamp: Date
}
interface Artifact {
type: 'grid' | 'chart' | 'list' | 'summary'
title?: string
data: any
}
interface ProposedAction {
action_id: string
type: string // 'create_override' | 'run_forecast' | ...
description: string
details: any
requires_confirmation: boolean
}Suggested Queries (Prompt Starters)
const suggestedQueries = [
'Show me items with forecast accuracy below 70%',
'What are the top 10 exceptions this week?',
'Run forecast for Northeast region',
'Add 15% uplift for Beverages in Q2',
'Compare baseline vs consensus scenario',
'Why is bias high in Electronics?',
]Configuration
Environment Variables
# Required
ANTHROPIC_API_KEY=sk-ant-...
# Optional
NODE_ENV=development|productionOnboarding Wizard Steps
- welcome - Introduction
- company - Company profile (name, industry, timezone, fiscal year)
- branding - Logo + color theme (optional)
- authentication - SSO providers (Microsoft, Google, Email)
- hierarchies - Product/Location hierarchy definition
- master-data - CSV upload for items/locations
- history - Demand history upload (52+ weeks)
- forecasting - Horizon, frequency, auto-forecast toggle
- users - Team invitations + role assignment
- review - Summary + launch
Accuracy Metrics
Calculation by Dimension
// Base accuracy: 76%
let accuracy = 76
// Category adjustments
if (category === 'accessories') accuracy += 5 // Very predictable
if (category === 'networking') accuracy += 4 // Stable B2B
if (category === 'smartphones') accuracy -= 3 // Tech cycles
if (category === 'gaming') accuracy -= 5 // Most volatile
// Channel adjustments
if (channel === 'retail') accuracy += 2
if (channel === 'ecommerce') accuracy -= 3 // Flash sales
if (channel === 'enterprise') accuracy += 3 // Contracted
// Region adjustments
if (region === 'west') accuracy += 1 // Tech hub
if (region === 'midwest') accuracy += 2 // StableKPI Definitions
| Metric | Formula | Target |
|---|---|---|
| Forecast Accuracy | 100 - WMAPE | 80% |
| Forecast Bias | Mean(Actual - Forecast) / Mean(Actual) | 0% |
| MAPE | Mean( | Actual - Forecast |
| Consensus Locked | Locked / Total (next 4 weeks) | 95% |
Data Volumes (Demo)
| Entity | Count |
|---|---|
| Categories | 12 |
| Subcategories | 68 |
| Items (SKUs) | ~700 |
| Locations | 28 |
| Regions | 5 |
| Channels | 4 |
| History | 104 weeks (2024-2025) |
| Forecast | 52 weeks (2026) |
Related Patterns
- Live Context Assembly: Dynamic system prompt construction
- Impact Scoring: Prioritization algorithm for exceptions
- Auto-Resolution: Rules-based exception handling
- Confidence Decay: Forecast reliability over time horizon
- Scenario Modeling: What-if analysis with factor adjustments
Reconstruction Notes
To rebuild DFAAS from this spec:
- Data Layer First: Implement
schema.tswith UDF support - Forecast Engine: Port the formula + seasonality arrays
- Exception Detection: Implement scoring + auto-resolve rules
- Context Builder: The
buildSystemPrompt()function is key - UI Last: Standard Next.js patterns throughout
The conversational interface's value comes from the live context assembly - ensure the AI always knows current system state.
Slots
North
slots:
- slug: beye-ai-one-pager
context:
- Linking DFAAS to parent Beye AI documentationSouth
slots:
- slug: fence-conversational-context
context:
- Linking fence spec to its source implementationEast
slots:
- slug: dfaas-wanderland-mapping
context:
- Linking component spec to its Wanderland implementation mappingWest
slots: []Provenance
Document
- Status: 🔴 Unverified
Changelog
- 2026-01-25 19:14: Node created by mcp - Creating component documentation for DFAAS demand forecasting application - extracting patterns for Wanderland port, especially the live context assembly for conversational AI