Statusrapporterna
YtaTar emot, prövar och visar projektets statusrapporter, från formuläret eller via API:t.
källa: apps/projekt/src/statusrapport, apps/projekt/src/app/(projekt)/status, apps/projekt/src/app/api/statusuppdaterad:
Ansvar
- Visa rapporterna på /status, senast först, med det senaste läget överst och en fast adress per rapport: /status/<id>.
- Ta emot rapporter från formuläret på /status/ny och från API:t på /api/status genom samma schema och samma serverfunktioner. Servern prövar varje fält själv och skapar inget som inte håller.
- Kräva skrivnyckeln för varje skrivning: Bearer-token i API:t, en signerad kaka i formuläret. Felaktiga nycklar räknas mot samma spärr som röstkoderna.
- Kräva en förklaring när läget är gult eller rött, och märka text skriven av AI med ✦ AI-genererat.
- Spara rapporterna så att de överlever en omdeploy: en JSON-fil i datavolymen, med köade skrivningar.
Filer
| Sökväg | Roll |
|---|---|
| statusrapport/regler.ts | Schemat (zod, strikt), lägena, provaRapport, id ur datumet, ISO-veckan och ordningen. Ren logik med tester. |
| statusrapport/statusrapport.test.ts | Felen från provaRapport: nycklarna för API:t, etiketterna för formuläret. |
| lagring.test.ts | Vaktar att varje lagringsfil (process.env.*_FIL) sätts till /app/data/ i Dockerfile, så att inget sparas utanför volymen. |
| statusrapport/lager.ts | JSON-filen i STATUS_FIL, som standard data/status.json. I containern sätter Dockerfile /app/data/status.json, i volymen – server.js byter katalog till apps/projekt, så utan den försvinner rapporterna vid nästa deploy. Skrivningarna köas och byter fil atomärt. |
| statusrapport/server.ts | Skrivnyckeln, kakan och skapa, rätta, ta bort – samma för formulär och API. |
| statusrapport/api.ts | Behörigheten för API:ts skrivningar: 503 utan nyckel på servern, 429 efter för många fel, 401 vid fel nyckel. |
| statusrapport/actions.ts | Formulärets server actions: logga in med nyckeln, spara, ta bort, logga ut. Varje åtgärd kontrollerar kakan själv. Inloggningen tar ett vidare-fält, så att att göra-listan (ADR-036) kan använda samma nyckel och kaka. |
| app/api/status/route.ts | GET alla rapporter, POST en ny. |
| app/api/status/[id]/route.ts | GET, PUT och DELETE på en rapport. |
| app/(projekt)/status/page.tsx | Alla rapporter, läget nu och vad färgerna betyder. |
| app/(projekt)/status/[id]/page.tsx | En rapport på sin fasta adress, med föregående och nästa. |
| app/(projekt)/status/ny/page.tsx | Skriv en rapport: nyckeln först, sedan formuläret. |
| app/(projekt)/status/[id]/andra/page.tsx | Rätta eller ta bort en rapport. |
| app/(projekt)/status/Rapport.tsx | Rapporten hel och som kort post, flödet som håller dem – utan kort, skilda av en linje – och lägeschipet. |
| app/(projekt)/status/Rapportformular.tsx | Formuläret. Klient bara för att visa serverns fel – per fält, med fältens etiketter ur ETIKETTER – utan att tappa det som skrivits. |
| atkomst/felforsok.ts | Spärren mot gissade koder, delad med röstningen. |
API
| Namn | Signatur | Beskrivning |
|---|---|---|
| GET /api/status | → 200 { rapporter: Statusrapport[] } | Alla rapporter, senast först. Öppet. |
| POST /api/status | Authorization: Bearer <STATUS_SKRIVNYCKEL>, body: RapportIn → 201 { rapport, url } | 400 { fel: string[] } | Skapar en rapport. Id blir datumet, med löpnummer om dagen redan har en. |
| GET /api/status/:id | → 200 { rapport } | 404 | En rapport. Öppet. |
| PUT /api/status/:id | Bearer, body: RapportIn → 200 { rapport, url } | 400 | 404 | Byter hela innehållet. Id och skapad ligger fast; andrad sätts. |
| DELETE /api/status/:id | Bearer → 204 | 404 | Tar bort rapporten för gott. |
| provaRapport | (indata: unknown) => { ok: true; rapport } | { ok: false; fel: string[]; faltfel: Fel[] } | Schemat plus regeln att gult och rött kräver lageText. `fel` nämner nycklarna (API:t), `faltfel` fälten med formulärets etiketter. |
Kontrakt
| Fält | Typ | Krav |
|---|---|---|
| datum | string | ÅÅÅÅ-MM-DD. Dagen rapporten gäller, oftast veckans sista arbetsdag. |
| rubrik | string | 1–120 tecken. |
| sammanfattning | string | 1–800 tecken. Skriv för en direktör: vad har hänt och vad betyder det? |
| lage | "gront" | "gult" | "rott" | Enligt plan, behöver bevakas eller kräver åtgärd. |
| lageText | string? | Krävs när lage är gult eller rött. Högst 400 tecken. |
| gjort | string[] | 1–15 punkter om vad som hänt, högst 400 tecken var. |
| harnast | string[]? | Högst 15 punkter. Standard tom. |
| hinder | string[]? | Högst 10 punkter. Standard tom. |
| avsandare | string? | Roll eller grupp, aldrig ett namn. Standard Projektteamet. |
| aiGenererad | boolean? | true när texten är skriven av AI. Visas som ✦ AI-genererat. Standard false. |
Skriv en rapport med curl, till exempel från Claude Code
curl -X POST https://start.sundsvall.dev/api/status \
-H "Authorization: Bearer $STATUS_SKRIVNYCKEL" \
-H "Content-Type: application/json" \
-d '{
"datum": "2026-10-16",
"rubrik": "Projektet på roten och första statusrapporten",
"sammanfattning": "Projektsidan är omgjord så att projektet är huvudsaken.",
"lage": "gront",
"gjort": ["Projektboken flyttad till roten", "Statusrapporter med API"],
"harnast": ["Case väljs"],
"avsandare": "Projektteamet",
"aiGenererad": true
}'- Okända fält avvisas (strikt schema). Felen kommer som en lista med fältets namn först: "lageText: Ett gult eller rött läge behöver en förklaring."
- Sidan är publik. En rapport skrivs därefter: inga känsliga personuppgifter, inget som bara teamet får veta.
- En agent som skriver en rapport sätter aiGenererad: true. Att modellen föreslår en rapport räcker inte – servern prövar den, och en människa ansvarar för att den publiceras.
- Utan STATUS_SKRIVNYCKEL på servern svarar alla skrivningar 503 och formuläret säger att skrivning är avstängd. Läsningen fungerar ändå.
Beroenden och beslut
- Projektets första sida
- Projektets yta
- bygge (gemensam, i devportalen)
- ui (gemensam, i devportalen)
- tokens (gemensam, i devportalen)
Beslut: ADR-032, ADR-012, ADR-028
Levererar: /status, /status/:id, /status/ny, GET/POST /api/status, GET/PUT/DELETE /api/status/:id, STATUS_SKRIVNYCKEL
Kvarstår
- STATUS_SKRIVNYCKEL är inte satt i Dokploy. Tills den är det kan ingen skriva.
- Ingen historik över ändringar: PUT skriver över, och DELETE går inte att ångra.
- Läget i rapporten är inte kopplat till tidslinjen. Visuell status över tid saknas.
- Inget utkast med AI ur tidslinjens händelser än – rapporten skrivs från noll eller av ett verktyg utanför sidan.
15 delar i projektportalen · gemensamma i devportalen: ai-adapter, anthropic, bygge, designsystem, dokploy, dokumentation, gemensamt, tokens, ui