108 lines
3.6 KiB
TypeScript
108 lines
3.6 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { getServerSession } from "next-auth/next";
|
|
import { authOptions } from "@/lib/auth/authOptions";
|
|
import { query } from "@/lib/db-postgres";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// POST — save a completed discovery phase into the project data
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export async function POST(
|
|
req: NextRequest,
|
|
{ params }: { params: Promise<{ projectId: string }> }
|
|
) {
|
|
const session = await getServerSession(authOptions);
|
|
if (!session?.user?.email) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
const { projectId } = await params;
|
|
|
|
let body: { phase: string; title: string; summary: string; data: Record<string, unknown> };
|
|
try {
|
|
body = await req.json();
|
|
} catch {
|
|
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
}
|
|
|
|
const { phase, title, summary, data } = body;
|
|
if (!phase || !data) {
|
|
return NextResponse.json({ error: "phase and data are required" }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
// Ensure the table has a phases column and merge the new phase in
|
|
await query(`
|
|
CREATE TABLE IF NOT EXISTS atlas_phases (
|
|
project_id TEXT NOT NULL,
|
|
phase TEXT NOT NULL,
|
|
title TEXT,
|
|
summary TEXT,
|
|
data JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
saved_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (project_id, phase)
|
|
)
|
|
`);
|
|
|
|
await query(
|
|
`INSERT INTO atlas_phases (project_id, phase, title, summary, data, saved_at)
|
|
VALUES ($1, $2, $3, $4, $5::jsonb, NOW())
|
|
ON CONFLICT (project_id, phase) DO UPDATE
|
|
SET title = EXCLUDED.title,
|
|
summary = EXCLUDED.summary,
|
|
data = EXCLUDED.data,
|
|
saved_at = NOW()`,
|
|
[projectId, phase, title ?? phase, summary ?? "", JSON.stringify(data)]
|
|
);
|
|
|
|
// Also mirror into fs_projects.data.phases for easy access elsewhere
|
|
await query(
|
|
`UPDATE fs_projects
|
|
SET data = jsonb_set(
|
|
COALESCE(data, '{}'::jsonb),
|
|
ARRAY['phases', $2],
|
|
$3::jsonb,
|
|
true
|
|
),
|
|
updated_at = NOW()
|
|
WHERE id = $1`,
|
|
[projectId, phase, JSON.stringify({ title, summary, data, savedAt: new Date().toISOString() })]
|
|
);
|
|
|
|
console.log(`[save-phase] Saved phase "${phase}" for project ${projectId}`);
|
|
return NextResponse.json({ saved: true, phase });
|
|
} catch (err) {
|
|
console.error("[save-phase] Error:", err);
|
|
return NextResponse.json({ error: "Failed to save phase" }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// GET — load all saved phases for this project
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export async function GET(
|
|
_req: NextRequest,
|
|
{ params }: { params: Promise<{ projectId: string }> }
|
|
) {
|
|
const session = await getServerSession(authOptions);
|
|
if (!session?.user?.email) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
const { projectId } = await params;
|
|
|
|
try {
|
|
const rows = await query<{ phase: string; title: string; summary: string; data: unknown; saved_at: string }>(
|
|
`SELECT phase, title, summary, data, saved_at
|
|
FROM atlas_phases
|
|
WHERE project_id = $1
|
|
ORDER BY saved_at ASC`,
|
|
[projectId]
|
|
);
|
|
return NextResponse.json({ phases: rows });
|
|
} catch {
|
|
return NextResponse.json({ phases: [] });
|
|
}
|
|
}
|