feat(confidence-engine): establish authenticated product boundary

This commit is contained in:
2026-09-08 16:30:07 +01:00
parent 1c17452bee
commit 30bf44f2e5
22 changed files with 487 additions and 8 deletions
+4 -1
View File
@@ -3,8 +3,9 @@ import {
PROMPT_VERSIONS,
DEFAULT_PROMPT_VERSION,
} from "@/lib/analysis";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
@@ -47,3 +48,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
+4 -1
View File
@@ -8,8 +8,9 @@
import { getProvider, getProviderModelName } from "@/lib/llm/provider.js";
import { synthesizeInvestigationOverview } from "@/lib/graph/investigation-overview-synthesis.js";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
@@ -66,3 +67,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
+4 -1
View File
@@ -1,6 +1,7 @@
import { startCase } from "@/lib/graph/orchestrator.js";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
const result = await startCase(body);
@@ -62,3 +63,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
+4 -1
View File
@@ -11,8 +11,9 @@
import { getProvider, getProviderModelName } from "@/lib/llm/provider.js";
import { synthesizeCurrentUnderstanding } from "@/lib/graph/current-understanding-synthesis.js";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
@@ -69,3 +70,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
+4 -1
View File
@@ -2,6 +2,7 @@ import { updateCase, reconsiderCompletedEpisode } from "@/lib/graph/orchestrator
import { applyValidatedProposal } from "@/lib/graph/apply-proposal.js";
import { prepareCompletedEpisode } from "@/lib/graph/episode-preparation.js";
import { updateCaseEpisodeRequestSchema } from "@/lib/graph/schema.js";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
function mapFailureStatus(result) {
switch (result?.stage) {
@@ -35,7 +36,7 @@ function buildFailureResponse(result) {
};
}
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
const isEpisodeMode = body?.episodeMode === true;
@@ -89,6 +90,8 @@ export async function POST(request) {
}
}
export const POST = withAuthenticatedApi(post);
/** Server-side completed-episode reconsideration flow. */
async function handleEpisodeMode(situationGraph, body) {
const prepared = prepareCompletedEpisode({
@@ -4,8 +4,9 @@ import {
focusedDeconstructJsonSchema,
validateFocusedDeconstructSchema,
} from "@/lib/graph/focused-investigation";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
let targetNodeId = null;
let startedAt = null;
try {
@@ -152,3 +153,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
@@ -1,6 +1,7 @@
import { formulateQuestionForTarget } from "@/lib/graph/focused-investigation";
import { withAuthenticatedApi } from "@/lib/supabase/api-auth.js";
export async function POST(request) {
async function post(request) {
try {
const body = await request.json();
@@ -50,3 +51,5 @@ export async function POST(request) {
);
}
}
export const POST = withAuthenticatedApi(post);
+26
View File
@@ -0,0 +1,26 @@
import { createServerClient } from "@supabase/ssr";
import { NextResponse } from "next/server";
export async function GET(request) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get("code");
const response = NextResponse.redirect(new URL("/", requestUrl.origin));
if (code) {
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
getAll: () => request.cookies.getAll(),
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => response.cookies.set(name, value, options));
},
},
},
);
await supabase.auth.exchangeCodeForSession(code);
}
return response;
}
+5 -1
View File
@@ -1,5 +1,6 @@
import "./globals.css";
import ThemeToggle from "@/components/theme-toggle";
import LogoutButton from "@/components/logout-button";
export const metadata = {
title: "Confidence Engine",
@@ -18,7 +19,10 @@ export default function RootLayout({ children }) {
<header className="app-chrome border-b border-gray-200/80">
<div className="mx-auto flex max-w-[1600px] items-center justify-between px-6 py-3">
<span className="text-sm font-semibold tracking-wide text-teal-700">Confidence Engine</span>
<ThemeToggle />
<div className="flex items-center gap-2">
<ThemeToggle />
<LogoutButton />
</div>
</div>
</header>
{children}
+5
View File
@@ -0,0 +1,5 @@
import LoginForm from "@/components/login-form";
export default function LoginPage() {
return <LoginForm />;
}