Enterprise scaling starts by identifying new business boundaries, compliance needs, load, and organizational ownership.
Course navigationPhase 36⌄
TaskFlow -> Enterprise Systems
Generalize TaskFlow patterns into larger enterprise systems while preserving modular boundaries, workflows, auditability, integration reliability, and migration paths.
Phase outcome and project increment
Learning outcome
Generalize TaskFlow patterns into larger enterprise systems while preserving modular boundaries, workflows, auditability, integration reliability, and migration paths.
Concrete deliverable
Enterprise expansion blueprint for an HRIS/procurement/inventory/payroll-style system with modules, workflows, events, audit, and scaling triggers.
Principles to keep while coding
Keep the modular monolith viable until scale or team boundaries justify distributing the system.
Add queues, caches, services, and orchestration only for concrete bottlenecks or ownership needs.
Design replaceable infrastructure interfaces so managed services can evolve without rewriting core business rules.
Guided phase lab
Do these in order. Each step should end with evidence before the next one starts.
- 01
Choose one enterprise domain and identify business capabilities before choosing services/databases.
- 02
Design modules with explicit ownership and public interfaces inside a modular monolith.
- 03
Model one long-running approval as a state machine with actors, transitions, evidence, and audit records.
- 04
Identify a transaction that crosses an integration boundary and design an outbox/event handoff.
- 05
Separate synchronous user requests from background work such as reports, imports, notifications, or payroll runs.
- 06
Write concrete scaling triggers that would justify extracting a service, queue, cache, or separate database later.
Failures you should know how to diagnose
Microservices before module boundaries are understood
Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.
Boolean fields replacing explicit workflow states
Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.
Dual writes to database and message broker without reliability design
Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.
Shared database tables with unclear ownership across domains
Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.
Lessons
The source chapters come first. Every phase now ends with a guided build, a debugging workshop, and an independent challenge so reading turns into transferable skill.
Modular Monolith and Domain Boundaries
Modular Monolith First: Domain Boundaries A growing system should first become modular in code and data ownership. A modular monolith keeps one deployment while giving each business capabili
Enterprise Domain Decomposition Blueprints
Domain Decomposition Blueprints TaskFlow concepts transfer into enterprise domains, but the nouns and invariants change. Model the business capability first, then reuse the architectural pat
Approval Workflows and Long Running Processes
Approval Workflows and Long-Running Processes Enterprise systems contain processes that live longer than one HTTP request. Model the workflow explicitly instead of scattering booleans such a
Audit Trails History and Effective Dates
Audit Trails, History, and Effective Dates Enterprise data often needs an answer to “who changed what, when, why, and from which business state?” That is different from ordinary application
Background Jobs Idempotency and Retries
Background Jobs, Idempotency, and Retries Payroll calculation, report generation, imports, email batches, document generation, and integrations should not turn user-facing HTTP requests into
Financial Correctness Payroll and Accounting
Financial Correctness: Payroll and Accounting Financial systems need stronger invariants than ordinary CRUD. Monetary arithmetic, finalization, periods, rounding, and reproducibility must be
Procurement Inventory and Stock Consistency
Procurement, Inventory, and Stock Consistency Procurement and inventory illustrate why enterprise systems need ledgers, reservations, and transaction boundaries rather than one mutable “quan
Integration Boundaries Events and Outbox
Integration Boundaries, Events, and the Outbox Pattern Enterprise systems integrate with banks, biometrics, email/SMS, government services, accounting systems, suppliers, and identity provid
Reporting Read Models and Exports
Reporting, Read Models, and Exports Operational screens and enterprise reports have different query needs. Do not distort transactional models only to make one heavy report convenient. Trans
Enterprise Permissions and Segregation of Duties
Enterprise Permissions and Segregation of Duties OWNER/ADMIN/MEMBER is sufficient for TaskFlow, but enterprise systems often need permission scopes, organizational context, approval limits,
Scaling Migration and Service Extraction
Scaling and Migration Without a Rewrite The TaskFlow architecture is intentionally replaceable. Scale the constrained boundary first, then extract only where independent operation creates mo
Enterprise Capstone and Course Exit
Enterprise Capstone and Course Exit The final exercise is to convert one enterprise domain into an implementable architecture using the same reasoning applied throughout TaskFlow. - - - - Pl
Guided Build Lab
Purpose Generalize TaskFlow patterns into larger enterprise systems while preserving modular boundaries, workflows, auditability, integration reliability, and migration paths.
Debugging Workshop
Goal Learn to diagnose this phase's failures systematically instead of reinstalling packages, changing random configuration, or copying a fix without understanding it.
Phase Synthesis & Independent Challenge
Mission Rebuild the capability of Phase 36 without following the exact code line-by-line. The goal is transfer: can you use the ideas when the variable names, UI, or route shape changes?
Mastery Capstone Lab
Integrate Phase 36 without following a transcript.
Exercises that increase independence
Choose one enterprise domain and identify business capabilities before choosing services/databases.
Model one long-running approval as a state machine with actors, transitions, evidence, and audit records.
reproduce and diagnose — Microservices before module boundaries are understood.
deliver Enterprise expansion blueprint for an HRIS/procurement/inventory/payroll-style system with modules, workflows, events, audit, and scaling triggers.
Can decompose by business capability and Can model long-running workflows.
Do not leave the phase only because you reached the bottom
Phase exit criteria
Scenario and concept quiz
These questions test engineering choices rather than whether you remember a lesson title.
Reference files
Attempt the work first. Use snapshots to compare a checkpoint, not as a substitute for understanding.
reference/TaskFlow_Enterprise_Systems_Blueprint/APPROVAL_WORKFLOW_TEMPLATE.md
# Approval Workflow Template ## States DRAFT -> SUBMITTED -> REVIEW -> APPROVED -> EXECUTED ## For each transition define - command name - allowed source state - target state - actor permission - organizational scope - monetary/other approval limits - preconditions - required reason/comment - audit event - side effects / queued work Never expose a generic API that lets a client assign any workflow state directly.
reference/TaskFlow_Enterprise_Systems_Blueprint/AUDIT_EVENT_SCHEMA.md
# Audit Event Schema Suggested fields: - id - occurredAt - actorUserId / auth subject - workspace/company/department context - action - entityType - entityId - reason - beforeJson (only appropriate fields) - afterJson (only appropriate fields) - requestId / correlationId - source (WEB/API/JOB/INTEGRATION) For critical changes, write the audit event in the same database transaction as the business change. Do not put credentials or unnecessary sensitive data into audit payloads.
reference/TaskFlow_Enterprise_Systems_Blueprint/CAPSTONE_BLUEPRINT.md
# Final Enterprise Capstone Blueprint Choose HRIS, Procurement+Inventory, or Accounting. Produce: 1. Module/bounded-context map. 2. Key entities and invariants. 3. State/approval workflows. 4. Permission + scope + segregation-of-duties matrix. 5. Transaction boundaries. 6. Audit-event model. 7. Background-job and idempotency plan. 8. Integration contracts and outbox/inbox strategy. 9. Reporting/read-model strategy. 10. Test matrix and failure-recovery cases. 11. Deployment/observability plan. 12. ADRs for the three highest-impact architecture decisions. 13. Evidence/triggers that would justify future service extraction.
reference/TaskFlow_Enterprise_Systems_Blueprint/DOMAIN_MODULE_CATALOG.md
# Domain Module Catalog | Module | Owns | Example commands | |---|---|---| | People | Employee/employment/org assignments | hireEmployee, transferEmployee, terminateEmployment | | Leave | Leave balances and requests | submitLeave, approveLeave, cancelLeave | | Payroll | Payroll runs/pay items/deductions | calculatePayroll, finalizePayroll, markPaid | | Procurement | Requisitions/POs/suppliers | submitRequisition, approvePO, cancelPO | | Inventory | Items/warehouses/movements | receiveStock, issueStock, transferStock | | Accounting | Accounts/journals/periods | postJournal, closePeriod, reverseJournal | | Recruitment | Openings/applicants/offers | advanceApplicant, approveOffer, hireApplicant | Each module exports a small public service/event contract. Do not expose repositories or Prisma models as the default cross-module API.
reference/TaskFlow_Enterprise_Systems_Blueprint/ENTERPRISE_ARCHITECTURE_MAP.md
# Enterprise Architecture Map
```text
Next.js
-> NestJS/Fastify modular application
-> People / Payroll / Leave / Procurement / Inventory / Accounting / Recruitment
-> Repository interfaces / Prisma implementations
-> PostgreSQL
-> BullMQ workers for long-running work
-> Supabase Auth / Storage / Realtime where applicable
```
Start as a modular monolith. Extract workers or services only when scaling, reliability, compliance, release cadence, or team ownership creates real pressure.reference/TaskFlow_Enterprise_Systems_Blueprint/ENTERPRISE_PERMISSION_MATRIX.md
# Enterprise Permission Matrix - Example | Role | Scope | Example permissions | Extra constraints | |---|---|---|---| | HR Officer | company/department | employee.read, leave.review | cannot edit payroll result | | Payroll Officer | company | payroll.calculate, payslip.generate | finalization may require second approver | | Supervisor | team | leave.approve, employee.read.team | relationship-scoped | | Procurement Officer | business unit | requisition.manage, po.create | cannot final approve own PO | | Department Head | department | po.approve | approval amount threshold | | Accounting | company | journal.post, period.read | closed-period rule | Authorization decision = identity + scope + permission + relationship + business rule.
reference/TaskFlow_Enterprise_Systems_Blueprint/FINANCIAL_CORRECTNESS.md
# Financial Correctness Checklist - Use exact decimal/numeric amounts, never binary float for authoritative money. - Store currency explicitly. - Define rounding mode and rounding stage. - Version tables/formulas/rates used for payroll calculations. - Finalized payroll/journals should be immutable; corrections use adjustments/reversals. - Journal entries must balance before posting. - Closed accounting periods reject normal postings. - Recalculation must be reproducible from durable inputs/version references.
reference/TaskFlow_Enterprise_Systems_Blueprint/IDEMPOTENCY_AND_JOBS.md
# Idempotency and Background Jobs Course line: - @nestjs/bullmq 12.0.0 - BullMQ 6.x ## Example job key `payroll-run:<runId>:calculate` ## Worker rule 1. Load durable operation state. 2. If already completed, return the durable result. 3. Claim/process according to concurrency policy. 4. Persist progress/results. 5. Make external side effects independently idempotent. BullMQ recommends idempotent jobs so retries converge to the same final state. BullMQ 6 uses Job Schedulers for recurring work.
reference/TaskFlow_Enterprise_Systems_Blueprint/INTEGRATION_BOUNDARIES.md
# Integration Boundaries ## Outbound Business transaction -> outbox row -> worker -> external provider -> delivery state. ## Inbound webhook Verify authenticity -> persist provider event ID -> deduplicate -> process business command -> persist result. ## Contract rule Use business events such as `PurchaseOrderApproved` and version their payloads. Avoid publishing raw Prisma rows as long-lived external contracts.
reference/TaskFlow_Enterprise_Systems_Blueprint/MIGRATION_ROADMAP.md
# Migration Roadmap ## Stage 1 - Modular monolith Single API, explicit Nest feature modules, one PostgreSQL cluster. ## Stage 2 - Worker separation BullMQ workers for payroll calculation, imports, exports, notification batches, integrations. ## Stage 3 - Read scaling Indexes, read models, replicas/analytics pipeline where evidence requires. ## Stage 4 - Selective service extraction Only modules with independent scale/reliability/team/compliance pressure. ## Infrastructure replacement path - Supabase PostgreSQL -> self-hosted/AWS PostgreSQL - Supabase Storage -> S3-compatible storage adapter - Upstash/managed Redis -> alternate Redis - Railway/Render -> AWS containers/Kubernetes when operations justify it
reference/TaskFlow_Enterprise_Systems_Blueprint/README.md
# TaskFlow Enterprise Systems Blueprint This is the final course reference snapshot. It does not turn TaskFlow into one giant ERP implementation. Instead it provides reusable architecture templates for evolving the same principles into HRIS, payroll, procurement, inventory, accounting, recruitment, and other enterprise modules. The default evolution strategy is: 1. modular monolith, 2. durable background workers, 3. purpose-built read models, 4. selective service extraction only when evidence justifies it.
reference/TaskFlow_Enterprise_Systems_Blueprint/REPORTING_ARCHITECTURE.md
# Reporting Architecture Start simple: 1. Indexed PostgreSQL query. 2. Purpose-built projection/select. 3. View/materialized read model if repeated pressure justifies it. 4. Background job for large Excel/PDF exports. 5. Store generated artifact metadata; Storage holds bytes. Always apply tenant/department authorization to reports and exports. Historical reports must use effective-dated/versioned business data where required.
reference/TaskFlow_Enterprise_Systems_Blueprint/SOURCES.md
# Phase 36 Sources Official references consulted: - NestJS Modules: https://docs.nestjs.com/modules - BullMQ Idempotent Jobs: https://docs.bullmq.io/patterns/idempotent-jobs - BullMQ Job IDs/Deduplication: https://docs.bullmq.io/guide/jobs/job-ids - BullMQ Job Schedulers: https://docs.bullmq.io/guide/job-schedulers/ - BullMQ Flows: https://docs.bullmq.io/guide/flows/ - @nestjs/bullmq npm: https://www.npmjs.com/package/@nestjs/bullmq - BullMQ npm: https://www.npmjs.com/package/bullmq - PostgreSQL 18 Monetary Types: https://www.postgresql.org/docs/18/datatype-money.html - PostgreSQL 18 Data Types (`numeric` / `decimal` exact numeric): https://www.postgresql.org/docs/18/datatype.html Architecture patterns such as modular monoliths, transactional outbox/inbox, effective-dated history, segregation of duties, and read models are presented as engineering patterns; their exact implementation must follow the target organization's regulatory and business requirements.
reference/TaskFlow_Enterprise_Systems_Blueprint/VERSION_LOCK.md
# Phase 36 Version Notes Existing course locks remain: - Next.js 16.x - NestJS 12.x - Fastify 5.x - Prisma 7.9.1 (hard course lock) - PostgreSQL 18 line - Zod 4.x - TanStack Query 5.x New enterprise-worker line verified for this phase: - @nestjs/bullmq 12.0.0 - BullMQ 6.x (current npm line observed: 6.3.x) Do not auto-upgrade these inside an existing course checkpoint. Verify release notes and tests first.
reference/TaskFlow_Enterprise_Systems_Blueprint/apps/api/src/modules/payroll/payroll-run.states.ts
export type PayrollRunState = | "DRAFT" | "CALCULATING" | "REVIEW" | "FINALIZED" | "PAID"; // FINALIZED results should normally become immutable. // Corrections should create explicit adjustments/reversals rather than // silently rewriting historical payroll evidence.
reference/TaskFlow_Enterprise_Systems_Blueprint/apps/api/src/modules/procurement/approval-state-machine.ts
export type PurchaseOrderState =
| "DRAFT"
| "SUBMITTED"
| "APPROVED"
| "REJECTED"
| "CANCELED";
export function canApprovePurchaseOrder(
state: PurchaseOrderState,
): boolean {
return state === "SUBMITTED";
}
// Real policy additionally checks permission, scope, approval limit,
// segregation of duties, budget, and other organization rules.reference/TaskFlow_Enterprise_Systems_Blueprint/apps/api/src/modules/procurement/procurement.module.ts
import { Module } from "@nestjs/common";
// Illustrative final-course module boundary.
@Module({
imports: [],
controllers: [],
providers: [],
exports: [],
})
export class ProcurementModule {}reference/TaskFlow_Enterprise_Systems_Blueprint/apps/api/src/workers/payroll.worker.example.ts
// Pseudocode-level example for Phase 36.
async function calculatePayrollJob(runId: string) {
const run = await loadPayrollRun(runId);
if (run.status === "FINALIZED" || run.status === "CALCULATED") {
return run; // durable idempotent result
}
await claimRunForCalculation(runId);
const result = await calculateFromVersionedInputs(runId);
return persistCalculatedResult(runId, result);
}
declare function loadPayrollRun(id: string): Promise<any>;
declare function claimRunForCalculation(id: string): Promise<void>;
declare function calculateFromVersionedInputs(id: string): Promise<any>;
declare function persistCalculatedResult(id: string, value: any): Promise<any>;reference/TaskFlow_Enterprise_Systems_Blueprint/tests/enterprise-test-matrix.md
# Enterprise Test Matrix | Risk | Minimum verification | |---|---| | Unauthorized payroll finalization | HTTP E2E + permission policy test | | Duplicate payroll job delivery | idempotency integration test | | PO creator self-approves despite SoD | authorization/business policy test | | Stock transfer partially commits | PostgreSQL transaction/failure integration test | | Accounting journal unbalanced | pure policy + service test | | Closed-period posting | service + HTTP E2E | | Webhook delivered twice | inbox/idempotency integration test | | Outbox publish fails after DB commit | worker recovery test | | Report leaks another department | real PostgreSQL scoped query + E2E | | Audit record missing on critical command | transaction integration test | | Finalized payroll mutated | repository/service invariant test | | Worker retry exposes duplicate external side effect | integration contract/idempotency test |