reparatie diverse bestanden
This commit is contained in:
@@ -0,0 +1,639 @@
|
||||
# Rename-MVP — Definitieve Codex instructie en technisch ontwerp
|
||||
|
||||
## Doel
|
||||
|
||||
Bouw verder aan een minimalistische webapplicatie als uitgeklede webversie van **Rename My TV Series**.
|
||||
|
||||
De applicatie moet:
|
||||
|
||||
- draaien in een **rootless Podman container**
|
||||
- lokale mediabestanden kunnen hernoemen binnen expliciet toegestane videomappen
|
||||
- metadata ophalen via **TheTVDB v4 API**
|
||||
- een **4-panel interface** hebben
|
||||
- altijd eerst een **preview** tonen voordat bestanden echt worden hernoemd
|
||||
- veilig omgaan met paden, tokens en bestandsoperaties
|
||||
- de **serienaam inclusief jaartal** gebruiken in de UI en in de bestandsnaam
|
||||
|
||||
Dit project heeft al een **werkende baseline**:
|
||||
- container build werkt
|
||||
- FastAPI health endpoint werkt
|
||||
- TVDB login werkt
|
||||
- JWT parsing werkt
|
||||
- token persistence werkt
|
||||
- auth-status endpoint werkt
|
||||
- TVDB search werkt
|
||||
- `token_source` werkt
|
||||
|
||||
Belangrijk: dit project is nu **geen greenfield ontwerp meer**, maar een **bestaand werkend project** dat gecontroleerd verder moet worden uitgebouwd.
|
||||
|
||||
---
|
||||
|
||||
# 1. Technische context
|
||||
|
||||
## Hostomgeving
|
||||
|
||||
- Host OS: Debian Trixie
|
||||
- Podman version: 5.4.2
|
||||
- Project root: `/home/kodi/.config/rename-mvp`
|
||||
|
||||
## Runtime
|
||||
|
||||
- Rootless Podman
|
||||
- FastAPI backend
|
||||
- SQLite voor app-state en logging
|
||||
- JSON voor TVDB auth state
|
||||
- TheTVDB API v4
|
||||
- Lokale tests via `127.0.0.1:8085`
|
||||
|
||||
## Bestaande paden
|
||||
|
||||
### Auth state JSON
|
||||
- Host: `/home/kodi/.config/rename-mvp/data/tvdb_auth.json`
|
||||
- Container: `/app/data/tvdb_auth.json`
|
||||
|
||||
### Werkende testscripts
|
||||
- `/home/kodi/.config/rename-mvp/regression_tests.sh`
|
||||
- `/home/kodi/.config/rename-mvp/feature_test_template.sh`
|
||||
|
||||
### Governance-bestanden
|
||||
- `/home/kodi/.config/rename-mvp/AGENTS.md`
|
||||
- `/home/kodi/.config/rename-mvp/CHANGE_POLICY.md`
|
||||
- `/home/kodi/.config/rename-mvp/SAFE_FILES.md`
|
||||
- `/home/kodi/.config/rename-mvp/docs/ARCHITECTURE.md`
|
||||
- `/home/kodi/.config/rename-mvp/contracts/API_GOLDEN.md`
|
||||
|
||||
---
|
||||
|
||||
# 2. Niet-onderhandelbare regels
|
||||
|
||||
## 2.1 Geen contractbreuk
|
||||
|
||||
Je mag geen bestaande API endpoints of bestaande response-structuren breken.
|
||||
|
||||
Je mag:
|
||||
- nieuwe velden toevoegen
|
||||
- nieuwe endpoints toevoegen
|
||||
|
||||
Je mag niet:
|
||||
- bestaande veldnamen wijzigen
|
||||
- bestaande velden verwijderen
|
||||
- response-structuren wijzigen
|
||||
- bestaande endpoints hernoemen
|
||||
- bestaande endpoints verwijderen
|
||||
|
||||
`contracts/API_GOLDEN.md` is leidend.
|
||||
|
||||
## 2.2 Geen speculative improvements
|
||||
|
||||
Voer **geen refactors, herstructureringen of “verbeteringen” uit die niet expliciet nodig zijn voor de gevraagde wijziging**.
|
||||
|
||||
Als een wijziging niet strikt nodig is om het gevraagde doel te bereiken, doe die wijziging niet.
|
||||
|
||||
## 2.3 Safe files
|
||||
|
||||
De volgende bestanden zijn beschermd en mogen alleen gewijzigd worden als dat expliciet noodzakelijk is en als je het duidelijk benoemt:
|
||||
|
||||
- `app/services/tvdb_auth_service.py`
|
||||
- `container/Containerfile`
|
||||
- `requirements.txt`
|
||||
- `contracts/API_GOLDEN.md`
|
||||
- `AGENTS.md`
|
||||
- `CHANGE_POLICY.md`
|
||||
- `SAFE_FILES.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
|
||||
## 2.4 Scopebeperking
|
||||
|
||||
Werk alleen binnen deze repository:
|
||||
|
||||
Pad op de host: `/home/kodi/.config/rename-mvp`
|
||||
Pad in deze codex omgeving: `/workspace/rename-mvp`
|
||||
|
||||
|
||||
Je mag niets aanpassen buiten deze projectscope.
|
||||
|
||||
## 2.5 Escalated execution
|
||||
|
||||
Escalated execution is toegestaan binnen deze projectscope voor:
|
||||
|
||||
- `podman build`
|
||||
- `podman run`
|
||||
- curl tests
|
||||
- lokale build- en testacties
|
||||
- bestanden aanmaken of aanpassen binnen dit project
|
||||
- dependency install binnen dit project
|
||||
|
||||
Niet toegestaan:
|
||||
|
||||
- systeembrede wijzigingen
|
||||
- firewallwijzigingen
|
||||
- system upgrades
|
||||
- andere repositories
|
||||
- andere stacks of containers aanpassen
|
||||
- destructieve cleanup acties buiten deze projectscope
|
||||
|
||||
---
|
||||
|
||||
# 3. Bestaande baseline die behouden moet blijven
|
||||
|
||||
Deze functionaliteit werkt al en mag niet stuk:
|
||||
|
||||
## 3.1 Health endpoint
|
||||
`GET /api/health`
|
||||
|
||||
Expected:
|
||||
```json
|
||||
{"status":"ok"}
|
||||
```
|
||||
|
||||
## 3.2 TVDB login endpoint
|
||||
`POST /api/tvdb/login`
|
||||
|
||||
Doet een expliciete forced login en vraagt een nieuw token aan.
|
||||
|
||||
Deze endpoint is **alleen voor debugging en handmatige auth-tests**, niet voor regressietests.
|
||||
|
||||
## 3.3 TVDB auth-status endpoint
|
||||
`GET /api/tvdb/auth-status`
|
||||
|
||||
Deze endpoint moet de actuele auth-status tonen inclusief:
|
||||
- configured
|
||||
- has_token
|
||||
- issued_at
|
||||
- expires_at
|
||||
- expires_at_unix
|
||||
- renew_after
|
||||
- renew_after_unix
|
||||
- is_expired
|
||||
- is_renewal_due
|
||||
- last_login_attempt_at
|
||||
- last_login_success_at
|
||||
- last_login_status
|
||||
- last_login_error
|
||||
- jwt_payload
|
||||
- token_source
|
||||
|
||||
## 3.4 TVDB search endpoint
|
||||
`GET /api/tvdb/search?q=elsbeth`
|
||||
|
||||
Deze endpoint werkt al en moet series teruggeven met ten minste:
|
||||
- id
|
||||
- name
|
||||
- year
|
||||
- display_name
|
||||
|
||||
De UI en bestandsnaamopbouw moeten het **jaartal van de serie** gebruiken.
|
||||
|
||||
## 3.5 Token lifecycle
|
||||
De TVDB bearer token is een JWT.
|
||||
Gebruik:
|
||||
- `exp` als primaire bron voor expiry
|
||||
- `iat` indien aanwezig
|
||||
- renew alleen wanneer nodig
|
||||
- niet onnodig opnieuw `/login` doen
|
||||
|
||||
De token mag **niet continu vernieuwd worden**.
|
||||
|
||||
## 3.6 token_source
|
||||
De auth-state gebruikt:
|
||||
- `none`
|
||||
- `login`
|
||||
- `cached`
|
||||
- `renewed`
|
||||
|
||||
Dit gedrag moet behouden blijven.
|
||||
|
||||
---
|
||||
|
||||
# 4. Functioneel doel van de applicatie
|
||||
|
||||
De uiteindelijke webapp moet een minimalistische 4-panel interface hebben.
|
||||
|
||||
## Paneel 1 — TVDB Search
|
||||
Functie:
|
||||
- zoekterm invoeren
|
||||
- zoeken via backend naar TheTVDB
|
||||
- resultaten tonen
|
||||
- gekozen serie details tonen
|
||||
|
||||
Zoekresultaten moeten minimaal tonen:
|
||||
- serienaam
|
||||
- jaar
|
||||
- first aired indien beschikbaar
|
||||
- network indien beschikbaar
|
||||
- poster indien beschikbaar
|
||||
|
||||
De series moeten in de UI worden weergegeven als bijvoorbeeld:
|
||||
|
||||
- `Elsbeth (2024)`
|
||||
- `The Office (2005)`
|
||||
|
||||
## Paneel 2 — Episodes
|
||||
Functie:
|
||||
- afleveringen van gekozen serie tonen
|
||||
- minimaal `Aired Order` ondersteunen
|
||||
- afleveringen per seizoen tonen
|
||||
- gebruiker kan willekeurige afleveringen selecteren
|
||||
|
||||
Afleveringen tonen bijvoorbeeld:
|
||||
- `S02E03 - Devil's Night - 2025-03-13`
|
||||
|
||||
## Paneel 3 — Selected Episodes
|
||||
Functie:
|
||||
- lijst van gekozen afleveringen voor de huidige sessie
|
||||
|
||||
Functionaliteit:
|
||||
- toevoegen
|
||||
- verwijderen
|
||||
- clear
|
||||
- reorder
|
||||
- move up / move down
|
||||
|
||||
## Paneel 4 — Selected Files
|
||||
Functie:
|
||||
- lijst van gekozen lokale videobestanden
|
||||
|
||||
Functionaliteit:
|
||||
- Add Files
|
||||
- Add Directory
|
||||
- Sort
|
||||
- Remove
|
||||
- Clear
|
||||
- Move Up / Move Down
|
||||
|
||||
## Workflow
|
||||
1. user zoekt serie
|
||||
2. user kiest serie
|
||||
3. backend haalt afleveringen op
|
||||
4. user voegt afleveringen toe aan selected episodes
|
||||
5. user voegt bestanden toe aan selected files
|
||||
6. backend maakt een 1-op-1 mapping op basis van volgorde
|
||||
7. backend maakt preview
|
||||
8. user bevestigt
|
||||
9. backend voert rename uit
|
||||
|
||||
---
|
||||
|
||||
# 5. Bestandsnaamopbouw
|
||||
|
||||
De standaard bestandsnaam moet zijn:
|
||||
|
||||
```text
|
||||
{series} ({year}) - S{season:02}E{episode:02} - {title}{ext}
|
||||
```
|
||||
|
||||
Voorbeeld:
|
||||
|
||||
```text
|
||||
Elsbeth (2024) - S02E03 - Devil's Night.mkv
|
||||
```
|
||||
|
||||
Belangrijk:
|
||||
- het **serienaam-jaartal** is verplicht onderdeel van de naam
|
||||
- het jaartal komt uit TheTVDB serie metadata
|
||||
- de UI moet dit jaartal ook tonen
|
||||
|
||||
De eerste MVP hoeft **airdate niet per se in de filename** te zetten zolang het afgesproken template hierboven intact blijft.
|
||||
|
||||
---
|
||||
|
||||
# 6. TVDB authenticatie en tokenbeheer
|
||||
|
||||
## 6.1 Authflow
|
||||
Gebruik de officiële TVDB v4 flow:
|
||||
- `POST /login`
|
||||
- body bevat `apikey`
|
||||
- `pin` alleen meesturen als aanwezig
|
||||
- response bevat bearer token
|
||||
|
||||
## 6.2 JWT verwerking
|
||||
De token is een JWT.
|
||||
|
||||
Verplicht:
|
||||
- decodeer payload
|
||||
- lees `exp`
|
||||
- lees `iat` indien aanwezig
|
||||
- gebruik `exp` als primaire expiry-bron
|
||||
|
||||
## 6.3 Opslag
|
||||
TVDB auth state wordt persistent opgeslagen in:
|
||||
|
||||
`/app/data/tvdb_auth.json`
|
||||
|
||||
Hostpad:
|
||||
|
||||
`/home/kodi/.config/rename-mvp/data/tvdb_auth.json`
|
||||
|
||||
In JSON mogen staan:
|
||||
- token
|
||||
- issued_at
|
||||
- expires_at
|
||||
- expires_at_unix
|
||||
- renew_after
|
||||
- renew_after_unix
|
||||
- last_login_attempt_at
|
||||
- last_login_success_at
|
||||
- last_login_status
|
||||
- last_login_error
|
||||
- jwt_payload
|
||||
- token_source
|
||||
|
||||
Niet in JSON:
|
||||
- `TVDB_API_KEY`
|
||||
- `TVDB_PIN`
|
||||
|
||||
Die moeten uit environment variables komen.
|
||||
|
||||
## 6.4 Renew-logica
|
||||
Renew alleen wanneer:
|
||||
- `now >= renew_after`
|
||||
- of TVDB `401` teruggeeft
|
||||
|
||||
Niet continu nieuwe tokens opvragen.
|
||||
|
||||
`POST /api/tvdb/login` is geen regressietest en geen normale flow; het is een debug endpoint.
|
||||
|
||||
---
|
||||
|
||||
# 7. Toegestane videopaden
|
||||
|
||||
De container moet dezelfde videopaden gebruiken als de host.
|
||||
|
||||
## Allowed media roots
|
||||
|
||||
- `/Volumes/8TB/Shared_Folders/TV_Shows`
|
||||
- `/Volumes/8TB_RAID1/Shared_Folders/Library/TV_Shows`
|
||||
|
||||
## Volume mappings
|
||||
|
||||
- `/Volumes/8TB/Shared_Folders/TV_Shows -> /Volumes/8TB/Shared_Folders/TV_Shows`
|
||||
- `/Volumes/8TB_RAID1/Shared_Folders/Library/TV_Shows -> /Volumes/8TB_RAID1/Shared_Folders/Library/TV_Shows`
|
||||
- `/home/kodi/.config/rename-mvp/data -> /app/data`
|
||||
|
||||
De app mag alleen lezen/schrijven binnen een van de toegestane media roots.
|
||||
|
||||
---
|
||||
|
||||
# 8. Securitymodel
|
||||
|
||||
## Bestandspaden
|
||||
Nooit:
|
||||
- absolute clientpaden blind vertrouwen
|
||||
- `..` toestaan
|
||||
- buiten allowed media roots resolven
|
||||
|
||||
Altijd:
|
||||
- path validation doen
|
||||
- binnen allowlist van media roots blijven
|
||||
- alleen toegestane extensies accepteren
|
||||
- preview afdwingen vóór rename
|
||||
|
||||
## Allowed extensions MVP
|
||||
- `.mkv`
|
||||
- `.mp4`
|
||||
- `.avi`
|
||||
- `.m4v`
|
||||
- `.srt`
|
||||
|
||||
## Logging
|
||||
Nooit loggen:
|
||||
- API keys
|
||||
- bearer tokens
|
||||
- env secrets
|
||||
|
||||
---
|
||||
|
||||
# 9. Container en runtime
|
||||
|
||||
## Containerfile
|
||||
De bestaande werkende runtime moet behouden blijven.
|
||||
|
||||
## Rootless Podman
|
||||
De applicatie draait rootless.
|
||||
|
||||
## Lokale test-URL
|
||||
Gebruik voor runtime-tests de BASE_URL die bereikbaar is vanuit de huidige omgeving:
|
||||
|
||||
- op de host meestal: http://127.0.0.1:8085
|
||||
- in sandbox/container-omgevingen meestal: http://host.containers.internal:8085
|
||||
|
||||
Gebruik niet automatisch localhost.
|
||||
|
||||
De testscripts moeten BASE_URL automatisch detecteren of expliciet meegegeven krijgen.
|
||||
|
||||
---
|
||||
|
||||
# 10. Verwachte repositorystructuur
|
||||
|
||||
Houd deze structuur aan. Geen onnodige nieuwe mappen toevoegen.
|
||||
|
||||
```text
|
||||
/home/kodi/.config/rename-mvp
|
||||
├── AGENTS.md
|
||||
├── CHANGE_POLICY.md
|
||||
├── SAFE_FILES.md
|
||||
├── regression_tests.sh
|
||||
├── feature_test_template.sh
|
||||
├── requirements.txt
|
||||
├── .env
|
||||
├── .env.example
|
||||
├── README.md
|
||||
├── app/
|
||||
├── container/
|
||||
├── data/
|
||||
├── contracts/
|
||||
│ └── API_GOLDEN.md
|
||||
└── docs/
|
||||
└── ARCHITECTURE.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 11. API-contract dat behouden moet blijven
|
||||
|
||||
## 11.1 Health
|
||||
`GET /api/health`
|
||||
|
||||
Response:
|
||||
```json
|
||||
{"status":"ok"}
|
||||
```
|
||||
|
||||
## 11.2 TVDB Login
|
||||
`POST /api/tvdb/login`
|
||||
|
||||
Response bevat ten minste:
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"issued_at": "...",
|
||||
"expires_at": "...",
|
||||
"renew_after": "..."
|
||||
}
|
||||
```
|
||||
|
||||
## 11.3 TVDB Auth Status
|
||||
`GET /api/tvdb/auth-status`
|
||||
|
||||
Response bevat ten minste:
|
||||
```json
|
||||
{
|
||||
"configured": true,
|
||||
"has_token": true,
|
||||
"expires_at": "...",
|
||||
"renew_after": "...",
|
||||
"token_source": "cached"
|
||||
}
|
||||
```
|
||||
|
||||
Meer velden zijn toegestaan, minder niet.
|
||||
|
||||
## 11.4 TVDB Search
|
||||
`GET /api/tvdb/search?q=query`
|
||||
|
||||
Response bevat ten minste:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "...",
|
||||
"name": "...",
|
||||
"year": "...",
|
||||
"display_name": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 12. Testbeleid
|
||||
|
||||
## 12.1 Verplichte regressietests na elke wijziging
|
||||
Na **iedere wijziging** moet dit script worden uitgevoerd:
|
||||
|
||||
```bash
|
||||
./regression_tests.sh
|
||||
```
|
||||
|
||||
Dit script is verplicht.
|
||||
|
||||
Het valideert de bestaande baseline en mag geen nieuw TVDB-token forceren.
|
||||
|
||||
## 12.2 Verplichte feature tests
|
||||
Na iedere wijziging moet je daarnaast **drie tests uitvoeren voor de nieuwe of gewijzigde functionaliteit**.
|
||||
|
||||
Gebruik hiervoor als basis:
|
||||
|
||||
```bash
|
||||
./feature_test_template.sh
|
||||
```
|
||||
|
||||
Deze template moet per feature worden aangepast zodat de nieuwe functionaliteit echt en mechanisch getest wordt.
|
||||
|
||||
## 12.3 Geen forced login in regressie
|
||||
Verboden als standaard regressietest:
|
||||
|
||||
```bash
|
||||
curl -X POST 127.0.0.1:8085/api/tvdb/login
|
||||
```
|
||||
|
||||
Deze endpoint is alleen voor debugging.
|
||||
|
||||
---
|
||||
|
||||
# 13. Ontwikkelworkflow voor Codex
|
||||
|
||||
Bij iedere opdracht moet je dit proces volgen:
|
||||
|
||||
1. lees eerst de bestaande governance-bestanden:
|
||||
- `AGENTS.md`
|
||||
- `CHANGE_POLICY.md`
|
||||
- `SAFE_FILES.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `contracts/API_GOLDEN.md`
|
||||
|
||||
2. vat kort samen wat je gaat wijzigen
|
||||
|
||||
3. benoem welke bestanden je wilt aanpassen
|
||||
|
||||
4. voer alleen de strikt noodzakelijke wijziging uit
|
||||
|
||||
5. draai verplichte regressietests:
|
||||
- `./regression_tests.sh`
|
||||
|
||||
6. draai drie feature tests voor de nieuwe functionaliteit
|
||||
|
||||
7. rapporteer:
|
||||
- welke bestanden zijn aangepast
|
||||
- welke regressietests zijn uitgevoerd
|
||||
- welke feature tests zijn uitgevoerd
|
||||
- welke risico’s of beperkingen er nog zijn
|
||||
|
||||
---
|
||||
|
||||
# 14. Eerste concrete opdracht aan Codex
|
||||
|
||||
Begin niet meteen met een brede refactor.
|
||||
|
||||
Begin met een gecontroleerde volgende stap.
|
||||
|
||||
## Eerste aanbevolen fase
|
||||
Bouw de volgende functionaliteit uit:
|
||||
|
||||
### Doel
|
||||
- endpoint om afleveringen van een gekozen TVDB serie op te halen
|
||||
- minimaal ondersteuning voor `aired order`
|
||||
- seriegegevens inclusief `year` behouden
|
||||
- output geschikt maken voor paneel 2 van de UI
|
||||
|
||||
### Verwachte richting
|
||||
Bijvoorbeeld iets als:
|
||||
|
||||
`GET /api/tvdb/series/{series_id}/episodes?order_type=aired`
|
||||
|
||||
Maar:
|
||||
- breek geen bestaande endpoints
|
||||
- wijzig geen bestaande auth-logica
|
||||
- wijzig geen container setup
|
||||
- gebruik bestaande TVDB token lifecycle
|
||||
- voeg tests toe
|
||||
|
||||
### Voor deze wijziging verplicht
|
||||
1. regressietests blijven slagen
|
||||
2. drie feature tests toevoegen/uitvoeren voor het nieuwe episodes endpoint
|
||||
3. output JSON valideren
|
||||
4. zoekresultaten en year-handling niet breken
|
||||
|
||||
---
|
||||
|
||||
# 15. Wat je uitdrukkelijk niet moet doen
|
||||
|
||||
- geen speculative refactors
|
||||
- geen auth-systeem herschrijven
|
||||
- geen token lifecycle vereenvoudigen
|
||||
- geen nieuwe frameworkkeuzes introduceren
|
||||
- geen projectstructuur wijzigen
|
||||
- geen governance-bestanden wijzigen tenzij expliciet nodig en gemeld
|
||||
- geen forced login gebruiken als regressietest
|
||||
- geen container- of pathmodel veranderen
|
||||
|
||||
---
|
||||
|
||||
# 16. Samenvatting voor Codex
|
||||
|
||||
Dit project heeft al een werkende baseline.
|
||||
|
||||
Jouw taak is niet om het project opnieuw te ontwerpen, maar om het gecontroleerd uit te bouwen.
|
||||
|
||||
Belangrijkste regels:
|
||||
- behoud werkende baseline
|
||||
- breek geen API contract
|
||||
- gebruik JWT `exp` als expiry-bron
|
||||
- renew token alleen wanneer nodig
|
||||
- gebruik seriejaar in UI en filename
|
||||
- werk alleen binnen allowed media roots
|
||||
- draai altijd `./regression_tests.sh`
|
||||
- draai altijd drie feature tests voor nieuwe functionaliteit
|
||||
- geen speculative improvements
|
||||
- escalated execution is toegestaan binnen alleen deze projectscope
|
||||
Reference in New Issue
Block a user