metatroncubeswdev e304626986 Content calendar: plan, production and the publishing queue per client
- Plan items (idea → brief → production → ready) with brief, caption, platforms, assignee, pillar
- Calendar merges plan items, library items with a target date and queued/published posts
- Month and week views, drag a card to another day (or change the date in the card), add from any day
- MCP tools content_plan, plan_add, plan_update; weekly-plan skill now fills the calendar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 09:18:53 -04:00

38 lines
2.1 KiB
JavaScript

// Content plan: create, validate, show on the calendar, move between days, remove. Uses temp files only.
import { test } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TMP = fs.mkdtempSync(path.join(os.tmpdir(), "quorla-plan-"));
process.env.QUORLA_PLAN_FILE = path.join(TMP, "plan.json");
process.env.QUORLA_SCHEDULE_DIR = path.join(TMP, "schedule");
const plan = await import("../src/plan.js");
const { PROJECT_ROOT } = await import("../src/env.js");
const client = fs.readdirSync(path.join(PROJECT_ROOT, "clients")).find((d) => !d.startsWith("_") && fs.existsSync(path.join(PROJECT_ROOT, "clients", d, "client.json")));
test("plan items: create, validate, calendar, move, remove", { skip: !client && "no client folder" }, () => {
const a = plan.createItem({ client, title: "Behind the counter reel", date: "2031-03-04", format: "REELS", status: "brief", brief: "15s, morning prep" }, "t");
assert.equal(a.status, "brief");
assert.throws(() => plan.createItem({ client, title: "", date: "2031-03-04" }), /title/);
assert.throws(() => plan.createItem({ client, title: "x", date: "4 March" }), /YYYY-MM-DD/);
assert.throws(() => plan.updateItem(a.id, { status: "published" }), /Status must be/);
assert.throws(() => plan.createItem({ client: "no-such-client", title: "x", date: "2031-03-04" }), /Unknown client/);
const cal = plan.calendar({ client, from: "2031-03-01", to: "2031-03-31" });
const mine = cal.items.find((i) => i.id === a.id);
assert.equal(mine.kind, "plan");
assert.equal(mine.stage, "brief");
plan.moveEntry("plan", a.id, "2031-03-09");
assert.equal(plan.calendar({ client, from: "2031-03-09", to: "2031-03-09" }).items.find((i) => i.id === a.id).date, "2031-03-09");
assert.equal(plan.calendar({ client, from: "2031-03-01", to: "2031-03-08" }).items.some((i) => i.id === a.id), false);
plan.updateItem(a.id, { status: "ready", assignee: "Elena" });
assert.equal(plan.listItems({ client }).find((i) => i.id === a.id).assignee, "Elena");
plan.removeItem(a.id);
assert.equal(plan.listItems({ client }).some((i) => i.id === a.id), false);
});