Upload files to "docs"
This commit is contained in:
470
docs/completed-features-summary.md
Normal file
470
docs/completed-features-summary.md
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
# HemHub – Sammanfattning av färdiga features
|
||||||
|
|
||||||
|
Detta dokument sammanfattar de features som är färdiga, verifierade och mergade till `main`.
|
||||||
|
|
||||||
|
Syftet är att ge ChatGPT, Codex och andra arbetsdialoger en kompakt överblick över projektets historik utan att samtliga fullständiga featuredokument behöver finnas som aktiva projektkällor.
|
||||||
|
|
||||||
|
De fullständiga och bindande historiska dokumenten finns fortsatt under:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/features/
|
||||||
|
```
|
||||||
|
|
||||||
|
Repositoryts aktuella kod, tester, `docs/architecture.md`, `docs/roadmap.md`, relevanta ADR:er och respektive fullständiga featuredokument har alltid företräde framför denna sammanfattning.
|
||||||
|
|
||||||
|
## Aktuellt läge
|
||||||
|
|
||||||
|
Feature 0–8 är färdiga, verifierade och mergade till `main`.
|
||||||
|
|
||||||
|
Nästa planerade produktfeature är:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Feature 9 – Deadline
|
||||||
|
```
|
||||||
|
|
||||||
|
Den aktuella applikationen har:
|
||||||
|
|
||||||
|
- React/Vite-frontend och Spring Boot-backend i ett monorepo;
|
||||||
|
- centralt lagrade användare och ett lokalt browserval av aktiv användare;
|
||||||
|
- en gemensam Kanban-bräda med Väntande, Pågående och Klart;
|
||||||
|
- uppgifter med titel, valfri beskrivning, poäng, status och valfri ansvarig;
|
||||||
|
- skapande, tilldelning, statusändring, drag-and-drop, permanent radering och redigering;
|
||||||
|
- låsning och felhantering per task-id;
|
||||||
|
- serverbekräftade uppdateringar för tilldelning, statusknappar, radering och redigering;
|
||||||
|
- optimistisk drag-and-drop med full rollback.
|
||||||
|
|
||||||
|
Aktiv användare är ett lokalt gränssnittsval och inte autentisering eller behörighetskontroll.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 0 – Projektgrund
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Monorepo med `backend/`, `frontend/` och `docs/`.
|
||||||
|
- Backend med Java 21, Spring Boot, Maven Wrapper och Spring Web.
|
||||||
|
- Frontend med React, TypeScript, Vite och pnpm.
|
||||||
|
- Health-endpoint: `GET /api/health`.
|
||||||
|
- Vite-proxy från `/api` till lokal backend på port 8080.
|
||||||
|
- Grundläggande backend- och frontendtester.
|
||||||
|
- Inledande `README.md`, `AGENTS.md` och `.gitignore`.
|
||||||
|
|
||||||
|
### Viktiga beslut
|
||||||
|
|
||||||
|
- Frontend och backend är separata applikationer i samma repository.
|
||||||
|
- Frontend använder relativa `/api`-adresser.
|
||||||
|
- Ingen generell CORS-konfiguration infördes.
|
||||||
|
|
||||||
|
### Begränsningar
|
||||||
|
|
||||||
|
Ingen databas, domänmodell, autentisering, deployment eller containerkonfiguration infördes.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `9957383e88b08dc006d2eaeb2a513c7769bd5705`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/000-project-foundation.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 1 – Användarval
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Centralt lagrade användare.
|
||||||
|
- API: `GET /api/users` och `POST /api/users`.
|
||||||
|
- UUID som användar-id.
|
||||||
|
- Namn trimmas och valideras.
|
||||||
|
- Skiftlägesokänslig unikhet genom internt normaliserat namn.
|
||||||
|
- Frontendflöden för användarval, skapande, laddning, fel och utloggning.
|
||||||
|
- Aktiv användares UUID lagras under `hemhub.activeUserId`.
|
||||||
|
|
||||||
|
### Viktiga beslut
|
||||||
|
|
||||||
|
- Backend är slutlig auktoritet för namnvalidering.
|
||||||
|
- Endast användar-id lagras lokalt.
|
||||||
|
- Id:t verifieras mot backendens användarlista vid appstart.
|
||||||
|
- Ogiltigt lagrat id tas bort.
|
||||||
|
- `Logga ut` rensar valet och visar användarvalet igen.
|
||||||
|
- Lösningen är inte autentisering.
|
||||||
|
|
||||||
|
### Databas
|
||||||
|
|
||||||
|
Flyway-migreringen `V1__create_users.sql` skapade `app_user`.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `1ec7a729085d456d3185a1c74d02f99f40de0e8d`
|
||||||
|
- Merge-commit: `050f248857a01db2dc236a0ca35982fd70dab3d6`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/001-user-selection.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 2 – Skapa uppgifter
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Persistent uppgiftsmodell.
|
||||||
|
- API: `GET /api/tasks` och `POST /api/tasks`.
|
||||||
|
- Kanban-bräda med `WAITING`, `IN_PROGRESS` och `COMPLETED`.
|
||||||
|
- Modal för att skapa uppgifter.
|
||||||
|
- Ursprungliga fält: UUID, titel, valfri beskrivning, status och skapandetid.
|
||||||
|
- Nya uppgifter får alltid status `WAITING`.
|
||||||
|
- Listningen sorteras efter `createdAt ASC, id ASC`.
|
||||||
|
|
||||||
|
### Validering
|
||||||
|
|
||||||
|
- Titel är obligatorisk, trimmas och får vara högst 100 Unicode-kodpunkter.
|
||||||
|
- Beskrivning är valfri, trimmas, får vara högst 500 Unicode-kodpunkter och lagras som `null` när den är tom.
|
||||||
|
|
||||||
|
### Frontendbeteende
|
||||||
|
|
||||||
|
- Titelfältet får fokus när modalen öppnas.
|
||||||
|
- Modalen kan före submit stängas med kryss, Escape eller bakgrundsklick.
|
||||||
|
- Dubbelsubmit blockeras.
|
||||||
|
- Inmatning behålls vid API-fel.
|
||||||
|
- Serverresponsen läggs sist i befintlig lista.
|
||||||
|
|
||||||
|
### Databas
|
||||||
|
|
||||||
|
Flyway-migreringen `V2__create_tasks.sql` skapade `task`.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `3f152eecccdd88f840066543bf9321b81b4cead8`
|
||||||
|
- Merge-commit: `2f7b99fb21c57c2e9c5f019a2b5073458e41c939`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/002-task-creation.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 3 – Uppgiftspoäng
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Obligatoriskt fält `points` på varje uppgift.
|
||||||
|
- Tillåtna värden är heltal 1–99.
|
||||||
|
- Skapandemodalen använder standardvärdet `1`.
|
||||||
|
- Frontend skickar alltid poäng uttryckligen.
|
||||||
|
- Backend fyller inte automatiskt i saknade poäng.
|
||||||
|
- Uppgiftskort visar `{points} p`.
|
||||||
|
|
||||||
|
### Databas
|
||||||
|
|
||||||
|
- Flyway-migreringen `V3__add_task_points.sql`.
|
||||||
|
- `points INTEGER NOT NULL`.
|
||||||
|
- Constraint för intervallet 1–99.
|
||||||
|
- Inget permanent databasdefaultvärde.
|
||||||
|
|
||||||
|
### Viktiga beslut
|
||||||
|
|
||||||
|
Poäng uttrycker uppgiftens samlade värde utifrån hur tidskrävande, besvärlig eller viktig den är.
|
||||||
|
|
||||||
|
Ingen poänghistorik, summering eller utdelning infördes.
|
||||||
|
|
||||||
|
Lokal utveckling ändrades till H2 in-memory och utvecklingsdata återställs vid omstart.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `059d4da9214969ed3e28592178160da6de614b4d`
|
||||||
|
- Merge-commit: `2e62261f49bb3142e28882483e41e0250ab11c5f`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/003-task-points.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 4 – Tilldelning av uppgifter
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- En uppgift kan vara otilldelad eller ha exakt en ansvarig.
|
||||||
|
- Valfri ansvarig vid skapande.
|
||||||
|
- API: `PUT /api/tasks/{taskId}/assignee`.
|
||||||
|
- Task-responsen innehåller `assignee: null` eller `{id, name}`.
|
||||||
|
- Frontend visar och ändrar ansvarig på kortet.
|
||||||
|
- Serverresponsen ersätter den lokala uppgiften utan omsortering.
|
||||||
|
|
||||||
|
### Viktiga beslut
|
||||||
|
|
||||||
|
- Högst en ansvarig.
|
||||||
|
- Ingen förvald ansvarig vid skapande.
|
||||||
|
- Aktiv användare är inte behörighetsgrund.
|
||||||
|
- Tilldelning ändrar inte status.
|
||||||
|
|
||||||
|
Feature 5 utvidgade senare de statusberoende tilldelningsreglerna.
|
||||||
|
|
||||||
|
### Databas
|
||||||
|
|
||||||
|
`V4__add_task_assignee.sql` lade till nullable `assignee_id` med främmande nyckel till `app_user`.
|
||||||
|
|
||||||
|
JPA-relationen är lazy `ManyToOne`, och entity graph används för att hämta ansvarig med uppgiften.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `aaebe888f3bae43b3413e9fa3893fec90afac8b4`
|
||||||
|
- Merge-commit: `d78611f5f77374228f1f69b66734931a988f8355`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/004-task-assignment.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 5 – Statusändring och statusregler
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- API: `PUT /api/tasks/{taskId}/status`.
|
||||||
|
- Alla direkta övergångar mellan `WAITING`, `IN_PROGRESS` och `COMPLETED`.
|
||||||
|
- Samma målstatus är giltig och idempotent.
|
||||||
|
- Knappbaserat statusflöde på korten.
|
||||||
|
- Serverbekräftad uppdatering och låsning per task-id.
|
||||||
|
|
||||||
|
### Status- och tilldelningsregler
|
||||||
|
|
||||||
|
- `IN_PROGRESS` måste ha ansvarig.
|
||||||
|
- `WAITING` och `COMPLETED` får vara otilldelade.
|
||||||
|
- Tilldelnings-API:t får tilldela eller byta ansvarig i alla statusar.
|
||||||
|
- Ansvarig får tas bort i `WAITING` och `COMPLETED`, men inte i `IN_PROGRESS`.
|
||||||
|
- Tilldelning ändrar aldrig status.
|
||||||
|
- När en otilldelad uppgift påbörjas skickar frontend aktiv användares id.
|
||||||
|
- Backend tilldelar användaren och ändrar status i samma transaktion.
|
||||||
|
- Befintlig ansvarig byts aldrig av statusoperationen.
|
||||||
|
|
||||||
|
### Centrala felkoder
|
||||||
|
|
||||||
|
- `TASK_NOT_FOUND`
|
||||||
|
- `INVALID_TASK_STATUS`
|
||||||
|
- `USER_NOT_FOUND`
|
||||||
|
- `TASK_REQUIRES_ASSIGNEE`
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `65a6488c0b268f49b1361591f025bdea8d67f754`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/005-task-status.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 6 – Drag-and-drop
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Drag-and-drop mellan statuskolumner.
|
||||||
|
- Återanvänder Feature 5:s status-API.
|
||||||
|
- Frontend använder `@dnd-kit/react` och `@dnd-kit/dom`.
|
||||||
|
- Ingen sortering inom kolumner och ingen persistent kortordning.
|
||||||
|
- Dragbiblioteket är avgränsat i `TaskDragAndDrop.tsx`.
|
||||||
|
|
||||||
|
### Uppdateringsstrategi
|
||||||
|
|
||||||
|
Drag-and-drop är optimistiskt:
|
||||||
|
|
||||||
|
1. hela tidigare task-versionen sparas;
|
||||||
|
2. kortet flyttas direkt;
|
||||||
|
3. kortet låses och tonas ned;
|
||||||
|
4. statusanropet skickas;
|
||||||
|
5. serverresponsen ersätter det optimistiska värdet;
|
||||||
|
6. vid fel återställs hela tidigare task-versionen.
|
||||||
|
|
||||||
|
Rollback omfattar hela uppgiften eftersom flytt till `IN_PROGRESS` även kan innebära optimistisk tilldelning till aktiv användare.
|
||||||
|
|
||||||
|
Statusknapparna förblev serverbekräftade.
|
||||||
|
|
||||||
|
### Interaktion
|
||||||
|
|
||||||
|
- Drop i samma kolumn är no-op.
|
||||||
|
- Avbruten dragning eller ogiltigt mål är no-op.
|
||||||
|
- Kortets icke-interaktiva yta är dragyta.
|
||||||
|
- Knappar och andra interaktiva kontroller startar inte drag.
|
||||||
|
- Låsning sker per task-id.
|
||||||
|
- Andra kort förblir interaktiva.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `c3c64482c062f144fd6cb6036e3c9db0afa5ec1e`
|
||||||
|
- Merge-commit: `2696195e741c155a197ae9838d1938bdf2148cc2`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/006-task-drag-and-drop.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 7 – Radera uppgift
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Permanent fysisk radering.
|
||||||
|
- API: `DELETE /api/tasks/{taskId}`.
|
||||||
|
- Lyckad radering ger `204 No Content`.
|
||||||
|
- Okänd eller redan raderad uppgift ger `404 TASK_NOT_FOUND`.
|
||||||
|
- Uppgifter får raderas i alla statusar.
|
||||||
|
- Aktiv användare och ansvarig påverkar inte möjligheten att radera.
|
||||||
|
|
||||||
|
### Frontendflöde
|
||||||
|
|
||||||
|
- Diskret inline-SVG-sopkorg i kortets åtgärdsområde.
|
||||||
|
- Separat bekräftelsemodal.
|
||||||
|
- Radering är serverbekräftad.
|
||||||
|
- Kort och modal ligger kvar under anropet.
|
||||||
|
- Samtliga stängningsvägar blockeras under anropet.
|
||||||
|
- Kortet tas bort först efter `204`.
|
||||||
|
- Vanliga fel behåller kort och dialog.
|
||||||
|
- Strukturerat `404 TASK_NOT_FOUND` tar bort ett inaktuellt lokalt kort.
|
||||||
|
|
||||||
|
### Viktiga beslut
|
||||||
|
|
||||||
|
- Ingen mjuk radering.
|
||||||
|
- Ingen papperskorg, återställning, undo eller arkivering.
|
||||||
|
- Ingen Flyway-migrering behövdes.
|
||||||
|
- Samma låsning per task-id används för status, tilldelning, drag och radering.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `f296d15`
|
||||||
|
- Merge-commit: `5df0146`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/007-task-deletion.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature 8 – Redigera uppgift
|
||||||
|
|
||||||
|
**Status:** Färdig och mergad till `main`.
|
||||||
|
|
||||||
|
### Resultat
|
||||||
|
|
||||||
|
- Redigering av titel, beskrivning och poäng.
|
||||||
|
- Separat redigeringsmodal.
|
||||||
|
- Synlig inline-SVG-redigeringsknapp bredvid sopkorgen.
|
||||||
|
- API: `PUT /api/tasks/{taskId}/details`.
|
||||||
|
- Requesten innehåller alltid hela den redigerbara fältuppsättningen.
|
||||||
|
- Lyckad uppdatering ger `200 OK` med fullständig task-respons.
|
||||||
|
|
||||||
|
### Avgränsning
|
||||||
|
|
||||||
|
Redigeringsflödet ändrar inte id, status, ansvarig eller skapandetid.
|
||||||
|
|
||||||
|
Status och ansvarig hanteras fortsatt genom sina specialiserade API:er.
|
||||||
|
|
||||||
|
### Frontendflöde
|
||||||
|
|
||||||
|
- Aktuella värden fylls i när modalen öppnas.
|
||||||
|
- `null`-beskrivning visas som tom sträng.
|
||||||
|
- Titelfältet får initialt fokus.
|
||||||
|
- Osparade ändringar kastas utan extra bekräftelse.
|
||||||
|
- Redigeringen är serverbekräftad.
|
||||||
|
- Gamla kortvärden ligger kvar under anropet.
|
||||||
|
- Modalen och kortet låses under save.
|
||||||
|
- Serverresponsen ersätter uppgiften på befintlig plats.
|
||||||
|
- Kolumn och ordning behålls.
|
||||||
|
- Vanliga fel behåller modal och inmatning.
|
||||||
|
- Strukturerat `404 TASK_NOT_FOUND` tar bort ett inaktuellt lokalt kort.
|
||||||
|
|
||||||
|
### Backendregler
|
||||||
|
|
||||||
|
- Samma validering som vid skapande.
|
||||||
|
- Samma värden accepteras idempotent.
|
||||||
|
- Redigering tillåts i alla statusar.
|
||||||
|
- Ingen `updatedAt`.
|
||||||
|
- Ingen Flyway-migrering behövdes.
|
||||||
|
|
||||||
|
### Verifierad begränsning
|
||||||
|
|
||||||
|
H2:s `VARCHAR` räknar UTF-16-kodenheter för vissa tecken utanför BMP. Applikationen validerar enligt Unicode-kodpunkter, men H2 kan därför avvisa vissa gränsfall med astrala tecken. Detta ska verifieras mot PostgreSQL när produktionsdatabasen införs.
|
||||||
|
|
||||||
|
### Relaterade commits
|
||||||
|
|
||||||
|
- Feature-commit: `443f686`
|
||||||
|
- Merge-commit: `28258f4`
|
||||||
|
|
||||||
|
Fullständig historik: `docs/features/008-task-editing.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tvärgående beslut efter Feature 8
|
||||||
|
|
||||||
|
### API och backend
|
||||||
|
|
||||||
|
- Backend är slutlig garant för affärsregler och validering.
|
||||||
|
- Task-operationer är avgränsade till skapande, detaljredigering, tilldelning, statusändring och radering.
|
||||||
|
- Serverns fullständiga task-respons är slutlig sanning.
|
||||||
|
- Kända fel använder gemensamt format med `code` och `message`.
|
||||||
|
|
||||||
|
### Frontend-state
|
||||||
|
|
||||||
|
- React-komponenter hanterar lokalt state.
|
||||||
|
- Ingen router eller separat global state-lösning används.
|
||||||
|
- Operationer låses per task-id.
|
||||||
|
- Andra kort förblir interaktiva när ett kort har ett pågående anrop.
|
||||||
|
- Statusknappar, tilldelning, radering och redigering är serverbekräftade.
|
||||||
|
- Drag-and-drop är optimistiskt med full rollback.
|
||||||
|
|
||||||
|
### Databas
|
||||||
|
|
||||||
|
Aktuella Flyway-migreringar:
|
||||||
|
|
||||||
|
```text
|
||||||
|
V1__create_users.sql
|
||||||
|
V2__create_tasks.sql
|
||||||
|
V3__add_task_points.sql
|
||||||
|
V4__add_task_assignee.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Lokal utveckling och automatiska tester använder H2 in-memory i PostgreSQL-kompatibilitetsläge.
|
||||||
|
|
||||||
|
PostgreSQL är planerad produktionsdatabas men ännu inte implementerad eller verifierad.
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
Planerad men ännu inte implementerad riktning:
|
||||||
|
|
||||||
|
- PostgreSQL;
|
||||||
|
- separata Docker-images för frontend och backend;
|
||||||
|
- Drone för bygge och publicering;
|
||||||
|
- privat registry;
|
||||||
|
- Watchtower för uppdatering;
|
||||||
|
- Nginx som möjlig reverse proxy;
|
||||||
|
- drift på Ubuntu-servern Biff.
|
||||||
|
|
||||||
|
### Utvecklingsprocess
|
||||||
|
|
||||||
|
- En kortlivad branch per feature.
|
||||||
|
- Branch skapas från uppdaterad `main`.
|
||||||
|
- Kod, tester och relevant dokumentation uppdateras tillsammans.
|
||||||
|
- Commit och push sker först efter uttrycklig instruktion.
|
||||||
|
- Merge sker efter automatisk och relevant manuell verifiering.
|
||||||
|
- Dokumentationen ska räcka för att förstå projektet utan tidigare dialoger eller raderade branches.
|
||||||
|
|
||||||
|
## Nästa feature
|
||||||
|
|
||||||
|
```text
|
||||||
|
Feature 9 – Deadline
|
||||||
|
```
|
||||||
|
|
||||||
|
Roadmapens nuvarande mål:
|
||||||
|
|
||||||
|
- valfri deadline;
|
||||||
|
- beslutad representation av datum och eventuell tid;
|
||||||
|
- visning på uppgiftskort;
|
||||||
|
- markering av försenade uppgifter.
|
||||||
|
|
||||||
|
Öppna frågor:
|
||||||
|
|
||||||
|
- datum utan tid eller datum och tid;
|
||||||
|
- tidszonshantering;
|
||||||
|
- definition av försenad uppgift.
|
||||||
Reference in New Issue
Block a user