Data Model & Schema Reference
Critical Path is built on a clean, strictly typed schema. All entities use ISO-8601 UTC date strings and UUID identifiers.
Task Entity
The Task interface represents an actionable work unit inside a project.
type Priority = 'urgent' | 'high' | 'medium' | 'low' | 'none';
type SemanticStatus = 'not_started' | 'in_progress' | 'completed' | 'canceled';
type TaskStatus = 'backlog' | 'todo' | 'in_progress' | 'in_review' | 'done' | 'canceled' | (string & {});
interface Task { id: string; projectId: string; title: string; description?: string; status: TaskStatus; semanticStatus?: SemanticStatus; priority: Priority; assigneeId?: string; reporterId?: string; sprintId?: string; dueDate?: string; // ISO-8601 string (e.g. 2026-09-15T00:00:00Z) estimatedHours?: number; // Used for Critical Path calculations loggedHours?: number; tags?: string[]; customFields?: Record<string, unknown>; parentId?: string; // Subtasks support createdAt: string; // ISO-8601 updatedAt: string; // ISO-8601}Semantic Status Mapping
In many organizations, teams use custom statuses like qa_in_review, waiting_on_client, or deployed_to_staging. To keep the critical path engine robust without sacrificing user customization, every status maps to a SemanticStatus:
| Semantic Status | Category Behavior | Default Statuses |
|---|---|---|
not_started | Tasks that have not commenced work | backlog, todo |
in_progress | Active work underway | in_progress, in_review |
completed | Successfully resolved; unblocks downstream tasks | done, closed |
canceled | Abandoned or discarded; bypasses blockers | canceled |
Project Entity
The Project interface represents the top-level container holding tasks and configuration.
interface Project { id: string; name: string; description?: string; key?: string; // e.g. "PRJ", "DEV" status?: string; statuses?: StatusDefinition[]; customFieldsSchema?: Record<string, CustomFieldDefinition>; createdAt: string; updatedAt: string;}Dependency Entity
Dependencies form a Directed Acyclic Graph (DAG) linking tasks together.
type DependencyType = | 'finish_to_start' // Standard: Task B cannot start until Task A finishes | 'start_to_start' // Task B cannot start until Task A starts | 'finish_to_finish' // Task B cannot finish until Task A finishes | 'start_to_finish'; // Task B cannot finish until Task A starts
interface Dependency { id: string; projectId: string; sourceTaskId: string; // Prerequisite task targetTaskId: string; // Dependent task type: DependencyType; lagHours?: number; // Optional delay or buffer in hours createdAt: string;}Critical Path Result
The result generated by engine.calculateCriticalPath(projectId):
interface CriticalPathAnalysis { projectId: string; calculatedAt: string; totalDurationHours: number; criticalTaskIds: string[]; tasks: Array<{ taskId: string; earlyStart: number; earlyFinish: number; lateStart: number; lateFinish: number; totalSlack: number; isCritical: boolean; }>;}Tasks where totalSlack === 0 lie on the critical path. Any delay in these tasks directly delays the overall project completion date.