# Manual SQL Migrations

Diese Datei sammelt SQL-Aenderungen, die auf Live/Test manuell eingespielt werden muessen, wenn das Produktions-Setup keine automatische Schema-Migration ausfuehrt.

## Pflege-Regel

Ab jetzt gilt fuer jede Schemaaenderung:

1. SQL fuer `test` und `live` direkt hier eintragen.
2. Datum, betroffene Tabelle/Felder und optionalen Backfill dokumentieren.
3. Erst danach den Frontend-/Backend-Teil als abgeschlossen markieren.

Ergaenzend:

- Die produktive Anwendung soll sich nicht auf `sync({ alter: true })` verlassen.
- Manuelle Migrationsschritte gehoeren in diese Datei, nicht nur in Chat-Verlaeufe oder Commit-Messages.
- Wenn eine Aenderung rueckwaertskompatibel ist, soll das hier explizit vermerkt werden.

## 2026-07-22

### `club_communication_threads.reply_to`

Optionale Antwortadresse je Kommunikationsvorgang:

```sql
ALTER TABLE club_communication_threads
  ADD COLUMN reply_to VARCHAR(320) NULL AFTER subject;
```

Rueckwaertskompatibilitaet:

- Bestehende Vorgange behalten eine leere Antwortadresse und verwenden weiterhin die globale Absenderadresse.

## 2026-03-17

### `predefined_activities.exclude_from_stats`

```sql
ALTER TABLE predefined_activities
  ADD COLUMN exclude_from_stats TINYINT(1) NOT NULL DEFAULT 0;
```

Optionale Initialmarkierung der bekannten Strukturaktivitaeten:

```sql
UPDATE predefined_activities
SET exclude_from_stats = 1
WHERE name IN (
  'Begruessung',
  'Aktivierung',
  'Aufbauen',
  'Turnier',
  'Abbauen',
  'Abschlussgespraech',
  'Einspielen',
  'Einspielen (VH/RH)'
);
```

### `participants.attendance_status`

```sql
ALTER TABLE participants
  ADD COLUMN attendance_status VARCHAR(32) NOT NULL DEFAULT 'present';
```

Optionaler Backfill:

```sql
UPDATE participants
SET attendance_status = 'present'
WHERE attendance_status IS NULL OR attendance_status = '';
```

Optionaler Schutz gegen doppelte Teilnehmerzeilen pro Trainingstag:

```sql
ALTER TABLE participants
  ADD UNIQUE KEY participants_diary_date_member_unique (diary_date_id, member_id);
```

Rueckwaertskompatibilitaet:

- Bestehende Datensaetze bleiben durch den Default `present` gueltig.

## 2026-03-24

### `member_orders`

```sql
CREATE TABLE IF NOT EXISTS member_orders (
  id INT NOT NULL AUTO_INCREMENT,
  member_id INT NOT NULL,
  club_id INT NOT NULL,
  item VARCHAR(255) NOT NULL,
  status ENUM('requested', 'ordered', 'arrived', 'handed_over') NOT NULL DEFAULT 'requested',
  order_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  status_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  cost DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  paid_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  KEY idx_member_orders_member_id (member_id),
  KEY idx_member_orders_club_id (club_id),
  KEY idx_member_orders_status (status)
);
```

### `member_order_history`

```sql
CREATE TABLE IF NOT EXISTS member_order_history (
  id INT NOT NULL AUTO_INCREMENT,
  member_order_id INT NOT NULL,
  member_id INT NOT NULL,
  club_id INT NOT NULL,
  item VARCHAR(255) NOT NULL,
  status ENUM('requested', 'ordered', 'arrived', 'handed_over') NOT NULL,
  changed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  cost DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  paid_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  KEY idx_member_order_history_order_id (member_order_id),
  KEY idx_member_order_history_member_id (member_id),
  KEY idx_member_order_history_club_id (club_id),
  KEY idx_member_order_history_changed_at (changed_at)
);
```

Rueckwaertskompatibilitaet:

- Das Feature ist additiv. Bestehende Mitglieder- und Vereinstabellen werden nicht veraendert.
- Das Frontend funktioniert auch ohne Bestelldaten; die neuen Tabellen werden nur fuer das Feature genutzt.
