# Arbeitsanweisung fuer Codex: mpc_obscode_api.bas

## Ziel

Das Projekt besteht primaer aus einer einzelnen FreeBASIC-Datei:

```text
mpc_obscode_api.bas
```

Diese Datei laedt MPC-Observatory-Code-Daten, synchronisiert eine lokale Snapshot-Datenbank und erzeugt eine FreeBASIC-Include-Datei.

## Wichtige Regeln fuer Aenderungen

1. Alles bleibt in **einer** `.bas`-Datei.
2. Keine Aufteilung in mehrere Module, ausser der Nutzer fordert das explizit.
3. Der Dateiname beim Nutzer ist:
   ```text
   mpc_obscode_api.bas
   ```
4. Wenn Screenshots einen anderen aktiven Dateinamen zeigen, darauf hinweisen.
5. Keine langen Codebloecke im Chat ausgeben; immer eine komplette Datei als Download/Artefakt erzeugen.
6. Konservativ arbeiten.
7. Keine Architekturentscheidung ohne Rueckfrage.
8. Nur die konkret genannte Funktion oder den konkret genannten Bereich aendern.
9. Die TSV-Feldreihenfolge nicht aendern.
10. Das MPC-Codeformat bleibt:
    ```text
    [0-9A-Z][0-9][0-9]
    ```
11. Die `.bi`-Datei enthaelt nur die Type-Definition und kurze Kopierhinweise, kein statisches Datenarray und keine Ladefunktion.
12. Dateiausgaben, UI-Texte und Beschriftungen in erzeugten Dateien immer auf Englisch schreiben.
13. Datenwerte niemals uebersetzen oder inhaltlich umdeuten.
14. Die Sprache im Chat bleibt Deutsch.
15. Tabellen in erzeugten Dateien immer mit links ausgerichteter Titelzeile schreiben.
16. Die erste Spalte jeder Tabelle bleibt links ausgerichtet.
17. Textspalten bleiben links ausgerichtet, Zahlenspalten rechts ausgerichtet.
18. Zahlen nach Moeglichkeit am Dezimalpunkt ausrichten, wenn Nachkommastellen unterschiedlich lang sind.
19. Tabellen sollen nur so breit sein wie noetig und nicht automatisch die ganze Seitenbreite fuellen.
20. Texte duerfen umbrechen, wenn die Tabelle sonst nicht passt, aber nicht so, dass in einer umgebrochenen Spalte weniger als 4 Zeichen bleiben.
21. Jede Titelzeile braucht einen erklaerenden Hover und am Ende jeder Tabelle eine Liste mit den Spaltenerklaerungen.
22. Alle Tabellen muessen sortierbar sein; wenn eine `Count`-Spalte existiert, ist die Startreihenfolge nach `Count` absteigend.
23. Jede Tabelle ist auf korrekte Sortierung der Spalten zu pruefen, bevor sie ausgeliefert wird.

## FreeBASIC-Stilvorgaben

- `Option Explicit` verwenden.
- Alle Subs und Functions am Programmanfang mit `Declare` deklarieren.
- Vor jeder `Sub` und jeder `Function` steht ein Kommentarblock mit:
  - `Erzeugungsdatum`
  - `Zweck`
  - `Uebergabe`
  - `Benoetigt`
  - `Rueckgabe`
- `Benoetigt` soll transitiv sein, also auch indirekt benoetigte Subs/Functions enthalten.
- Parameter nach Moeglichkeit mit `ByRef`.
- Bei Array-Parametern keine explizite `ByRef`-Schreibweise, wenn FreeBASIC/FBide sie nicht akzeptiert:
  ```basic
  snapshotRecords() As ObsCodeSnapshotRecord
  ```
- Sub-Aufrufe immer mit Klammern:
  ```basic
  MPC_LoadObsCode(testObscode, observatoryData, keepRequestJsonFile)
  ```
- Blockeinrueckung: 2 Leerzeichen.
- Jede sinnvolle Codezeile soll mit Apostroph-Kommentar enden.
- Kommentarapostroph direkt nach der Anweisung, dann Leerzeichen bis ca. Spalte 81:
  ```basic
  End Function'                                                                    Funktion beenden
  ```
- Kommentare und Strings moeglichst ASCII-sicher halten:
  - `Uebergabe` statt `Übergabe`
  - `fuer` statt `für`
  - `Aenderung` statt `Änderung`

## Aktuelle Daten- und Dateiformate

### Snapshot-Datei

```text
mpc_obscode_snapshot.tsv
```

Tab-separierte Datei, eine Zeile pro Observatory-Code.

Felder:

1. `Obscode`
2. `LastCheckedDate`
3. `Longitude`
4. `Rhocosphi`
5. `Rhosinphi`
6. `Name`
7. `NameUtf8`
8. `NameLatex`
9. `ShortName`
10. `FirstDate`
11. `LastDate`
12. `WebLink`
13. `CreatedAt`
14. `UpdatedAt`
15. `UsesTwoLineObservations`
16. `OldNamesJson`
17. `ObservationsType`
18. `StatusText`
19. `LastErrorCode`

TSV-Felder muessen vor dem Schreiben mit `CleanTextForTsv()` bereinigt werden:
- TAB -> Leerzeichen
- CR -> Leerzeichen
- LF -> Leerzeichen

### Include-Datei

```text
mpc_obscode_snapshot_data.bi
```

Wird aus dem Snapshot erzeugt und enthaelt nur die Type-Definition samt kurzen Hinweisen zum manuellen Kopieren.

### Logdatei

```text
mpc_obscode_sync.log
```

Logrotation:
- `mpc_obscode_sync.log` -> `.1`
- `.1` -> `.2`
- bis `.10`

## Wichtige Funktionen

### API

- `MPC_LoadObsCode(...)`
- `BuildCurlHttpErrorText(...)`
- `RunPipeCommand(...)`

### JSON

- `JsonGetStringValue(...)`
- `JsonGetBooleanValue(...)`
- `JsonGetArrayRawValue(...)`
- `EscapeTextForJson(...)`

### Snapshot/Storage

- `LoadSnapshotFile(...)`
- `SaveSnapshotFile(...)`
- `SaveSnapshotFileAtomic(...)`
- `SaveSnapshotIncludeFile(...)`
- `SaveSnapshotIncludeFileAtomic(...)`
- `RepairSnapshotFile(...)`
- `CleanTextForTsv(...)`

### Sync

- `SyncObsCodeSnapshots(...)`
- `CalculateDailyQuota(...)`
- `SleepBetweenApiRequests(...)`
- `ShuffleIntegerArray(...)`

### CLI

- `MainProgram()`
- `PrintHelpText()`
- `ParseMaxAgeDaysArgument(...)`
- `ParseLimitArgument(...)`
- `ParseCheckArgument(...)`
- `ConfirmDeleteAll()`

## Aktuelle Sync-Logik

- Gueltiges MPC-Codeformat aktuell:
  ```text
  [0-9A-Z][0-9][0-9]
  ```
- Maximale theoretische Codezahl aktuell:
  ```text
  3600
  ```
- Zielzyklus:
  ```text
  20 Tage
  ```
- Tagesquote:
  ```text
  min(obsCodeCount, 3600) / 20
  ```
  aufgerundet.
- Zwischen API-Abfragen:
  ```text
  3000 ms +/- 1000 ms
  ```

## CLI-Schalter

- `--help`
- `--sync`
- `--check=XXX`
- `--stats`
- `--max-age-days=N`
- `--limit=N`
- `--dry-run`
- `--changed-only`
- `--keep-json`
- `--pause`
- `--deleteall`
- `--backup-delete`

`--deleteall` muss mit `YES` bestaetigt werden.

## Bekannte Fehlerquellen

1. Deklarationen vor `Type`-Definitionen:
   - Nicht zulaessig, wenn der Declare einen benutzerdefinierten Type verwendet.
   - Declare-Block muss nach beiden Type-Definitionen stehen.

2. Array-Parameter:
   - `ByRef snapshotRecords() As ...` kann in FBide Probleme machen.
   - Verwenden:
     ```basic
     snapshotRecords() As ObsCodeSnapshotRecord
     ```

3. TSV-Felder mit Zeilenumbruechen:
   - Fuehren in Python/HTML-Auswertung zu Warnungen.
   - Immer `CleanTextForTsv()` verwenden.

4. HTML-Code-Liste:
   - Parser darf nicht beliebige 3-Zeichen-Fragmente aus HTML ziehen.
   - Nur echte ObsCode-Zeilen akzeptieren.
   - Formatvalidierung streng halten.

5. Kommentar-Apostroph:
   - Nicht so:
     ```basic
     End Function                                                                    ' Funktion beenden
     ```
   - Sondern so:
     ```basic
     End Function'                                                                    Funktion beenden
     ```

## Testempfehlung nach jeder Aenderung

1. Kompilieren in FBide oder:
   ```bat
   fbc mpc_obscode_api.bas
   ```

2. Hilfe pruefen:
   ```bat
   mpc_obscode_api.exe --help
   ```

3. Einzelcode pruefen:
   ```bat
   mpc_obscode_api.exe --check=X09
   ```

4. Trockenen Sync pruefen:
   ```bat
   mpc_obscode_api.exe --sync --dry-run --limit=3
   ```

5. Statistik pruefen:
   ```bat
   mpc_obscode_api.exe --stats
   ```

6. Zusätzliche Prüfregel:
   - `fbc` nur ausführen, wenn sich eine `.bas`-Datei geändert hat.
   - Python nur ausführen, wenn sich eine `.py`-Datei geändert hat.
   - Beide Pruefungen bleiben als Anweisungen erhalten und ergaenzen die bisherigen Tests.

## Python-Auswertung

Die HTML-Statistik wird mit:

```text
mpc_obscode_tsv_to_html.py
```

aus der TSV-Datei erzeugt.

Wenn sich nur Python-Dateien geaendert haben, wird nur die Python-Auswertung neu ausgefuehrt.

Code-Links muessen so aussehen:

```text
https://www.jostjahn.de/stations/Code.html
```

Beispiel:

```text
https://www.jostjahn.de/stations/X09.html
```

Wichtiger Website-Link:

```text
indexseite.html
```
