Skip to content

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 StatusCategory BehaviorDefault Statuses
not_startedTasks that have not commenced workbacklog, todo
in_progressActive work underwayin_progress, in_review
completedSuccessfully resolved; unblocks downstream tasksdone, closed
canceledAbandoned or discarded; bypasses blockerscanceled

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.