Files
aerzte/app/api/appointments/[id]/route.ts
T
admin 1a0fe18e89 Umstellung auf Next.js (App Router), Design analog werte-next
Führt das getrennte React/Vite-Frontend und Express/MongoDB-Backend in
eine einzelne Next.js-Anwendung zusammen:

- UI: React-Client-Komponenten (TabLayout, AppointmentForm, -List,
  ConfirmationModal) im Look von werte-next (Farben #CCCCFF/#85B7D7/
  #FFFFDD, Rahmenbox, Tabellen-Liste, Footer mit Version/Datum)
- API: Next.js Route Handler unter /api/appointments (GET/POST/PUT/DELETE,
  Soft-Delete beibehalten)
- DB: MongoDB via lib/db.ts (gecachter Client, Standard appointmentsdb)
- Tailwind 4 + TypeScript, Standalone-Docker-Build wie werte-next
- Druckansicht der aktuellen offenen Termine beibehalten
- Deployment: Dockerfile (multi-stage), docker-compose(.prod), deploy.sh

Entfernt die alten frontend/- und backend/-Verzeichnisse.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:24:34 +02:00

94 lines
2.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { ObjectId, WithId, Document } from 'mongodb';
import { getDb, APPOINTMENTS_COLLECTION } from '@/lib/db';
import { Appointment } from '@/types/appointment';
function normalize(doc: WithId<Document>): Appointment {
return {
id: doc._id.toString(),
arztName: doc.arztName,
arztArt: doc.arztArt ?? '',
termin: new Date(doc.termin).toISOString(),
erledigt: Boolean(doc.erledigt),
bemerkungen: doc.bemerkungen ?? '',
};
}
// PUT /api/appointments/:id - Termin aktualisieren (ganz oder teilweise)
export async function PUT(
request: NextRequest,
context: { params: Promise<{ id: string }> }
) {
try {
const { id } = await context.params;
const body = await request.json();
// Nur bekannte Felder übernehmen; termin ggf. in Date umwandeln.
const updateFields: Record<string, unknown> = {};
if (body.arztName !== undefined) updateFields.arztName = body.arztName;
if (body.arztArt !== undefined) updateFields.arztArt = body.arztArt;
if (body.termin !== undefined) updateFields.termin = new Date(body.termin);
if (body.erledigt !== undefined) updateFields.erledigt = Boolean(body.erledigt);
if (body.bemerkungen !== undefined) updateFields.bemerkungen = body.bemerkungen;
const db = await getDb();
const filter = { _id: new ObjectId(id) };
const result = await db
.collection(APPOINTMENTS_COLLECTION)
.updateOne(filter, { $set: updateFields });
if (result.matchedCount === 0) {
return NextResponse.json(
{ success: false, error: 'Termin nicht gefunden.' },
{ status: 404 }
);
}
const updated = await db
.collection(APPOINTMENTS_COLLECTION)
.findOne(filter);
return NextResponse.json({ success: true, data: normalize(updated!) });
} catch (error) {
console.error('Fehler beim Aktualisieren des Termins:', error);
return NextResponse.json(
{ success: false, error: 'Ungültige ID oder Serverfehler' },
{ status: 400 }
);
}
}
// DELETE /api/appointments/:id - Soft-Delete (setzt deleted-Flag)
export async function DELETE(
request: NextRequest,
context: { params: Promise<{ id: string }> }
) {
try {
const { id } = await context.params;
const db = await getDb();
const result = await db
.collection(APPOINTMENTS_COLLECTION)
.updateOne(
{ _id: new ObjectId(id) },
{ $set: { deleted: true, deletedAt: new Date() } }
);
if (result.matchedCount === 0) {
return NextResponse.json(
{ success: false, error: 'Termin nicht gefunden.' },
{ status: 404 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error('Fehler beim Löschen des Termins:', error);
return NextResponse.json(
{ success: false, error: 'Ungültige ID oder Serverfehler' },
{ status: 400 }
);
}
}