Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
repositories/aaf-holdings/hq01/lib/content/assignments.ts
2.2 KB
import path from "node:path";
import { cache } from "react";
import { CONTENT_ROOT } from "./config";
import { parseDoc, pick, readText, relPath, walkFiles } from "./fs";
import { normalizeStatus } from "./normalize";
import type { Assignment } from "./types";
function isAssignmentFile(p: string): boolean {
const norm = p.split(path.sep).join("/");
if (/\/templates?\//.test(norm)) return false;
return (
/\/assignments\/.+\/assignment\.md$/.test(norm) ||
/\/assignments\/A-[^/]+\.md$/.test(norm) ||
/\/assignment\.md$/.test(norm)
);
}
function assignmentId(filePath: string): string {
const dir = path.basename(path.dirname(filePath));
if (dir && dir !== "assignments") return dir;
return path.basename(filePath, ".md");
}
function normalizeWoRef(ref?: string): string | null {
if (!ref) return null;
return ref.trim().replace(/\s+/g, "-");
}
function toAssignment(filePath: string): Assignment {
const doc = parseDoc(readText(filePath));
const id = assignmentId(filePath);
return {
id,
title: doc.title || id,
status: normalizeStatus(pick(doc.meta, "status")),
workOrderId: normalizeWoRef(pick(doc.meta, "work order", "work-order")),
owner: pick(doc.meta, "owner", "worker") ?? "—",
workerTemplate: pick(doc.meta, "worker template", "worker-template") ?? "—",
objective: pick(doc.blocks, "objective") ?? "",
body: doc.body,
sourcePath: relPath(filePath),
};
}
export const getAssignments = cache((): Assignment[] => {
const files = walkFiles(CONTENT_ROOT, isAssignmentFile);
const byId = new Map<string, Assignment>();
for (const f of files) {
const a = toAssignment(f);
if (!byId.has(a.id)) byId.set(a.id, a);
}
return [...byId.values()].sort((a, b) => a.id.localeCompare(b.id));
});
export const getAssignment = cache((id: string): Assignment | undefined => {
return getAssignments().find((a) => a.id === id);
});
export const getAssignmentsForWorkOrder = cache((workOrderId: string): Assignment[] => {
return getAssignments().filter((a) => {
if (!a.workOrderId) return false;
return (
a.workOrderId === workOrderId ||
workOrderId.startsWith(a.workOrderId) ||
a.workOrderId.startsWith(workOrderId)
);
});
});
root · /srv/aaf