Compare commits
1 Commits
chore/004-
...
170994b44d
| Author | SHA1 | Date | |
|---|---|---|---|
| 170994b44d |
@ -1,439 +0,0 @@
|
|||||||
# 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:
|
|
||||||
|
|
||||||
> 1–99 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 1–99.
|
|
||||||
|
|
||||||
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 1–99 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.
|
|
||||||
Reference in New Issue
Block a user