docs: establish project documentation baseline
This commit is contained in:
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.
|
||||
Reference in New Issue
Block a user