feat: model selection+visibility, better filenames, picdrop direct upload + configurable gallery
- studio: quality/model selector (friendly names from active models); library shows model used - seed 2 models (Schnell/Beste Qualitaet); GET /api/models for studio+library - filename: YYYY-MM-DD_motif_format.png (was redundant slug, no date) - picdrop: direct upload to final name (fix .tmp- leftover from failed rename on picdrop); cleanupTmp helper - configurable default gallery (migration 003, settings + admin field); base_path=SFTP root, gallery=subfolder
This commit is contained in:
@@ -15,6 +15,7 @@ export const GET: APIRoute = async () => {
|
||||
openrouter_key_masked: orMask, openrouter_key_set: !!s.openrouter_key_enc,
|
||||
picdrop_host: s.picdrop_host, picdrop_protocol: s.picdrop_protocol, picdrop_port: s.picdrop_port,
|
||||
picdrop_user: s.picdrop_user, picdrop_base_path: s.picdrop_base_path,
|
||||
picdrop_default_gallery: s.picdrop_default_gallery,
|
||||
picdrop_password_set: !!s.picdrop_password_enc,
|
||||
default_dpi: s.default_dpi, default_crop_mode: s.default_crop_mode, concurrency: s.concurrency,
|
||||
cricut_sheet_cm: s.cricut_sheet_cm, monthly_budget: s.monthly_budget, n8n_webhook_url: s.n8n_webhook_url,
|
||||
@@ -29,7 +30,7 @@ export const PATCH: APIRoute = async ({ request }) => {
|
||||
if (b.openrouter_key) set('openrouter_key_enc', encrypt(String(b.openrouter_key)));
|
||||
if (b.picdrop_password) set('picdrop_password_enc', encrypt(String(b.picdrop_password)));
|
||||
for (const col of ['picdrop_host', 'picdrop_protocol', 'picdrop_port', 'picdrop_user', 'picdrop_base_path',
|
||||
'default_dpi', 'default_crop_mode', 'concurrency', 'cricut_sheet_cm', 'monthly_budget', 'n8n_webhook_url']) {
|
||||
'picdrop_default_gallery', 'default_dpi', 'default_crop_mode', 'concurrency', 'cricut_sheet_cm', 'monthly_budget', 'n8n_webhook_url']) {
|
||||
if (col in b) set(col, b[col] === '' ? null : b[col]);
|
||||
}
|
||||
if (!sets.length) return json({ ok: true });
|
||||
|
||||
@@ -24,7 +24,7 @@ export const GET: APIRoute = async ({ url, locals }) => {
|
||||
|
||||
const rows = await query(
|
||||
`SELECT i.id, i.filename, i.output_px, i.has_alpha, i.result_path, i.folder_id,
|
||||
i.delivery_status, i.created_at, u.display_name AS by_name,
|
||||
i.delivery_status, i.created_at, i.model_used, u.display_name AS by_name,
|
||||
j.recipe_snapshot->'tasks' AS tasks
|
||||
FROM items i
|
||||
JOIN jobs j ON j.id = i.job_id
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { APIRoute } from 'astro';
|
||||
import { query } from '../../lib/db';
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
// Aktive Modelle mit freundlichen Namen (für Studio-Auswahl + Ergebnis-Anzeige).
|
||||
export const GET: APIRoute = async ({ locals }) => {
|
||||
if (!locals.user) return new Response('Unauthorized', { status: 401 });
|
||||
const models = await query(
|
||||
`SELECT model_id, label, description, is_default, supports_alpha FROM models
|
||||
WHERE active ORDER BY sort, label`);
|
||||
return new Response(JSON.stringify({ models }), { headers: { 'Content-Type': 'application/json' } });
|
||||
};
|
||||
Reference in New Issue
Block a user