Eén app store, twee apps
umbrelOS leest per store één repo, dus twee apps in twee repo's kan niet. Deze repo is de store en bevat vanaf nu Electrum Gate en het werk aan Evolu Relay. Opgezet als verse repo op verzoek van de gebruiker: de historie van ElectrumTLS en van EvoluRelay komt niet mee. Dat heeft één gevolg dat verder gaat dan opruimen. In de historie van ElectrumTLS staat het domein van de gebruiker en het certificaatpad, van vóór de opschoning van 19-08. Die komt hier niet in. Zolang die repo op de Git-server blijft staan verandert dat niets, dus het weghalen ervan is het laatste stuk van open punt 3 van het plan Appstore, en geen bijzaak. De store zelf hoefde niet te veranderen: store-id whatsnext, en dus blijft het app-id whatsnext-electrum-gate. Dat hangt aan het store-id en niet aan de URL, dus voor umbrelOS is dit dezelfde app in een andere store. Dat de store op 19-08 naar de maker genoemd werd in plaats van naar deze ene app, betaalt zich hier uit. Wat de documentatie betreft is dit één wortel voor beide apps, en dat was de reden om samen te voegen en niet de prijs ervan: de appstore-spec, het pinnen van images en de werkwijze golden al voor allebei en stonden in twee repo's naast elkaar. De kruisverwijzing die daarvoor nodig was (Referenties/Umbrel-appstore.md in de oude EvoluRelay-repo) is verdwenen; wat daarin stond over de plekken waar de relay een ander geval is, staat nu als ontwerp in het masterplan Umbrelapp §4. Botsende namen kregen een achtervoegsel met de app, en alleen die: Publicatie werd Publicatie-Gate en Publicatie-Relay, CHANGELOG.md werd CHANGELOG-electrum-gate.md. Proefopstelling kreeg 007, tussen de twee bestaande nummers, zodat de bovenkant van de reeks op tier-orde blijft staan. CONTINUE_HERE.md heeft een kolom App, maar de tiers lopen over beide apps heen: er is één volgorde van werken. Electrum Gate gaat naar 0.0.15, want website, repo, support, submission en icon wijzen nu naar UmbrelApps en zonder versieverhoging rolt dat niet uit. De release notes leggen aan de gebruiker uit dat hij de store opnieuw moet toevoegen. Of een geïnstalleerde app een wisseling van store-URL overleeft is nog steeds niet uitgezocht; dat blijkt bij het omzetten. Twee dingen in de plannen van Electrum Gate waren door deze verhuizing niet meer waar en zijn bijgewerkt: de taak "de repo hernoemen" in fase 7 is afgevinkt, en de repo-vorm in PLAN.md §4a toonde nog de store-id electrumtls, die al sinds fase 7 achterhaald was. Tests: 39 goed 0 fout en 54 goed 0 fout, niets overgeslagen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# Open punten - Webinterface
|
||||
|
||||
> Beslissingen die nog een **eigenaar** of een **moment** nodig hebben. Wordt een punt een taak, dan
|
||||
> verhuist het naar [TAKEN.md](TAKEN.md).
|
||||
>
|
||||
> **Nummers blijven staan**, ook als een punt beslist is: er kan elders naar verwezen worden. Beslissen
|
||||
> betekent verplaatsen naar de kop hieronder, niet hernummeren.
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
3. **Komt het activiteitenlog er?**
|
||||
Toegevoegd 19-08-2026, nadat de gebruiker vroeg of er iets over live client-aanroepen te tonen is, en
|
||||
bijgesteld naar logregels onder elkaar. Het ontwerp staat in [PLAN.md](PLAN.md) §4e en de kaart staat
|
||||
al op de pagina in de `no data`-toestand, dus de vorm is te beoordelen zonder dat er iets gebouwd is.
|
||||
|
||||
Wat er beslist moet worden is niet "kan het" maar "is dit het waard, nu het niet is wat er gevraagd
|
||||
werd". Er was gevraagd om **elk verzoek** te loggen, en dat kan niet zonder het Electrum-verkeer van de
|
||||
gebruiker uit te lezen. Wat overblijft is een regel per verbinding en per verkeerspiek. Het vraagt een
|
||||
`log_format` die langs de template-invulling moet, plus een tweede weg naar de bytetellers van een
|
||||
lopende verbinding, want nginx logt een stream-sessie pas bij het sluiten en een wallet houdt hem
|
||||
twaalf uur open.
|
||||
**Moment:** na fase 2, want dan draait de schrijflus toch al · **Eigenaar:** gebruiker
|
||||
|
||||
5. **Wordt er gecontroleerd of de TLS-poort zelf antwoordt?**
|
||||
Toegevoegd 19-08-2026, nadat de badge "Serving this page" eruit ging. De gebruiker wees erop dat die
|
||||
badge niets zei: de pagina wordt nooit getoond aan een wallet die op 50022 verbindt. Mijn gedachte
|
||||
erachter was dat de pagina en de TLS-terminatie in dezelfde container zitten, dus dat de een de ander
|
||||
bewijst, maar dat stond er niet en niemand leest het zo.
|
||||
|
||||
Wat daarbij opvalt en het eigenlijke punt is: **de app controleert wel of de Electrum-server antwoordt,
|
||||
maar niet of hij zelf antwoordt.** Dat is precies zijn enige taak. De agent zou een TLS-verbinding naar
|
||||
de eigen poort kunnen opzetten en de handdruk kunnen afmaken; dat bewijst het luisteren, het certificaat
|
||||
en de doorverbinding in één keer, en het is dezelfde truc waarmee de einddatum van het actieve
|
||||
certificaat te lezen valt.
|
||||
|
||||
Waarom het nog geen taak is: het raakt de agent, en die heeft nog nooit gedraaid. Er is weinig aan om
|
||||
een tweede ongeteste controle op een eerste ongeteste controle te bouwen. Zodra de agent op de Umbrel
|
||||
loopt, is dit de eerstvolgende zinvolle toevoeging aan het dashboard.
|
||||
**Moment:** nadat de agent draait · **Eigenaar:** gebruiker
|
||||
|
||||
7. **Kan Zoraxy of Nginx Proxy Manager verplicht gesteld worden bij de installatie?** Gevraagd door de
|
||||
gebruiker op 20-08-2026, die erbij opmerkte dat sommige apps bij de installatie twee dropdowns tonen.
|
||||
**Technisch antwoord: nee, niet als "de een of de ander".** Nagetrokken in de bron, zie
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md) §4, met bronlinks.
|
||||
|
||||
Kort: dat dialoog toont één dropdown **per afhankelijkheid** en niet per keuze. In het schema van
|
||||
umbreld is `dependencies` een platte lijst van app-id's, en wat er in een dropdown staat komt van de
|
||||
andere kant, namelijk elke app die `implements: [<dat id>]` declareert. Het voorbeeld dat de gebruiker
|
||||
zag is `mempool` met `dependencies: [bitcoin, electrs]`. Zoraxy en NPM declareren geen `implements`,
|
||||
dus er is geen gedeelde rol om naar te wijzen, en dat staat in hún manifest en niet in het onze.
|
||||
|
||||
Wat overblijft is Zoraxy hard eisen, en dat is een dropdown met één optie. Wat er nog over te beslissen
|
||||
is, is of dat wenselijk is: het sluit de bron `Own folder` uit, en Zoraxy deïnstalleren zou deze app
|
||||
meesleuren.
|
||||
**Moment:** vrij · **Eigenaar:** gebruiker beslist
|
||||
|
||||
## Beslist
|
||||
|
||||
8. **Welke tagline, en waar?** - **Overal die van de appstore** (20-08-2026, gebruiker).
|
||||
"Your own node from anywhere, without waiting for Tor" staat nu ook op de pagina; daar stond "TLS in
|
||||
front of your own Electrum server".
|
||||
|
||||
De afweging was dat de twee lezers op een ander moment zitten: in de winkel moet de regel iemand
|
||||
overtuigen die de app niet kent, op het dashboard staat iemand die hem al draait. Dat pleit voor twee
|
||||
regels. Wat de doorslag gaf is dat deze afweging al eerder gemaakt is: bij het hernoemen naar Electrum
|
||||
Gate was de reden dat de oude naam het **middel** beschreef en niet de opbrengst. Met die maatstaf was
|
||||
de dashboardregel de achterblijver, niet de winkelregel.
|
||||
|
||||
Een toets houdt de twee plekken nu gelijk. Niet omdat het kan, maar omdat ze ver uit elkaar staan:
|
||||
niemand die het manifest aanpast, opent daarna de pagina.
|
||||
|
||||
6. **Kan een certificaat via de pagina geupload worden?** - **Ja, en gebouwd** (20-08-2026, op verzoek van
|
||||
de gebruiker). Zie [CHANGELOG-electrum-gate.md](../../../CHANGELOG-electrum-gate.md) 0.0.7 voor de vier
|
||||
stukken die het vroeg.
|
||||
|
||||
Twee besluiten die eruit voortkwamen en die het waard zijn om terug te lezen:
|
||||
|
||||
- **de bestandsnaam komt uit het certificaat en niet uit het verzoek.** Daarmee is de hele klasse
|
||||
padtrucs weg zonder dat er iets gefilterd hoeft te worden op invoer die je niet vertrouwt. Wat er
|
||||
niet in het alfabet zit gaat eruit, dus een jokerteken-certificaat voor `*.example.org` wordt
|
||||
`example.org`;
|
||||
- **uploaden kiest niet.** De nieuwe komt voorgeselecteerd in de lijst en de gebruiker drukt op de
|
||||
bestaande knop. Zo blijft er precies één plek waar TLS van certificaat wisselt, en dat is dezelfde
|
||||
reden waarom de app bij twijfel niets kiest.
|
||||
|
||||
Het geheim door een formulier: te verantwoorden omdat het pad achter de inlog van umbrelOS zit en de
|
||||
sleutel in de app-data van de gebruiker zelf landt, met rechten 0600. De agent kapt af op 96k en nginx
|
||||
ook, dus een verzoek dat te groot is komt niet eens bij de validatie.
|
||||
|
||||
|
||||
4. **Wat gebeurt er met de blokken-per-uur-grafiek in het eerste etmaal?** - **Vervallen** (19-08-2026).
|
||||
De vraag ging over een grafiek die er niet meer is: de gebruiker heeft blokken per uur diezelfde dag
|
||||
geschrapt, als grafiek én als tegel. Zie [PLAN.md](PLAN.md) §3.
|
||||
|
||||
1. **Wat toont de pagina als `status.json` ontbreekt?** - **Een neutrale melding, geen fout**
|
||||
(19-08-2026).
|
||||
"No readings yet", met de uitleg dat dit normaal is in de eerste minuten na een installatie of een
|
||||
herstart. Bewust neutraal opgemaakt en niet rood: het bestand ontbreekt in de normale gang van zaken
|
||||
even, en een foutkleur op een normale toestand leert mensen foutkleuren negeren.
|
||||
|
||||
Daarnaast blijft elk afzonderlijk veld op `unknown` staan in plaats van leeg. Een leeg veld leest als
|
||||
"in orde", en dit is de pagina die juist geraadpleegd wordt wanneer er iets mis lijkt.
|
||||
|
||||
2. **Nederlands of Engels?** - **Engels, en alles** (19-08-2026, gebruiker).
|
||||
Dat betekent de pagina én de teksten in `umbrel-app.yml`, want een Engelse pagina onder een
|
||||
Nederlandse winkelbeschrijving is een halve keuze. Codecommentaar blijft Nederlands: de
|
||||
projectafspraak koppelt zichtbare UI-tekst aan de taal van de app, en commentaar niet.
|
||||
@@ -0,0 +1,288 @@
|
||||
# Webinterface - plan
|
||||
|
||||
> Gepromoveerd op 19-08-2026 vanuit `Plannen/Masterplannen/`, omdat het werk begonnen is: de pagina is
|
||||
> herbouwd. Taken staan in [TAKEN.md](TAKEN.md), open punten in [OPEN.md](OPEN.md), de geschiedenis in
|
||||
> [PROGRESS.md](PROGRESS.md).
|
||||
>
|
||||
> **De afhankelijkheid van Configuratie is vervallen.** Die stond er omdat de pagina de ingestelde
|
||||
> waarden moet tonen. In het ontwerp dat er nu ligt haalt de pagina álles uit `status.json` en uit de
|
||||
> umbrel-variabelen, en staat er geen enkele installatiespecifieke waarde meer in het bestand. Daarmee
|
||||
> hoefde Configuratie er niet vóór, en is dit deel van Configuratie fase 2 meteen af.
|
||||
|
||||
## 1. Doel
|
||||
|
||||
De statuspagina toont verzonnen gegevens. De statuswaarden staan als de tekst `Online` in de HTML, het
|
||||
domein staat er hardgecodeerd in en er wordt niets uitgelezen. De pagina meldt dus ook "Online" als
|
||||
stunnel omgevallen is, en dat is erger dan geen pagina: hij wordt geraadpleegd juist wanneer er iets mis
|
||||
lijkt, en geeft dan het verkeerde antwoord.
|
||||
|
||||
Als dit af is, toont de pagina alleen dingen die waar zijn, of hij zegt dat hij het niet weet.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
Vastgesteld op 18-08-2026, na het zien van de pagina in bedrijf.
|
||||
|
||||
- De verzonnen status en het verzonnen logvenster eruit.
|
||||
- **Blokhoogte en backend-status.** De hoogte via het Electrum-protocol, plus welke implementatie actief
|
||||
is en of hij antwoordt. Dit is meteen de echte gezondheidscontrole.
|
||||
- **Certificaat:** geldig tot, resterende dagen, een zichtbare waarschuwing onder de dertig dagen, en het
|
||||
tijdstip van de laatste herlading.
|
||||
- **Reactietijd van de backend**, en de geschiedenis daarvan als sparkline.
|
||||
- Aansluiten op het design-systeem in `HomeGit/Docs/website-design-system.html`: donker-eerst met een
|
||||
lichte variant, tokens voor kleur en radius, en de bestaande componenten `card`, `card-stat`, `badge`,
|
||||
`alert` en `list-item`.
|
||||
- **Verbindingsregels per client**, met kopieerknop. Toegevoegd 19-08-2026 op verzoek van de gebruiker.
|
||||
De ene wallet wil `domein:poort:s` op één regel, de andere wil host en poort in aparte velden met SSL
|
||||
aangevinkt, en juist die kleine verschillen kosten mensen tijd. De rijen komen uit
|
||||
[Referenties/Clients.md](../../Referenties/Clients.md) §4; wie er een bijzet, zet hem daar ook bij.
|
||||
- **Een activiteitenlog**, zie §4e. Herziening van een eerder niet-doel.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **Een backend of API.** Zodra de pagina iets moet opvragen, is er een proces nodig dat luistert, en dan
|
||||
is dit geen configuratie-app meer. De weg eromheen staat in §4.
|
||||
- **Live logs, in de zin van een logvenster.** Ruwe logregels in de browser vragen precies de backend uit
|
||||
het vorige punt, en bij een TLS-proxy staan er verbindingsgegevens in. `docker logs` blijft de plek
|
||||
voor de echte logs. Wat er **wel** komt is een uitgedunde samenvatting per sessie; zie §4e. Dat is
|
||||
op 19-08-2026 herzien op verzoek van de gebruiker, en het is een andere zaak dan een logvenster.
|
||||
- **Instellingen bewerken in de pagina.** Uitdrukkelijk zo besloten in het plan **Configuratie**.
|
||||
- **Koersgegevens en koersgrafieken.** Besloten op 18-08-2026, na afweging. Het vraagt een externe API,
|
||||
en dan haalt de browser van iedereen die dit dashboard opent data op bij een derde partij. Bij een
|
||||
zelfgehoste Bitcoin-opstelling is dat precies het soort lek dat deze app juist dichtzet, en umbrelOS
|
||||
heeft er bovendien al widgets voor. **Alles op het dashboard komt uit lokale bronnen.**
|
||||
- **Verbindingen per uur als grafiek.** Kan wel, maar bij één of twee wallets is die grafiek vrijwel
|
||||
leeg. Het activiteitenlog uit §4e dekt dezelfde vraag beter.
|
||||
- **De blokhoogte zelf als grafiek.** Die loopt met ongeveer één per tien minuten omhoog, dus het is
|
||||
altijd dezelfde schuine lijn.
|
||||
- **Blokken per uur, in welke vorm dan ook.** Geschrapt op 19-08-2026 door de gebruiker, nadat het als
|
||||
grafiek én als tegel op de pagina had gestaan. Het antwoordt op een vraag die de gebruiker niet heeft:
|
||||
of de node meekomt met het netwerk is de zorg van de Electrum-server en niet van deze proxy, en de
|
||||
blokhoogte zelf zegt dat al. Gevolg voor het ontwerp: `history` in `status.json` hoeft alleen nog de
|
||||
reactietijd te bewaren, want de sparkline is de enige afnemer.
|
||||
- **De afweging Tor tegenover TLS op het dashboard.** Ook 19-08-2026, door de gebruiker. Die uitleg is
|
||||
positionering en hoort in de winkelbeschrijving in `umbrel-app.yml`, waar iemand staat te kiezen. Wie
|
||||
het dashboard opent, heeft al gekozen en komt iets nakijken. De onderbouwing blijft in
|
||||
[Referenties/Clients.md](../../../Referenties/Clients.md) §1 staan; die voedt nu alleen de marketing.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
### 4a0. Wél een backend, en waarom die er alsnog is
|
||||
|
||||
Herzien op 19-08-2026, nadat de gebruiker vroeg of de WebDAV-truc uit §4f van
|
||||
**Configuratie** eigenlijk de gebruikelijke manier is om een backend in een Umbrel-app te bouwen. Het
|
||||
antwoord was nee, en het onderzoek eromheen veranderde deze paragraaf.
|
||||
|
||||
**Wat umbrelOS zelf aanbiedt is één instelling per app: de afhankelijkheidskeuze.** In
|
||||
`AppSettingsSchema` staat `dependencies: z.record(z.string())` en verder niets. Daarom kostte het wisselen
|
||||
tussen Electrs, Fulcrum en ElectrumX twee regels: dát mechanisme bestaat. Er is géén generiek
|
||||
instellingenformulier dat een community-app kan declareren, en de andere umbrel-haken (`hooks/`,
|
||||
`exports.sh`, `*.template`) zijn er voor het opstarten en voor andere apps, niet voor de gebruiker.
|
||||
|
||||
**Apps die wél instelbare configuratie hebben, zijn zelf een backend.** Nginx Proxy Manager, Home
|
||||
Assistant en Jellyfin brengen hun eigen server en hun eigen instellingenscherm mee, in hun eigen image.
|
||||
umbrelOS levert dat scherm niet; de app doet het. De juiste conclusie is dus niet "umbrelOS heeft er iets
|
||||
voor" maar "die apps hebben een backend".
|
||||
|
||||
**Besluit van de gebruiker: een tweede container met een klein programma.** Een officiële
|
||||
`python:3-alpine`, met het script uit `agent.py.template` zodat het bij een update meekomt. Geen eigen
|
||||
image, dus geen bouwstap, geen registry en geen multi-arch-gedoe. Dat laatste is de reden dat een eigen
|
||||
image afvalt, niet de complexiteit van het programma.
|
||||
|
||||
Wat die keuze onderweg oploste, en dat was de eigenlijke aanleiding:
|
||||
|
||||
- **de shell-lus was aan zijn plafond.** Een certificaatdatum lezen, een JSON-RPC-verzoek doen, een
|
||||
geschiedenis bijhouden en een keuze valideren zijn geen dingen die je met `openssl` en `nc` aan elkaar
|
||||
knoopt zonder dat het stil verkeerde antwoorden gaat geven;
|
||||
- **de controles op `openssl`, `nc` en de WebDAV-module vervallen alle drie.** De agent doet dat werk zelf
|
||||
met de standaardbibliotheek, dus de app hangt niet meer af van wat er toevallig in de nginx-image zit;
|
||||
- **het hardgecodeerde domein is weg uit `docker-compose.yml` en `nginx.conf.template`.** De agent
|
||||
schrijft `cert.conf` met de paden die hij gevonden heeft, en nginx doet daar een `include` op. Daarmee
|
||||
is dat deel van **Configuratie** fase 2 af.
|
||||
|
||||
**Wat het kost.** Een tweede container, en een echt API-oppervlak in plaats van geen. Klein, maar niet
|
||||
nul, en daarom staat de verantwoording bij de `location /api/` in `nginx.conf.template` en niet alleen
|
||||
hier.
|
||||
|
||||
**nginx herladen kan de agent niet zelf**, want dat vraagt de Docker-socket en die is er bewust uit. De
|
||||
agent zet een vlagbestand neer en de nginx-container herlaadt zichzelf zodra hij dat ziet. Die lus
|
||||
verplaatst wat eerst de certificaatbewaking was, en doet nu alleen nog dit ene ding.
|
||||
|
||||
### 4a. Statusgegevens uit status.json
|
||||
|
||||
De pagina vraagt nooit iets aan een dienst die kan omvallen: de agent schrijft elke ronde een
|
||||
`status.json`, en de pagina haalt dat op met `fetch` en vult zichzelf. Dat blijft de kern, ook nu er een
|
||||
agent is; het alternatief, een pagina die live naar de backend vraagt, zou de pagina zelf laten hangen
|
||||
als de backend hangt.
|
||||
|
||||
Wat er in staat: het domein en de poort waar de wallet heen moet, het adres en de naam van de backend, de
|
||||
blokhoogte en de reactietijd, de einddatum van het actieve certificaat, de lijst met gevonden
|
||||
certificaten, een geschiedenis van reactietijden over 24 uur, en de logregels. Plus het tijdstip van
|
||||
schrijven, en dat is het belangrijkste veld van allemaal.
|
||||
|
||||
Wat de vorm oplevert:
|
||||
|
||||
- **de pagina kan niet meer liegen over "draait het".** Elk veld heeft een zichtbare onbekend-toestand en
|
||||
nooit een lege waarde, want een leeg veld leest als "in orde". Dit is de pagina die juist geraadpleegd
|
||||
wordt wanneer er iets mis lijkt;
|
||||
- **oude gegevens zijn herkenbaar, en wel bij de waarde zelf.** Onder de blokhoogte staat "as of ... ago",
|
||||
de badge bij de backend gaat van groen naar grijs met "last answered", en de voettekst noemt het
|
||||
tijdstip. Dat is de enige manier waarop de pagina een gestopte agent kan opmerken.
|
||||
|
||||
**Bewust geen melding bovenaan daarvoor.** Die heeft er even gestaan en is er op 19-08-2026 op verzoek
|
||||
van de gebruiker uit. De afweging is het opschrijven waard, want hij geldt voor elke volgende melding
|
||||
die iemand wil toevoegen: een banner die hetzelfde zegt als wat er drie regels lager bij het getal
|
||||
staat, voegt geen informatie toe maar wel gewicht, en dat gewicht gaat ten koste van de meldingen die
|
||||
wél iets nieuws zeggen. Een melding bovenaan is er voor iets wat je nergens anders ziet, zoals een
|
||||
ontbrekend certificaat;
|
||||
- **de lus valt nooit stil.** Een mislukte ronde wordt gelogd en overgeslagen; stoppen zou de pagina op
|
||||
oude gegevens bevriezen zonder dat iemand het ziet.
|
||||
|
||||
### 4a1. De indeling van de pagina
|
||||
|
||||
Vastgesteld door de gebruiker op 19-08-2026, na het bekijken van de eerste versie.
|
||||
|
||||
**De volgorde, van boven naar beneden:** Electrum-server, de drie statustegels, de certificaatkeuze, het
|
||||
activiteitenlog, en onderaan het instellen van je wallet. De regel erachter: **eerst waar je naar kijkt
|
||||
als je iets nakomt, onderaan waar je naar kijkt als je iets instelt.** Dat laatste doe je één keer.
|
||||
|
||||
De laatste twee zijn op verzoek van de gebruiker omgedraaid ten opzichte van de eerste opzet. Dat pakte
|
||||
beter uit dan alleen als voorkeur: het certificaatkader is nu het smalle kader links en het log het brede
|
||||
rechts, waardoor de kolomgrens samenvalt met die van de rij erboven in plaats van ertegenin te lopen. En
|
||||
logregels zijn monospace, dus die hebben de breedte beter nodig dan een lijst met keuzerondjes.
|
||||
|
||||
**Twee kaders zijn er één geworden.** "Point your wallet here" en "Setting up your wallet" stelden dezelfde
|
||||
vraag, dus het verbindingsadres met de kopieerknop staat nu bovenaan het instelkader in plaats van in een
|
||||
eigen kader erboven.
|
||||
|
||||
**Breed, met kaders naast elkaar.** Twaalf kolommen, en de rijen wisselen 5/7 en 7/5 af: de
|
||||
Electrum-server naast de statustegels, het log naast de certificaatkeuze, en het instelkader vol breed.
|
||||
Afgekapt op 1760px, want op een ultrawide monitor levert een kader van 2500px regels op die niemand leest.
|
||||
|
||||
**Elk kader is hetzelfde opgebouwd.** Een `card-head` met een titel in `t-h3`, dan de inhoud. Bijgesteld op
|
||||
19-08-2026 door de gebruiker: de drie statustegels hadden een eigen kleine grijze kop in kapitalen, en dat
|
||||
maakte ze een apart soort ding zonder dat daar een reden voor was. De titel gebruikt de token
|
||||
`--text-primary` en niet letterlijk wit, want in de lichte variant is wit onzichtbaar.
|
||||
|
||||
Wat daarbij vastligt en niet per ongeluk mag verschuiven:
|
||||
|
||||
- **de leesvolgorde in de HTML ís de bedoelde volgorde.** Er staat nergens een `order` of een `row-start`
|
||||
die de opmaak laat afwijken van de bron, dus bij een smal scherm stapelt alles precies zoals het gelezen
|
||||
hoort te worden. Wie hier een kader bijzet, zet het op de goede plek in de HTML en niet op de goede plek
|
||||
in het raster;
|
||||
- **de statustegels rekken mee met hun buur**, met de titel boven en het getal onder, want van zichzelf
|
||||
zijn ze lager dan het kader ernaast en dan staat er een gat rechtsboven. De onderregel van een tegel
|
||||
heeft daarvoor dezelfde hoogte als de sparkline, anders staat het getal van "Backend response" hoger dan
|
||||
de andere twee;
|
||||
- **het logblok scrollt zelf horizontaal in plaats van af te kappen.** Met puntjes zou een smal scherm de
|
||||
bytes stil verbergen, en dat is dezelfde soort onwaarheid als een verzonnen statuswaarde;
|
||||
- **twee kaders naast elkaar zijn even hoog**, en het langste bepaalt de rij. Wat mag meegroeien zegt dat
|
||||
zelf: het logblok en de certificaatlijst. Daardoor is de certificaatlijst een scrollend vak in plaats van
|
||||
een lijst die de pagina oprekt, en dat was nodig: een gedeelde certificatenmap kan er tientallen bevatten.
|
||||
Het aantal staat in de kop, want zodra er een scrollbalk is, is niet meer te zien hoeveel er onder de rand
|
||||
staan.
|
||||
|
||||
**Bewust een lijst en geen dropdown.** De gebruiker vroeg op 19-08-2026 of een dropdown niet netter was,
|
||||
en dat is het visueel ook, maar het botst met wat dit besturingselement moet doen: je kiest hier op de
|
||||
hostnaam waarop je wallet verbindt, en dan wil je bron, naam en resterende dagen naast elkaar kunnen
|
||||
vergelijken. In een dropdown zie je er één per keer, en een verlopen certificaat kan er niet rood in
|
||||
omdat `option`-opmaak per browser verschilt. De hoogtewinst die de dropdown zou opleveren komt er met een
|
||||
scrollend vak ook, dus er hoefde niets ingeleverd te worden;
|
||||
|
||||
- **er is geen voetregel.** Er heeft er een gestaan met "Last reading ... ago" en het versienummer; die is
|
||||
er op verzoek van de gebruiker uit. De leeftijd stond al bij de waarden zelf, dus dat was een derde keer
|
||||
hetzelfde.
|
||||
|
||||
Het **versienummer** is wel gebleven, klein achter de tagline als `v0.0.3`. Dat is een aparte afweging en
|
||||
hij viel andersom uit dan de rest van de voetregel: dit project verloor een keer een dag aan een wijziging
|
||||
die niet uitrolde door een niet-verhoogde `version`, en dan is "welke versie zie ik nu eigenlijk" precies
|
||||
de vraag die je stelt. Het staat in `--text-sec` en niet in `--text-ter`, want die laatste is in de lichte
|
||||
variant `#bbbbbb` op wit en op deze grootte niet te lezen.
|
||||
|
||||
### 4b. Waarschuwen op een aflopend certificaat
|
||||
|
||||
Met de einddatum in `status.json` is dit een vergelijking in de pagina zelf: onder de dertig dagen een
|
||||
opvallende melding, verlopen een duidelijke fout. Dat is de enige echte toevoeging ten opzichte van nu,
|
||||
en hij is goedkoop omdat de datum er toch al is.
|
||||
|
||||
### 4c. Welke backend er gekozen is
|
||||
|
||||
Die volgt uit `${APP_ELECTRS_NODE_IP}` en `${APP_ELECTRS_NODE_PORT}`, maar dat is een IP-adres en geen
|
||||
naam. De adressen liggen per app vast (Electrs op `10.21.21.10`, Fulcrum op `10.21.21.200`, ElectrumX op
|
||||
`10.21.21.199`), dus een vertaaltabel kan er een naam van maken. Dat is aardig, maar het is een tabel die
|
||||
stilzwijgend veroudert als Umbrel de adressen wijzigt. Voorstel: het adres tonen, en de naam alleen als
|
||||
extra wanneer hij in de tabel staat. Dan is de pagina bij veroudering minder informatief in plaats van
|
||||
onwaar.
|
||||
|
||||
### 4e. Het activiteitenlog
|
||||
|
||||
Toegevoegd 19-08-2026, nadat de gebruiker vroeg of er iets over live client-aanroepen te tonen is, en
|
||||
diezelfde dag bijgesteld naar logregels onder elkaar in plaats van een lijst met sessiekaarten.
|
||||
|
||||
**Eerst de grens, want die bepaalt de rest. Een regel per protocolaanroep kan niet.** De wallet doet zijn
|
||||
verzoeken *binnen* één TLS-verbinding die hier getermineerd wordt en daarna als bytestroom naar de backend
|
||||
gaat. nginx `stream` kent geen verzoeken, alleen verbindingen. Ze wél tellen zou betekenen dat de app de
|
||||
Electrum-berichten van de gebruiker uitleest, en dat is precies het verkeer waarvoor deze app bestaat. Dat
|
||||
is geen implementatiedrempel maar een ontwerpgrens, en hij hoort ook op de pagina te staan zodat niemand
|
||||
denkt dat het log iets verzwijgt.
|
||||
|
||||
Wat er wél per regel in kan:
|
||||
|
||||
| Gebeurtenis | Waar het vandaan komt |
|
||||
|-|-|
|
||||
| `connect` | de verbindingsteller is opgelopen sinds de vorige ronde |
|
||||
| ~~`traffic`~~ | vervallen op 20-08-2026, zie punt 2 onderaan deze paragraaf |
|
||||
| `disconnect` | de `access_log`-regel van nginx, met duur en bytes |
|
||||
| `probe` | een sessie die eindigde zonder één byte in beide richtingen. Toegevoegd 20-08-2026: een doorgestuurde poort wordt gescand, en zonder dit onderscheid gaf elke scan een rode `refused`-regel terwijl er niets geweigerd is. Bewust op de bytes en niet op de duur of de status: een scan die tien seconden open blijft is nog steeds een scan, en een echte sessie die na een halve seconde omvalt is nog steeds een storing |
|
||||
| `refused` | de verbinding gaf wél verkeer door en liep daarna stuk. Dit is het geval dat rood mag zijn |
|
||||
| `reload` | het certificaat is gewijzigd en nginx is herladen |
|
||||
| `start` | de container is gestart en luistert |
|
||||
|
||||
Die regels komen als `log` in `status.json`, afgekapt op 24 uur. De pagina toont ze nieuwste bovenaan, in
|
||||
een monospace-blok dat scrollt.
|
||||
|
||||
**Bewust niet gelogd: het IP-adres van de client en de bronpoort.** Dat is precies het soort gegeven dat
|
||||
deze app van het netwerk af houdt, en om te zien dát het werkt is het niet nodig.
|
||||
|
||||
Twee dingen die eerst uitgezocht moeten worden, en die het bouwen kunnen blokkeren:
|
||||
|
||||
1. **Een `log_format` bevat nginx-variabelen met een dollarteken, en dit bestand is een template.** De
|
||||
invulling bij het starten vervangt die en zou ze leegmaken; dat is dezelfde valkuil die nu bovenaan
|
||||
`nginx.conf.template` beschreven staat. De uitweg is de `log_format` niet in het template te zetten
|
||||
maar door het `command`-blok in `docker-compose.yml` te laten wegschrijven als een `include`-bestand,
|
||||
want daar wordt een dollarteken al als `$$` ontsnapt. Te verifiëren.
|
||||
2. **nginx `stream` schrijft zijn regel pas bij het sluiten van de sessie.** Een verbinding die twaalf uur
|
||||
openstaat, verschijnt dus pas na afloop, en dat is de normale toestand van een wallet. Daarom komen
|
||||
`connect` en `traffic` niet uit de log maar uit de lopende verbinding; anders lijkt een actieve wallet
|
||||
afwezig. **Uitgezocht en gebouwd op 20-08-2026, nadat de gebruiker meldde dat hij van zijn verbonden
|
||||
wallet niets terugzag:**
|
||||
|
||||
- **`connect` komt uit `/proc/net/tcp`.** Kolom 2 is het lokale adres met de poort in hex, kolom 4 de
|
||||
toestand; tellen wat op `:C366` staat met toestand `01` geeft het aantal open wallet-verbindingen.
|
||||
Dat bestand geldt **per netwerk-namespace**, en daar zit de bevinding: de agent kan het niet lezen,
|
||||
want hij zit in een andere container. De teller staat daarom in de achtergrondlus van de
|
||||
nginx-container, die het aantal naar een bestand schrijft dat de agent oppikt. Zelfde patroon als de
|
||||
herlaadvlag, en om dezelfde reden: geen Docker-socket. Geteld wordt alleen het aantal;
|
||||
- **`traffic` vervalt.** Bytes van een lopende sessie zijn er niet af te lezen: `/proc/net/tcp` heeft
|
||||
geen tellers, en de interfacetellers van de container bevatten ook het dashboard- en backendverkeer.
|
||||
Wat er dan overblijft is een schatting die als meting leest, en dat is precies wat §4c verbiedt. De
|
||||
sessieregel bij het sluiten geeft de echte aantallen;
|
||||
- **de pagina toont de teller in de badge van het activiteitenlog** en niet als logregel alleen. De
|
||||
vraag is "is mijn wallet nu verbonden", en die hoort niet uit een lijst afgeleid te worden.
|
||||
|
||||
## 5. Het werk
|
||||
|
||||
Staat in [TAKEN.md](TAKEN.md), met de fase-indeling en wat er af is.
|
||||
|
||||
## 6. Open punten
|
||||
|
||||
Staan in [OPEN.md](OPEN.md).
|
||||
|
||||
## 7. Verificatie
|
||||
|
||||
Handmatig, want het gaat om wat er in een browser staat:
|
||||
|
||||
- de pagina toont het werkelijk ingestelde domein en de werkelijke poorten, niet die uit de HTML;
|
||||
- na een certificaatvernieuwing verandert de einddatum op de pagina;
|
||||
- **stunnel of de proxy stoppen laat de pagina niet "Online" tonen.** Dit is de controle die de aanleiding
|
||||
van dit plan afdekt en de enige die per se gedaan moet worden;
|
||||
- een certificaat dat binnen dertig dagen verloopt, geeft een zichtbare waarschuwing.
|
||||
@@ -0,0 +1,339 @@
|
||||
# Voortgang - Webinterface
|
||||
|
||||
## 20-08-2026 - scans zijn geen weigeringen, en meer lucht tussen de kaders
|
||||
|
||||
De gebruiker vroeg wat een logregel `refused ... status 500` met nul bytes betekende. Antwoord: een
|
||||
TLS-handdruk die niet is afgemaakt, en op een doorgestuurde poort vrijwel altijd een scanner. Dat is geen
|
||||
storing, maar het log liep er wel vol met rode regels die suggereerden dat de app iets geweigerd had.
|
||||
|
||||
**Nu een eigen soort `probe`, en de grens ligt bij de bytes.** Niet bij de duur en niet bij de status: een
|
||||
scan die tien seconden open blijft is nog steeds een scan, en een sessie die na een halve seconde omvalt
|
||||
maar wél verkeer had is nog steeds een storing. Dat de bytetellers niets over de handdruk zeggen, bleek uit
|
||||
de sessies van de gebruiker zelf: een mislukte verbinding kwam op 0 en 0 uit terwijl er wél een handdruk
|
||||
geprobeerd is. Rood is nu voorbehouden aan het geval waar je iets aan moet doen.
|
||||
|
||||
Verder de ruimte tussen de kaders van 1 naar 1,5rem. De kaders hebben 1,8rem binnenin, dus de ruimte ertussen
|
||||
was kleiner dan die erbinnen; dat is de reden dat het krap aanvoelde.
|
||||
|
||||
**Geraakt:** `agent.py.template`, `index.html.template`, `umbrel-app.yml` (0.0.14), `PLAN.md` §4e-tabel,
|
||||
`tests/test_agent_certificates.py`. **Tests:** 54 goed 0 fout en 39 goed 0 fout, niets overgeslagen; de
|
||||
indeling van de sessieregels is mutatie-getest met een grens op de duur in plaats van de bytes, en dat viel
|
||||
om zoals het moest.
|
||||
|
||||
## 20-08-2026 - de mobiele opmaak, en een tegel minder
|
||||
|
||||
De pagina liep op een telefoon buiten beeld. **De oorzaak was één regel CSS:** de clientlijst stond op
|
||||
`minmax(420px, 1fr)`, en dat eist een track van minstens 420 pixels ook op een smaller scherm. Nu met
|
||||
`min(420px, 100%)` eromheen. Daarbij vouwen de lijstregels en de logregels onder de 700 pixels om, met de
|
||||
waarde onder de titel in plaats van ernaast.
|
||||
|
||||
Voor de logregels is dat een **herziening** van een eerdere keuze: die scrollen liever dan dat ze afkappen,
|
||||
omdat de kolomvorm dan blijft staan. Dat argument geldt op een breed scherm en daar blijft het zo, maar op
|
||||
een telefoon betekende het dat je de bytes nooit zag.
|
||||
|
||||
Verder is de tegel met het aantal dagen tot het certificaat verloopt eruit, op verzoek van de gebruiker.
|
||||
Dezelfde redenering als bij de badges: de kaart eronder zegt het al, en met een datum erbij. Backend
|
||||
response is nu twee kolommen breed, want de sparkline is het enige op die rij dat met breedte iets doet.
|
||||
|
||||
**Diezelfde dag nagekeken op een telefoon en het ziet er goed uit.** Eén regressie kwam eruit: door het
|
||||
omvouwen volgde de kopieerknop de tekst, en het ene adres is langer dan het andere, dus stonden de knoppen
|
||||
niet op één lijn. Verholpen in **0.0.11** met `margin-left: auto` op de knop, en niet met `space-between` op
|
||||
de rij: bij de gesplitste weergave staat er ook een notitie naast de waarde die daar tegenaan hoort te
|
||||
blijven staan.
|
||||
|
||||
Bijvangst die geen opmaak is: **`0.0.10` na `0.0.9` leverde gewoon een update op.** Daarmee is de aanname
|
||||
uit die release bevestigd en is een tekstvergelijking met groter-dan uitgesloten. Staat in de naslag, want
|
||||
het scheelt de volgende keer een omweg via `0.1.0`.
|
||||
|
||||
**Geraakt:** `index.html.template`, `umbrel-app.yml` (0.0.10 en 0.0.11), `CHANGELOG.md`,
|
||||
`Referenties/Umbrel-appstore-spec.md`. **Tests:** 39 goed 0 fout op de manifest- en configuratietoetsen; aan
|
||||
de agent is niets geraakt.
|
||||
|
||||
## 20-08-2026 - nagekeken in de browser, en dit plan is nu tier A
|
||||
|
||||
Na de verse installatie van 0.0.9 heeft de gebruiker alles nagekeken wat alleen met de hand kan.
|
||||
**Uploaden werkt, kiezen werkt, ook met de certificaten uit Zoraxy**, de keuzelijst bij het installeren zag
|
||||
er goed uit en het versienummer op de pagina klopt. Daarmee is het uploadpad uit 0.0.7 bewezen op het
|
||||
gelukkige pad; alleen de weigering bij een sleutel die niet bij het certificaat hoort is nog niet in een
|
||||
browser gezien.
|
||||
|
||||
**Dit plan is naar tier A gegaan** en van nummer 020 naar 005. Niet omdat er meer werk bij kwam, maar omdat
|
||||
het het enige plan is met werk dat nu te doen is: **Appstore** is in de kern af en wacht op een herstart die
|
||||
niet te plannen is, en **Publicatie** wacht op een publieke repo.
|
||||
|
||||
Eén nieuwe bevinding van de gebruiker om mee te beginnen: in mobiele weergave lopen de verbindingsregels
|
||||
met hun kopieerknoppen en de logregels buiten beeld. Dat laatste is een bewuste keuze geweest (de logregels
|
||||
scrollen liever dan dat ze afgekapt worden), maar op een telefoon is dat het verkeerde antwoord.
|
||||
|
||||
**Geraakt:** alleen documentatie. **Tests:** niet van toepassing.
|
||||
|
||||
## 20-08-2026 - uploaden gebouwd, en de pagina verder uitgekleed
|
||||
|
||||
**Een certificaat uploaden kan nu via de pagina**, open punt 6. Het echte werk zat niet in het formulier
|
||||
maar in de validatie: het paar gaat onder een `.tmp`-naam naar de doelmap en wordt daar door
|
||||
`ssl.SSLContext.load_cert_chain` geopend, dezelfde OpenSSL die nginx straks gebruikt. Zonder die controle
|
||||
levert een verkeerde sleutel een nginx die niet meer herlaadt, en dat is dezelfde klasse storing als
|
||||
waardoor 0.0.3 niet startte. **De bestandsnaam komt uit het certificaat zelf**, dus de hele klasse padtrucs
|
||||
is weg zonder invoerfiltering. Uploaden kiest niet: de nieuwe komt voorgeselecteerd in de lijst.
|
||||
|
||||
Twee dingen die bij het bouwen bijna fout gingen en het opschrijven waard zijn: `os.replace` uit `/tmp`
|
||||
naar `/certs/own` faalt met EXDEV omdat dat een bind-mount is, en `-subj "/CN=../.."` in openssl leest de
|
||||
schuine streep als scheidingsteken, waardoor de padtruc-toets zichzelf stil oversloeg.
|
||||
|
||||
Verder op verzoek van de gebruiker: het app-icoon in de kop in plaats van het schildje, de badges uit de
|
||||
hoek van álle kaders, "your choice" weg achter het actieve certificaat, en Trezor Suite is niet
|
||||
desktop-only. Die laatste is de tweede keer dat leveranciersdocumentatie het aflegt tegen één keer kijken.
|
||||
Bijgevangen: de teller zweeg over een wallet die al verbonden was voordat de agent begon, en dat is precies
|
||||
het geval waarin iemand komt kijken.
|
||||
|
||||
Aan het eind van de dag nog één tekstbesluit: de pagina had een andere tagline dan de appstore, en die van
|
||||
de appstore wint (0.0.8). Zie [OPEN.md](OPEN.md) punt 8; de reden is dezelfde maatstaf als bij het
|
||||
hernoemen van de app, namelijk de opbrengst en niet het middel.
|
||||
|
||||
**Geraakt:** `agent.py.template`, `index.html.template`, `nginx.conf.template`, `docker-compose.yml`,
|
||||
`umbrel-app.yml` (0.0.7 en 0.0.8), `OPEN.md` punt 6 en 8, `Referenties/Clients.md`, beide testbestanden.
|
||||
**Tests:** 48 goed 0 fout en 24 goed 0 fout, niets overgeslagen; de sleutelcontrole en de beschrijfbare
|
||||
mount zijn mutatie-getest. **Niet geverifieerd:** het uploaden in een echte browser.
|
||||
|
||||
## 20-08-2026 - de pagina naast een werkende app, en §4e afgemaakt
|
||||
|
||||
Eerste sessie met een app die echt draait, en dat leverde meteen de bevinding op waar §4e om vroeg: de
|
||||
gebruiker zag van zijn verbonden wallet niets terug. Oorzaak is bekend en staat in het plan, namelijk dat
|
||||
nginx `stream` pas bij het sluiten van een sessie logt. Het open punt was hoe je de lopende verbinding dan
|
||||
wél afleest. **Antwoord: `/proc/net/tcp`, geteld in de nginx-container**, want dat bestand geldt per
|
||||
netwerk-namespace en de agent zit in een andere. Het aantal gaat via een bestand naar de agent, net als de
|
||||
herlaadvlag. **`traffic` is daarbij vervallen:** bytes van een lopende sessie zijn er niet af te lezen, en
|
||||
een schatting die als meting leest is precies wat §4c verbiedt.
|
||||
|
||||
Daarnaast een reeks verzoeken van de gebruiker, alle om dezelfde reden: de pagina was te druk. De
|
||||
certificaatkeuze is een dropdown geworden (met veertien certificaten was die lijst het drukste onderdeel
|
||||
van de pagina, voor iets wat je één keer doet), `disconnected` heet `session ended` met leesbare details
|
||||
erachter, en er zijn vijf stukken tekst geschrapt: de voetnoot onder het log, de regel bij Certificate, de
|
||||
stip in de badges, de zin over apps op de Umbrel zelf en de uitleg over één regel versus twee velden.
|
||||
Bijgevangen bij de dropdown: de oude keuzelijst zette zichzelf elke ronde terug, dus een keuze verdween
|
||||
binnen tien seconden weer. Verder heet Blockstream Green nu Blockstream; die app is omgedoopt.
|
||||
|
||||
**Geraakt:** `index.html.template`, `agent.py.template`, `docker-compose.yml`, `umbrel-app.yml` (0.0.6),
|
||||
`PLAN.md` §4e, `OPEN.md` punt 6 en 7, `Referenties/Clients.md`, `tests/`. **Tests:** 29 goed 0 fout en 19
|
||||
goed 0 fout, niets overgeslagen; de teller en de logregel zijn mutatie-getest. **Niet geverifieerd:** alles
|
||||
in de browser, dus de dropdown, de hoogtes en de badge. Dat is handwerk van de gebruiker.
|
||||
|
||||
## 19-08-2026 - sessie afgesloten; plan zakt naar tier C
|
||||
|
||||
Laatste twee wijzigingen van de dag: certificaat en activiteitenlog omgedraaid, en het losse
|
||||
verbindingsadres met kopieerknop eruit samen met het label "tested clients". Het omdraaien pakte beter uit
|
||||
dan als voorkeur alleen, want de kolomgrens valt nu samen met die van de rij erboven (x=738 in beide rijen)
|
||||
en logregels hebben de breedte beter nodig dan keuzerondjes. Het adres verdween zonder verlies: het staat
|
||||
bij elke clientregel in de vorm die díe client wil, met kopieerknop.
|
||||
|
||||
**Het plan zakt van A naar C**, wachtend op de installatie. De pagina is af voor zover dat zonder de Umbrel
|
||||
kan; al het resterende werk hier begint met kijken of de agent doet wat hij zou moeten doen.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template`, de plannen, `CONTINUE_HERE.md`.
|
||||
**Tests:** 21 goed, 0 fout. Die raken de pagina niet.
|
||||
**Niet geverifieerd:** de agent heeft nooit gedraaid, en ik heb de pagina zelf nooit gezien; het
|
||||
browserpaneel bleef dicht, dus alles is gemeten in plaats van bekeken.
|
||||
|
||||
## 19-08-2026 - voetregel weg, certificaatlijst scrollt, kaders gelijk
|
||||
|
||||
De voetregel met "Last reading ... ago" en het versienummer is eruit; de gebruiker houdt van een rustige
|
||||
interface en de leeftijd stond al bij de waarden zelf. Het **versienummer** is op verzoek dezelfde dag
|
||||
teruggezet, klein achter de tagline als `v0.0.3`: dit project verloor een keer een dag aan een wijziging
|
||||
die niet uitrolde door een niet-verhoogde `version`, en dan is dat precies de vraag die je stelt. Het
|
||||
staat in `--text-sec`, want `--text-ter` is in de lichte variant `#bbbbbb` op wit en op die grootte niet
|
||||
te lezen.
|
||||
|
||||
De gebruiker vroeg of de certificaatlijst een scrollbalk moest krijgen of beter een dropdown werd, en of
|
||||
het logblok en het certificaatkader dan even hoog konden. Het is een scrollende lijst geworden en geen
|
||||
dropdown, want je kiest hier op de hostnaam waarop je wallet verbindt en dan wil je bron, naam en
|
||||
resterende dagen kunnen vergelijken; in een dropdown zie je er één per keer en kan een verlopen
|
||||
certificaat er niet rood in. De hoogtewinst kwam er met een scrollend vak toch, dus er hoefde niets
|
||||
ingeleverd te worden. Het aantal staat nu in de kop, want met een scrollbalk is niet meer te zien hoeveel
|
||||
er onder de rand staan.
|
||||
|
||||
Gemeten met negentien certificaten: 1062px inhoud in een vak van 360px, en de knop blijft eronder staan.
|
||||
Met vier: geen scrollbalk, dus geen leeg vak. In beide gevallen zijn de twee kaders exact even hoog, 773px
|
||||
respectievelijk 636px. Eerst stond het vak op 460px, maar dan werd de rij 873px en vulde die op een
|
||||
1080p-scherm het hele beeld.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet. Nagemeten op 1760px en op mobiel, in beide gevallen
|
||||
zonder horizontale schuifbalk en zonder console-fouten.
|
||||
|
||||
## 19-08-2026 - kaders gelijkgetrokken, en een badge die niets zei
|
||||
|
||||
De drie statustegels hadden een eigen kleine grijze kop in kapitalen en de andere kaders een witte titel.
|
||||
Op verzoek is dat nu overal hetzelfde: een `card-head` met een titel in `t-h3`. Wel met de token
|
||||
`--text-primary` en niet met letterlijk wit, want in de lichte variant is wit onzichtbaar. Bij het
|
||||
nameten bleek het getal van "Backend response" 21px hoger te staan dan de andere twee, omdat daar een
|
||||
sparkline onder hangt in plaats van een tekstregel; de onderregel van een tegel heeft nu dezelfde hoogte
|
||||
als die sparkline.
|
||||
|
||||
De badge "Serving this page" is eruit. De gebruiker wees erop dat die niets zegt: de pagina wordt nooit
|
||||
getoond aan een wallet die op 50022 verbindt. Mijn gedachte erachter was dat de pagina en de
|
||||
TLS-terminatie in dezelfde container zitten en dat de een de ander dus bewijst, maar dat stond er niet en
|
||||
zo leest niemand het. Een badge waarvan de betekenis niet in één zin op te schrijven is, hoort er niet te
|
||||
staan.
|
||||
|
||||
Wat dat wel opleverde, en dat is als open punt 5 vastgelegd: **de app controleert of de Electrum-server
|
||||
antwoordt, maar niet of hij zelf antwoordt**, en dat is zijn enige taak. Een TLS-verbinding naar de eigen
|
||||
poort zou het luisteren, het certificaat en de doorverbinding in één keer bewijzen. Nog geen taak, want
|
||||
het raakt de agent en die heeft nog nooit gedraaid.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet. Gemeten in beide thema's en op 1760px: zeven
|
||||
identieke koppen, drie getallen op één lijn, geen horizontale schuifbalk, geen console-fouten.
|
||||
|
||||
## 19-08-2026 - de vervallen-melding eruit
|
||||
|
||||
De gebruiker vond de melding "Readings are out of date" niet nuttig, en dat klopt: dezelfde mededeling
|
||||
staat al onder de blokhoogte ("as of ... ago"), in de badge bij de Electrum-server die grijs wordt met
|
||||
"last answered", en in de voettekst met het tijdstip. De banner was een vierde keer hetzelfde en wel de
|
||||
hardste.
|
||||
|
||||
De berekening blijft staan, want die stuurt de badge; alleen de melding is weg. Gecontroleerd met een
|
||||
`status.json` van een uur oud: geen enkele melding zichtbaar, badge grijs met "last answered 2 hours ago",
|
||||
"as of 2 hours ago" onder de blokhoogte, en de voettekst met datum en tijd. Er gaat dus geen informatie
|
||||
verloren.
|
||||
|
||||
De afweging staat nu in [PLAN.md](PLAN.md) §4a, omdat hij geldt voor elke volgende melding die iemand wil
|
||||
toevoegen: een banner is er voor iets wat je nergens anders ziet.
|
||||
|
||||
Wat de gebruiker zag was trouwens de preview en niet de app: die `status.json` is een vast bestand dat
|
||||
niets ververst, dus die verloopt altijd als je het tabblad open laat staan.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** 21 goed, 0 fout; die raken de pagina niet.
|
||||
|
||||
## 19-08-2026 - de pagina opnieuw ingedeeld, breed en met kaders naast elkaar
|
||||
|
||||
De gebruiker zag dat "Point your wallet here" en "Setting up your wallet" dezelfde vraag stelden. Die zijn
|
||||
er één geworden, en dat kader is naar onderen verhuisd. De volgorde is nu: Electrum-server, de drie
|
||||
statustegels, het activiteitenlog, de certificaatkeuze, en onderaan het instellen. De regel erachter is de
|
||||
moeite van het opschrijven waard, want hij beslist waar een volgend kader komt: eerst waar je naar kijkt
|
||||
als je iets nakomt, onderaan waar je naar kijkt als je iets instelt.
|
||||
|
||||
Op verzoek ook breed, met kaders naast elkaar: twaalf kolommen, rijen die 5/7 en 7/5 afwisselen, afgekapt
|
||||
op 1760px omdat een kader van 2500px regels oplevert die niemand leest. Belangrijk detail dat bewust zo is
|
||||
gebouwd: er staat geen `order` in de CSS, dus de leesvolgorde in de HTML is de bedoelde volgorde en
|
||||
stapelen op een smal scherm geeft exact dezelfde reeks.
|
||||
|
||||
Twee dingen die het meten opleverde en die anders waren blijven staan. De statustegels waren 146px naast een
|
||||
kader van 293px, dus stond er een gat rechtsboven; ze rekken nu mee en zetten hun inhoud onderaan. En het
|
||||
logblok kapte op een smal scherm de bytes af met puntjes; het scrollt nu zelf horizontaal, want stil
|
||||
verbergen is dezelfde soort onwaarheid als een verzonnen statuswaarde.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** de suite raakt de pagina niet; wel gedraaid en groen (21). Gecontroleerd via de afmetingen van
|
||||
de kaders op 1760px en op mobiel: volgorde gelijk, geen horizontale schuifbalk op de pagina, logblok
|
||||
scrollt zelf, geen console-fouten.
|
||||
**Niet geverifieerd:** ik heb de pagina niet met eigen ogen gezien; het browserpaneel stond dicht, dus dit
|
||||
is gemeten en niet bekeken.
|
||||
|
||||
## 19-08-2026 - een tweede container, en de eerste tests in dit project
|
||||
|
||||
De gebruiker vroeg of de WebDAV-truc de gebruikelijke manier is om een backend in een Umbrel-app te
|
||||
bouwen. Dat was hij niet, en het uitzoeken veranderde het ontwerp. umbrelOS biedt precies één instelling
|
||||
per app, de afhankelijkheidskeuze in `AppSettingsSchema`; apps met instelbare configuratie zijn zelf een
|
||||
backend, in hun eigen image. De gebruiker koos daarop een tweede container met een klein python-programma,
|
||||
uit een `*.template` zodat het bij een update meekomt, zonder eigen image.
|
||||
|
||||
Dat loste meer op dan de keuzelijst. De controles op `openssl`, `nc` en de WebDAV-module zijn alle drie
|
||||
vervallen, want de agent doet dat werk met de standaardbibliotheek. En het hardgecodeerde domein is weg uit
|
||||
`docker-compose.yml` en `nginx.conf.template`: de agent schrijft `cert.conf` en nginx doet daar een
|
||||
`include` op. Daarmee is dat deel van **Configuratie** fase 2 af.
|
||||
|
||||
Twee dingen die het bouwen opleverde. De standaardbibliotheek heeft geen X.509-parser, dus die is er nu:
|
||||
een DER-lezer voor de einddatum en de domeinnamen. Dat is precies het soort code dat niet faalt met een
|
||||
fout maar met een verkeerd antwoord, en een certificaatdatum die er een jaar naast zit valt nooit op.
|
||||
Daarom is hij getoetst tegen `ssl` op 74 echte CA-certificaten, op een levend servercertificaat voor de
|
||||
subjectAltName, en op beide tijdvormen met zelfgebouwde certificaten, want het CA-materiaal gebruikt
|
||||
uitsluitend UTCTime na 2000. Dit project had nog geen suite; die staat nu in `tests/` en `CLAUDE.md`
|
||||
vertelt hoe je hem draait.
|
||||
|
||||
Het tweede: bij het schrijven van de compose bleek mijn eigen `choose` het plan **Configuratie** §4c tegen
|
||||
te spreken. Die koos bij meerdere certificaten "de langst geldige", terwijl daar uitdrukkelijk staat dat er
|
||||
niet gegokt mag worden. Nu weigert de app en noemt de kandidaten, en de pagina zet er een foutmelding
|
||||
boven, want geen certificaat betekent geen TLS.
|
||||
|
||||
**Geraakt:** nieuw `whatsnext-electrum-gate/agent.py.template`, nieuw `tests/`, nieuw `CLAUDE.md`,
|
||||
gewijzigd `docker-compose.yml`, `nginx.conf.template`, `index.html.template`, en de plannen.
|
||||
**Tests:** 21 goed, 0 fout. Mutatietest gedaan op de twee guards: de keuze-validatie en de verloopfilter,
|
||||
allebei met de juiste enkele test die omvalt.
|
||||
**Niet geverifieerd:** de agent heeft nog nooit op de Umbrel gedraaid. Alles over de echte werking, dus de
|
||||
certificaatscan op de Zoraxy-map, de Electrum-vraag, het herladen via de vlag en de keuze via de API, staat
|
||||
nog open.
|
||||
|
||||
## 19-08-2026 - certificaatkeuze op het dashboard
|
||||
|
||||
De gebruiker vroeg hoe je aanwijst welk certificaat van welke app je wilt gebruiken, en koos daarbij voor
|
||||
een keuzelijst op het dashboard boven een sleutel in een configuratiebestand. Dat draait het niet-doel
|
||||
"geen instellingenscherm in de web-UI" terug, en dat is opgeschreven als uitzondering met de reden erbij:
|
||||
dit is de enige instelling waarvan de app de mogelijke waarden zelf al kent, want hij kijkt in de
|
||||
gemounte mappen.
|
||||
|
||||
Terugschrijven kan zonder backend met de WebDAV-module van nginx: één `location` die een `PUT` van
|
||||
hooguit een kilobyte aanneemt, naar `${APP_DATA_DIR}/config/` zodat de keuze een herstart overleeft.
|
||||
Of die module in de image zit, is de eerste van drie controles die nu op de Umbrel moeten gebeuren.
|
||||
|
||||
Twee dingen bewust níet gedaan. De mount voor Nginx Proxy Manager staat uitgecommentarieerd, want het pad
|
||||
is een gok en Docker maakt een ontbrekend bind-mountpad aan; dat zou een lege maphierarchie neerzetten in
|
||||
de app-data van een app die er misschien niet is. En de pagina meldt geen succes na het opslaan: nginx
|
||||
moet het certificaat nog herladen, en dat blijkt pas uit de volgende `status.json`.
|
||||
|
||||
**Geraakt:** `index.html.template`, `nginx.conf.template`, `docker-compose.yml`, en de plannen
|
||||
Webinterface en Configuratie.
|
||||
**Tests:** geen suite. In de lokale render gecontroleerd dat de lijst vier certificaten toont met het
|
||||
verlopen exemplaar als zodanig, dat het actieve aangevinkt staat, en dat de knop pas aangaat bij een
|
||||
andere keuze. **Het wegschrijven zelf is niet geprobeerd**, want daar is de Umbrel voor nodig.
|
||||
|
||||
## 19-08-2026 - dashboard uitgedund na de eerste blik
|
||||
|
||||
De gebruiker heeft de pagina bekeken en er drie dingen af gehaald: de grafiek blokken per uur, de tegel
|
||||
blokken laatste uur, en het kader over Tor tegenover TLS. De eerste twee beantwoorden een vraag over de
|
||||
Electrum-server en niet over deze proxy; de derde is positionering en hoort in de winkelbeschrijving,
|
||||
waar iemand nog staat te kiezen. Er blijven drie tegels over. `history` in `status.json` hoeft daardoor
|
||||
alleen nog de reactietijd te bewaren.
|
||||
|
||||
De badge bij de Electrum-server zei `answering`, en op de vraag wat dat betekende was er geen goed
|
||||
antwoord: het liet in het midden of dat nú gold of ooit. Hij noemt nu de meting en het moment, dus
|
||||
`answered 2 minutes ago`, `no answer 2 minutes ago` of `not checked yet`.
|
||||
|
||||
De activiteitenkaart is omgebouwd tot logregels onder elkaar in monospace, nieuwste bovenaan. Daarbij
|
||||
hoort een grens die op de pagina zelf staat: een regel per protocolaanroep kan niet, want die verzoeken
|
||||
zitten in de versleutelde verbinding en ze tellen zou betekenen dat de app het verkeer van de gebruiker
|
||||
uitleest.
|
||||
|
||||
Kopieerknoppen in een lijstregel verschijnen nu bij hover. Met `opacity` en niet met `display`, zodat ze
|
||||
met de tab-toets bereikbaar blijven; op aanraakschermen staan ze altijd aan.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` en de plannen.
|
||||
**Tests:** geen suite. In de lokale render gecontroleerd: drie tegels, zestien logregels, geen
|
||||
console-fouten, blokkengrafiek en Tor-kader weg.
|
||||
|
||||
## 19-08-2026 - plan werd actief, en de pagina is herbouwd
|
||||
|
||||
Gepromoveerd vanuit `Plannen/Masterplannen/` omdat het werk begon. De oude pagina beweerde `Online` als
|
||||
platte tekst in de HTML, had een verzonnen logvenster en noemde een hardgecodeerd domein. Die is
|
||||
vervangen door een pagina die alles uit `status.json` haalt en elk veld dat hij niet kent zichtbaar op
|
||||
`unknown` laat staan.
|
||||
|
||||
Twee dingen die het ontwerp veranderd hebben ten opzichte van het masterplan. De pagina is verhuisd van
|
||||
`web/index.html` naar `index.html.template` in de app-root: umbreld ververst bij een update alleen een
|
||||
whitelist, dus onder `web/` zou elke latere wijziging stilzwijgend niet aankomen en een herinstallatie
|
||||
kosten. En doordat de pagina niets meer hardgecodeerd heeft, is de afhankelijkheid van **Configuratie**
|
||||
vervallen; dat deel van Configuratie fase 2 is hiermee meteen af.
|
||||
|
||||
Op verzoek van de gebruiker zijn er drie dingen bijgekomen: verbindingsregels per client met een
|
||||
kopieerknop (uit `Referenties/Clients.md` §4), een korte eerlijke uitleg over Tor tegenover TLS, en een
|
||||
kaart voor wallet-activiteit die nu op `no data` staat zodat de vorm beoordeeld kan worden voordat er
|
||||
iets voor gebouwd wordt. Dat laatste is een herziening van het niet-doel "live logs", en de grens ligt
|
||||
bij een samenvatting per sessie zonder client-IP.
|
||||
|
||||
**Geraakt:** `whatsnext-electrum-gate/index.html.template` (was `web/index.html`),
|
||||
`nginx.conf.template`, `docker-compose.yml`, `umbrel-app.yml`.
|
||||
**Tests:** dit project heeft geen suite. Handmatig gecontroleerd in een lokale render met een
|
||||
voorbeeld-`status.json`: beide thema's, alle kaarten, geen console-fouten.
|
||||
**Nog niet geverifieerd:** alles wat een echte `status.json` vraagt, want die wordt nog niet geschreven
|
||||
(fase 2). De kopieerknop is niet achter de app-proxy van umbrelOS geprobeerd, en dat is juist het pad
|
||||
waar de terugval voor http gebruikt wordt.
|
||||
@@ -0,0 +1,210 @@
|
||||
# Taken - Webinterface
|
||||
|
||||
> Prioriteit: **A** | Wacht op: –
|
||||
>
|
||||
> **Van C naar B naar A op 20-08-2026, op één dag.** Eerst verviel de blokkade "de app geïnstalleerd en de
|
||||
> agent draaiend". Aan het eind van die dag is dit het enige plan met werk dat nú te doen is: **Appstore**
|
||||
> heeft alleen nog een herstart nodig die niet te plannen is, en **Publicatie** wacht op een publieke repo.
|
||||
> Het nummer is daarom van 020 naar 005 gegaan; alleen dit plan kreeg een nieuw nummer, Appstore houdt 010.
|
||||
>
|
||||
> Afgezakt van A naar C op 19-08-2026 bij het afsluiten van de sessie. De pagina is af voor zover dat
|
||||
> zonder de Umbrel kan; al het resterende werk in dit plan begint met kijken of de agent doet wat hij zou
|
||||
> moeten doen, en dat kan niet vóór de installatie.
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [x] **0.0.10 op een telefoon nagekeken. In orde (20-08-2026).** De gebruiker meldt dat het er goed uitziet
|
||||
op mobiel. Eén ding kwam eruit: de kopieerknoppen stonden niet op één lijn, omdat de knop door het
|
||||
omvouwen de lengte van het adres volgde. Verholpen in 0.0.11 met `margin-left: auto` op de knop.
|
||||
Bijvangst: `0.0.10` na `0.0.9` levert wél een update op, dus tweecijferige versiedelen zijn veilig
|
||||
|
||||
- [x] **De agent zien draaien. Gelukt op 20-08-2026, over drie versies.** De agent start en luistert, de
|
||||
pagina laadt, hij vond veertien certificaten in `/certs/zoraxy` en weigerde daarom te kiezen, een
|
||||
keuze op de pagina werd aangenomen, en daarna verbindt een wallet over 50022. De keten waar dit plan
|
||||
op wachtte is dus rond.
|
||||
|
||||
- [ ] **Het uploaden op het niet-gelukkige pad proberen**, het enige stuk van 0.0.7 dat nog niet in een
|
||||
browser gezien is: een sleutel die niet bij het certificaat hoort. Verwacht: een weigering met een
|
||||
leesbare reden, en niets dat achterblijft in `data/certs`. De guard is met echte sleutelparen getoetst
|
||||
en mutatie-getest, dus dit gaat over de weg van de melding naar de pagina en niet over de controle
|
||||
zelf. **Eigenaar: gebruiker**
|
||||
|
||||
- [x] **0.0.7 en 0.0.9 in de browser nagekeken. Gelukt (20-08-2026):** uploaden werkt, kiezen werkt, ook
|
||||
met de certificaten uit Zoraxy, de keuzelijst bij het installeren zag er goed uit en het
|
||||
versienummer op de pagina klopt. Daarmee is het uploadpad uit 0.0.7 bewezen op het gelukkige pad
|
||||
|
||||
- [x] **0.0.6 in de browser nagekeken (20-08-2026).** Ziet er goed uit volgens de gebruiker. Wat eruit
|
||||
kwam: de badges konden weg, "your choice" zei niets, Trezor Suite is niet desktop-only, en
|
||||
Blockstream Green heet Blockstream
|
||||
|
||||
- [x] **De pagina naast een werkende app gelegd (20-08-2026).** Blokhoogte en backend-reactietijd komen
|
||||
binnen. Wat eruit kwam: van een verbonden wallet was niets te zien, de keuzelijst was te druk, en
|
||||
een reeks uitleg-teksten kon weg. Alles verwerkt in 0.0.6
|
||||
|
||||
- [ ] **Het activiteitenlog een etmaal laten lopen** en dan kijken of het klopt: komt er een
|
||||
`connected`-regel bij een nieuwe wallet, en wat staat er na een nacht in. De teller is nieuw en is
|
||||
alleen tegen tijdelijke bestanden getoetst, niet tegen een echte wallet
|
||||
|
||||
Daarna, en niet eerder:
|
||||
|
||||
- [ ] Uitzoeken waar Nginx Proxy Manager op umbrelOS zijn certificaten neerzet. De mount staat
|
||||
uitgecommentarieerd in `docker-compose.yml`: een gok invullen zou Docker een lege maphierarchie
|
||||
laten aanmaken in de app-data van een app die er misschien niet eens is
|
||||
- [ ] Open punt 5: laten controleren of de TLS-poort zélf antwoordt. Dat is nu het enige wat de app niet
|
||||
over zichzelf weet, en het is zijn enige taak
|
||||
- [x] **Open punt 6: een certificaat uploaden via de pagina. Gebouwd in 0.0.7** (20-08-2026). Beschrijfbare
|
||||
mount voor de agent, een eigen nginx-locatie met een grotere limiet, en validatie met
|
||||
`load_cert_chain` voordat er iets geplaatst wordt. De bestandsnaam komt uit het certificaat zelf,
|
||||
dus padtrucs kunnen niet. **Nog niet in een browser geprobeerd**
|
||||
- [ ] Open punt 7: beslissen of Zoraxy een harde afhankelijkheid wordt. "Zoraxy of NPM" kan niet, en dat
|
||||
is op 20-08-2026 in de bron nagetrokken; alleen de wens staat nog open. Zie [OPEN.md](OPEN.md)
|
||||
punt 7
|
||||
- [ ] Fase 5, het activiteitenlog, als de gebruiker het wil
|
||||
|
||||
De drie controles op `openssl`, `nc` en de WebDAV-module zijn **vervallen** met de komst van de agent: die
|
||||
doet dat werk zelf met de standaardbibliotheek. Zie [PLAN.md](PLAN.md) §4a0.
|
||||
|
||||
Daarna, in deze volgorde:
|
||||
|
||||
- [ ] Fase 2 bouwen op de uitkomst van die controle
|
||||
- [ ] Fase 5, als de gebruiker de wallet-activiteit wil
|
||||
|
||||
## Fase 1 - Het liegen eruit
|
||||
|
||||
- [x] De verzonnen statusblokken (`Online`, `Online`) en het verzonnen logvenster weg
|
||||
- [x] Het hardgecodeerde domein weg. De pagina bevat geen enkele installatiespecifieke waarde meer
|
||||
- [x] Taal naar Engels, zie [OPEN.md](OPEN.md) punt 2
|
||||
- [x] Opnieuw opgebouwd op het design-systeem: tokens, `card`, `badge`, `alert`, `list-item`, `btn`,
|
||||
donker met een lichte variant en een schakelaar
|
||||
- [x] **De pagina verhuisd naar `index.html.template` in de app-root.** Onder `web/` zou elke latere
|
||||
wijziging een herinstallatie kosten: umbreld ververst bij een update alleen een whitelist en die
|
||||
kijkt niet in submappen. Als template zit hij in de whitelist én wordt hij bij elke start ingevuld
|
||||
|
||||
## Fase 2 - De agent schrijft `status.json`
|
||||
|
||||
Herzien 19-08-2026: dit is een tweede container met een python-programma geworden in plaats van een
|
||||
shell-lus in de compose. Onderbouwing in [PLAN.md](PLAN.md) §4a0.
|
||||
|
||||
- [x] `agent.py.template`, met de instellingen uit de omgeving in plaats van uit template-invulling.
|
||||
Daardoor staat er geen accolade-variabele in en blijft het geldige Python, dus is het te importeren
|
||||
in een test. De eerste toets in `tests/` controleert precies die aanname
|
||||
- [x] Schrijft `status.json` atomair via een tijdelijk bestand en `os.replace`, want de pagina leest het
|
||||
elke minuut en een half geschreven bestand geeft een lege pagina
|
||||
- [x] Einddatum van het certificaat met een eigen DER-lezer. Getoetst tegen `ssl` op 74 echte
|
||||
CA-certificaten, op een levend servercertificaat, en op beide tijdvormen
|
||||
- [x] Blokhoogte en reactietijd via `blockchain.headers.subscribe` over een verse socket
|
||||
- [x] Een `history`-reeks bijhouden, afgekapt op 24 uur, met alléén de reactietijd. De sparkline is sinds
|
||||
19-08-2026 de enige afnemer
|
||||
- [x] Herkennen welke backend het is aan de hand van het adres, en `unknown` als hij niet in de tabel
|
||||
staat. Zie [PLAN.md](PLAN.md) §4c: liever minder informatief dan onwaar
|
||||
- [x] De lus valt nooit stil: een mislukte ronde wordt gelogd en overgeslagen. Stoppen zou de pagina op
|
||||
oude gegevens bevriezen, en dat is precies het liegen dat dit plan moest afschaffen
|
||||
- [ ] Draaien op de Umbrel. Niets hiervan is buiten de tests uitgevoerd
|
||||
|
||||
## Fase 3 - De pagina vult zichzelf
|
||||
|
||||
- [x] `fetch` op `status.json`, elke minuut
|
||||
- [x] Elk veld heeft een zichtbare onbekend-toestand; nooit een leeg veld, want dat leest als "in orde"
|
||||
- [x] "Laatst bijgewerkt" tonen, en oude gegevens als zodanig laten zien zodra ze ouder zijn dan twee
|
||||
schrijfronden. **Bijgesteld 19-08-2026 op verzoek van de gebruiker:** dat gebeurt niet meer met een
|
||||
melding bovenaan de pagina maar alleen bij de waarden zelf, want die melding zei voor de vierde keer
|
||||
wat er al onder de blokhoogte, in de badge bij de Electrum-server en in de voettekst stond
|
||||
- [x] Leesbare melding als het bestand ontbreekt, zonder dat het op een fout lijkt.
|
||||
Zie [OPEN.md](OPEN.md) punt 1
|
||||
- [ ] Verifiëren tegen een échte `status.json` in plaats van tegen de voorbeeldversie uit de preview
|
||||
|
||||
## Fase 4a - De indeling
|
||||
|
||||
Vastgesteld door de gebruiker op 19-08-2026 na het bekijken van de eerste versie. Ontwerp in
|
||||
[PLAN.md](PLAN.md) §4a1.
|
||||
|
||||
- [x] Volgorde: Electrum-server, drie statustegels, activiteitenlog, certificaatkeuze, instellen van je
|
||||
wallet
|
||||
- [x] "Point your wallet here" opgegaan in "Setting up your wallet"; het waren dezelfde kaders
|
||||
- [x] Breed met een raster van twaalf kolommen, rijen die 5/7 en 7/5 afwisselen, afgekapt op 1760px
|
||||
- [x] De leesvolgorde in de HTML is de bedoelde volgorde, zonder `order` in de CSS, zodat stapelen op een
|
||||
smal scherm dezelfde volgorde geeft. Gecontroleerd op 1760px en op mobiel
|
||||
- [x] Statustegels rekken mee met de hoogte van hun buur, anders staat er een gat rechtsboven
|
||||
- [x] Het logblok scrollt zelf horizontaal in plaats van de regel met puntjes af te kappen
|
||||
- [x] **Alle kaders hetzelfde opgebouwd** (19-08-2026): een `card-head` met een titel in `t-h3`, dan de
|
||||
inhoud. De drie statustegels hadden een eigen kleine grijze kop in kapitalen. De titel gebruikt de
|
||||
token `--text-primary`, niet letterlijk wit, anders is hij onzichtbaar in de lichte variant
|
||||
- [x] De onderregel van een statustegel is even hoog als de sparkline, zodat de drie getallen op één lijn
|
||||
staan. Gecontroleerd: koppen op y=153, getallen op y=311
|
||||
- [x] **De badge "Serving this page" verwijderd** (19-08-2026, op aanwijzing van de gebruiker). Zie
|
||||
[OPEN.md](OPEN.md) punt 5 voor wat er wél op die plek zou horen
|
||||
- [x] **De voetregel verwijderd** (19-08-2026). Daarin stond "Last reading ... ago" plus het versienummer;
|
||||
het eerste stond al bij de waarden zelf
|
||||
- [x] **Het versienummer teruggezet**, klein achter de tagline als `v0.0.3`. Dezelfde dag op verzoek van de
|
||||
gebruiker. In `--text-sec` en niet in `--text-ter`, want die laatste is in de lichte variant `#bbbbbb`
|
||||
op wit en op deze grootte onleesbaar
|
||||
- [x] **De certificaatlijst scrollt**, met het aantal in de kop. Een gedeelde certificatenmap kan er
|
||||
tientallen bevatten. Gecontroleerd met 19 certificaten: 1062px inhoud in een vak van 360px, knop
|
||||
blijft eronder staan
|
||||
- [x] **Het logblok en het certificaatkader zijn even hoog.** Het langste kader van de rij bepaalt de
|
||||
hoogte, en wat mag meegroeien zegt dat zelf met flex. Gemeten: 636px bij vier certificaten, 773px bij
|
||||
negentien, in beide gevallen allebei gelijk
|
||||
- [x] **Certificaat en activiteitenlog omgedraaid** (19-08-2026, op verzoek). Certificaat links en smal,
|
||||
log rechts en breed. Dat pakt twee kanten goed uit: de kolomgrens valt nu samen met die van de rij
|
||||
erboven (gemeten: x=738 in beide rijen), en monospace logregels hebben de breedte beter nodig
|
||||
- [x] **Het losse verbindingsadres met kopieerknop eruit**, plus het label "tested clients". Zonder
|
||||
verlies: hetzelfde adres staat bij elke clientregel, in de vorm die díe client wil, met een
|
||||
kopieerknop erbij. Het instelkader werd daarmee 533px in plaats van 610px
|
||||
- [ ] Nog niet met eigen ogen gezien op een echt breed scherm; gecontroleerd via de afmetingen van de
|
||||
kaders, niet visueel, want het browserpaneel stond dicht
|
||||
|
||||
## Fase 4 - Bruikbaar in plaats van alleen eerlijk
|
||||
|
||||
- [x] Verloopwaarschuwing onder de dertig dagen, en een foutmelding als het certificaat verlopen is
|
||||
- [x] Kopieerknop op het verbindingsadres, met terugval voor http zonder de clipboard-API
|
||||
- [x] Verbindingsregels per client, met kopieerknop per regel. Bron: `Referenties/Clients.md` §4
|
||||
- [x] Kopieerknoppen verschijnen bij hover over de regel. Met `opacity` en niet met `display`, zodat ze
|
||||
met de tab-toets bereikbaar blijven, plus `focus-within` en altijd zichtbaar op aanraakschermen
|
||||
- [ ] De kopieerknop echt uitproberen achter de app-proxy van umbrelOS. Die draait over http, dus de
|
||||
terugval met `execCommand` is daar het pad dat gebruikt wordt en niet de uitzondering. Wat op
|
||||
19-08-2026 lokaal wél bewezen is: de **faalroute** meldt "Press Ctrl+C" in plaats van stil niets te
|
||||
doen. De geslaagde route vraagt een echte muisklik, want de clipboard-API weigert een klik die uit
|
||||
een script komt
|
||||
|
||||
## Fase 4b - De certificaatkeuze
|
||||
|
||||
Besloten 19-08-2026 door de gebruiker: een keuzelijst op het dashboard in plaats van een sleutel in het
|
||||
configuratiebestand. Het ontwerp hoort bij het plan **Configuratie** §4e en §4f; hier staat alleen wat de
|
||||
pagina en de compose ervoor doen.
|
||||
|
||||
- [x] Keuzelijst op de pagina, met per certificaat de bron, de bestandsnaam, het domein en het aantal
|
||||
resterende dagen. Een verlopen certificaat staat er rood bij en wordt niet verborgen: het bestaat,
|
||||
en het kiezen ervan moet een zichtbare vergissing zijn en geen onvindbare
|
||||
- [x] `PUT` naar `api/certificate`, doorgestuurd naar de agent. De WebDAV-truc is vervallen: de agent
|
||||
neemt de keuze aan en kan hem ook controleren, wat WebDAV niet kon
|
||||
- [x] De pagina meldt níet zelf dat het gelukt is. Nginx moet het certificaat nog herladen, en dat blijkt
|
||||
pas uit de volgende `status.json`
|
||||
- [x] De Zoraxy-mount van `/certs` naar `/certs/zoraxy`, en `/certs/own` erbij, zodat er per bron een map
|
||||
is. Beide containers hebben ze nodig: de agent om te kiezen, nginx om het bestand te openen
|
||||
- [x] `certificates` in `status.json`, met per certificaat de bron, de naam, het domein uit het
|
||||
certificaat en de einddatum
|
||||
- [x] **De guard: een id die de agent niet zelf gevonden heeft, wordt geweigerd.** Zowel bij de `PUT` als
|
||||
bij het kiezen. Getest, inclusief de mutatietest
|
||||
- [x] **Bij meerdere kandidaten kiest de app niet.** Bijgesteld nadat bleek dat mijn eerste versie "de
|
||||
langst geldige" pakte, wat het plan **Configuratie** §4c uitdrukkelijk verbiedt: een verkeerd
|
||||
certificaat geeft een verbinding die het lijkt te doen en bij de wallet stukloopt op
|
||||
naamverificatie. De pagina toont dan een foutmelding met de kandidaten erin
|
||||
- [x] De pagina toont bovenaan een foutmelding als er geen certificaat actief is, want dan is er geen TLS
|
||||
en dat is het ergste wat deze app kan overkomen
|
||||
|
||||
## Fase 5 - Het activiteitenlog
|
||||
|
||||
Voorstel, nog niet besloten. Ontwerp in [PLAN.md](PLAN.md) §4e. De kaart staat al op de pagina en toont
|
||||
`no data`, zodat de vorm te beoordelen is voordat er iets voor gebouwd wordt.
|
||||
|
||||
- [x] Vorm: logregels onder elkaar, monospace, nieuwste bovenaan, met de grens erbij vermeld dat een
|
||||
regel per protocolaanroep niet kan zonder het verkeer van de gebruiker uit te lezen
|
||||
- [ ] Uitzoeken of een `log_format` met dollartekens langs de template-invulling te krijgen is, via een
|
||||
`include` die het `command`-blok wegschrijft
|
||||
- [ ] Uitzoeken hoe de bytetellers van een lopende verbinding in de container af te lezen zijn; nginx
|
||||
logt een stream-sessie pas bij het sluiten
|
||||
- [ ] `log` in `status.json`, zonder client-IP en zonder bronpoort
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
- [ ] Niets. De afhankelijkheid van **Configuratie** is vervallen, zie [PLAN.md](PLAN.md)
|
||||
Reference in New Issue
Block a user