154 lines
5.5 KiB
JavaScript
154 lines
5.5 KiB
JavaScript
// src/server.js
|
|
import 'dotenv/config';
|
|
import express from 'express';
|
|
import cors from 'cors';
|
|
import { connectToDb, getDb } from './db/db.js';
|
|
import { ObjectId } from 'mongodb'; // Wichtig für die Arbeit mit MongoDB IDs
|
|
|
|
// Initialisiert Express
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
// Middleware konfigurieren - CORS muss vor allen Routen kommen
|
|
app.use((req, res, next) => {
|
|
console.log(`📥 ${req.method} ${req.path} from ${req.get('origin') || 'unknown origin'}`);
|
|
res.header('Access-Control-Allow-Origin', 'http://localhost:5173');
|
|
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
|
res.header('Access-Control-Allow-Credentials', 'true');
|
|
|
|
// Handle preflight requests
|
|
if (req.method === 'OPTIONS') {
|
|
console.log('✅ Preflight request handled');
|
|
return res.sendStatus(200);
|
|
}
|
|
next();
|
|
});
|
|
app.use(express.json());
|
|
|
|
// -----------------------------------------------------
|
|
// API ROUTEN
|
|
// -----------------------------------------------------
|
|
|
|
// 1. READ: Alle Termine abrufen (GET /api/appointments)
|
|
app.get('/api/appointments', async (req, res) => {
|
|
try {
|
|
const db = getDb();
|
|
// Finde alle Dokumente in der Collection 'appointments'
|
|
const appointments = await db.collection('appointments')
|
|
.find({})
|
|
// Optional: Nach Termindatum sortieren (aufsteigend)
|
|
.sort({ termin: 1 })
|
|
.toArray();
|
|
|
|
// Sende die Daten zurück an das Frontend
|
|
res.json(appointments);
|
|
|
|
} catch (error) {
|
|
console.error("Fehler beim Abrufen der Termine:", error);
|
|
res.status(500).json({ message: "Interner Serverfehler beim Abrufen der Daten." });
|
|
}
|
|
});
|
|
|
|
// 2. CREATE: Neuen Termin erstellen (POST /api/appointments)
|
|
app.post('/api/appointments', async (req, res) => {
|
|
try {
|
|
const db = getDb();
|
|
const appointmentData = req.body; // Die Daten kommen vom React-Formular
|
|
|
|
// Validiere, dass der Termin ein gültiges Datum hat (Optional, aber gut)
|
|
if (!appointmentData.arztName || !appointmentData.termin) {
|
|
return res.status(400).json({ message: "Arztname und Termin sind erforderlich." });
|
|
}
|
|
|
|
// Mongo generiert die _id automatisch.
|
|
const result = await db.collection('appointments').insertOne(appointmentData);
|
|
|
|
// Der eingefügte Termin, inklusive der von Mongo erstellten _id
|
|
const newAppointment = { _id: result.insertedId, ...appointmentData };
|
|
|
|
// Sende den neu erstellten Termin zurück an das Frontend (Status 201 Created)
|
|
res.status(201).json(newAppointment);
|
|
|
|
} catch (error) {
|
|
console.error("Fehler beim Erstellen des Termins:", error);
|
|
res.status(500).json({ message: "Interner Serverfehler beim Speichern der Daten." });
|
|
}
|
|
});
|
|
|
|
// 3. UPDATE: Termin aktualisieren (PUT /api/appointments/:id)
|
|
app.put('/api/appointments/:id', async (req, res) => {
|
|
try {
|
|
const db = getDb();
|
|
const { id } = req.params;
|
|
const updatedFields = req.body; // Enthält alle Felder (oder nur die geänderten)
|
|
|
|
// Die _id des Dokuments muss ein gültiges ObjectId-Objekt sein
|
|
const filter = { _id: new ObjectId(id) };
|
|
|
|
// Entferne das _id Feld aus den aktualisierten Daten, um Fehler zu vermeiden
|
|
delete updatedFields._id;
|
|
|
|
// Führe die Aktualisierung durch
|
|
const result = await db.collection('appointments').updateOne(
|
|
filter,
|
|
{ $set: updatedFields }
|
|
);
|
|
|
|
if (result.matchedCount === 0) {
|
|
return res.status(404).json({ message: "Termin nicht gefunden." });
|
|
}
|
|
|
|
// Hole das aktualisierte Dokument, um es zurückzusenden (optional, aber nützlich)
|
|
const updatedAppointment = await db.collection('appointments').findOne(filter);
|
|
|
|
res.json(updatedAppointment);
|
|
|
|
} catch (error) {
|
|
console.error(`Fehler beim Aktualisieren des Termins ${req.params.id}:`, error);
|
|
// Gib einen 400 Bad Request zurück, falls die ID ungültig ist (z.B. falsches Format)
|
|
res.status(400).json({ message: "Ungültige ID oder Serverfehler." });
|
|
}
|
|
});
|
|
|
|
// 4. DELETE: Termin löschen (DELETE /api/appointments/:id)
|
|
app.delete('/api/appointments/:id', async (req, res) => {
|
|
try {
|
|
const db = getDb();
|
|
const { id } = req.params;
|
|
|
|
const filter = { _id: new ObjectId(id) };
|
|
|
|
const result = await db.collection('appointments').deleteOne(filter);
|
|
|
|
if (result.deletedCount === 0) {
|
|
return res.status(404).json({ message: "Termin nicht gefunden." });
|
|
}
|
|
|
|
// Sende Status 204 (No Content), um den erfolgreichen Löschvorgang zu signalisieren
|
|
res.status(204).send();
|
|
|
|
} catch (error) {
|
|
console.error(`Fehler beim Löschen des Termins ${req.params.id}:`, error);
|
|
res.status(400).json({ message: "Ungültige ID oder Serverfehler." });
|
|
}
|
|
});
|
|
|
|
|
|
// -----------------------------------------------------
|
|
// Server Start Logik
|
|
// -----------------------------------------------------
|
|
async function startServer() {
|
|
try {
|
|
await connectToDb();
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`🚀 Server läuft auf Port ${PORT}`);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Fehler beim Starten des Servers:", error);
|
|
}
|
|
}
|
|
|
|
startServer(); |