docs: specify task points feature #5

Merged
urban merged 1 commits from docs/003-task-points into main 2026-07-26 16:41:52 +02:00

View File

@ -0,0 +1,439 @@
# Feature 3 Uppgiftspoäng
## Status
Planerad.
## Bakgrund
HemHub ska på sikt kunna använda spelifiering för att uppmuntra
familjemedlemmar att utföra uppgifter. Exempel på framtida funktioner kan vara
mål, achievements och belöningar baserade på hur många poäng en användare
samlar under en viss period.
Feature 3 inför den grundläggande poänginformationen på uppgiften. Funktionen
registrerar endast uppgiftens poängvärde. Intjäning av poäng och övrig
spelifiering införs i senare features.
## Mål
Feature 3 ska:
- lägga till ett obligatoriskt poängvärde på varje uppgift;
- låta användaren ange poäng när en uppgift skapas;
- visa poängen på uppgiftskortet;
- validera poängen konsekvent i frontend och backend;
- dokumentera hur lokal utvecklingsdata hanteras.
## Betydelsen av poäng
Poängen uttrycker uppgiftens samlade värde utifrån hur:
- tidskrävande uppgiften är;
- besvärlig uppgiften är;
- viktig uppgiften är.
När poängintjäning införs i en senare feature ska samma värde motsvara hur många
poäng användaren får när uppgiften slutförs.
Poängen är inte en exakt tidsuppskattning. En snabb men viktig uppgift kan
därför ha ett högre poängvärde än en längre men mindre betydelsefull uppgift.
Feature 3 registrerar endast poängvärdet. Den ska inte registrera:
- vem som har tjänat poängen;
- om poängen har delats ut;
- när poängen har tjänats in;
- någon historik över poäng.
## Poängskala
Poäng ska vara ett heltal mellan 1 och 99, inklusive gränsvärdena.
Alla heltal i intervallet är tillåtna. Feature 3 inför inte någon fast skala med
fördefinierade steg.
Giltiga exempel:
- 1
- 7
- 25
- 99
Ogiltiga exempel:
- inget värde;
- `null`;
- 0;
- negativa tal;
- 100 eller högre;
- decimaltal;
- text som inte kan tolkas som ett heltal.
En fast poängskala kan införas senare om erfarenhet från användningen visar att
det är lämpligt.
## Avgränsning
Feature 3 omfattar endast:
- uppgiftens titel;
- uppgiftens valfria beskrivning;
- uppgiftens obligatoriska poängvärde;
- visning av poäng på uppgiftskortet.
Feature 3 ska inte införa:
- tilldelning av uppgifter;
- ändring av uppgiftsstatus;
- drag-and-drop;
- redigering av befintliga uppgifter;
- radering av uppgifter;
- deadlines;
- återkommande uppgifter;
- poänghistorik;
- användares poängsaldo;
- topplistor;
- statistik;
- mål;
- achievements;
- belöningar;
- automatisk utdelning av poäng när en uppgift slutförs.
Dessa funktioner hanteras i senare features enligt roadmapen.
## Användarflöde
När användaren öppnar dialogen för att skapa en uppgift ska formuläret
innehålla:
- titel;
- beskrivning;
- poäng.
Poängfältet ska initialt innehålla värdet `1`.
Användaren kan behålla standardvärdet eller ange ett annat heltal mellan 1 och
99.
När uppgiften skapas ska frontend alltid skicka poängvärdet uttryckligen till
backend. Backend ska inte själv fylla i ett saknat värde.
Efter att en uppgift har skapats framgångsrikt ska formuläret återställas.
Poängfältet ska då återgå till `1`.
Om dialogen stängs och senare öppnas igen ska poängfältet också börja på `1`.
## Skapandedialog
Poäng ska anges med ett vanligt numeriskt inmatningsfält.
Fältet ska ha:
- etiketten `Poäng`;
- initialt värde `1`;
- minsta värde `1`;
- högsta värde `99`;
- heltalssteg.
En kort hjälptext kan visas:
> 199 poäng beroende på hur tidskrävande, besvärlig eller viktig uppgiften är.
Fältet får tillfälligt vara tomt medan användaren redigerar värdet. Frontend ska
inte automatiskt återställa värdet till `1` medan användaren skriver.
Validering ska främst ske när användaren försöker skicka formuläret. Avancerad
validering vid varje tangenttryckning ingår inte i denna feature.
## Frontendvalidering
Frontend ska blockera skapandeanropet om poängen inte är ett heltal mellan 1 och
99.
Vid ett ogiltigt värde ska följande meddelande visas:
> Poäng måste vara ett heltal mellan 1 och 99.
Samma meddelande kan användas för:
- tomt värde;
- värde under 1;
- värde över 99;
- decimaltal;
- annat ogiltigt innehåll.
HTML-fältets attribut för minsta värde, högsta värde och heltalssteg får användas
som stöd, men formulärlogiken ska också kontrollera värdet explicit.
Backend är alltid den slutliga garanten för valideringsreglerna.
## Visning på uppgiftskortet
Uppgiftens poäng ska visas på uppgiftskortet som en kompakt och dynamisk badge.
Badgen ska:
- renderas som en vanlig React- och HTML-komponent;
- använda text och CSS;
- läsa värdet från uppgiftens `points`;
- visa värdet i formatet `{points} p`.
Exempel:
- `1 p`
- `7 p`
- `99 p`
Ingen genererad bild eller statisk grafik ska användas för själva poängvärdet.
Placering och visuell utformning ska följa projektets befintliga skärmbilder och
nuvarande kortdesign. Poängindikatorn ska ligga i kortets metadataområde på
motsvarande plats som poängindikatorn i designreferensen.
Mindre justeringar får göras för att passa den faktiska kortimplementationen.
Feature 3 ska däremot inte införa en ny övergripande design för uppgiftskortet.
## API
Fältnamnet ska vara `points` genomgående i API, backend och frontend.
### Skapa uppgift
Requesten för att skapa en uppgift ska innehålla:
```json
{
"title": "Töm diskmaskinen",
"description": "Ställ in allt i rätt skåp",
"points": 3
}
```
`points` är obligatoriskt.
Backend ska inte tolka ett saknat värde som `1`.
### Uppgiftssvar
API-svar som innehåller en uppgift ska också innehålla `points`.
Exempel:
```json
{
"id": "00000000-0000-0000-0000-000000000000",
"title": "Töm diskmaskinen",
"description": "Ställ in allt i rätt skåp",
"status": "WAITING",
"points": 3,
"createdAt": "2026-07-26T12:00:00Z"
}
```
Det gäller både:
- svaret efter att en uppgift skapats;
- listning av uppgifter.
Det exakta API-formatet ska i övrigt följa den befintliga implementationen.
## Backendregler
En uppgift får aldrig existera med ett poängvärde utanför intervallet 199.
Regeln ska skyddas genom hela backend, inte bara i HTTP-lagret.
Beroende på repositoryts befintliga struktur ska valideringen tillämpas på
relevanta nivåer, exempelvis:
- requestvalidering;
- applikations- eller domänlogik;
- entitetsmodell;
- databasens schema.
Implementation ska följa projektets etablerade kodstruktur och inte introducera
ett nytt arkitekturmönster enbart för denna feature.
## Felhantering
Ett ogiltigt eller saknat `points` ska ge:
```text
400 Bad Request
```
Backend ska använda projektets befintliga felformat och befintliga
felhantering.
Feature 3 ska inte introducera en separat felmodell endast för poäng.
Backend får ge mer precisa valideringsdetaljer för exempelvis:
- saknat värde;
- `null`;
- värde under 1;
- värde över 99.
Frontend behöver inte återge varje backenddetalj separat, utan kan visa det
gemensamma användarmeddelandet:
> Poäng måste vara ett heltal mellan 1 och 99.
Vid andra eller oväntade backendfel ska frontend fortsätta använda projektets
befintliga generella felhantering.
## Databas
Databasschemat ska innehålla ett obligatoriskt heltalsfält för uppgiftens poäng.
Det logiska slutläget är:
```text
points INTEGER NOT NULL
```
Databasen ska, om den befintliga schemahanteringen stödjer det, även skydda
intervallet 199 med en motsvarande constraint.
Databasen ska inte ha ett permanent defaultvärde för nya uppgifter. Nya
uppgifter ska alltid få ett uttryckligt poängvärde från applikationen.
Det förvalda värdet `1` är ett frontendbeteende och inte ett sätt för backend
eller databasen att tyst komplettera ofullständiga anrop.
## Lokal utvecklingsdatabas
Den lokala utvecklingsdatabasen ska vara en in-memory H2-databas.
Databasen och dess innehåll ska återställas när backend startas om.
Lokal utvecklingsdata betraktas därför som tillfällig. Användare och uppgifter
som skapats manuellt under utveckling behöver inte bevaras mellan starter.
Detta innebär att Feature 3 inte behöver migrera verkliga befintliga
utvecklingsposter. En ny databas skapas direkt med det obligatoriska
poängfältet.
Codex ska kontrollera repositoryts faktiska konfiguration. Om H2 för närvarande
är filbaserad ska den ändras till in-memory och relevant
utvecklingsdokumentation ska uppdateras.
## Schemahantering och framtida migrering
Att lokal utvecklingsdata inte bevaras innebär inte att framtida
produktionsdata kan återställas vid varje release.
När HemHub börjar använda en beständig Postgres-databas med data som ska bevaras
måste schemaändringar hanteras med kontrollerade migreringar.
Feature 3 behöver inte införa eller färdigställa hela den framtida
produktionsstrategin om den ännu inte finns i repositoryt.
Projektet använder redan Flyway och versionshanterade migreringar. Feature 3 ska
därför lägga till en ny Flyway-migrering för poängfältet och inte ändra tidigare
migreringar. Hibernate ska fortsatt validera schemat i stället för att skapa
det.
Bytet till in-memory H2 innebär att befintliga lokala utvecklingsposter inte
behöver bevaras eller fyllas på med poäng. Själva schemaändringen ska ändå
hanteras som en kontrollerad migrering så att migrationshistoriken förblir
sammanhängande inför framtida beständig data.
Repositoryts faktiska arkitektur och dokumentation har företräde.
## Backendtester
Feature 3 ska minst verifiera att:
- en uppgift kan skapas med ett giltigt `points`;
- det skapade API-svaret innehåller samma `points`;
- listning av uppgifter innehåller `points`;
- gränsvärdet `1` accepteras;
- gränsvärdet `99` accepteras;
- saknat `points` ger `400 Bad Request`;
- `points: null` ger `400 Bad Request`;
- `points: 0` ger `400 Bad Request`;
- negativa värden ger `400 Bad Request`;
- `points: 100` ger `400 Bad Request`.
Testerna ska följa befintlig teststil och utöka nuvarande tester där det är
lämpligt.
## Frontendtester
Feature 3 ska minst verifiera att:
- skapandedialogen öppnas med poängvärdet `1`;
- ett giltigt poängvärde skickas i create-anropet;
- tomt poängfält blockerar submit;
- ett värde under 1 blockerar submit;
- ett värde över 99 blockerar submit;
- ett ogiltigt värde visar felmeddelandet;
- formuläret återställs till poängvärdet `1` efter lyckad skapning;
- ett uppgiftskort visar uppgiftens dynamiska poängbadge;
- badgen visar värdet från uppgiftsdata, exempelvis `7 p`.
Testerna ska inte vara beroende av en viss pixelplacering eller detaljerad CSS.
## Manuell verifiering
Följande ska verifieras manuellt:
1. Starta frontend och backend enligt projektets utvecklingsinstruktioner.
2. Skapa en uppgift utan att ändra poängfältet.
3. Verifiera att uppgiften får `1 p`.
4. Skapa en uppgift med ett mellanvärde, exempelvis `7`.
5. Verifiera att uppgiften får `7 p`.
6. Skapa en uppgift med `99`.
7. Verifiera att uppgiften får `99 p`.
8. Försök skapa en uppgift med tomt poängfält.
9. Verifiera att anropet blockeras och att rätt felmeddelande visas.
10. Försök använda värdena `0` och `100`.
11. Verifiera att båda avvisas.
12. Kontrollera att poängbadgen följer projektets designreferens och fungerar
med ett- och tvåsiffriga värden.
13. Starta om backend.
14. Verifiera att den lokala utvecklingsdatan inte finns kvar.
## Acceptanskriterier
Feature 3 är klar när:
- varje ny uppgift har ett obligatoriskt `points`;
- `points` är ett heltal mellan 1 och 99;
- frontendens standardvärde är `1`;
- frontend alltid skickar `points` uttryckligen;
- backend avvisar saknat eller ogiltigt `points`;
- backend fyller inte automatiskt i ett saknat värde;
- uppgiftens poäng returneras av API:t;
- uppgiftens poäng visas dynamiskt på uppgiftskortet;
- frontend- och backendtester täcker centrala giltiga och ogiltiga fall;
- lokal H2 körs som in-memory och återställs vid omstart;
- relevant dokumentation är uppdaterad;
- Feature 3 inte inför funktionalitet som hör till senare features.
## Implementationsprinciper
När Feature 3 senare implementeras ska Codex först läsa:
```text
AGENTS.md
README.md
docs/architecture.md
docs/development.md
docs/roadmap.md
docs/decisions/
docs/features/
```
Codex ska även läsa relevant backendkod, frontendkod och befintliga tester innan
ändringar görs.
Repositoryts faktiska kod och dokumentation har företräde framför antaganden i
denna featurebeskrivning.
Dokumentation, implementation och tester ska uppdateras tillsammans.
Codex ska inte committa, pusha, skapa pull request eller merga utan uttrycklig
instruktion.