# Requirements Clarification Questions — Gitea Deployment Workflow Vul je keuze in achter elke `[Answer]:`-tag. Kies de laatste optie (`Anders`) als niets past en beschrijf dan je voorkeur. Waar ik iets al uit de code of uit je SlpSoftware-workflow kon opmaken, staat dat als context boven de vraag — dan hoef je alleen te bevestigen of te corrigeren. --- ## A. Hosting en transport ### Question 1 **Context**: de referentie-workflow uploadt via `scp` met `sshpass` naar een Raspberry Pi. Shared hosting zoals mijnhostingpartner.nl biedt doorgaans geen SSH, maar wel FTP/FTPS en soms Web Deploy (msdeploy). Dit bepaalt de hele deploy-stap. Hoe komt de gepubliceerde .NET-applicatie op de **productie**-host terecht? A) FTPS — FTP over TLS, meestal standaard beschikbaar op shared hosting B) Web Deploy / msdeploy — de MSBuild-native manier voor IIS-hosting, ondersteunt `app_offline` en incrementele sync C) SSH/SCP — zoals de referentie, alleen als de host SSH aanbiedt D) Ik weet nog niet wat de host ondersteunt — neem FTPS als uitgangspunt en documenteer hoe je overstapt X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: X, Op de pi kan ik met FileZilla ook verbinden met SFTP. Is dat voldoende om FTP als uitgangspunt te nemen? Anders beginnen met opzetten zoals de referentie met SSH/SCP en later aanpassen naar FTPS als dat nodig is. ### Question 2 **Context**: je hebt lokaal, test en productie. De referentie draait test én productie op dezelfde Raspberry Pi's. Waar draait de **testomgeving** van de CMS? A) Op dezelfde shared host als productie, als een tweede site/subdomein (bijv. `test.`) B) Op je eigen Raspberry Pi-infrastructuur (zoals de referentie), met een .NET runtime erop C) Op een andere shared-hostingaccount of -pakket X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: B ### Question 3 **Context**: de referentie gebruikt een zelf-gehoste Gitea Actions runner op Podman, waarbij container-based actions (`appleboy/scp-action`) faalden met een 409-fout — vandaar shell-stappen. De publish van deze CMS heeft bovendien **zowel de .NET 10 SDK als Node + pnpm** nodig. Op welke runner draait deze workflow? A) Dezelfde zelf-gehoste Podman-runner als de SlpSoftware-workflow — ik zorg dat .NET 10 SDK en Node/pnpm beschikbaar zijn (of laat de workflow ze installeren) B) Dezelfde runner, maar installeer de toolchain expliciet in de workflow met `actions/setup-dotnet` en `pnpm/action-setup` C) Een nieuwe/aparte runner speciaal voor .NET-builds X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: B --- ## B. De publieke website in `wwwroot` ### Question 4 **Belangrijk risico dat ik in de code vond**: de publieke website van de klant staat in `wwwroot/`, en de admin-SPA in `wwwroot/admin/`. Een deploy die de hele `wwwroot` overschrijft of spiegelt, **wist daarmee de website van de klant** (die immers uit een andere workspace komt en niet in deze repo zit). Hoe moet de deploy hiermee omgaan? A) De CMS-deploy raakt `wwwroot/` nooit behalve `wwwroot/admin/` — de rest blijft staan, en de website-workspace deployt onafhankelijk zijn eigen bestanden in `wwwroot/` B) De CMS-deploy overschrijft alles behalve een expliciete uitsluitingslijst, die ik in de workflow configureer C) De publieke website komt in een aparte submap (bijv. `wwwroot/site/`) zodat de scheiding fysiek duidelijker is — vereist een kleine wijziging in `Program.cs` X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: C, noem de map "web" in plaats van "site", Dus dan krijgen we uiteindelijk 3 mappen in wwwroot: admin, web en eventueel een map voor de API (indien nodig). ### Question 5 Wat moeten de instructies voor een website-workspace precies vastleggen? (Het bouwen/deployen van de website zelf blijft buiten scope — dit gaat om het contract waaraan zo'n workspace zich moet houden.) A) Alleen het doelpad en de mapstructuur — waar de build-output heen moet en welke paden verboden zijn (`admin/`) B) Doelpad plus technische randvoorwaarden — routing/SPA-fallback-gedrag, verboden bestandsnamen, hoe je `/api/v1` vanaf de website aanroept C) Doelpad, randvoorwaarden én een voorbeeld-deploystap (een YAML-snippet die een website-workspace kan overnemen in zijn eigen workflow) X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: B --- ## C. Workflow-opzet en gates ### Question 6 **Context**: in de referentie draait de testdeploy automatisch bij een push/merge naar `master`, en productie alleen bij een handmatige `workflow_dispatch` met een `deploy_production`-vinkje — bewust, zodat niemand per ongeluk productie deployt. Wil je diezelfde triggerstrategie hier? A) Ja, identiek aan de referentie — PR's valideren, `master` deployt naar test, productie alleen expliciet via `workflow_dispatch` B) Ja, maar productie moet ook een handmatige goedkeuringsstap of aparte bevestiging hebben bovenop het vinkje C) Productie mag automatisch bij een tag/release (bijv. `v1.2.3`) in plaats van via een vinkje X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: A ### Question 7 **Gemeten feit**: `pnpm run lint` faalt nu met 5 errors en 1 warning (in `AddCmsInstanceDialog.tsx`, `InviteUserDialog.tsx` 2×, `SettingsPage.tsx`, `SetStatusDialog.tsx`). Alle 219 backend- en 213 frontend-tests slagen wél. Een lint-gate wordt dus meteen rood. Hoe gaan we hiermee om? A) Los de 5 lint-errors op als onderdeel van deze feature, en zet de lint-gate daarna blokkerend B) Zet de lint-gate blokkerend en laat de fixes over aan `tech-debt-backlog` — de workflow is dan pas groen ná die feature C) Neem lint op als niet-blokkerende stap (rapporteert, faalt de build niet) en maak hem later blokkerend X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 8 **Gemeten feit**: `Microsoft.OpenApi` 2.0.0 en `System.Security.Cryptography.Xml` 10.0.9 hebben high-severity advisories; beide komen transitief binnen. Wil je een vulnerability-gate in de workflow? A) Ja, blokkerend — en we pinnen de twee packages naar gepatchte versies als onderdeel van deze feature B) Ja, maar niet-blokkerend (rapporteert alleen), zodat de deploy niet vastloopt op transitieve advisories C) Nee, geen vulnerability-scan in deze workflow X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 9 Welke gates moeten er in de pipeline zitten vóór een deploy? (Meerdere letters mogen, bijv. `A, B, C`.) A) Backend build (`dotnet build -c Release`) B) Backend tests (`dotnet test`) C) Frontend type-check + build (`tsc -b && vite build`) D) Frontend tests (`vitest run`) E) Frontend lint / format-check F) Code coverage-drempel (nu is er geen enkele drempel afgedwongen) X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: A, B, C, D, E --- ## D. Database en configuratie ### Question 10 **Gemeten feit**: `AvailabilityDbContext` en `MasterDbContext` migreren zichzelf bij het opstarten, maar `ApplicationDbContext` (Identity) **nooit**. Een verse deploy start dus zonder Identity-tabellen tot iemand handmatig `dotnet ef database update` draait. Op shared hosting kun je vaak geen CLI-commando's op de server uitvoeren. Hoe worden migraties in test en productie toegepast? A) De pipeline genereert een idempotent SQL-script (`dotnet ef migrations script --idempotent`) als build-artifact, dat ik zelf uitvoer op de database — expliciet en controleerbaar B) De pipeline past migraties direct toe op de database vanuit de runner (vereist dat de runner de database kan bereiken) C) Laat `ApplicationDbContext` bij het opstarten automatisch migreren, net als de twee module-contexts — dan is deploy self-contained D) Combinatie: automatisch bij opstarten voor test, idempotent script voor productie X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: C ### Question 11 **Gemeten feit**: de admin-SPA eist `VITE_API_BASE_URL` als **absolute** URL (Zod-gevalideerd in `config.ts`). In het single-host model staat de API echter op dezelfde origin als `/admin`, dus dit is technisch onnodig — maar zolang het zo is, moet je per omgeving een aparte bundel bouwen. Wat doen we hiermee? A) Pas `config.ts` aan zodat de API-basis-URL leeg/relatief mag zijn en standaard same-origin is — dan is één bundel geldig voor test én productie B) Laat het zoals het is en bouw twee keer (aparte test- en productie-build), zoals de referentie doet voor `VITE_APP_ENV` C) Pas het aan naar same-origin, maar houd een optionele override-variabele voor uitzonderingsgevallen X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: X, Het mag naar same-origin, maar de frontend kan ook een aparte test-build hebben net als de referentie website. Ook is het zo dat nu lokaal wel een url moet worden opgegeven. Als dat verder ook blijft werken hoeft de url variabele niet blokkerend te zijn voor een enkele bundel ### Question 12 **Gemeten feit**: er is geen `appsettings.Test.json` en geen `ASPNETCORE_ENVIRONMENT`-waarde voor test. Productiegeheimen worden verwacht als environment-variabelen (`ConnectionStrings__DefaultConnection`, `JwtSettings__Secret`, etc.). Hoe wordt de test/productie-configuratie geleverd? A) Environment-variabelen op de host, per omgeving handmatig ingesteld — de workflow raakt ze niet B) De workflow schrijft ze bij deploy in een bestand (bijv. `appsettings.Production.json`) op basis van Gitea Secrets C) Environment-variabelen op de host voor geheimen, plus een nieuw `appsettings.Test.json` in de repo voor niet-geheime test-instellingen X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 13 **Gemeten feit**: Data Protection gebruikt de standaard bestandssysteem-key-ring zonder persistente store. Een redeploy die die map wist, maakt opgeslagen slave API keys **onleesbaar** — master↔slave-communicatie stopt dan tot instanties opnieuw worden toegevoegd. Dit staat al als waarschuwing in de README. Nemen we dit mee in deze feature? A) Ja — configureer een persistente key ring (`PersistKeysToDbContext`, gebruikt de bestaande database) zodat een redeploy veilig is B) Ja, maar alleen documenteren welke map bij een deploy niet overschreven mag worden — geen codewijziging C) Nee, buiten scope — apart oppakken X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A --- ## E. Monitoring en observability ### Question 14 **Context**: je gebruikt Sentry plus console-logging. De referentie heeft alleen een frontend (`@sentry/react`); hier is er ook een .NET-backend. Waar komt Sentry? A) Beide — `Sentry.AspNetCore` in de API én `@sentry/react` in de admin-SPA B) Alleen de backend — de admin-SPA is intern gebruik, daar volstaat console-logging C) Alleen de frontend, net als de referentie X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 15 **Context**: de referentie gebruikt één Sentry-project voor beide omgevingen en onderscheidt ze met een `environment`-tag. Hoe richten we Sentry-projecten in voor de CMS? A) Eén Sentry-project voor de CMS, met `environment`-tags voor test en productie (zoals de referentie) B) Aparte Sentry-projecten per omgeving C) Aparte Sentry-projecten voor backend en frontend, elk met environment-tags X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 16 **Gemeten feit**: het productie-loglevel staat op `Warning` en er is alleen de console-logger. Op shared hosting is een console vaak niet zichtbaar — logs zijn dan effectief nergens. Wat is de logging-opzet in productie? A) Console-logging blijft (voor lokaal/test) en Sentry vangt fouten op — dat is voldoende B) Console plus een logbestand op de host, met dagelijkse rotatie C) Console plus structured logging naar Sentry inclusief informatievere niveaus dan alleen exceptions X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:C ### Question 17 **Context**: `AddHealthChecks()` + `MapHealthChecks("/health")` kost geen package; `.AddDbContextCheck()` kost er één. `/health` moet op de bypass-lijst van `AvailabilityMiddleware`, anders geeft de gate een 503 als een instantie is uitgezet. Wat moet de health check controleren? A) Alleen liveness — draait het proces? Geen database-aanroep, snelste en meest stabiele signaal voor UptimeRobot B) Liveness plus database-connectiviteit (`AddDbContextCheck`) C) Liveness, database én openstaande migraties — dan zie je ook een half-gedeployde staat D) Twee endpoints: `/health` voor liveness (voor UptimeRobot) en `/health/ready` met database en migraties (voor jezelf) X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Question 18 Wat moet UptimeRobot monitoren? A) Alleen `/health` per omgeving B) `/health` plus de publieke website (`/`) — die wordt namelijk buiten de availability-gate om geserveerd C) `/health`, de publieke website en `/admin` X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:C ### Question 19 **Context**: de referentie heeft een zelf-gehoste Umami op `analytics.slpsoftware.nl` (Podman op de Pi), met per omgeving een eigen website-ID. Hoe gebruiken we Umami hier? A) Hergebruik de bestaande zelf-gehoste Umami — voeg alleen nieuwe website-entries toe voor de CMS-omgevingen B) Nieuwe, aparte Umami-instantie voor de CMS C) Hergebruik de bestaande instantie, maar dit is per-klant: elke CMS-installatie krijgt zijn eigen website-ID X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: A ### Question 20 **Context**: de admin-SPA is een intern beheerscherm; de publieke website komt uit een andere workspace. Wat wordt er met Umami gemeten? A) Alleen de publieke website — en de instructies leggen vast hoe een website-workspace het script meekrijgt B) Publieke website plus de admin-SPA (om te zien hoe beheerders het CMS gebruiken) C) Alleen de admin-SPA — de publieke website regelt zijn eigen analytics volledig zelf X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:B --- ## F. Rollback en betrouwbaarheid ### Question 21 **Context**: de referentie rolt terug door een eerdere commit opnieuw te bouwen en te uploaden. Bij een .NET-app met database-migraties is dat riskanter, omdat een migratie niet zomaar terugdraait. Wat is de rollback-strategie? A) Opnieuw bouwen en deployen van een eerdere commit, en migraties bewust voorwaarts-compatibel houden (nooit destructief) B) Zoals A, plus de vorige publish-output bewaren op de host zodat je snel kunt terugzetten zonder te bouwen C) Zoals B, plus een database-backup vóór elke productie-deploy X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:C ### Question 22 **Context**: op IIS-hosting kun je met een `app_offline.htm`-bestand de app netjes stilleggen tijdens een deploy — zonder serverconfiguratie. Zonder dat kunnen bezoekers halve bestanden of vergrendelde DLL's tegenkomen. Wil je downtime-beheersing tijdens de deploy? A) Ja — plaats `app_offline.htm` vóór de upload en verwijder het erna B) Nee, korte downtime tijdens de upload is acceptabel C) Ja, en gebruik daarnaast de bestaande availability-functionaliteit om de instantie in onderhoudsmodus te zetten X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A --- ## G. Workflow-extensies en fasering ### Vraag: Beveiligingsextensies Moeten de beveiligingsregels als harde vereisten worden afgedwongen voor dit project? A) Ja — dwing alle BEVEILIGINGSREGELS af als blokkerende vereisten (aanbevolen voor productietoepassingen) B) Nee — sla alle BEVEILIGINGSREGELS over (geschikt voor PoC's, prototypes en experimentele projecten) X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A ### Vraag: Property-Based Testing Extensie Moeten de property-based testing (PBT) regels worden afgedwongen voor dit project? A) Ja — dwing alle PBT-regels af als blokkerende vereisten (aanbevolen voor projecten met bedrijfslogica, datatransformaties, serialisatie of stateful componenten) B) Gedeeltelijk — dwing PBT-regels alleen af voor pure functies en serialisatie round-trips (geschikt voor projecten met beperkte algoritmische complexiteit) C) Nee — sla alle PBT-regels over (geschikt voor eenvoudige CRUD-applicaties, UI-only projecten of dunne integratielagen zonder significante bedrijfslogica) X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:C ### Vraag: Operations-fase Moet deze feature na Construction door de Operations-fase (deployment- en monitoring-opzet)? **Toelichting**: voor deze feature is dat vermoedelijk het zwaartepunt — de deployment-instructies, monitoring-opzet en productie-readiness-checklist horen daar thuis. A) Ja — draai de Operations-fase na Construction (deployment + monitoring setup) B) Nee — stop na Build and Test (deployment/monitoring vallen buiten scope voor deze feature) C) Nog niet zeker — vraag het me opnieuw na de Construction-fase X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A