# Tijdelijk Persoonlijk

Staycation-planner voor familieactiviteiten, gebouwd als Flask-app in de persoonlijke productieomgeving.

## Toelichting

De app helpt Ardy, Marije, Isis en Ids om samen plannen te verzamelen voor de staycation. Het eerste scherm heet `Start`. Een nieuw toestel voert daar eenmalig de toegangscode in en kiest daarna gewoon een naam. Die naam wordt lokaal onthouden, maar dezelfde gebruiker kan ook vanaf een ander toestel werken zolang dat toestel de toegangscode heeft ingevoerd.

Iedereen kan ideeen toevoegen in de groepen Overdag, Lunch, Diner en Avond. Een idee bevat een naam, omschrijving, tijdsduur, locatie, haalbaarheidsstatus en optioneel een voorkeursdatum met dagdeel. De locatie wordt in de app als Google Maps-link getoond. De maker van een idee kan het idee later openen via de titel en aanpassen.

Stemmen gaat pas open als iedere gebruiker minimaal vier ideeen heeft toegevoegd. Daarna heeft iedere gebruiker 20 punten om te verdelen. Punten kunnen later weer worden weggehaald en ergens anders worden ingezet. Als alle punten op zijn, helpt de app met een pop-up om eerst punten vrij te maken. De app toont alleen totaalscores, niet wie hoeveel punten heeft gegeven.

Iedere gebruiker heeft daarnaast 1 veto. Als het veto al gebruikt is en iemand het ergens anders wil inzetten, verschijnt een korte pop-up om het veto te verplaatsen of vrij te maken. Ook veto's worden alleen als totaal per idee getoond.

Ardy kan ideeen in het weekoverzicht zetten. Meerdere ideeen mogen in hetzelfde dagdeel staan; bij overlap markeert de app voorlopig het idee met de meeste stemmen als winnaar. Als er iets verandert, kan een dagelijkse Signal-update de wijzigingen per gebruiker bundelen. De update noemt nieuwe ideeen, aangepaste ideeen en veto's met de naam van het idee. Stemmen blijven inhoudelijk anoniem: de update meldt alleen dat iemand heeft gestemd, niet waarop of met hoeveel punten.

In het weekoverzicht kan een gebruiker op een geplande activiteit klikken om direct naar dat idee in het stemscherm te gaan. Onder de weekplanning staat ook een overzicht van ideeen die nog niet zijn ingepland.

Op de kaart van een idee in het stemscherm is zichtbaar of het idee al in de weekplanning staat. Ardy kan een geplande activiteit daar ook direct weer uit de planning halen.

## Functionaliteit

- Gebruikers: Ardy, Marije, Isis en Ids.
- De gekozen gebruiker wordt op het toestel onthouden.
- Een onbekend toestel moet eenmalig toegang krijgen met code `060874`; daarna kunnen gebruikers vanaf meerdere toestellen werken.
- Ideeen hebben een groep, naam, omschrijving, tijdsduur, locatie, haalbaarheid en eventueel een voorkeursdatum met dagdeel.
- Gebruikers kunnen hun eigen ideeen openen en wijzigen via de titel van het idee.
- Groepen: Overdag, Lunch, Diner, Avond.
- Stemmen opent pas als iedere gebruiker minimaal vier ideeen heeft toegevoegd.
- Iedere gebruiker heeft 20 punten en kan die punten vrij herverdelen over de ideeen.
- Iedere gebruiker heeft 1 veto en kan dat veto verplaatsen.
- Een dagelijkse Signal-update kan wijzigingen bundelen als er die dag iets is aangepast.
- Ideeen en stemmen worden gedeeld opgeslagen in `data/staycation_state.json`.
- Ardy is hoofdgebruiker en kan ideeen in het weekoverzicht plaatsen.
- Weekkaarten linken terug naar het bijbehorende idee in het stemscherm.
- Geplande plekken en planningknoppen op de stemkaart zijn alleen zichtbaar voor Ardy en kunnen daar door Ardy worden verwijderd.
- Het weekoverzicht toont ook ideeen die nog niet zijn ingepland.
- Het weekoverzicht loopt van zaterdag 18 juli 2026 tot en met zaterdag 25 juli 2026.
- Meerdere ideeen kunnen in hetzelfde dagdeel staan; bij overlap wordt het idee met de meeste stemmen als voorlopige winnaar gemarkeerd.
- De mobiele interface heeft aparte tabs voor start/toegang, ideeen toevoegen, stemmen en weekoverzicht.

## Lokaal starten

```powershell
cd "C:\dev\persoonlijk\tijdelijk-persoonlijk"
python tijdelijk_persoonlijk_app.py
```

Open daarna `http://127.0.0.1:6005/staycation`.

Health-check: `http://127.0.0.1:6005/staycation/health`.

Root favicon fallback: `http://127.0.0.1:6005/favicon.ico`.

## Productie in de persoonlijke container

Deze app draait als tijdelijke Flask-appgroep op poort `6005`.

Voeg de labels uit `deploy/traefik-labels.yml` toe aan de bestaande persoonlijke containerstack. Daarmee wordt alles onder `https://me.ardyduwel.net/staycation` naar deze Flask-app gestuurd.

Dezelfde labels sturen ook `https://me.ardyduwel.net/favicon.ico` naar deze app. Dat voorkomt dat browsers met een root-favicon-aanvraag de Apache-root raken.

Voeg de inhoud van `deploy/supervisord-staycation.conf` toe aan de bestaande supervisord-config. Daarmee start de container deze tijdelijke appgroep automatisch op poort `6005`.

De Signal-update draait als extra supervisord-proces `staycation-signal-digest`. Deze taak verstuurt maximaal 1 update per dag, alleen als er wijzigingen klaarstaan. Zet hiervoor in de containeromgeving:

```text
SIGNAL_SENDER=+316...
SIGNAL_RECIPIENTS=+316...,+316...
```

Of gebruik een Signal-groep:

```text
SIGNAL_SENDER=+316...
SIGNAL_GROUP_ID=...
```

Optioneel:

```text
SIGNAL_CLI_BIN=signal-cli
STAYCATION_SIGNAL_HOUR=20
STAYCATION_SIGNAL_MINUTE=0
STAYCATION_TIMEZONE=Europe/Amsterdam
STAYCATION_ACCESS_TOKEN=060874
```

Een dry-run toont welk bericht verstuurd zou worden, zonder Signal te gebruiken en zonder wijzigingen uit de wachtrij te verwijderen:

```powershell
cd "C:\dev\persoonlijk\tijdelijk-persoonlijk"
python staycation_signal_digest.py --dry-run --force
```

Volgende tijdelijke apps in deze projectmap kunnen onder dezelfde basisroute worden toegevoegd, bijvoorbeeld `/staycation/nieuwe-app`, zonder een extra Traefik-router te maken.

## Project

- Lokale projectmap: `C:\dev\persoonlijk\tijdelijk-persoonlijk`
- Git-remote: `\\netdrive_new\mounts\codex-git\tijdelijk-persoonlijk.git`
- Productiemap: `\\netdrive_new\web\persoonlijk\tijdelijk-persoonlijk`
- Database slug: `tijdelijk_persoonlijk`
