Migrate: PocketBase → SvelteKit + better-sqlite3 + JWT
Vollständige Migration weg von PocketBase. Neuer Stack: - better-sqlite3 (WAL-Mode, direkte SQLite-Abfragen) - jose (JWT HS256, 30 Tage Laufzeit) - bcryptjs (Passwort-Hashing, cost 12) Neue Dateien: - src/lib/server/db.ts → SQLite-Singleton + Schema + Helpers - src/lib/server/auth.ts → JWT sign/verify, bcrypt, Bearer-Token - src/lib/user.ts → Svelte-Store (ersetzt pb.authStore) - src/lib/api.ts → fetch()-Wrapper (ersetzt pb.collection()) - src/app.d.ts → App.Locals TypeScript-Deklaration - 30 neue API-Routes unter src/routes/api/ Entfernt: - Abhängigkeit von pocketbase npm-Paket (bleibt im package.json bis alle Referenzen bereinigt sind) - PocketBase-Container aus docker-compose.yml - Migrations und Hooks aus Deploy-Pipeline Docker: Ein einziger Container, SQLite-Volume unter /data/ Makefile: PocketBase-spezifische Targets entfernt seed.js: Komplett neu für neue REST-API
This commit is contained in:
parent
61c430f2e6
commit
39981c0d17
58 changed files with 2313 additions and 651 deletions
37
app/src/routes/api/beitraege/+server.ts
Normal file
37
app/src/routes/api/beitraege/+server.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { json, error } from '@sveltejs/kit';
|
||||
import { getDb, newId, rows, row } from '$lib/server/db';
|
||||
import { requireAuth } from '$lib/server/auth';
|
||||
|
||||
export async function GET({ request }) {
|
||||
const u = await requireAuth(request);
|
||||
const db = getDb();
|
||||
const items = db.prepare(
|
||||
'SELECT * FROM beitraege WHERE verein_id = ? ORDER BY name'
|
||||
).all(u.verein_id);
|
||||
return json(rows(items as Record<string, unknown>[]));
|
||||
}
|
||||
|
||||
export async function POST({ request }) {
|
||||
const u = await requireAuth(request);
|
||||
const db = getDb();
|
||||
const body = await request.json();
|
||||
|
||||
if (!body.name || body.betrag == null) throw error(400, 'Name und Betrag sind Pflichtfelder');
|
||||
|
||||
const id = newId();
|
||||
|
||||
db.prepare(`
|
||||
INSERT INTO beitraege (id, verein_id, name, betrag, rhythmus, beschreibung)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(
|
||||
id,
|
||||
u.verein_id,
|
||||
body.name,
|
||||
body.betrag,
|
||||
body.rhythmus ?? 'jaehrlich',
|
||||
body.beschreibung ?? null
|
||||
);
|
||||
|
||||
const beitrag = db.prepare('SELECT * FROM beitraege WHERE id = ?').get(id);
|
||||
return json(row(beitrag as Record<string, unknown>), { status: 201 });
|
||||
}
|
||||
52
app/src/routes/api/beitraege/[id]/+server.ts
Normal file
52
app/src/routes/api/beitraege/[id]/+server.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { json, error } from '@sveltejs/kit';
|
||||
import { getDb, row } from '$lib/server/db';
|
||||
import { requireAuth } from '$lib/server/auth';
|
||||
|
||||
export async function GET({ request, params }) {
|
||||
const u = await requireAuth(request);
|
||||
const db = getDb();
|
||||
const beitrag = db.prepare(
|
||||
'SELECT * FROM beitraege WHERE id = ? AND verein_id = ?'
|
||||
).get(params.id, u.verein_id);
|
||||
if (!beitrag) throw error(404, 'Beitrag nicht gefunden');
|
||||
return json(row(beitrag as Record<string, unknown>));
|
||||
}
|
||||
|
||||
export async function PUT({ request, params }) {
|
||||
const u = await requireAuth(request);
|
||||
const db = getDb();
|
||||
|
||||
const existing = db.prepare(
|
||||
'SELECT id FROM beitraege WHERE id = ? AND verein_id = ?'
|
||||
).get(params.id, u.verein_id);
|
||||
if (!existing) throw error(404, 'Beitrag nicht gefunden');
|
||||
|
||||
const body = await request.json();
|
||||
|
||||
db.prepare(`
|
||||
UPDATE beitraege SET
|
||||
name = ?, betrag = ?, rhythmus = ?, beschreibung = ?,
|
||||
updated = strftime('%Y-%m-%dT%H:%M:%SZ','now')
|
||||
WHERE id = ? AND verein_id = ?
|
||||
`).run(
|
||||
body.name,
|
||||
body.betrag,
|
||||
body.rhythmus ?? 'jaehrlich',
|
||||
body.beschreibung ?? null,
|
||||
params.id,
|
||||
u.verein_id
|
||||
);
|
||||
|
||||
const beitrag = db.prepare('SELECT * FROM beitraege WHERE id = ?').get(params.id);
|
||||
return json(row(beitrag as Record<string, unknown>));
|
||||
}
|
||||
|
||||
export async function DELETE({ request, params }) {
|
||||
const u = await requireAuth(request);
|
||||
const db = getDb();
|
||||
const result = db.prepare(
|
||||
'DELETE FROM beitraege WHERE id = ? AND verein_id = ?'
|
||||
).run(params.id, u.verein_id);
|
||||
if (result.changes === 0) throw error(404, 'Beitrag nicht gefunden');
|
||||
return new Response(null, { status: 204 });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue