V 1.0.0 (front/backend) Erste lauffähige Version

This commit is contained in:
rxf
2025-11-23 12:14:58 +01:00
commit 3a6af1caca
20 changed files with 1085 additions and 0 deletions

154
backend/src/server.js Normal file
View File

@@ -0,0 +1,154 @@
// 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();