Compare commits
4 Commits
2f7b99fb21
...
chore/004-
| Author | SHA1 | Date | |
|---|---|---|---|
| 77be23de5d | |||
| a2ed8a64d6 | |||
| 1462f9dc0c | |||
| f9246d4463 |
@ -9,4 +9,11 @@
|
|||||||
- Affärsregler ska senare säkerställas i backend och inte enbart i frontend.
|
- Affärsregler ska senare säkerställas i backend och inte enbart i frontend.
|
||||||
- Kod, tester och dokumentation ska hållas uppdaterade tillsammans.
|
- Kod, tester och dokumentation ska hållas uppdaterade tillsammans.
|
||||||
- Större arkitekturella beslut ska diskuteras innan de införs.
|
- Större arkitekturella beslut ska diskuteras innan de införs.
|
||||||
|
- Aktuell arkitektur, utvecklingsprocess, beslut och featurehistorik dokumenteras
|
||||||
|
under `docs/`.
|
||||||
|
- En feature ska uppdatera berörda dokument så att repositoryt förblir projektets
|
||||||
|
facit även efter att feature-branchen har raderats.
|
||||||
|
- Nästa feature ska väljas från `docs/roadmap.md`.
|
||||||
|
- Roadmapen ska uppdateras innan en feature delas, flyttas, ersätts eller läggs
|
||||||
|
till. En enskild dialog får inte etablera en alternativ featureplan utan att
|
||||||
|
repositoryts roadmap uppdateras.
|
||||||
|
|||||||
13
README.md
13
README.md
@ -49,3 +49,16 @@ Frontend:
|
|||||||
cd frontend
|
cd frontend
|
||||||
pnpm test
|
pnpm test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Dokumentation
|
||||||
|
|
||||||
|
Projektets aktuella arkitektur, utvecklingsprocess, övergripande beslut och
|
||||||
|
featurehistorik finns i [`docs/`](docs/):
|
||||||
|
|
||||||
|
- [arkitektur](docs/architecture.md)
|
||||||
|
- [roadmap och planerad featureordning](docs/roadmap.md)
|
||||||
|
- [utvecklingsprocess](docs/development.md)
|
||||||
|
- [arkitekturbeslut](docs/decisions/)
|
||||||
|
- [implementerade features](docs/features/)
|
||||||
|
|
||||||
|
Dokumentationen ska uppdateras tillsammans med implementation och tester.
|
||||||
|
|||||||
183
docs/architecture.md
Normal file
183
docs/architecture.md
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
# HemHubs arkitektur
|
||||||
|
|
||||||
|
Detta dokument beskriver den arkitektur som kan verifieras i repositoryts kod,
|
||||||
|
tester och konfiguration. Historiska implementationssteg finns under
|
||||||
|
[`features/`](features/) och övergripande beslut under
|
||||||
|
[`decisions/`](decisions/).
|
||||||
|
|
||||||
|
## Aktuell implementation
|
||||||
|
|
||||||
|
### Monorepo
|
||||||
|
|
||||||
|
HemHub ligger i ett Git-repository med två separata applikationer:
|
||||||
|
|
||||||
|
```text
|
||||||
|
hemhub/
|
||||||
|
├── backend/
|
||||||
|
├── frontend/
|
||||||
|
└── docs/
|
||||||
|
```
|
||||||
|
|
||||||
|
Applikationerna har egna byggverktyg och beroenden. De delar inte källkod eller
|
||||||
|
byggprocess.
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
|
||||||
|
Frontend finns i `frontend/` och använder React 19, TypeScript, Vite och pnpm.
|
||||||
|
Den ansvarar för:
|
||||||
|
|
||||||
|
- hämtning och presentation av användare och uppgifter;
|
||||||
|
- lokalt val av aktiv användare;
|
||||||
|
- formulär för att skapa användare och uppgifter;
|
||||||
|
- klientnära validering och begripliga felmeddelanden;
|
||||||
|
- uppgiftsbrädan med kolumnerna Väntande, Pågående och Klart.
|
||||||
|
|
||||||
|
Tillståndet hanteras lokalt i React-komponenter. Ingen router eller separat
|
||||||
|
global state-lösning används.
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
|
||||||
|
Backend finns i `backend/` och använder Java 21, Spring Boot 4.1.0, Maven,
|
||||||
|
Spring Web, Spring Data JPA och Flyway. Maven Wrapper ingår i repositoryt.
|
||||||
|
|
||||||
|
Backend ansvarar för API, slutlig validering, skapande av UUID och tidsstämplar,
|
||||||
|
persistens samt sortering av returnerade användare och uppgifter.
|
||||||
|
|
||||||
|
### Kommunikation
|
||||||
|
|
||||||
|
Alla applikationsendpoints ligger under `/api`. Frontend använder enbart
|
||||||
|
relativa adresser, exempelvis `/api/users` och `/api/tasks`.
|
||||||
|
|
||||||
|
Vid lokal utveckling kör Vite normalt på port 5173 och proxar `/api` till
|
||||||
|
`http://localhost:8080`, där Spring Boot körs. Ingen generell
|
||||||
|
CORS-konfiguration finns i backend. Webbläsaren anropar därmed Vites origin,
|
||||||
|
och utvecklingsservern vidarebefordrar API-anropen.
|
||||||
|
|
||||||
|
Aktuella endpoints:
|
||||||
|
|
||||||
|
- `GET /api/health`
|
||||||
|
- `GET /api/users`
|
||||||
|
- `POST /api/users`
|
||||||
|
- `GET /api/tasks`
|
||||||
|
- `POST /api/tasks`
|
||||||
|
|
||||||
|
### Databas och migreringar
|
||||||
|
|
||||||
|
Lokal körning använder en filbaserad H2-databas under `backend/data`. Katalogen
|
||||||
|
ignoreras av Git. Automatiska backendtester använder en separat H2-databas i
|
||||||
|
minnet.
|
||||||
|
|
||||||
|
Båda anslutningarna använder H2:s `MODE=PostgreSQL`,
|
||||||
|
`DATABASE_TO_LOWER=TRUE` och `DEFAULT_NULL_ORDERING=HIGH`. Det är en verifierbar
|
||||||
|
kompatibilitetsinställning, inte samma sak som att applikationen har verifierats
|
||||||
|
mot PostgreSQL.
|
||||||
|
|
||||||
|
Flyway kör migreringarna:
|
||||||
|
|
||||||
|
- `V1__create_users.sql`
|
||||||
|
- `V2__create_tasks.sql`
|
||||||
|
|
||||||
|
Hibernate är konfigurerat med `ddl-auto=validate`; Flyway skapar schemat och
|
||||||
|
Hibernate validerar entiteterna mot det.
|
||||||
|
|
||||||
|
### Domänmodell
|
||||||
|
|
||||||
|
#### Användare
|
||||||
|
|
||||||
|
En användare lagras i tabellen `app_user` med:
|
||||||
|
|
||||||
|
- `id`: UUID;
|
||||||
|
- `name`: visningsnamn, högst 50 tecken;
|
||||||
|
- `normalized_name`: trimmat namn i gemener, internt och unikt;
|
||||||
|
- `created_at`: en `Instant`, lagrad som `TIMESTAMP WITH TIME ZONE`.
|
||||||
|
|
||||||
|
`normalized_name` exponeras inte via API. Användare returneras alfabetiskt efter
|
||||||
|
visningsnamn med deterministiska sekundära jämförelser.
|
||||||
|
|
||||||
|
#### Uppgift
|
||||||
|
|
||||||
|
En uppgift lagras i tabellen `task` med:
|
||||||
|
|
||||||
|
- `id`: UUID;
|
||||||
|
- `title`: obligatorisk titel, högst 100 tecken;
|
||||||
|
- `description`: valfri beskrivning, högst 500 tecken;
|
||||||
|
- `status`: `WAITING`, `IN_PROGRESS` eller `COMPLETED`;
|
||||||
|
- `created_at`: en `Instant`, lagrad som `TIMESTAMP WITH TIME ZONE`.
|
||||||
|
|
||||||
|
Status lagras som enumens textvärde genom `EnumType.STRING`. Nya uppgifter får
|
||||||
|
alltid status `WAITING`. Det finns ingen relation mellan uppgifter och
|
||||||
|
användare; alla aktiva användare ser samma uppgiftslista.
|
||||||
|
|
||||||
|
### Aktiv användare
|
||||||
|
|
||||||
|
Användarlistan hämtas från backend. Frontend lagrar endast den valda
|
||||||
|
användarens UUID i webbläsarens `localStorage` under nyckeln
|
||||||
|
`hemhub.activeUserId`.
|
||||||
|
|
||||||
|
Vid start verifieras det lagrade id:t mot backendens aktuella användarlista. Ett
|
||||||
|
giltigt val återanvänds i samma browser. Ett ogiltigt val tas bort. Valet är
|
||||||
|
lokalt per browser och utgör inte autentisering eller behörighetskontroll.
|
||||||
|
|
||||||
|
### Felhantering
|
||||||
|
|
||||||
|
Backend använder ett litet gemensamt JSON-format med `code` och `message`.
|
||||||
|
`ApiExceptionHandler` översätter kända valideringsfel till `400 Bad Request`
|
||||||
|
och dubbletter av användarnamn till `409 Conflict`.
|
||||||
|
|
||||||
|
Frontend skiljer mellan fel vid hämtning och skapande. Hämtfel kan
|
||||||
|
återförsökas. Formulärfel visas nära formuläret och inmatningen behålls vid
|
||||||
|
misslyckade API-anrop.
|
||||||
|
|
||||||
|
### Teststrategi
|
||||||
|
|
||||||
|
Backend har JUnit 5-tester:
|
||||||
|
|
||||||
|
- ett fristående MockMvc-test för health-endpointen;
|
||||||
|
- Spring Boot-integrationstester via MockMvc mot H2 in-memory för användar- och
|
||||||
|
uppgifts-API.
|
||||||
|
|
||||||
|
Frontend använder Vitest, jsdom och React Testing Library. `fetch` och
|
||||||
|
`localStorage` ersätts i testerna, så frontendtesterna kräver inte en körande
|
||||||
|
backend. Produktionsbygget kör TypeScript-kompilering följt av Vite.
|
||||||
|
|
||||||
|
### Produktionsdeployment
|
||||||
|
|
||||||
|
Ingen produktionsdeployment är implementerad i repositoryt. Det finns inga
|
||||||
|
Dockerfiler, pipelinefiler eller produktionsspecifika Nginx-, Watchtower- eller
|
||||||
|
databaskonfigurationer. H2 används både lokalt och i automatiska tester; någon
|
||||||
|
PostgreSQL-konfiguration finns ännu inte.
|
||||||
|
|
||||||
|
## Beslutad planerad riktning
|
||||||
|
|
||||||
|
Repositoryt anger att affärsregler även framöver ska säkerställas i backend och
|
||||||
|
att större arkitekturella beslut ska diskuteras innan de införs.
|
||||||
|
|
||||||
|
Följande produktionsriktning är beslutad men ännu inte implementerad:
|
||||||
|
|
||||||
|
- PostgreSQL ska användas som produktionsdatabas.
|
||||||
|
- Frontend och backend ska paketeras som separata Docker-images.
|
||||||
|
- Källkoden ligger i Gitea.
|
||||||
|
- Drone ska bygga och publicera images till ett privat registry.
|
||||||
|
- Watchtower ska uppdatera de körande tjänsterna när nya images publiceras.
|
||||||
|
- Nginx kan användas som reverse proxy framför tjänsterna.
|
||||||
|
- Produktionsmiljön ska köras på Ubuntu-servern Biff.
|
||||||
|
|
||||||
|
Den planerade riktningen beskrivs även i
|
||||||
|
[`005-production-deployment-direction.md`](decisions/005-production-deployment-direction.md).
|
||||||
|
Punkterna ovan beskriver målbilden och ska inte tolkas som att motsvarande
|
||||||
|
konfiguration redan finns eller har verifierats.
|
||||||
|
|
||||||
|
## Fortfarande öppna detaljer
|
||||||
|
|
||||||
|
Följande har inte fastställts i dokumentationen och ska beslutas i samband med
|
||||||
|
att produktionslösningen implementeras:
|
||||||
|
|
||||||
|
- exakt containerstruktur och tjänsteindelning;
|
||||||
|
- image-namn och taggningsstrategi;
|
||||||
|
- produktions-URL;
|
||||||
|
- hantering och distribution av secrets;
|
||||||
|
- exakt Nginx-konfiguration;
|
||||||
|
- exakt Drone-, registry-, Watchtower- och deploymentkonfiguration.
|
||||||
|
|
||||||
|
Miljöspecifika adresser, credentials och secrets ska inte lagras i dessa
|
||||||
|
arkitekturdokument.
|
||||||
28
docs/decisions/001-monorepo.md
Normal file
28
docs/decisions/001-monorepo.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# 001 – Monorepo med separata applikationer
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepterat
|
||||||
|
|
||||||
|
## Datum
|
||||||
|
|
||||||
|
2026-07-23
|
||||||
|
|
||||||
|
## Sammanhang
|
||||||
|
|
||||||
|
HemHub behöver en webbläsarklient och ett server-API. Båda delarna utvecklas
|
||||||
|
inkrementellt och behöver kunna versionshanteras och dokumenteras tillsammans.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Frontend och backend ligger i samma Git-repository, i katalogerna `frontend/`
|
||||||
|
respektive `backend/`. De är separata applikationer med egna byggverktyg,
|
||||||
|
beroenden och startkommandon.
|
||||||
|
|
||||||
|
## Konsekvenser
|
||||||
|
|
||||||
|
- En feature kan ändra frontend, backend, tester och dokumentation atomärt.
|
||||||
|
- En gemensam historik beskriver hela systemet.
|
||||||
|
- Applikationerna kan startas och testas oberoende.
|
||||||
|
- Repositoryt har ingen gemensam rotbyggprocess; relevanta kommandon körs i
|
||||||
|
respektive applikationskatalog.
|
||||||
32
docs/decisions/002-same-origin-api-proxy.md
Normal file
32
docs/decisions/002-same-origin-api-proxy.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# 002 – Relativa API-adresser och lokal utvecklingsproxy
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepterat
|
||||||
|
|
||||||
|
## Datum
|
||||||
|
|
||||||
|
2026-07-23
|
||||||
|
|
||||||
|
## Sammanhang
|
||||||
|
|
||||||
|
Frontend körs lokalt med Vite på port 5173 och backend med Spring Boot på port
|
||||||
|
8080. Frontend behöver nå API:t utan miljöspecifika, hårdkodade backendadresser
|
||||||
|
i applikationskoden.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Frontend använder relativa API-adresser under `/api`. Vites utvecklingsserver
|
||||||
|
proxar `/api` till `http://localhost:8080`.
|
||||||
|
|
||||||
|
Ingen generell CORS-konfiguration införs i backend så länge webbläsaren anropar
|
||||||
|
Vites origin och Vite vidarebefordrar anropet.
|
||||||
|
|
||||||
|
## Konsekvenser
|
||||||
|
|
||||||
|
- Frontendkoden innehåller inte en lokal fullständig backend-URL.
|
||||||
|
- Lokal utveckling kräver att backend är tillgänglig på port 8080 för
|
||||||
|
API-anrop via proxyn.
|
||||||
|
- En separat CORS-policy behöver inte underhållas för nuvarande lokala flöde.
|
||||||
|
- En framtida driftlösning måste ge `/api` en motsvarande same-origin-väg eller
|
||||||
|
medföra ett nytt dokumenterat beslut.
|
||||||
34
docs/decisions/003-central-users-local-active-user.md
Normal file
34
docs/decisions/003-central-users-local-active-user.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# 003 – Centrala användare och lokalt val av aktiv användare
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepterat
|
||||||
|
|
||||||
|
## Datum
|
||||||
|
|
||||||
|
2026-07-24
|
||||||
|
|
||||||
|
## Sammanhang
|
||||||
|
|
||||||
|
HemHub behöver veta vem som använder gränssnittet, men har ännu ingen
|
||||||
|
autentisering. Användarlistan ska vara gemensam medan själva valet kan vara
|
||||||
|
lokalt för den aktuella browsern.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Användare lagras centralt via backend och hämtas från `/api/users`. Frontend
|
||||||
|
lagrar endast vald användares UUID i `localStorage` med nyckeln
|
||||||
|
`hemhub.activeUserId`.
|
||||||
|
|
||||||
|
Vid appstart jämförs det lokala id:t med backendens användarlista. Ett giltigt id
|
||||||
|
återanvänds och ett ogiltigt id tas bort. `Logga ut` tar bort nyckeln och visar
|
||||||
|
användarvalet igen.
|
||||||
|
|
||||||
|
## Konsekvenser
|
||||||
|
|
||||||
|
- Samma browser kan återanvända sitt senaste giltiga användarval.
|
||||||
|
- En annan browser eller en rensad browserlagring måste välja användare igen.
|
||||||
|
- Endast id lagras lokalt; aktuellt namn kommer från backendens lista.
|
||||||
|
- Valet synkroniseras inte mellan browsers eller enheter.
|
||||||
|
- Lösningen identifierar en användare i gränssnittet men ger ingen säker
|
||||||
|
autentisering, session eller behörighetskontroll.
|
||||||
30
docs/decisions/004-feature-branch-workflow.md
Normal file
30
docs/decisions/004-feature-branch-workflow.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# 004 – Kortlivade feature-branches
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepterat
|
||||||
|
|
||||||
|
## Sammanhang
|
||||||
|
|
||||||
|
HemHub utvecklas inkrementellt med avgränsade ändringar. Historiska
|
||||||
|
feature-branches ska kunna raderas efter merge utan att projektets motiv och
|
||||||
|
aktuella läge försvinner.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Varje feature eller avgränsad ändring utvecklas på en kortlivad branch som
|
||||||
|
skapas från uppdaterad `main`. Kod, tester och relevant dokumentation ingår i
|
||||||
|
samma ändring.
|
||||||
|
|
||||||
|
Commit och push görs först efter uttrycklig instruktion. Merge sker efter
|
||||||
|
verifiering, och `main` ska representera verifierad kod. Därefter kan branchen
|
||||||
|
raderas.
|
||||||
|
|
||||||
|
## Konsekvenser
|
||||||
|
|
||||||
|
- Pågående arbete isoleras från `main`.
|
||||||
|
- En feature kan granskas och verifieras som en sammanhållen ändring.
|
||||||
|
- Dokumentationen måste uppdateras före merge så att raderade branches inte
|
||||||
|
behövs för att förstå projektet.
|
||||||
|
- Övergripande beslut bevaras i `docs/decisions/` och faktisk featurehistorik i
|
||||||
|
`docs/features/`.
|
||||||
52
docs/decisions/005-production-deployment-direction.md
Normal file
52
docs/decisions/005-production-deployment-direction.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# 005 – Riktning för produktionsdeployment
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepterat som planerad riktning, ännu inte implementerat
|
||||||
|
|
||||||
|
## Sammanhang
|
||||||
|
|
||||||
|
HemHub använder i nuläget H2 för lokal utveckling och tester. Repositoryt saknar
|
||||||
|
fortfarande container-, pipeline- och produktionskonfiguration, men den
|
||||||
|
övergripande målbilden för byggande och drift behöver vara dokumenterad innan
|
||||||
|
den implementeras.
|
||||||
|
|
||||||
|
Källkoden ligger i Gitea och den planerade produktionsmiljön är Ubuntu-servern
|
||||||
|
Biff.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
- PostgreSQL ska användas som produktionsdatabas.
|
||||||
|
- Frontend och backend ska paketeras som Docker-images.
|
||||||
|
- Drone ska bygga och publicera images till ett privat registry.
|
||||||
|
- Watchtower ska uppdatera tjänsterna när nya images publiceras.
|
||||||
|
- Nginx kan användas som reverse proxy.
|
||||||
|
|
||||||
|
Detta ADR fastställer komponenterna och ansvarsfördelningen på övergripande
|
||||||
|
nivå. Det inför inte någon konfiguration och innebär inte att lösningen redan
|
||||||
|
har driftverifierats.
|
||||||
|
|
||||||
|
## Konsekvenser
|
||||||
|
|
||||||
|
- Kommande produktionsarbete behöver införa och verifiera PostgreSQL-stöd,
|
||||||
|
Dockerpaketering och en Drone-baserad leveranskedja.
|
||||||
|
- Images behöver kunna publiceras till ett privat registry som Biff kan nå.
|
||||||
|
- Uppdateringsflödet behöver utformas så att Watchtower kan hämta och starta nya
|
||||||
|
images på ett kontrollerat sätt.
|
||||||
|
- Nginx är ett möjligt reverse proxy-lager, inte en fastställd detaljkonfiguration.
|
||||||
|
- Lokal utveckling och automatiska tester fortsätter använda H2 tills ett
|
||||||
|
separat beslut eller en feature ändrar detta.
|
||||||
|
|
||||||
|
## Öppna detaljer
|
||||||
|
|
||||||
|
Följande beslutas först när produktionslösningen implementeras:
|
||||||
|
|
||||||
|
- exakt containerstruktur;
|
||||||
|
- image-namn och taggningsstrategi;
|
||||||
|
- produktions-URL;
|
||||||
|
- secrets och hur de tillförs till pipeline och tjänster;
|
||||||
|
- exakt Nginx-konfiguration;
|
||||||
|
- exakt Drone-, registry-, Watchtower- och deploymentkonfiguration.
|
||||||
|
|
||||||
|
IP-adresser, credentials och andra miljöspecifika känsliga värden ska inte
|
||||||
|
dokumenteras här.
|
||||||
63
docs/development.md
Normal file
63
docs/development.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# Utvecklingsprocess
|
||||||
|
|
||||||
|
Repositoryt är projektets facit. ChatGPT- eller Codex-dialoger kan användas som
|
||||||
|
arbetsyta, men implementation, tester och dokumentation ska tillsammans göra
|
||||||
|
projektets läge begripligt utan tidigare dialoger eller raderade branches.
|
||||||
|
|
||||||
|
## Arbetssätt
|
||||||
|
|
||||||
|
- Använd en kortlivad branch per feature eller annan avgränsad ändring.
|
||||||
|
- Skapa branchen från en uppdaterad `main`.
|
||||||
|
- En feature per ChatGPT-dialog är en praktisk arbetsform, inte en
|
||||||
|
dokumentationskälla.
|
||||||
|
- Välj nästa feature från [`roadmap.md`](roadmap.md).
|
||||||
|
- Uppdatera roadmapen innan en feature delas, flyttas, ersätts eller läggs till.
|
||||||
|
En dialog får inte skapa en parallell featureplan som saknas i repositoryt.
|
||||||
|
- Skapa eller uppdatera feature-dokumentet inom samma feature.
|
||||||
|
- Ge Codex en tydligt avgränsad specifikation.
|
||||||
|
- Implementera endast uttryckliga krav och undvik spekulativ funktionalitet.
|
||||||
|
- Kör relevanta tester före commit och gör manuell verifiering när beteendet
|
||||||
|
motiverar det.
|
||||||
|
- Commit och push sker först efter uttrycklig instruktion.
|
||||||
|
- Merge sker först när ändringen har verifierats.
|
||||||
|
- Uppdatera arkitektur- och beslutsdokument när övergripande beslut förändras.
|
||||||
|
|
||||||
|
`main` ska innehålla verifierad kod. När en feature har mergats ska dess branch
|
||||||
|
kunna raderas utan att projektkunskap går förlorad.
|
||||||
|
|
||||||
|
## Rekommenderad featureprocess
|
||||||
|
|
||||||
|
1. Uppdatera `main`.
|
||||||
|
2. Välj nästa feature från roadmapen och dokumentera först eventuell ändring av
|
||||||
|
planen.
|
||||||
|
3. Skapa en avgränsad branch.
|
||||||
|
4. Skapa eller uppdatera feature-dokumentet.
|
||||||
|
5. Implementera specifikationen.
|
||||||
|
6. Kör relevanta automatiska tester och bygge.
|
||||||
|
7. Gör manuell verifiering där det är relevant.
|
||||||
|
8. Uppdatera dokumentationen så att den beskriver den faktiska lösningen.
|
||||||
|
9. Commit och push efter uttrycklig instruktion.
|
||||||
|
10. Merge efter verifiering.
|
||||||
|
11. Radera den mergade branchen.
|
||||||
|
|
||||||
|
## Verifiering före merge
|
||||||
|
|
||||||
|
För nuvarande projekt bör verifieringen normalt omfatta:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
./mvnw test
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
pnpm test
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
Kör även `git diff --check` och granska `git status --short`. Manuell lokal
|
||||||
|
verifiering av berörda flöden kompletterar, men ersätter inte, automatiska
|
||||||
|
tester.
|
||||||
|
|
||||||
|
Om ett befintligt test misslyckas av ett skäl utanför ändringens omfattning ska
|
||||||
|
det rapporteras; produktionskod ska inte ändras enbart för att dölja felet.
|
||||||
76
docs/features/000-project-foundation.md
Normal file
76
docs/features/000-project-foundation.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Feature 0 – Projektgrund
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
## Bakgrund
|
||||||
|
|
||||||
|
HemHub behövde en minimal projektgrund för inkrementell utveckling av en
|
||||||
|
webbapplikation med separat frontend och backend.
|
||||||
|
|
||||||
|
## Mål
|
||||||
|
|
||||||
|
Skapa körbara React- och Spring Boot-applikationer, koppla ihop dem lokalt och
|
||||||
|
etablera grundläggande tester och dokumentation.
|
||||||
|
|
||||||
|
## Omfattning
|
||||||
|
|
||||||
|
- monorepo med `backend/` och `frontend/`;
|
||||||
|
- Java 21, Spring Boot och Maven Wrapper;
|
||||||
|
- React, TypeScript, Vite och pnpm;
|
||||||
|
- health-endpoint och en tillfällig frontendstatus;
|
||||||
|
- Vite-proxy och grundtester;
|
||||||
|
- `README.md`, `AGENTS.md` och `.gitignore`.
|
||||||
|
|
||||||
|
## Avgränsningar
|
||||||
|
|
||||||
|
Feature 0 införde ingen databas, domänmodell, autentisering, deployment,
|
||||||
|
containerkonfiguration eller produktionskonfiguration.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Frontend och backend skapades som separata applikationer i samma repository.
|
||||||
|
Frontend använder relativa `/api`-adresser, och Vite proxar dem lokalt till
|
||||||
|
backend på port 8080. Ingen generell CORS-konfiguration infördes.
|
||||||
|
|
||||||
|
## Implementerad lösning
|
||||||
|
|
||||||
|
Backend skapades med Spring Boot 4.1.0, Java 21, Spring Web och Maven Wrapper.
|
||||||
|
Frontend skapades med React 19, TypeScript, Vite och pnpm.
|
||||||
|
|
||||||
|
Den ursprungliga startsidan anropade health-endpointen och visade backendstatus
|
||||||
|
eller ett anslutningsfel. Senare features har ersatt denna startsida, men
|
||||||
|
health-endpointen och dess test finns kvar.
|
||||||
|
|
||||||
|
## API-förändringar
|
||||||
|
|
||||||
|
`GET /api/health` infördes och returnerar:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"status":"UP"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Databasförändringar
|
||||||
|
|
||||||
|
Inga.
|
||||||
|
|
||||||
|
## Frontendförändringar
|
||||||
|
|
||||||
|
En minimal startsida visade rubriken HemHub, att frontend hade startat och
|
||||||
|
resultatet från `/api/health`. Vite konfigurerades att proxya `/api` till
|
||||||
|
`http://localhost:8080`.
|
||||||
|
|
||||||
|
## Tester och verifiering
|
||||||
|
|
||||||
|
Ett MockMvc-test verifierar status 200 och `status: UP`. Det ursprungliga
|
||||||
|
frontendtestet verifierade rubriken HemHub med mockat API-anrop.
|
||||||
|
|
||||||
|
## Kända begränsningar
|
||||||
|
|
||||||
|
Projektgrunden innehöll ingen användar- eller uppgiftsfunktionalitet. Den
|
||||||
|
ursprungliga health-vyn är inte längre appens aktiva vy.
|
||||||
|
|
||||||
|
## Relaterade commits
|
||||||
|
|
||||||
|
- `9957383e88b08dc006d2eaeb2a513c7769bd5705` – `Initialize HemHub project foundation`
|
||||||
99
docs/features/001-user-selection.md
Normal file
99
docs/features/001-user-selection.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# Feature 1 – Användarval
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
## Bakgrund
|
||||||
|
|
||||||
|
HemHub behövde centralt lagrade användare och ett enkelt sätt att välja vem som
|
||||||
|
använder applikationen, utan att införa autentisering.
|
||||||
|
|
||||||
|
## Mål
|
||||||
|
|
||||||
|
Göra det möjligt att lista och skapa användare, välja en aktiv användare,
|
||||||
|
återanvända valet i samma browser och lämna den aktiva vyn.
|
||||||
|
|
||||||
|
## Omfattning
|
||||||
|
|
||||||
|
- persistens, API och validering för användare;
|
||||||
|
- startflöden för tom och befintlig användarlista;
|
||||||
|
- lokalt lagrad aktiv användare;
|
||||||
|
- användarval, skapande och felhantering;
|
||||||
|
- automatiserade backend- och frontendtester.
|
||||||
|
|
||||||
|
## Avgränsningar
|
||||||
|
|
||||||
|
Ingen autentisering, lösenord, roll, behörighet, e-post, avatar,
|
||||||
|
hushållsrelation, redigering eller radering infördes.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Backend är slutlig auktoritet för namnvalidering. Namn normaliseras separat för
|
||||||
|
skiftlägesokänslig unikhet. Frontend lagrar endast UUID under
|
||||||
|
`hemhub.activeUserId` och verifierar det mot den hämtade användarlistan.
|
||||||
|
|
||||||
|
## Implementerad lösning
|
||||||
|
|
||||||
|
Vid appstart hämtar frontend alltid användarna. En tom lista leder direkt till
|
||||||
|
formuläret Skapa användare. Om användare finns men inget giltigt lokalt val
|
||||||
|
finns visas Vem är du?.
|
||||||
|
|
||||||
|
Val eller lyckat skapande sparar användarens id och aktiverar användaren. Ett
|
||||||
|
ogiltigt lagrat id rensas utan tekniskt fel. Feature 1:s tillfälliga startsida
|
||||||
|
och kontrollen Byt användare ersattes i Feature 2 av uppgiftsbrädan och
|
||||||
|
kontrollen Logga ut; lagringsmekanismen är oförändrad.
|
||||||
|
|
||||||
|
## API-förändringar
|
||||||
|
|
||||||
|
- `GET /api/users` returnerar alla användare.
|
||||||
|
- `POST /api/users` skapar en användare och returnerar `201 Created`.
|
||||||
|
|
||||||
|
API-responsen innehåller `id`, `name` och `createdAt`. `normalizedName` exponeras
|
||||||
|
inte.
|
||||||
|
|
||||||
|
Tomt namn eller namn längre än 50 Unicode-kodpunkter ger `400` med
|
||||||
|
`INVALID_USER_NAME`. Ett dubblettnamn utan hänsyn till stora och små bokstäver
|
||||||
|
ger `409` med `USER_NAME_ALREADY_EXISTS`.
|
||||||
|
|
||||||
|
## Databasförändringar
|
||||||
|
|
||||||
|
Flyway-migreringen `V1__create_users.sql` skapade tabellen `app_user`:
|
||||||
|
|
||||||
|
- UUID som primärnyckel;
|
||||||
|
- `name VARCHAR(50)`;
|
||||||
|
- unikt `normalized_name VARCHAR(150)`;
|
||||||
|
- `created_at TIMESTAMP WITH TIME ZONE`.
|
||||||
|
|
||||||
|
Lokalt används filbaserad H2 och i tester H2 in-memory. Backend genererar UUID
|
||||||
|
och `createdAt` med en UTC-klocka.
|
||||||
|
|
||||||
|
## Frontendförändringar
|
||||||
|
|
||||||
|
Frontend fick laddnings-, fel-, användarvals- och användarskapandevyer.
|
||||||
|
Skapandeformuläret trimmar namnet, gör en enkel längdkontroll, blockerar
|
||||||
|
dubbelsubmit och behåller inmatningen vid fel.
|
||||||
|
|
||||||
|
Nuvarande utloggning tar bort `hemhub.activeUserId`, rensar aktiv användare och
|
||||||
|
visar Vem är du? även om endast en användare finns.
|
||||||
|
|
||||||
|
## Tester och verifiering
|
||||||
|
|
||||||
|
Backendens integrationstester verifierar tom lista, skapande och listning,
|
||||||
|
trimning, ogiltiga namn, skiftlägesokänsliga dubbletter och alfabetisk
|
||||||
|
sortering.
|
||||||
|
|
||||||
|
Frontendtesterna verifierar tom lista, användarval, automatisk aktivering efter
|
||||||
|
skapande, bevarad inmatning vid fel, hämtfel med återförsök, ogiltigt lagrat id
|
||||||
|
och utloggning. API-anropen mockas.
|
||||||
|
|
||||||
|
## Kända begränsningar
|
||||||
|
|
||||||
|
Aktiv användare är ett lokalt gränssnittsval, inte säker autentisering. Valet
|
||||||
|
synkroniseras inte mellan browsers eller enheter. Användare kan inte redigeras
|
||||||
|
eller raderas.
|
||||||
|
|
||||||
|
## Relaterade commits
|
||||||
|
|
||||||
|
- `1ec7a729085d456d3185a1c74d02f99f40de0e8d` – `feat: add user selection flow`
|
||||||
|
- `050f248857a01db2dc236a0ca35982fd70dab3d6` – merge till `main`
|
||||||
108
docs/features/002-task-creation.md
Normal file
108
docs/features/002-task-creation.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Feature 2 – Skapa uppgifter
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
## Bakgrund
|
||||||
|
|
||||||
|
Efter införandet av aktiv användare behövde HemHub en första gemensam
|
||||||
|
uppgiftsmodell och en enkel bräda för att skapa och visa uppgifter.
|
||||||
|
|
||||||
|
## Mål
|
||||||
|
|
||||||
|
Låta en aktiv användare se tre statuskolumner, skapa en uppgift med titel och
|
||||||
|
valfri beskrivning samt se den sparade uppgiften efter omladdning.
|
||||||
|
|
||||||
|
## Omfattning
|
||||||
|
|
||||||
|
- persistent uppgiftsmodell och Flyway-migrering;
|
||||||
|
- API för att skapa och lista uppgifter;
|
||||||
|
- bräda med Väntande, Pågående och Klart;
|
||||||
|
- modal för att skapa uppgifter;
|
||||||
|
- laddnings-, validerings- och felhantering;
|
||||||
|
- automatiserade backend- och frontendtester.
|
||||||
|
|
||||||
|
## Avgränsningar
|
||||||
|
|
||||||
|
Ingen ändring av status, drag-and-drop, tilldelning, användarrelation, poäng,
|
||||||
|
deadline, återkommande uppgift, redigering, radering, sökning, filtrering eller
|
||||||
|
paginering infördes.
|
||||||
|
|
||||||
|
## Beslut
|
||||||
|
|
||||||
|
Alla användare ser samma uppgifter; uppgiftsmodellen har ingen relation till en
|
||||||
|
användare. Backend väljer alltid status `WAITING` vid skapande. Listningen
|
||||||
|
sorteras i backend efter `createdAt ASC, id ASC`, och frontend bevarar den
|
||||||
|
ordningen.
|
||||||
|
|
||||||
|
## Implementerad lösning
|
||||||
|
|
||||||
|
JPA-entiteten `Task` innehåller UUID, titel, valfri beskrivning, status och
|
||||||
|
skapandetid. Backend genererar UUID och `createdAt` med en UTC-klocka.
|
||||||
|
|
||||||
|
Frontend visar uppgiftsbrädan när ett giltigt aktivt användarval finns. Uppgifter
|
||||||
|
hämtas vid montering, grupperas efter status och visas med endast titel och
|
||||||
|
eventuell beskrivning. Tomma kolumner saknar tomlägestext.
|
||||||
|
|
||||||
|
## API-förändringar
|
||||||
|
|
||||||
|
- `GET /api/tasks` returnerar samtliga uppgifter, äldst först och med UUID som
|
||||||
|
sekundär sorteringsnyckel.
|
||||||
|
- `POST /api/tasks` skapar en uppgift och returnerar `201 Created`.
|
||||||
|
|
||||||
|
Titel trimmas, är obligatorisk och får omfatta högst 100 Unicode-kodpunkter.
|
||||||
|
Beskrivning trimmas, får omfatta högst 500 Unicode-kodpunkter och lagras som
|
||||||
|
`null` om den är tom. Ogiltiga anrop ger `400` med felkoden `INVALID_TASK`.
|
||||||
|
|
||||||
|
## Databasförändringar
|
||||||
|
|
||||||
|
Flyway-migreringen `V2__create_tasks.sql` skapade tabellen `task`:
|
||||||
|
|
||||||
|
- `id UUID PRIMARY KEY`;
|
||||||
|
- `title VARCHAR(100) NOT NULL`;
|
||||||
|
- `description VARCHAR(500)`;
|
||||||
|
- `status VARCHAR(20) NOT NULL`;
|
||||||
|
- `created_at TIMESTAMP WITH TIME ZONE NOT NULL`.
|
||||||
|
|
||||||
|
Status lagras som text genom `@Enumerated(EnumType.STRING)`. Databasen har ingen
|
||||||
|
check constraint för enumvärden.
|
||||||
|
|
||||||
|
## Frontendförändringar
|
||||||
|
|
||||||
|
Feature 1:s tillfälliga aktiva vy ersattes med uppgiftsbrädan. Sidhuvudet visar
|
||||||
|
aktiv användares namn, Logga ut och Ny uppgift.
|
||||||
|
|
||||||
|
Skapandemodalen innehåller titel och valfri beskrivning. Titelfältet får fokus
|
||||||
|
när modalen öppnas. När inget submit-anrop pågår kan den stängas med kryss,
|
||||||
|
Escape eller klick på bakgrunden. Normal stängning avmonterar komponenten och
|
||||||
|
nollställer därmed formuläret.
|
||||||
|
|
||||||
|
Vid submit gör frontend samma grundläggande längdkontroller, skickar trimmade
|
||||||
|
värden och blockerar uppenbara dubbelsubmit. Vid fel stannar modalen öppen med
|
||||||
|
bevarad inmatning. Vid framgång läggs API-svaret sist i den befintliga listan,
|
||||||
|
vilket placerar den nya `WAITING`-uppgiften längst ned i Väntande utan att
|
||||||
|
sortera om backendens ordning.
|
||||||
|
|
||||||
|
## Tester och verifiering
|
||||||
|
|
||||||
|
Backendens integrationstester verifierar skapande, `WAITING`, trimning, tom
|
||||||
|
beskrivning som `null`, längdvalidering samt sorteringen `createdAt ASC, id ASC`.
|
||||||
|
|
||||||
|
Frontendtesterna verifierar bräda och statusgruppering, tomma kolumner,
|
||||||
|
modalöppning och fokus, skapande, ordning efter skapande, bevarad formulärdata
|
||||||
|
vid API-fel samt utloggning. Parametriserade testfall verifierar också stängning
|
||||||
|
med kryss, Escape och bakgrundsklick samt att formuläret är rensat när modalen
|
||||||
|
öppnas igen.
|
||||||
|
|
||||||
|
## Kända begränsningar
|
||||||
|
|
||||||
|
Statusvärden utöver `WAITING` kan visas om de redan finns i databasen, men inget
|
||||||
|
nuvarande API eller gränssnitt kan flytta en uppgift mellan kolumnerna. Det
|
||||||
|
finns ingen koppling mellan uppgifter och skapande eller aktiv användare.
|
||||||
|
Modalen har ingen fokusfälla eller explicit fokusåterställning.
|
||||||
|
|
||||||
|
## Relaterade commits
|
||||||
|
|
||||||
|
- `3f152eecccdd88f840066543bf9321b81b4cead8` – `feat: add task creation board`
|
||||||
|
- `2f7b99fb21c57c2e9c5f019a2b5073458e41c939` – merge till `main`
|
||||||
439
docs/features/003-task-points.md
Normal file
439
docs/features/003-task-points.md
Normal 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:
|
||||||
|
|
||||||
|
> 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.
|
||||||
439
docs/roadmap.md
Normal file
439
docs/roadmap.md
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
# HemHub roadmap
|
||||||
|
|
||||||
|
## Syfte
|
||||||
|
|
||||||
|
Roadmapen är HemHubs styrande plan för val och ordning av kommande features. Den
|
||||||
|
utgår från den faktiska implementationen efter Feature 2 och från beslut som
|
||||||
|
dokumenterats i arkitektur- och beslutsdokumenten.
|
||||||
|
|
||||||
|
Planen är ändringsbar. Ordningen uttrycker nuvarande prioritering och beroenden,
|
||||||
|
inte ett löfte om att alla features måste genomföras oförändrade.
|
||||||
|
|
||||||
|
## Regler för användning
|
||||||
|
|
||||||
|
- Nästa feature ska väljas från denna roadmap.
|
||||||
|
- Feature 0–2 behåller sina nummer och sin historiska betydelse.
|
||||||
|
- Ändra roadmapen innan en feature delas, flyttas, ersätts eller läggs till.
|
||||||
|
- Dokumentera motiv och beroendeförändringar innan utveckling påbörjas.
|
||||||
|
- En ChatGPT- eller Codex-dialog får inte skapa en alternativ featureplan utan
|
||||||
|
att roadmapen först uppdateras i repositoryt.
|
||||||
|
- Håll varje feature tillräckligt liten för separat implementation och
|
||||||
|
verifiering.
|
||||||
|
- Beskriv mål och affärsregler här; bindande implementationsdetaljer hör till
|
||||||
|
feature-specifikationen och relevanta beslutsdokument.
|
||||||
|
- En designfeature producerar dokument och beslut, inte produktionskod, om inget
|
||||||
|
annat uttryckligen beslutas.
|
||||||
|
|
||||||
|
Följande statusvärden används:
|
||||||
|
|
||||||
|
- **Klar** – implementerad, verifierad och mergad.
|
||||||
|
- **Planerad** – ingår i nuvarande ordning men har inte påbörjats.
|
||||||
|
- **Pågående** – utveckling pågår i en aktiv feature.
|
||||||
|
- **Villkorad** – genomförs endast om det angivna villkoret uppfylls.
|
||||||
|
- **Ersatt** – har ersatts av en dokumenterad annan feature eller plan.
|
||||||
|
|
||||||
|
## Nuvarande läge
|
||||||
|
|
||||||
|
Feature 0–2 är klara. Den aktuella applikationen har:
|
||||||
|
|
||||||
|
- ett monorepo med separat React/Vite-frontend och Spring Boot-backend;
|
||||||
|
- centralt lagrade användare och ett lokalt browserval av aktiv användare;
|
||||||
|
- gemensamma uppgifter med titel, valfri beskrivning och status;
|
||||||
|
- skapande och listning av uppgifter;
|
||||||
|
- en bräda med Väntande, Pågående och Klart;
|
||||||
|
- nya uppgifter som alltid skapas med status `WAITING`.
|
||||||
|
|
||||||
|
Det finns ännu inga poäng, uppgiftstilldelningar, statusändringar,
|
||||||
|
drag-and-drop, redigeringar, raderingar, deadlines eller återkommande uppgifter.
|
||||||
|
Nuvarande användarval är inte autentisering.
|
||||||
|
|
||||||
|
**Feature 3 – Uppgiftspoäng är nästa planerade produktfeature.**
|
||||||
|
|
||||||
|
## Featureöversikt
|
||||||
|
|
||||||
|
| Feature och namn | Status | Beroenden | Huvudsakligt resultat |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 0 – Projektgrund | Klar | – | Körbar frontend, backend och lokal API-koppling |
|
||||||
|
| 1 – Användarval | Klar | 0 | Centrala användare och lokalt aktivt användar-id |
|
||||||
|
| 2 – Skapa uppgifter | Klar | 0–1 | Gemensamma uppgifter och trekolumnsbräda |
|
||||||
|
| 3 – Uppgiftspoäng | Planerad | 2 | Poäng på uppgifter |
|
||||||
|
| 4 – Tilldelning | Planerad | 1–2 | Valfri ansvarig användare |
|
||||||
|
| 5 – Statusändring | Planerad | 4 | Backendstyrda statusövergångar |
|
||||||
|
| 6 – Drag-and-drop | Planerad | 5 | Kortflytt via status-API |
|
||||||
|
| 7 – Radera uppgift | Planerad | 2 | Bekräftad radering |
|
||||||
|
| 8 – Redigera uppgift | Planerad | 3 | Titel, beskrivning och poäng |
|
||||||
|
| 9 – Deadline | Planerad | 2 | Valfri deadline och förseningsmarkering |
|
||||||
|
| 10 – Sökning och filtrering | Planerad | 2; 4 för ansvarig; 9 för deadline | Sökning och filter på brädan |
|
||||||
|
| 11 – Design av återkommande uppgifter | Planerad | 3–5, 9 | Beslut och plan, ingen produktionskod |
|
||||||
|
| 12 – Återkommande uppgifter | Planerad | 5, 9, 11 | Implementerad återkommandemodell |
|
||||||
|
| 13 – Poänghistorik och summering | Planerad | 3–5, 12 | Slutförandehistorik och summering |
|
||||||
|
| 14 – PostgreSQL | Planerad | 0–13 | Verifierad produktionsdatabas |
|
||||||
|
| 15 – Dockerpaketering | Planerad | 14 | Images och produktionslik lokal körning |
|
||||||
|
| 16 – Pipeline och deployment | Planerad | 15 | Bygge, publicering och drift på Biff |
|
||||||
|
| 17 – Autentisering | Villkorad | 16, extern åtkomst | Säker internetexponering |
|
||||||
|
|
||||||
|
## Genomförda features
|
||||||
|
|
||||||
|
### Feature 0 – Projektgrund
|
||||||
|
|
||||||
|
**Status:** Klar
|
||||||
|
|
||||||
|
Feature 0 etablerade monorepot, React/Vite-frontend, Spring Boot-backend,
|
||||||
|
health-endpoint, lokal Vite-proxy och grundtester. Den faktiska lösningen
|
||||||
|
beskrivs i
|
||||||
|
[`000-project-foundation.md`](features/000-project-foundation.md).
|
||||||
|
|
||||||
|
### Feature 1 – Användarval
|
||||||
|
|
||||||
|
**Status:** Klar
|
||||||
|
|
||||||
|
Feature 1 införde skapande och listning av användare, val av aktiv användare och
|
||||||
|
lokal lagring av användarens id. Lösningen är ett browserlokalt användarval,
|
||||||
|
inte riktig autentisering. Den faktiska lösningen beskrivs i
|
||||||
|
[`001-user-selection.md`](features/001-user-selection.md).
|
||||||
|
|
||||||
|
### Feature 2 – Skapa uppgifter
|
||||||
|
|
||||||
|
**Status:** Klar
|
||||||
|
|
||||||
|
Feature 2 införde en grundläggande uppgiftsmodell, API för att lista och skapa
|
||||||
|
uppgifter samt en bräda med tre statuskolumner. Uppgifter har titel, valfri
|
||||||
|
beskrivning och status; nya uppgifter skapas som `WAITING`. Den faktiska
|
||||||
|
lösningen beskrivs i
|
||||||
|
[`002-task-creation.md`](features/002-task-creation.md).
|
||||||
|
|
||||||
|
## Fas 1 – Komplettera den centrala uppgiftsmodellen
|
||||||
|
|
||||||
|
Fasen lägger till den domändata och de backendregler som behövs innan mer
|
||||||
|
interaktiv brädhantering införs.
|
||||||
|
|
||||||
|
### Feature 3 – Uppgiftspoäng
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 2
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- lägga till obligatoriska poäng på uppgifter;
|
||||||
|
- välja och dokumentera poängskala;
|
||||||
|
- ange poäng vid skapande;
|
||||||
|
- visa poäng på uppgiftskort;
|
||||||
|
- migrera befintliga uppgifter kontrollerat.
|
||||||
|
|
||||||
|
Feature 3 ligger först eftersom poäng blir ett centralt uppgiftsfält som senare
|
||||||
|
ska kunna redigeras och historikföras.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- exakt poängskala;
|
||||||
|
- standardvärde för befintliga uppgifter.
|
||||||
|
|
||||||
|
### Feature 4 – Tilldelning av uppgifter
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 1 och Feature 2
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- lägga till en valfri ansvarig användare;
|
||||||
|
- tillåta ansvarig vid skapande;
|
||||||
|
- visa ansvarig på uppgiftskort;
|
||||||
|
- kunna ändra ansvarig på en befintlig uppgift.
|
||||||
|
|
||||||
|
En väntande uppgift får vara tilldelad eller otilldelad. Tilldelning införs före
|
||||||
|
statusändring eftersom en pågående uppgift senare måste ha en ansvarig.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- om en uppgift ska ha endast en ansvarig;
|
||||||
|
- hur borttagna användare ska hanteras när användarradering införs.
|
||||||
|
|
||||||
|
### Feature 5 – Statusändring och statusregler
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 4
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- införa backend-API för statusändring;
|
||||||
|
- stödja `WAITING`, `IN_PROGRESS` och `COMPLETED`;
|
||||||
|
- säkerställa statusregler i backend;
|
||||||
|
- ge ett enkelt UI för statusändring före drag-and-drop.
|
||||||
|
|
||||||
|
`IN_PROGRESS` kräver en ansvarig användare. Statusflödet införs före
|
||||||
|
drag-and-drop så att affärsregeln och API:t kan verifieras utan att samtidigt
|
||||||
|
bygga en komplex interaktion.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- vad som sker när en otilldelad uppgift sätts till `IN_PROGRESS`;
|
||||||
|
- om aktiv användare ska föreslås automatiskt;
|
||||||
|
- vad som sker om ansvarig tas bort från en pågående uppgift.
|
||||||
|
|
||||||
|
### Feature 6 – Drag-and-drop
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 5
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- flytta uppgiftskort mellan statuskolumner;
|
||||||
|
- använda status-API:t från Feature 5;
|
||||||
|
- hantera serverfel och återställning av UI;
|
||||||
|
- hantera en otilldelad uppgift som flyttas till Pågående.
|
||||||
|
|
||||||
|
Drag-and-drop kommer efter det enklare statusflödet för att återanvända
|
||||||
|
verifierade backendregler.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- optimistisk eller serverbekräftad uppdatering;
|
||||||
|
- exakt tilldelningsflöde vid flytt till Pågående.
|
||||||
|
|
||||||
|
## Fas 2 – Hantering av uppgifter
|
||||||
|
|
||||||
|
Fasen kompletterar livscykeln för enskilda uppgifter efter att den centrala
|
||||||
|
modellen och statusreglerna finns.
|
||||||
|
|
||||||
|
### Feature 7 – Radera uppgift
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 2
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- införa backend-API för radering;
|
||||||
|
- radera en uppgift från brädan;
|
||||||
|
- kräva bekräftelse före radering.
|
||||||
|
|
||||||
|
Radering hålls separat från redigering så att databorttagning och dess
|
||||||
|
konsekvenser kan verifieras isolerat.
|
||||||
|
|
||||||
|
**Öppen fråga:**
|
||||||
|
|
||||||
|
- permanent radering eller mjuk radering.
|
||||||
|
|
||||||
|
### Feature 8 – Redigera uppgift
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 3
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- ändra titel;
|
||||||
|
- ändra beskrivning;
|
||||||
|
- ändra poäng.
|
||||||
|
|
||||||
|
Featuren ligger efter poäng för att redigeringsflödet ska omfatta den då
|
||||||
|
aktuella uppgiftsmodellen. Ansvarig ska fortsatt ändras genom
|
||||||
|
tilldelningsflödet från Feature 4 och status genom statusflödet från Feature 5.
|
||||||
|
|
||||||
|
### Feature 9 – Deadline
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 2
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- lägga till en valfri deadline;
|
||||||
|
- stödja beslutad representation av datum och eventuell tid;
|
||||||
|
- visa deadline på uppgiftskort;
|
||||||
|
- markera försenade uppgifter.
|
||||||
|
|
||||||
|
Deadline införs före återkommande uppgifter eftersom framtida förekomster måste
|
||||||
|
kunna ärva eller beräkna deadlines.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- datum utan tid eller datum och tid;
|
||||||
|
- tidszonshantering;
|
||||||
|
- definition av en försenad uppgift.
|
||||||
|
|
||||||
|
### Feature 10 – Sökning och filtrering
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 2; Feature 4 för ansvarigfilter; Feature 9 om
|
||||||
|
deadlinefilter ska ingå
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- söka på titel och beskrivning;
|
||||||
|
- filtrera på ansvarig och status;
|
||||||
|
- eventuellt filtrera på deadline.
|
||||||
|
|
||||||
|
Datamängden i ett familjehushåll är sannolikt liten. Klientbaserad sökning kan
|
||||||
|
därför vara tillräcklig initialt, men valet ska göras i feature-specifikationen.
|
||||||
|
Sökning på titel och beskrivning samt statusfiltrering kan byggas från Feature
|
||||||
|
2. Filtrering på ansvarig kräver Feature 4, och deadlinefilter kräver Feature 9
|
||||||
|
om det ska ingå.
|
||||||
|
|
||||||
|
**Öppen fråga:**
|
||||||
|
|
||||||
|
- klientbaserad eller serverbaserad sökning.
|
||||||
|
|
||||||
|
## Fas 3 – Återkommande arbete och historik
|
||||||
|
|
||||||
|
Fasen kräver först ett uttryckligt modellbeslut, eftersom återkommande arbete
|
||||||
|
påverkar status, deadline, ansvarig och poäng.
|
||||||
|
|
||||||
|
### Feature 11 – Design av återkommande uppgifter
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Typ:** Designfeature
|
||||||
|
|
||||||
|
**Beroenden:** Beslutade modeller från Feature 3–5 och Feature 9
|
||||||
|
|
||||||
|
**Ingen produktionskod ska implementeras i denna feature.**
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- besluta skillnaden mellan uppgiftsmall och konkret förekomst;
|
||||||
|
- definiera hur nästa förekomst skapas;
|
||||||
|
- definiera vad slutförande betyder;
|
||||||
|
- definiera hur en förekomst hoppas över;
|
||||||
|
- definiera hur ändringar påverkar framtida förekomster;
|
||||||
|
- definiera hur ansvarig, poäng och deadline ärvs.
|
||||||
|
|
||||||
|
Resultatet ska vara ett beslutsdokument och en avgränsad implementationsplan för
|
||||||
|
Feature 12. Designsteget ligger före implementationen för att undvika att
|
||||||
|
domänbeslut byggs in implicit.
|
||||||
|
|
||||||
|
### Feature 12 – Implementera återkommande uppgifter
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 5, Feature 9 och Feature 11
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- implementera modellen som beslutades i Feature 11.
|
||||||
|
|
||||||
|
### Feature 13 – Poänghistorik och summering
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 3, Feature 4, Feature 5 och Feature 12
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- registrera vem som slutförde en uppgift;
|
||||||
|
- registrera när uppgiften slutfördes;
|
||||||
|
- summera poäng per användare och period;
|
||||||
|
- visa enkel historik.
|
||||||
|
|
||||||
|
Historik ligger efter status, poäng och återkommande uppgifter eftersom
|
||||||
|
slutförandet måste vara en backendvaliderad händelse med ett definierat
|
||||||
|
poängvärde och en definierad konkret förekomst.
|
||||||
|
|
||||||
|
**Öppna frågor:**
|
||||||
|
|
||||||
|
- om tilldelad och slutförande användare kan vara olika;
|
||||||
|
- om poäng delas ut vid varje återkommande förekomst;
|
||||||
|
- hur återöppnade uppgifter påverkar historik.
|
||||||
|
|
||||||
|
## Fas 4 – Produktion
|
||||||
|
|
||||||
|
Produktionsfasen realiserar den beslutade riktningen i
|
||||||
|
[`005-production-deployment-direction.md`](decisions/005-production-deployment-direction.md).
|
||||||
|
Inget i denna fas är implementerat i nuläget.
|
||||||
|
|
||||||
|
### Feature 14 – PostgreSQL och produktionsdatabas
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Föregående produktfeatures vars persistens ska produktionssättas
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- lägga till produktionskonfiguration för PostgreSQL;
|
||||||
|
- verifiera Flyway-migreringar mot PostgreSQL;
|
||||||
|
- införa PostgreSQL-baserade integrationstester, exempelvis med Testcontainers;
|
||||||
|
- behålla en enkel lokal utvecklingsupplevelse.
|
||||||
|
|
||||||
|
PostgreSQL införs före paketering för att databasdrivrutin, migreringar och
|
||||||
|
konfiguration ska vara verifierade innan en produktionslik stack byggs.
|
||||||
|
|
||||||
|
**Öppen fråga:**
|
||||||
|
|
||||||
|
- om lokal utveckling fortsatt ska kunna använda H2.
|
||||||
|
|
||||||
|
### Feature 15 – Dockerpaketering
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 14
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- skapa en backend-image;
|
||||||
|
- skapa en frontend-image;
|
||||||
|
- stödja produktionslik lokal körning;
|
||||||
|
- ge same-origin `/api` via Nginx.
|
||||||
|
|
||||||
|
Paketeringen kommer före pipelinearbetet så att images kan byggas och verifieras
|
||||||
|
lokalt.
|
||||||
|
|
||||||
|
### Feature 16 – Pipeline och deployment
|
||||||
|
|
||||||
|
**Status:** Planerad
|
||||||
|
|
||||||
|
**Beroenden:** Feature 15
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- skapa en Drone-pipeline;
|
||||||
|
- publicera images till ett privat registry;
|
||||||
|
- driftsätta på Ubuntu-servern Biff;
|
||||||
|
- uppdatera tjänster med Watchtower;
|
||||||
|
- införa nödvändig Nginx-konfiguration;
|
||||||
|
- hantera secrets utanför Git.
|
||||||
|
|
||||||
|
Exakta miljödetaljer ska beslutas inom featuren och känsliga värden ska inte
|
||||||
|
committas.
|
||||||
|
|
||||||
|
## Fas 5 – Eventuell extern åtkomst
|
||||||
|
|
||||||
|
### Feature 17 – Autentisering och internetexponering
|
||||||
|
|
||||||
|
**Status:** Villkorad
|
||||||
|
|
||||||
|
**Beroenden:** Beslut att exponera HemHub mot internet och en säker
|
||||||
|
produktionsgrund, normalt Feature 16
|
||||||
|
|
||||||
|
Featuren ska endast genomföras om HemHub ska göras åtkomlig från internet.
|
||||||
|
Nuvarande aktiva användarval är uttryckligen inte autentisering.
|
||||||
|
|
||||||
|
**Mål:**
|
||||||
|
|
||||||
|
- införa riktig autentisering;
|
||||||
|
- införa behörighetsregler;
|
||||||
|
- använda säker sessions- eller tokenhantering;
|
||||||
|
- konfigurera TLS och extern exponering;
|
||||||
|
- säkerhetsgranska API och deployment.
|
||||||
|
|
||||||
|
## Öppna tvärgående frågor
|
||||||
|
|
||||||
|
- Vilken poängskala ska användas och vilket standardvärde får befintliga
|
||||||
|
uppgifter?
|
||||||
|
- Ska uppgifter raderas permanent eller mjukt?
|
||||||
|
- Hur ska datum, tider och tidszoner representeras?
|
||||||
|
- Ska H2 behållas för lokal utveckling efter PostgreSQL-införandet?
|
||||||
|
- Hur ska användare senare kunna redigeras eller raderas, särskilt när de är
|
||||||
|
ansvariga för eller har slutfört uppgifter?
|
||||||
|
- Vid vilken typ av extern åtkomst krävs riktig autentisering?
|
||||||
|
- Hur ska UI-designen från befintliga skisser införas inkrementellt utan att
|
||||||
|
blanda in framtida funktionalitet?
|
||||||
|
|
||||||
|
## Ändringshistorik
|
||||||
|
|
||||||
|
- 2026-07-26: Roadmapen etablerades. Feature 0–2 markerades som klara, Feature
|
||||||
|
3–16 planerades och Feature 17 markerades som villkorad.
|
||||||
Reference in New Issue
Block a user