- Custom workflow statuses: per-project configurable status definitions replacing the fixed task_status enum. Each project defines its own workflow with drag-to-reorder, color coding, and category mapping. - Gantt/timeline view: full project roadmap with task bars, dependency arrows, milestone diamonds, zoom levels (day/week/month), and drag to reschedule. - Natural-language quick-add: NLP parser extracts dates, priorities, projects, labels, and recurrence from free text. Floating bar with 'n' shortcut and live parsed preview. - Automation rules: no-code trigger-action system per project. Triggers on status change, task creation, due date approaching. Actions set status/priority, add labels, create notifications. - Notification center: in-app bell icon with unread badge, slide-out panel, real-time SSE updates, mark read/all read. Replaces raw activity feed dropdown. Schema: adds status_definitions, automation_rules, notifications tables. Migrations: 0007, 0008, 0009. 41 NLP parser tests pass.
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);
|
|
} |