New API routes: - statuses.ts: CRUD for custom task statuses - automations.ts: automation rules engine - timeline.ts: entity timeline/activity view - activity.ts: activity feed endpoint New UI components: - gantt/: gantt chart (6 files: chart, task-bar, milestone, timeline, deps, utils) - automation-rule-builder.tsx: visual rule editor - notification-center.tsx: in-app notifications - quick-add-bar.tsx: global quick-add - entities/: detail-page, activity, comments, inline-edit, note-editor - tasks/: recurrence-picker New hooks: - use-optimistic-patch.ts: optimistic UI updates New libs: - nlp-parser.ts + test: natural language task parsing - notify.ts: notification dispatch - automation-engine.ts: rule evaluation DB migrations: - 0007_custom_task_statuses.sql - 0008_automation_rules.sql - 0009_notifications.sql - migrate-task-statuses.ts: backfill script Modified: - tasks.ts: plane-lift integration (stateId/moduleId/cycleId) - analytics.ts: updated for new schema - canvas/$id.tsx: restored
22 lines
960 B
TypeScript
22 lines
960 B
TypeScript
import { fileURLToPath } from "node:url";
|
|
import { sql } from "../packages/db/src/client";
|
|
|
|
// Apply the custom-workflow-statuses migration idempotently.
|
|
// 0007_custom_task_statuses.sql uses CREATE ... IF NOT EXISTS, pg_constraint /
|
|
// information_schema guards, and idempotent backfill UPDATEs, so it is safe to
|
|
// run on every deploy. It must run BEFORE `drizzle-kit push`: the push removes
|
|
// the legacy tasks.status column and task_status enum type, and this script
|
|
// backfills tasks.status_id from that column first.
|
|
const statusesFile = fileURLToPath(
|
|
new URL("../drizzle/0007_custom_task_statuses.sql", import.meta.url),
|
|
);
|
|
|
|
try {
|
|
console.log(`Applying custom task statuses migration from ${statusesFile} ...`);
|
|
await sql.file(statusesFile);
|
|
console.log("Custom task statuses migration applied successfully.");
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error("Failed to apply custom task statuses migration:", error);
|
|
process.exit(1);
|
|
} |