← Files Electrical Progress TrackerARCHIVED FILE

skills/create-tracker/assets/source/app/api/notes/route.ts

3.29 KB · Oct 4, 2026 · 12:34 UTC

↓ Download file

import { progressDb } from "../../../db/progress";
import { getChatGPTUser } from "../../chatgpt-auth";
import { requireManager } from "../../../db/manager-access";

function validTag(value: unknown): value is string {
  return typeof value === "string" && value.length > 0 && value.length <= 100 && /^[a-z0-9][a-z0-9-]*$/i.test(value);
}

export async function GET() {
  try {
    const result = await progressDb().prepare("SELECT id, content, system, floor, created_at AS createdAt, updated_at AS updatedAt FROM tracker_notes ORDER BY updated_at DESC, id DESC").all();
    return Response.json({ notes: result.results });
  } catch {
    return Response.json({ error: "Notes are temporarily unavailable" }, { status: 503 });
  }
}

export async function POST(request: Request) {
  try {
    if (!(await requireManager(await getChatGPTUser()))) return Response.json({ error: "Manager access required" }, { status: 403 });
    const body = await request.json() as { content?: string; system?: string | null; floor?: string | null };
    const content = body.content?.trim() || "";
    if (!content || content.length > 4000) return Response.json({ error: "A note between 1 and 4,000 characters is required" }, { status: 400 });
    const system = validTag(body.system) ? body.system : null;
    const floor = validTag(body.floor) ? body.floor : null;
    const result = await progressDb().prepare("INSERT INTO tracker_notes (content, system, floor, created_at, updated_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, content, system, floor, created_at AS createdAt, updated_at AS updatedAt").bind(content, system, floor).first();
    return Response.json({ note: result }, { status: 201 });
  } catch {
    return Response.json({ error: "Note could not be saved" }, { status: 503 });
  }
}

export async function PATCH(request: Request) {
  try {
    if (!(await requireManager(await getChatGPTUser()))) return Response.json({ error: "Manager access required" }, { status: 403 });
    const body = await request.json() as { id?: number; content?: string };
    const content = body.content?.trim() || "";
    if (!Number.isInteger(body.id) || !content || content.length > 4000) return Response.json({ error: "A valid note is required" }, { status: 400 });
    const result = await progressDb().prepare("UPDATE tracker_notes SET content = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? RETURNING id, content, system, floor, created_at AS createdAt, updated_at AS updatedAt").bind(content, body.id).first();
    if (!result) return Response.json({ error: "Note not found" }, { status: 404 });
    return Response.json({ note: result });
  } catch {
    return Response.json({ error: "Note could not be updated" }, { status: 503 });
  }
}

export async function DELETE(request: Request) {
  try {
    if (!(await requireManager(await getChatGPTUser()))) return Response.json({ error: "Manager access required" }, { status: 403 });
    const body = await request.json() as { id?: number };
    if (!Number.isInteger(body.id)) return Response.json({ error: "A valid note is required" }, { status: 400 });
    await progressDb().prepare("DELETE FROM tracker_notes WHERE id = ?").bind(body.id).run();
    return Response.json({ deleted: body.id });
  } catch {
    return Response.json({ error: "Note could not be deleted" }, { status: 503 });
  }
}

SHA-256: 859bcdc7aa3148c9e75104e096547757af1ef7ecaa01c364a3457cb5ef684f54