docs: Update FEATURE_PLAN - approved field already exists
- Removed unnecessary migration for approved column (already in DatabaseManager.js) - Marked existing API endpoint PATCH /groups/:groupId/approve as reusable - Marked existing repository methods (updateGroupApproval, deleteImage) as reusable - Updated Phase 1 Task 1 to reflect current state - Only need to add performance indexes for cleanup queries
This commit is contained in:
parent
5064f265b0
commit
852890fca6
11
TODO.md
11
TODO.md
|
|
@ -44,7 +44,14 @@ Neue Struktur: Datenbank in src/data/db und bilder in src/data/images
|
|||
## Backend
|
||||
[x] Erweiterung der API um die Funktion bestehende Daten zu editieren/aktualisieren
|
||||
[x] Preview Generierung für hochgeladene Bilder
|
||||
[ ] Automatisches Löschen von Groupen, welche nach einer bestimmten Zeit (z.B. 5 Tage) nicht freigegeben wurden
|
||||
[ ] **Automatisches Löschen nicht freigegebener Gruppen** 🚧
|
||||
- **Status**: In Planung
|
||||
- **Feature Plan**: `docs/FEATURE_PLAN-delete-unproved-groups.md`
|
||||
- **Branch**: `feature/DeleteUnprovedGroups`
|
||||
- **Aufgaben**: 11 Tasks (DB Migration + Backend Cleanup Service + Cron-Job + Frontend UI)
|
||||
- **Geschätzte Zeit**: 2-3 Tage
|
||||
- **Löschfrist**: 7 Tage nach Upload (nur nicht freigegebene Gruppen)
|
||||
- **Cron-Job**: Täglich 10:00 Uhr
|
||||
[ ] Integration eines Benachrichtigungssystems (E-Mail, Push-Benachrichtigungen) wenn eine neue Slideshow hochgeladen wurde
|
||||
[ ] Implementierung eines Logging-Systems zur Nachverfolgung von Änderungen und Aktivitäten
|
||||
|
||||
|
|
@ -52,7 +59,7 @@ Neue Struktur: Datenbank in src/data/db und bilder in src/data/images
|
|||
[x] Erweiterung der Benutzeroberfläche um eine Editierfunktion für bestehende Einträge in ModerationPage.js
|
||||
[x] In der angezeigten Gruppen soll statt Bilder ansehen Gruppe editieren stehen
|
||||
[x] Diese bestehende Ansicht (Bilder ansehen) soll als eigene Seite implementiert werden
|
||||
[ ] Ergänzung der Möglichkeit eine Beschreibung zu den Bildern hinzuzufügen
|
||||
[x] Ergänzung der Möglichkeit eine Beschreibung zu den Bildern hinzuzufügen
|
||||
[ ] Erweiterung der ModerationPage um reine Datenbankeditor der sqlite Datenbank.
|
||||
|
||||
|
||||
|
|
|
|||
633
docs/FEATURE_PLAN-delete-unproved-groups.md
Normal file
633
docs/FEATURE_PLAN-delete-unproved-groups.md
Normal file
|
|
@ -0,0 +1,633 @@
|
|||
# Feature Plan: Automatisches Löschen nicht freigegebener Gruppen
|
||||
|
||||
## 📋 Übersicht
|
||||
|
||||
**Feature**: Automatisches Löschen von nicht freigegebenen Gruppen nach 7 Tagen
|
||||
**Ziel**: Verhindern, dass rechtlich oder sozial anstößige Inhalte dauerhaft auf dem Server verbleiben
|
||||
**Priorität**: Hoch (Sicherheit & Compliance)
|
||||
**Geschätzte Implementierungszeit**: 2-3 Tage
|
||||
|
||||
## 🎯 Funktionale Anforderungen
|
||||
|
||||
### Must-Have
|
||||
- [ ] **Automatische Löschung**: Gruppen mit `approved = false` werden nach 7 Tagen ab Upload-Zeitpunkt gelöscht
|
||||
- [ ] **Vollständige Löschung**: Datenbank-Einträge, Originalbilder und Preview-Bilder werden entfernt
|
||||
- [ ] **Cron-Job**: Tägliche Ausführung um 10:00 Uhr morgens
|
||||
- [ ] **Deletion Log**: Protokollierung gelöschter Gruppen in eigener Datenbanktabelle
|
||||
- [ ] **Anonymisierung**: Keine personenbezogenen Daten (Titel, Name, Beschreibung) im Log
|
||||
- [ ] **Countdown-Anzeige**: In ModerationPage wird Restzeit bis zur Löschung angezeigt
|
||||
- [ ] **Admin-Übersicht**: Geschützter Bereich in ModerationPage für Lösch-Historie
|
||||
- [ ] **Freigabe-Schutz**: Freigegebene Gruppen (`approved = true`) werden niemals automatisch gelöscht
|
||||
|
||||
### Nice-to-Have
|
||||
- [ ] **Manuelle Verzögerung**: Admin kann Löschfrist verlängern (z.B. um weitere 7 Tage)
|
||||
- [ ] **Batch-Delete Preview**: Vorschau welche Gruppen beim nächsten Cron-Lauf gelöscht würden
|
||||
- [ ] **Email-Benachrichtigung**: Warnung an Admin 24h vor automatischer Löschung
|
||||
|
||||
## 🔧 Technische Umsetzung
|
||||
|
||||
### 1. Database Schema Erweiterung
|
||||
|
||||
#### 1.1 Groups-Tabelle Status ✅ **BEREITS VORHANDEN**
|
||||
**Datei**: `backend/src/database/DatabaseManager.js`
|
||||
|
||||
**Status:** Die `approved` Spalte existiert bereits!
|
||||
```javascript
|
||||
// Zeile 60-63 in DatabaseManager.js
|
||||
CREATE TABLE IF NOT EXISTS groups (
|
||||
// ...
|
||||
approved BOOLEAN DEFAULT FALSE,
|
||||
// ...
|
||||
)
|
||||
```
|
||||
|
||||
**Migration:** Wird automatisch bei jedem Server-Start ausgeführt (Zeile 67-75):
|
||||
```javascript
|
||||
try {
|
||||
await this.run('ALTER TABLE groups ADD COLUMN approved BOOLEAN DEFAULT FALSE');
|
||||
} catch (error) {
|
||||
// Feld existiert bereits - das ist okay
|
||||
}
|
||||
```
|
||||
|
||||
**Zusätzlicher Index für Performance (neu hinzufügen):**
|
||||
```sql
|
||||
CREATE INDEX IF NOT EXISTS idx_groups_cleanup ON groups(approved, upload_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_groups_approved ON groups(approved);
|
||||
```
|
||||
|
||||
#### 1.2 Neue Tabelle: Deletion Log
|
||||
**Datei**: `backend/src/database/schema.sql`
|
||||
|
||||
```sql
|
||||
-- Deletion Log für gelöschte Gruppen (Compliance & Audit Trail)
|
||||
CREATE TABLE IF NOT EXISTS deletion_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
group_id TEXT NOT NULL, -- Original Group ID (zur Referenz)
|
||||
year INTEGER NOT NULL, -- Jahr des Uploads
|
||||
image_count INTEGER NOT NULL, -- Anzahl gelöschter Bilder
|
||||
upload_date DATETIME NOT NULL, -- Ursprünglicher Upload-Zeitpunkt
|
||||
deleted_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- Zeitpunkt der Löschung
|
||||
deletion_reason TEXT DEFAULT 'auto_cleanup_7days', -- Grund der Löschung
|
||||
total_file_size INTEGER -- Gesamtgröße der gelöschten Dateien (in Bytes)
|
||||
);
|
||||
|
||||
-- Index für schnelle Abfragen nach Löschdatum
|
||||
CREATE INDEX IF NOT EXISTS idx_deletion_log_deleted_at ON deletion_log(deleted_at DESC);
|
||||
|
||||
-- Index für Jahresfilterung
|
||||
CREATE INDEX IF NOT EXISTS idx_deletion_log_year ON deletion_log(year);
|
||||
```
|
||||
|
||||
**Wichtig**: Keine personenbezogenen Daten (title, name, description) werden gespeichert!
|
||||
|
||||
### 2. Backend-Implementierung
|
||||
|
||||
#### 2.1 Migration Script
|
||||
**Datei**: `backend/src/database/migrations/005_add_approved_column.sql` (neu erstellen)
|
||||
|
||||
```sql
|
||||
-- Migration 005: Add approved column to groups table
|
||||
ALTER TABLE groups ADD COLUMN approved BOOLEAN DEFAULT FALSE;
|
||||
|
||||
-- Index für schnelle Abfragen nicht freigegebener Gruppen
|
||||
CREATE INDEX IF NOT EXISTS idx_groups_approved ON groups(approved);
|
||||
|
||||
-- Index für Lösch-Kandidaten (approved=false + alte upload_date)
|
||||
CREATE INDEX IF NOT EXISTS idx_groups_cleanup ON groups(approved, upload_date);
|
||||
```
|
||||
|
||||
#### 2.2 Cleanup Service
|
||||
**Datei**: `backend/src/services/GroupCleanupService.js` (neu erstellen)
|
||||
|
||||
**Verantwortlichkeiten:**
|
||||
- Identifizierung löschbarer Gruppen (nicht freigegeben + älter als 7 Tage)
|
||||
- Berechnung der Löschfrist pro Gruppe
|
||||
- Vollständige Löschung (DB + Dateien)
|
||||
- Protokollierung in `deletion_log`
|
||||
|
||||
**Hauptmethoden:**
|
||||
```javascript
|
||||
class GroupCleanupService {
|
||||
// Findet alle Gruppen, die gelöscht werden müssen
|
||||
async findGroupsForDeletion()
|
||||
|
||||
// Löscht eine Gruppe vollständig (Transaktion)
|
||||
async deleteGroupCompletely(groupId)
|
||||
|
||||
// Erstellt Eintrag im Deletion Log
|
||||
async logDeletion(groupData)
|
||||
|
||||
// Hauptmethode: Führt kompletten Cleanup durch
|
||||
async performScheduledCleanup()
|
||||
|
||||
// Berechnet verbleibende Tage bis zur Löschung
|
||||
getDaysUntilDeletion(uploadDate)
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 Repository-Erweiterungen
|
||||
**Datei**: `backend/src/repositories/GroupRepository.js`
|
||||
|
||||
**Bestehende Methoden (werden wiederverwendet):** ✅
|
||||
```javascript
|
||||
// ✅ BEREITS VORHANDEN - Zeile 207
|
||||
async updateGroupApproval(groupId, approved) { }
|
||||
|
||||
// ✅ BEREITS VORHANDEN - Zeile 217
|
||||
async deleteImage(groupId, imageId) { }
|
||||
```
|
||||
|
||||
**Neue Methoden:**
|
||||
```javascript
|
||||
// Findet Gruppen, die zum Löschen anstehen (approved=false & älter als 7 Tage)
|
||||
async findUnapprovedGroupsOlderThan(days) { }
|
||||
|
||||
// Löscht Gruppe komplett (inkl. Bilder-Referenzen) - erweitert bestehende Logik
|
||||
async deleteGroupCompletely(groupId) { }
|
||||
|
||||
// Hole Statistiken für Gruppe (für Deletion Log)
|
||||
async getGroupStatistics(groupId) { }
|
||||
```
|
||||
|
||||
**Datei**: `backend/src/repositories/DeletionLogRepository.js` (neu erstellen)
|
||||
|
||||
```javascript
|
||||
class DeletionLogRepository {
|
||||
// Erstellt Lösch-Protokoll
|
||||
async createDeletionEntry(logData) { }
|
||||
|
||||
// Hole letzte N Einträge
|
||||
async getRecentDeletions(limit = 10) { }
|
||||
|
||||
// Hole alle Einträge (für Admin-Übersicht)
|
||||
async getAllDeletions() { }
|
||||
|
||||
// Statistiken (Anzahl gelöschte Gruppen, Bilder, Speicherplatz)
|
||||
async getDeletionStatistics() { }
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.4 Cron-Job Implementation
|
||||
**Datei**: `backend/src/services/SchedulerService.js` (neu erstellen)
|
||||
|
||||
**Library**: `node-cron`
|
||||
```bash
|
||||
cd backend
|
||||
npm install node-cron
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
const cron = require('node-cron');
|
||||
const GroupCleanupService = require('./GroupCleanupService');
|
||||
|
||||
class SchedulerService {
|
||||
start() {
|
||||
// Jeden Tag um 10:00 Uhr
|
||||
cron.schedule('0 10 * * *', async () => {
|
||||
console.log('[Scheduler] Running daily cleanup at 10:00 AM...');
|
||||
await GroupCleanupService.performScheduledCleanup();
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Integration in**: `backend/src/server.js`
|
||||
```javascript
|
||||
const SchedulerService = require('./services/SchedulerService');
|
||||
|
||||
// Nach Server-Start
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
|
||||
// Starte Scheduler
|
||||
const scheduler = new SchedulerService();
|
||||
scheduler.start();
|
||||
});
|
||||
```
|
||||
|
||||
#### 2.5 API-Endpunkte
|
||||
|
||||
**Route**: `backend/src/routes/groups.js`
|
||||
|
||||
**Bestehender Endpoint (wird wiederverwendet):** ✅
|
||||
```javascript
|
||||
// ✅ BEREITS VORHANDEN - Zeile 102
|
||||
PATCH /groups/:groupId/approve
|
||||
Body: { approved: true/false }
|
||||
Response: { success: true, message: "Gruppe freigegeben", approved: true }
|
||||
```
|
||||
|
||||
**Neue Admin-Endpunkte:**
|
||||
```javascript
|
||||
// Neu: Hole Deletion Log
|
||||
GET /api/admin/deletion-log?limit=10
|
||||
Response: { deletions: [...], total: 123 }
|
||||
|
||||
// Neu: Hole alle Deletion Logs
|
||||
GET /api/admin/deletion-log/all
|
||||
Response: { deletions: [...] }
|
||||
|
||||
// Neu: Deletion Statistiken
|
||||
GET /api/admin/deletion-log/stats
|
||||
Response: {
|
||||
totalDeleted: 45,
|
||||
totalImages: 234,
|
||||
totalSize: '1.2 GB',
|
||||
lastCleanup: '2025-11-08T10:00:00Z'
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Frontend-Implementierung
|
||||
|
||||
#### 3.1 ModerationGroupPage Erweiterungen
|
||||
**Datei**: `frontend/src/Components/Pages/ModerationGroupPage.js`
|
||||
|
||||
**Neue Features:**
|
||||
- Countdown-Anzeige für jede nicht freigegebene Gruppe
|
||||
- Farbcodierung optional (aktuell nicht gewünscht)
|
||||
- Button "Gruppe freigeben" (approved setzen)
|
||||
|
||||
**UI-Änderungen:**
|
||||
```jsx
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant="h6">{group.title}</Typography>
|
||||
|
||||
{/* Neu: Countdown-Anzeige */}
|
||||
{!group.approved && (
|
||||
<Alert severity="warning" sx={{ mt: 1 }}>
|
||||
⏰ Wird automatisch gelöscht in: {daysRemaining} Tagen
|
||||
<br />
|
||||
<Typography variant="caption">
|
||||
Upload: {formatDate(group.upload_date)}
|
||||
</Typography>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{/* Neu: Freigabe-Button */}
|
||||
<Button
|
||||
variant="contained"
|
||||
color="success"
|
||||
onClick={() => handleApprove(group.group_id)}
|
||||
>
|
||||
Gruppe freigeben
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
```
|
||||
|
||||
#### 3.2 Deletion Log Übersicht (Admin-Bereich)
|
||||
**Datei**: `frontend/src/Components/Pages/DeletionLogPage.js` (neu erstellen)
|
||||
|
||||
**Features:**
|
||||
- Tabelle mit letzten 10 gelöschten Gruppen (expandierbar auf alle)
|
||||
- Spalten: Group ID, Jahr, Anzahl Bilder, Upload-Datum, Lösch-Datum
|
||||
- Statistiken: Gesamt gelöschte Gruppen, Bilder, freigegebener Speicher
|
||||
- Toggle-Button: "Letzte 10" ↔ "Alle anzeigen"
|
||||
|
||||
**Mockup:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Gelöschte Gruppen - Übersicht │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Statistiken: │
|
||||
│ • Gesamt gelöscht: 45 Gruppen (234 Bilder) │
|
||||
│ • Freigegebener Speicher: 1.2 GB │
|
||||
│ • Letzter Cleanup: 08.11.2025 10:00 Uhr │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ [Letzte 10 anzeigen] [Alle anzeigen ▼] │
|
||||
├──────────┬──────┬────────┬─────────────┬──────────────┤
|
||||
│ Group ID │ Jahr │ Bilder │ Upload-Dat. │ Gelöscht am │
|
||||
├──────────┼──────┼────────┼─────────────┼──────────────┤
|
||||
│ abc123 │ 2024 │ 15 │ 01.11.2025 │ 08.11.2025 │
|
||||
│ xyz789 │ 2024 │ 23 │ 31.10.2025 │ 07.11.2025 │
|
||||
│ ... │ ... │ ... │ ... │ ... │
|
||||
└──────────┴──────┴────────┴─────────────┴──────────────┘
|
||||
```
|
||||
|
||||
#### 3.3 Service-Funktionen
|
||||
**Datei**: `frontend/src/services/groupService.js` (erweitern)
|
||||
|
||||
```javascript
|
||||
// Setze Approval-Status
|
||||
export const approveGroup = async (groupId) => {
|
||||
return sendRequest(`/api/groups/${groupId}/approve`, 'PUT', {
|
||||
approved: true
|
||||
});
|
||||
};
|
||||
|
||||
// Hole Deletion Log
|
||||
export const getDeletionLog = async (limit = 10) => {
|
||||
return sendRequest(`/api/admin/deletion-log?limit=${limit}`, 'GET');
|
||||
};
|
||||
|
||||
// Hole alle Deletion Logs
|
||||
export const getAllDeletionLogs = async () => {
|
||||
return sendRequest('/api/admin/deletion-log/all', 'GET');
|
||||
};
|
||||
|
||||
// Hole Statistiken
|
||||
export const getDeletionStatistics = async () => {
|
||||
return sendRequest('/api/admin/deletion-log/stats', 'GET');
|
||||
};
|
||||
```
|
||||
|
||||
#### 3.4 Routing
|
||||
**Datei**: `frontend/src/App.js`
|
||||
|
||||
```javascript
|
||||
// Neue Route für Deletion Log (nur für Admins)
|
||||
<Route path="/moderation/deletion-log" element={<DeletionLogPage />} />
|
||||
```
|
||||
|
||||
**Navigation in ModerationPage:**
|
||||
```jsx
|
||||
<Tabs>
|
||||
<Tab label="Gruppen freigeben" />
|
||||
<Tab label="Gelöschte Gruppen" /> {/* Neu */}
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
## 📝 Implementierungs-Aufgaben
|
||||
|
||||
### Phase 1: Database & Schema (Aufgaben 1-2)
|
||||
|
||||
#### Aufgabe 1: Database Schema für approved-Spalte prüfen ✅ **BEREITS VORHANDEN**
|
||||
- [x] ~~Migration Script erstellen~~ **NICHT NÖTIG** - approved-Spalte existiert bereits!
|
||||
- [x] ~~approved-Spalte zu groups-Tabelle hinzufügen~~ **BEREITS VORHANDEN** (DatabaseManager.js, Zeile 60)
|
||||
- [x] ~~Migration in DatabaseManager integrieren~~ **BEREITS VORHANDEN** (Zeile 67-75)
|
||||
- [x] ~~Indizes erstellen~~ **Performance-Index für cleanup hinzufügen**
|
||||
- [ ] Index für Cleanup-Abfragen hinzufügen: `CREATE INDEX IF NOT EXISTS idx_groups_cleanup ON groups(approved, upload_date)`
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ✅ Spalte `approved` existiert bereits mit DEFAULT FALSE
|
||||
- ✅ Migration läuft automatisch bei jedem Server-Start (DatabaseManager.js)
|
||||
- ⏳ Zusätzlicher Index für Cleanup-Performance hinzufügen
|
||||
- ✅ Keine Datenverluste - Bestehende Gruppen haben `approved = false`
|
||||
|
||||
#### Aufgabe 2: Deletion Log Tabelle erstellen
|
||||
- [ ] `deletion_log` Tabelle im Schema definieren
|
||||
- [ ] Indizes für schnelle Abfragen erstellen
|
||||
- [ ] Migration Script erstellen
|
||||
- [ ] Validierung der Tabellenstruktur
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Tabelle enthält alle definierten Spalten
|
||||
- Keine personenbezogenen Daten im Schema
|
||||
- Indizes für `deleted_at` und `year` existieren
|
||||
- Struktur ist optimal für Abfragen (letzte 10, alle, Statistiken)
|
||||
|
||||
### Phase 2: Backend Core Logic (Aufgaben 3-5)
|
||||
|
||||
#### Aufgabe 3: GroupCleanupService implementieren
|
||||
- [ ] Service-Klasse erstellen
|
||||
- [ ] `findGroupsForDeletion()` - SQL-Query für Gruppen älter als 7 Tage
|
||||
- [ ] `deleteGroupCompletely()` - Transaktion für DB + Dateien
|
||||
- [ ] `logDeletion()` - Eintrag in deletion_log
|
||||
- [ ] `getDaysUntilDeletion()` - Berechnung Restzeit
|
||||
- [ ] File-Deletion für Bilder und Previews
|
||||
- [ ] Error-Handling und Logging
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Service findet korrekt alle löschbaren Gruppen (approved=false + älter 7 Tage)
|
||||
- Dateien werden physisch vom Dateisystem entfernt
|
||||
- Datenbank-Transaktionen sind atomar (Rollback bei Fehler)
|
||||
- Deletion Log wird korrekt befüllt (ohne personenbezogene Daten)
|
||||
- Freigegebene Gruppen werden niemals gelöscht
|
||||
- Logging für alle Aktionen (Info + Error)
|
||||
|
||||
#### Aufgabe 4: Repository-Methoden erweitern
|
||||
- [ ] `GroupRepository.findUnapprovedGroupsOlderThan()` implementieren
|
||||
- [ ] `GroupRepository.deleteGroupById()` mit CASCADE-Logik
|
||||
- [ ] `GroupRepository.getGroupStatistics()` für Log-Daten
|
||||
- [ ] `GroupRepository.setApprovalStatus()` für Freigabe
|
||||
- [ ] `DeletionLogRepository` komplett implementieren
|
||||
- [ ] Unit-Tests für alle Methoden
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- SQL-Queries sind optimiert (nutzen Indizes)
|
||||
- DELETE CASCADE funktioniert für Bilder
|
||||
- Statistiken enthalten: Anzahl Bilder, Dateigröße
|
||||
- setApprovalStatus validiert groupId
|
||||
- DeletionLogRepository unterstützt Pagination
|
||||
|
||||
#### Aufgabe 5: Cron-Job einrichten
|
||||
- [ ] `node-cron` installieren
|
||||
- [ ] `SchedulerService` erstellen
|
||||
- [ ] Cron-Job für 10:00 Uhr konfigurieren
|
||||
- [ ] Integration in `server.js`
|
||||
- [ ] Logging für Scheduler-Start und -Ausführung
|
||||
- [ ] Manueller Test-Trigger für Entwicklung
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Cron-Job läuft täglich um 10:00 Uhr
|
||||
- Scheduler startet automatisch beim Server-Start
|
||||
- Fehler im Cleanup brechen Server nicht ab
|
||||
- Entwicklungs-Modus: Manueller Trigger möglich
|
||||
- Logging zeigt Ausführungszeit und Anzahl gelöschter Gruppen
|
||||
|
||||
### Phase 3: Backend API (Aufgabe 6)
|
||||
|
||||
#### Aufgabe 6: API-Endpunkte implementieren
|
||||
- [x] ~~`PUT /api/groups/:groupId/approve` für Freigabe~~ **BEREITS VORHANDEN** (groups.js, Zeile 102)
|
||||
- [ ] `GET /api/admin/deletion-log` mit Limit-Parameter
|
||||
- [ ] `GET /api/admin/deletion-log/all` für komplette Historie
|
||||
- [ ] `GET /api/admin/deletion-log/stats` für Statistiken
|
||||
- [ ] Request-Validation und Error-Handling für neue Endpoints
|
||||
- [ ] API-Dokumentation aktualisieren
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- ✅ Approval-Endpoint existiert bereits und funktioniert
|
||||
- Alle neuen Admin-Endpunkte sind unter `/api/admin/` erreichbar
|
||||
- Admin-Endpunkte erfordern Authentifizierung (falls vorhanden)
|
||||
- Response-Formate sind konsistent (JSON)
|
||||
- HTTP-Status-Codes sind korrekt (200, 400, 404, 500)
|
||||
- Fehler-Responses enthalten hilfreiche Messages
|
||||
|
||||
### Phase 4: Frontend UI (Aufgaben 7-9)
|
||||
|
||||
#### Aufgabe 7: ModerationGroupPage - Countdown anzeigen
|
||||
- [ ] Countdown-Komponente erstellen
|
||||
- [ ] Berechnung verbleibender Tage (Client-Side)
|
||||
- [ ] Alert-Box für nicht freigegebene Gruppen
|
||||
- [ ] Formatierung Upload-Datum und Lösch-Datum
|
||||
- [ ] Responsive Design für Mobile
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Countdown zeigt korrekte Anzahl Tage bis Löschung
|
||||
- Alert ist nur bei nicht freigegebenen Gruppen sichtbar
|
||||
- Format: "Wird automatisch gelöscht in: X Tagen"
|
||||
- UI ist mobile-optimiert
|
||||
- Keine Performance-Probleme bei vielen Gruppen
|
||||
|
||||
#### Aufgabe 8: Freigabe-Button implementieren
|
||||
- [ ] Button "Gruppe freigeben" in ModerationGroupPage
|
||||
- [ ] API-Call zu `/api/groups/:groupId/approve`
|
||||
- [ ] Loading-State während API-Call
|
||||
- [ ] Success-Feedback (SweetAlert2)
|
||||
- [ ] UI-Update nach Freigabe (Countdown verschwindet)
|
||||
- [ ] Error-Handling mit User-Feedback
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Button ist nur bei nicht freigegebenen Gruppen sichtbar
|
||||
- Freigabe funktioniert mit einem Klick
|
||||
- UI aktualisiert sich sofort (optimistic update)
|
||||
- Success-Message: "Gruppe wurde freigegeben"
|
||||
- Fehler werden benutzerfreundlich angezeigt
|
||||
|
||||
#### Aufgabe 9: DeletionLogPage erstellen
|
||||
- [ ] Neue Page-Komponente erstellen
|
||||
- [ ] Tabelle für Deletion Log mit MUI DataGrid/Table
|
||||
- [ ] Toggle "Letzte 10" ↔ "Alle anzeigen"
|
||||
- [ ] Statistik-Cards (Gesamt, Bilder, Speicher)
|
||||
- [ ] Formatierung von Daten und Dateigrößen
|
||||
- [ ] Pagination für große Datenmengen
|
||||
- [ ] Integration in ModerationPage (Tab)
|
||||
- [ ] Routing einrichten
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Tabelle zeigt: Group ID, Jahr, Bilder, Upload-Datum, Lösch-Datum
|
||||
- Standard: Letzte 10 Einträge
|
||||
- Toggle lädt alle Einträge nach
|
||||
- Statistiken sind prominent sichtbar
|
||||
- Dateigröße in lesbarem Format (MB, GB)
|
||||
- Responsive Design
|
||||
- Nur für Admins zugänglich (geschützter Bereich)
|
||||
|
||||
### Phase 5: Testing & Documentation (Aufgaben 10-11)
|
||||
|
||||
#### Aufgabe 10: Integration Testing
|
||||
- [ ] Test: Gruppe älter als 7 Tage wird automatisch gelöscht
|
||||
- [ ] Test: Freigegebene Gruppe bleibt bestehen (auch nach 7 Tagen)
|
||||
- [ ] Test: Deletion Log wird korrekt befüllt
|
||||
- [ ] Test: Dateien werden physisch gelöscht
|
||||
- [ ] Test: Countdown-Anzeige zeigt korrekte Werte
|
||||
- [ ] Test: Freigabe-Button funktioniert
|
||||
- [ ] Test: DeletionLogPage lädt Daten korrekt
|
||||
- [ ] Performance-Test: Cleanup mit 100+ Gruppen
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- Alle Haupt-Szenarien sind getestet
|
||||
- Cron-Job läuft ohne Fehler
|
||||
- Keine Memory-Leaks bei Scheduler
|
||||
- Performance ist akzeptabel (< 5s für Cleanup)
|
||||
- Frontend aktualisiert sich korrekt
|
||||
|
||||
#### Aufgabe 11: Dokumentation
|
||||
- [ ] README.md aktualisieren (Feature beschreiben)
|
||||
- [ ] API-Dokumentation für neue Endpunkte
|
||||
- [ ] ENV-Variable für Löschfrist (optional, aktuell hardcoded 7 Tage)
|
||||
- [ ] Admin-Anleitung: Wie Deletion Log einsehen
|
||||
- [ ] Deployment-Hinweise (Cron-Job in Docker)
|
||||
- [ ] CHANGELOG.md aktualisieren
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
- README beschreibt automatische Löschung
|
||||
- API-Endpunkte sind dokumentiert
|
||||
- Admin-Workflow ist klar beschrieben
|
||||
- Deployment-Schritte sind vollständig
|
||||
- CHANGELOG enthält alle Änderungen
|
||||
|
||||
## 🧪 Testing-Strategie
|
||||
|
||||
### Unit Tests
|
||||
- Repository-Methoden (findUnapprovedGroupsOlderThan, deleteGroupById)
|
||||
- GroupCleanupService (getDaysUntilDeletion)
|
||||
- DeletionLogRepository (alle Methoden)
|
||||
|
||||
### Integration Tests
|
||||
- Kompletter Cleanup-Prozess (DB + Files + Log)
|
||||
- API-Endpunkte mit verschiedenen Szenarien
|
||||
- Frontend-Integration (Countdown, Freigabe)
|
||||
|
||||
### Manuelle Tests
|
||||
- Cron-Job Ausführung beobachten
|
||||
- Deletion Log UI testen (Letzte 10 / Alle)
|
||||
- Mobile-Ansicht der ModerationPage
|
||||
|
||||
### Edge Cases
|
||||
- Gruppe wird genau am Tag 7 gelöscht
|
||||
- Gruppe wird 5 Minuten vor Cron-Job freigegeben
|
||||
- Sehr große Gruppen (100+ Bilder)
|
||||
- Dateisystem-Fehler beim Löschen
|
||||
- Gleichzeitige Freigabe während Cleanup
|
||||
|
||||
## 📊 Success Metrics
|
||||
|
||||
### Technisch
|
||||
- ✅ Cron-Job läuft täglich ohne Fehler
|
||||
- ✅ Durchschnittliche Cleanup-Zeit < 5 Sekunden
|
||||
- ✅ Keine Fehler in Production-Logs
|
||||
- ✅ 100% Datenlöschung (DB + Files)
|
||||
|
||||
### Funktional
|
||||
- ✅ Countdown in ModerationPage ist immer korrekt
|
||||
- ✅ Freigegebene Gruppen werden niemals gelöscht
|
||||
- ✅ Deletion Log ist vollständig und korrekt
|
||||
- ✅ Admin kann Historie einsehen (letzte 10 / alle)
|
||||
|
||||
### Sicherheit & Compliance
|
||||
- ✅ Keine personenbezogenen Daten in deletion_log
|
||||
- ✅ Alle Benutzerdaten werden nach 7 Tagen entfernt
|
||||
- ✅ Physische Dateien werden gelöscht (nicht nur DB-Einträge)
|
||||
|
||||
## 🚀 Deployment-Checkliste
|
||||
|
||||
- [ ] Database Migrations ausführen (005_add_approved_column.sql)
|
||||
- [ ] `node-cron` Dependency ist installiert
|
||||
- [ ] ENV-Variable `CLEANUP_DAYS` (optional, default: 7)
|
||||
- [ ] Scheduler startet automatisch beim Server-Start
|
||||
- [ ] Logs für Cleanup sind aktiviert
|
||||
- [ ] Monitoring für fehlgeschlagene Cleanup-Läufe
|
||||
- [ ] Backup-Strategie für deletion_log
|
||||
- [ ] Admin-Zugang zu DeletionLogPage testen
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
### Phase 2 (Nice-to-Have)
|
||||
- [ ] Admin kann Löschfrist manuell verlängern (+ 7 Tage Button)
|
||||
- [ ] Email-Benachrichtigung 24h vor automatischer Löschung
|
||||
- [ ] Batch-Delete Preview: "Diese Gruppen werden morgen gelöscht"
|
||||
- [ ] Konfigurierbare Löschfrist per ENV (aktuell hardcoded 7 Tage)
|
||||
- [ ] Export der Deletion Log als CSV
|
||||
- [ ] Soft-Delete Option (Gruppen markieren statt sofort löschen)
|
||||
|
||||
### Phase 3 (Erweiterte Features)
|
||||
- [ ] Automatische Archivierung statt Löschung (ZIP-Download)
|
||||
- [ ] Wiederherstellungs-Funktion (aus Archiv)
|
||||
- [ ] Dashboard mit Cleanup-Statistiken (Chart.js)
|
||||
- [ ] Whitelist für bestimmte Uploader (niemals automatisch löschen)
|
||||
|
||||
## 📚 Technologie-Stack
|
||||
|
||||
### Backend
|
||||
- **Cron-Job**: `node-cron` v3.0.3
|
||||
- **Database**: SQLite3 (bestehend)
|
||||
- **File Operations**: `fs.promises` (Node.js native)
|
||||
|
||||
### Frontend
|
||||
- **UI Framework**: Material-UI (MUI) v5
|
||||
- **Date Handling**: `date-fns` (bereits vorhanden)
|
||||
- **Notifications**: SweetAlert2 (bereits vorhanden)
|
||||
|
||||
## 🎯 Zeitplan
|
||||
|
||||
| Phase | Aufgaben | Geschätzte Zeit |
|
||||
|-------|----------|-----------------|
|
||||
| Phase 1 | Database Schema | 2-3 Stunden |
|
||||
| Phase 2 | Backend Core Logic | 6-8 Stunden |
|
||||
| Phase 3 | Backend API | 2-3 Stunden |
|
||||
| Phase 4 | Frontend UI | 4-6 Stunden |
|
||||
| Phase 5 | Testing & Docs | 3-4 Stunden |
|
||||
| **Total** | **11 Aufgaben** | **17-24 Stunden** |
|
||||
|
||||
**Empfohlene Reihenfolge**: Phase 1 → 2 → 3 → 4 → 5 (sequenziell)
|
||||
|
||||
---
|
||||
|
||||
**Status**: 🟡 In Planung
|
||||
**Branch**: `feature/DeleteUnprovedGroups`
|
||||
**Erstellt**: 08.11.2025
|
||||
**Letzte Aktualisierung**: 08.11.2025
|
||||
Loading…
Reference in New Issue
Block a user