5bc413da50
Adds new admin section 'Заметки Зеро' (☕) with:
- manual 'Generate' button with channel/bucket/allow-dup form
- status filter tabs with counters (draft/approved/published/failed/skipped)
- per-note actions: approve / edit inline / regenerate with bucket pick / skip
- status-colored cards with bucket icon, pose, scheduled time MSK
- error display with attempt counter
- tokens & model footer
Files:
app/api/admin/zero/[...path]/route.js catch-all proxy → engine
components/admin/AdminZero.js main component
components/AdminPanel.js +section in sidebar
47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
/**
|
|
* Catch-all proxy для /api/admin/zero/* → engine /api/admin/zero/*
|
|
* Принимает любой метод и любой путь. Auth: session cookie → user.isAdmin.
|
|
*/
|
|
import { NextResponse } from 'next/server';
|
|
import { requireUser } from '@/lib/session';
|
|
|
|
const ENGINE_URL = process.env.ENGINE_URL || 'http://127.0.0.1:3030';
|
|
const ENGINE_SECRET = process.env.ENGINE_SECRET || '';
|
|
|
|
async function proxy(req, { params }) {
|
|
const user = await requireUser();
|
|
if (!user?.isAdmin) {
|
|
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
|
}
|
|
const tail = (params?.path || []).join('/');
|
|
const qs = req.url.split('?')[1];
|
|
const url = `${ENGINE_URL}/api/admin/zero${tail ? '/' + tail : ''}${qs ? '?' + qs : ''}`;
|
|
|
|
const headers = {
|
|
'x-internal-secret': ENGINE_SECRET,
|
|
'x-user-id': String(user.id),
|
|
};
|
|
|
|
let body;
|
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
const ct = req.headers.get('content-type') || '';
|
|
if (ct.includes('application/json')) {
|
|
headers['Content-Type'] = 'application/json';
|
|
const raw = await req.text();
|
|
body = raw || undefined;
|
|
} else {
|
|
body = await req.text();
|
|
}
|
|
}
|
|
|
|
const res = await fetch(url, { method: req.method, headers, body, cache: 'no-store' });
|
|
const data = await res.json().catch(() => ({ error: 'invalid engine response' }));
|
|
return NextResponse.json(data, { status: res.status });
|
|
}
|
|
|
|
export const GET = proxy;
|
|
export const POST = proxy;
|
|
export const PATCH = proxy;
|
|
export const PUT = proxy;
|
|
export const DELETE = proxy;
|