Flexibele kluissoorten: soorten in de database, beheer op de website

- Tabellen vault_categories en vault_category_fields (db/21), startrijen handmatig (db/handmatig/21b)
- VaultCategoryService met regels voor zichtbaarheid, gebruik en eigen velden
- Beheer > Kluissoorten (/beheer/soorten) met gebruikstellers; soort in gebruik niet te verwijderen
- Kluis en Nalatenschap (web en app) tonen soorten en eigen velden uit de database
- Socketprotocol: vault.categories; GRANTs voor mijnbesluit_app in db/02
- db/20 herhaalbaar gemaakt
- App versie 1.1 (versiecode 3)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MGLqt1uKfNARQHut9ifcx
This commit is contained in:
jf
2026-10-20 08:15:40 +00:00
co-authored by Claude Sonnet 5.5
parent a3a0bcfc05
commit af13d0e533
36 changed files with 2540 additions and 94 deletions
+1
View File
@@ -104,6 +104,7 @@ in plaats van dat er stilletjes onzin uit komt.
Bewust leesbaar, omdat er anders niet te zoeken of te sorteren valt:
- de titel en de categorie van een kluisitem;
- de naam van een kluissoort die de beheerder zelf maakte (zie [Kluissoorten](Kluissoorten.md));
- het onderwerp, de afzender, de ontvanger en de bezorgdatum van een bericht;
- namen, e-mailadressen en relaties.
+74
View File
@@ -0,0 +1,74 @@
# Kluissoorten
Wat iemand in zijn kluis kan vastleggen (Wachtwoord, Polis, Uitvaartwens, ... en alles wat de
beheerder er zelf bij zet, zoals "Niet reanimeren" of "Dementie") staat in de database en niet in de
code. Een nieuwe soort vraagt daarom **geen nieuwe versie van de app** in de Play Store of App Store.
## Hoe het werkt
* Tabel `vault_categories`: één rij per soort. Nummers 1-11 en 99 (Overig) zijn de ingebouwde
soorten en houden hun oude nummer; soorten die de beheerder maakt beginnen bij 100.
`vault_items.category` blijft een gewoon getal.
* Tabel `vault_category_fields`: de velden van een eigen soort (label, soort veld, keuzes, hulptekst,
verplicht, actief, volgorde).
* De app en de website vragen de lijst op bij de server (`vault.categories`) en tekenen het
formulier van een eigen soort naar zijn velden. Een ingebouwde soort heeft zijn invulscherm in de
app zelf; die velden zijn niet te wijzigen. Wil je voor iets als "Polis" andere velden, maak dan
een eigen soort.
* De ingevulde waarden van een eigen soort staan versleuteld in `VaultPayload.Velden`, op de vaste
`sleutel` van het veld. Een label hernoemen mag dus zonder dat iemands gegevens loskomen van hun veld.
## Regels
1. **Wat in gebruik is verdwijnt nooit.** Een soort met kluisitems kan niet worden verwijderd,
alleen op niet-actief gezet. Een niet-actieve soort staat niet meer in de lijst van wie hem nog
nooit gebruikte; wie er al een item van heeft, ziet hem nog en kan zijn items gewoon bekijken en
wijzigen. Hetzelfde geldt voor een veld: met items eronder kan het alleen op niet-actief.
2. **De beheerder ziet aantallen, nooit inhoud.** Per soort zie je hoeveel items en hoeveel mensen,
niet wie en niet wat.
3. **"Bespreken met" is een instelling per soort.** Startwaarden: aan bij Uitvaartwens en
Donorcodicil, uit bij de rest.
4. **De server controleert alles.** Een oudere of andere app stuurt wat hij wil: alleen bekende
velden blijven over, verplichte velden moeten gevuld zijn en datums moeten kloppen.
## Privacy: de naam van een soort is leesbaar voor de server
Alleen de *inhoud* van een kluisitem is versleuteld. De titel en de soort staan leesbaar in de
database, net als de naam die de beheerder aan een soort geeft. Een soort die "Dementieverklaring"
heet, zet dat woord dus in de database en laat zien hoe vaak het gebruikt wordt. Kies een neutrale
naam als de soort zelf iets over gezondheid zegt, en zet het gevoelige deel in de velden: die
waarden blijven versleuteld. Het beheerscherm waarschuwt hiervoor.
## Beheren
Website, ingelogd als beheerder: **Beheer > Kluissoorten** (`/beheer/soorten`). Daar maak je een
soort, hernoem je hem, zet je hem actief of niet-actief, kies je de plek in de lijst, zet je
"bespreken met" aan of uit en beheer je de velden. Elke wijziging komt in het logboek
(`KluisSoortBeheerd`).
## Uitrollen
1. **Database, eenmalig als root** (in cmd, niet in PowerShell). De uitrolagent heeft een beperkt
account dat tabellen mag maken maar geen gegevens mag invoegen en geen rechten mag uitdelen;
daarom zitten deze twee stappen niet in de uitrol zelf:
```
mysql -u root -p < db\02_applicatiegebruiker.sql
mysql -u root -p mijnbesluit < db\handmatig\21b_kluissoorten_startrijen.sql
```
De eerste geeft de applicatiegebruiker rechten op de twee nieuwe tabellen (zonder die rechten
krijgt de server "SELECT command denied"), de tweede zet de twaalf bestaande soorten erin.
Beide mogen opnieuw gedraaid worden. Controle: de tweede meldt `aantal_soorten` 12.
2. **Uitroller:** `21_kluissoorten.sql` maakt de tabellen (de uitrolagent draait dit mee),
daarna komen de website en de SocketServer. Draai stap 1 vóór je uitrolt: de nieuwe server leest
die tabellen meteen.
3. Nieuwe versie van de app (verhoog `ApplicationVersion`) voor Android en iOS. Die versie kan het
formulier van een eigen soort tekenen. Oudere versies blijven werken: een eigen soort toont
daar als "Overig", de items zijn zichtbaar maar niet te wijzigen (de server weigert, zodat er niets
van de ingevulde velden verloren gaat). Alleen de soorten zelf hoeven daarna nooit meer een release.
## Wat nog meer zonder release kan
Niet gebouwd, wel mogelijk op dezelfde manier: een mededelingenbalk in de app, een minimaal vereiste
appversie, de lijst met sociale media en instelwaarden (bezwaartermijn, limieten).
+2
View File
@@ -74,6 +74,8 @@ aanvoelt. Bij `"Error"` staat in `message` een tekst die je zo aan de gebruiker
| `vault.list` | ja | Titels en categorieën (geen inhoud) |
| `vault.open` | ja | Eén item ontsleutelen |
| `vault.save` | ja | Item versleuteld opslaan |
| `vault.categories` | ja | De soorten kluisitems die jij te zien krijgt: de actieve plus die waar je al een item van hebt, met naam, uitleg, "bespreken met" en bij een eigen soort de velden van het formulier |
| `vault.category` | ja | Eén soort op nummer, ook als hij niet actief is (nodig om het item van een ander te lezen); alleen de beschrijving, nooit inhoud |
| `message.inbox` / `message.outbox` | ja | Berichten voor en door jou |
| `message.read` | ja | Bericht lezen en als gelezen markeren |
| `message.compose` | ja | Bericht klaarzetten |