mirror of
https://github.com/velocitatem/PHANTOM.git
synced 2026-06-01 00:53:36 +00:00
introduced supabase and experiment management UI (#23)
* introduced supabase and experiment management UI * fixing cookie import
This commit is contained in:
committed by
GitHub
parent
ab8b8787a8
commit
894ce87a5d
@@ -1,10 +1,40 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getAllExperiments } from '@/lib/sessionStore';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { createClient } from '@/utils/supabase/server';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export async function GET() {
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
const exps = getAllExperiments();
|
||||
return NextResponse.json({ experiments: exps });
|
||||
const cookieStore = await cookies();
|
||||
const supabase = createClient(cookieStore);
|
||||
|
||||
const { searchParams } = new URL(req.url);
|
||||
const id = searchParams.get('id');
|
||||
|
||||
if (id) {
|
||||
const { data, error } = await supabase
|
||||
.from('experiments')
|
||||
.select(`
|
||||
*,
|
||||
task:tasks(*)
|
||||
`)
|
||||
.eq('id', id)
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
return NextResponse.json({ experiment: data });
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('experiments')
|
||||
.select(`
|
||||
*,
|
||||
task:tasks(*)
|
||||
`)
|
||||
.order('created_at', { ascending: false });
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
return NextResponse.json({ experiments: data || [] });
|
||||
} catch (err: any) {
|
||||
console.error('experiments list error:', err);
|
||||
return NextResponse.json(
|
||||
@@ -13,3 +43,44 @@ export async function GET() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const supabase = createClient(cookieStore);
|
||||
const body = await req.json();
|
||||
|
||||
const { subject_name, xp_human_only, xp_market_mode, xp_task_id } = body;
|
||||
|
||||
if (!subject_name) {
|
||||
return NextResponse.json(
|
||||
{ error: 'subject_name is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('experiments')
|
||||
.insert([{
|
||||
subject_name,
|
||||
xp_human_only: xp_human_only ?? false,
|
||||
xp_market_mode: xp_market_mode || null,
|
||||
xp_task_id: xp_task_id || null,
|
||||
}])
|
||||
.select(`
|
||||
*,
|
||||
task:tasks(*)
|
||||
`)
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
return NextResponse.json({ experiment: data });
|
||||
} catch (err: any) {
|
||||
console.error('experiment creation error:', err);
|
||||
return NextResponse.json(
|
||||
{ error: err.message || 'unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
58
web/src/app/api/admin/tasks/route.ts
Normal file
58
web/src/app/api/admin/tasks/route.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { createClient } from '@/utils/supabase/server';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const supabase = createClient(cookieStore);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('tasks')
|
||||
.select('*')
|
||||
.order('created_at', { ascending: false });
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
return NextResponse.json({ tasks: data || [] });
|
||||
} catch (err: any) {
|
||||
console.error('tasks fetch error:', err);
|
||||
return NextResponse.json(
|
||||
{ error: err.message || 'unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const supabase = createClient(cookieStore);
|
||||
const body = await req.json();
|
||||
|
||||
const { task_name, task_description, task_def_of_done } = body;
|
||||
|
||||
if (!task_name) {
|
||||
return NextResponse.json(
|
||||
{ error: 'task_name is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('tasks')
|
||||
.insert([{ task_name, task_description, task_def_of_done }])
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
return NextResponse.json({ task: data });
|
||||
} catch (err: any) {
|
||||
console.error('task creation error:', err);
|
||||
return NextResponse.json(
|
||||
{ error: err.message || 'unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { getSession, createSession } from '@/lib/sessionStore';
|
||||
import { getSession, createSession, setExperiment } from '@/lib/sessionStore';
|
||||
|
||||
const COOKIE_NAME = 'phantom_session_id';
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
try {
|
||||
// check for existing session cookie
|
||||
const existingSession = req.cookies.get(COOKIE_NAME)?.value;
|
||||
|
||||
if (existingSession) {
|
||||
@@ -18,13 +17,11 @@ export async function GET(req: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
// mint new session id
|
||||
const sessionId = randomUUID();
|
||||
createSession(sessionId);
|
||||
|
||||
const res = NextResponse.json({ sessionId, experimentId: undefined });
|
||||
|
||||
// set httpOnly cookie with security flags
|
||||
res.cookies.set({
|
||||
name: COOKIE_NAME,
|
||||
value: sessionId,
|
||||
@@ -32,7 +29,7 @@ export async function GET(req: NextRequest) {
|
||||
sameSite: 'lax',
|
||||
secure: isProd,
|
||||
path: '/',
|
||||
maxAge: 60 * 60 * 24 * 30, // 30 days
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
});
|
||||
|
||||
return res;
|
||||
@@ -44,3 +41,52 @@ export async function GET(req: NextRequest) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json();
|
||||
const { experimentId } = body;
|
||||
|
||||
if (!experimentId) {
|
||||
return NextResponse.json(
|
||||
{ error: 'experimentId is required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
let sessionId = req.cookies.get(COOKIE_NAME)?.value;
|
||||
|
||||
if (!sessionId) {
|
||||
sessionId = randomUUID();
|
||||
createSession(sessionId);
|
||||
}
|
||||
|
||||
setExperiment(sessionId, experimentId);
|
||||
|
||||
const res = NextResponse.json({
|
||||
sessionId,
|
||||
experimentId,
|
||||
success: true
|
||||
});
|
||||
|
||||
if (!req.cookies.get(COOKIE_NAME)) {
|
||||
res.cookies.set({
|
||||
name: COOKIE_NAME,
|
||||
value: sessionId,
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
secure: isProd,
|
||||
path: '/',
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch (err: any) {
|
||||
console.error('session update error:', err);
|
||||
return NextResponse.json(
|
||||
{ error: err.message || 'unknown error' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user