6a97a98325
Eliminare un articolo non lasciava nulla di recuperabile: ora la riga finisce nel cestino (colonna deleted_at, aggiunta anche ai database già esistenti) e sparisce da sito e pannello, ma resta ripristinabile dalla nuova pagina /admin/cestino, dove sta anche la cancellazione definitiva. L'API la accetta solo su articoli già cestinati, così il contenuto non si perde per un clic distratto. Ogni lettura pubblica — elenco, recenti, archivio per mese, pagina del singolo articolo — filtra il cestino, e chi non gestisce vede nel cestino soltanto i propri articoli. Le azioni di riga diventano icone (matita e cestino) come nell'elenco utenti, con etichetta accessibile che nomina l'articolo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
57 lines
2.5 KiB
TypeScript
57 lines
2.5 KiB
TypeScript
import type { APIRoute } from 'astro';
|
|
import { getDb } from '../../../../lib/db';
|
|
import { getPostById, updatePost, deletePost, trashPost, restorePost, canModifyPost } from '../../../../lib/posts';
|
|
import { parsePostBody } from '../../../../lib/post-body';
|
|
export const prerender = false;
|
|
|
|
const json = (status: number, body: object) =>
|
|
new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } });
|
|
|
|
export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
const id = Number(params.id);
|
|
const existing = getPostById(getDb(), id);
|
|
if (!existing) return json(404, { error: 'Articolo non trovato.' });
|
|
if (!canModifyPost(locals.user!.role, locals.user!.id, existing)) return json(403, { error: 'Non puoi modificare questo articolo.' });
|
|
let data: Record<string, unknown>;
|
|
try { data = await request.json(); } catch { return json(400, { error: 'Dati non validi.' }); }
|
|
const parsed = parsePostBody(data);
|
|
if ('error' in parsed) return json(400, { error: parsed.error });
|
|
try {
|
|
updatePost(getDb(), id, parsed.value);
|
|
return json(200, { ok: true });
|
|
} catch (err: any) {
|
|
if (String(err?.message).includes('UNIQUE')) return json(400, { error: 'Slug già esistente.' });
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Sposta l'articolo nel cestino. Con `?definitivo=1` lo cancella davvero: è la sola via per
|
|
* perdere il contenuto, e vale solo per ciò che è già nel cestino.
|
|
*/
|
|
export const DELETE: APIRoute = ({ params, locals, url }) => {
|
|
const id = Number(params.id);
|
|
const existing = getPostById(getDb(), id);
|
|
if (!existing) return json(404, { error: 'Articolo non trovato.' });
|
|
if (!canModifyPost(locals.user!.role, locals.user!.id, existing)) return json(403, { error: 'Non puoi eliminare questo articolo.' });
|
|
|
|
if (url.searchParams.get('definitivo') === '1') {
|
|
if (!existing.deleted_at) return json(400, { error: 'Sposta prima l\'articolo nel cestino.' });
|
|
deletePost(getDb(), id);
|
|
return json(200, { ok: true, definitivo: true });
|
|
}
|
|
|
|
trashPost(getDb(), id);
|
|
return json(200, { ok: true });
|
|
};
|
|
|
|
/** Riporta l'articolo fuori dal cestino, nello stato in cui era (bozza o pubblicato). */
|
|
export const POST: APIRoute = ({ params, locals }) => {
|
|
const id = Number(params.id);
|
|
const existing = getPostById(getDb(), id);
|
|
if (!existing) return json(404, { error: 'Articolo non trovato.' });
|
|
if (!canModifyPost(locals.user!.role, locals.user!.id, existing)) return json(403, { error: 'Non puoi ripristinare questo articolo.' });
|
|
restorePost(getDb(), id);
|
|
return json(200, { ok: true });
|
|
};
|