diff --git a/PROGRESS.md b/PROGRESS.md index 7df2037..e779399 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -47,6 +47,7 @@ - Soft rejection/removal states for users/listings with timestamps; owner listing removal; login redirects home; listing visibility hides removed/not-published. - Profile page now allows editing name and password (email immutable). - Docs: Added docs in `docs/` (tracked, not shipped) with HTML + PlantUML sequences + draw.io diagrams. Ignored from deploy via runtime paths; kept in git. +- Documentation pivoted to Mermaid-only diagrams (sequence + architecture/infra/pipeline), rendered in-browser; legacy draw.io/PlantUML assets removed for simplicity. - Listing details: right rail now surfaces quick facts + amenity icons; browse map given fixed height so OpenStreetMap tiles show reliably; footer links to privacy page with version indicator. To resume: diff --git a/docs/architecture.html b/docs/architecture.html index 3c7da6c..5e27d31 100644 --- a/docs/architecture.html +++ b/docs/architecture.html @@ -12,25 +12,26 @@
-

Components

- -
- -
-

Layers Diagram

-

Source: docs/drawio/architecture.drawio. Edit with draw.io and export locally.

-
- -
-

Domain Model Snapshot

+

Component map

-
erDiagram
+          
+flowchart LR
+  Browser[Client browser] -->|HTTP/HTTPS| Next[Next.js App Router
SSR/ISR + API routes] + Next --> Prisma[Prisma ORM] + Prisma --> Postgres[(PostgreSQL)] + Next --> Mailer[SMTP mailer
(smtp.sohva.org + DKIM)] + Next --> Storage[Image URLs (remote/bucket)] + Admin[Admin / Moderators] --> Next + Next --> Auth[Auth module
JWT session cookie] +
+
+
Edit the Mermaid block above to evolve the architecture.
+
+ +
+

Domain model

+
+
erDiagram
   USER ||--o{ LISTING : owns
   USER ||--o{ LISTING : approves
   LISTING ||--|{ LISTINGTRANSLATION : has
@@ -67,14 +68,24 @@
     string id
     string url
   }
-
+
-

Auth Flow (High-Level)

-

See PlantUML source: docs/plantuml/auth-register-login.puml. Render locally with PlantUML.

+

Key notes

+
+ diff --git a/docs/build.html b/docs/build.html index da92956..1e47db5 100644 --- a/docs/build.html +++ b/docs/build.html @@ -11,6 +11,26 @@
Node/Next build, Docker multi-stage, registry push, kubectl rollout.
+
+

Pipeline at a glance

+
+
+flowchart LR
+  Dev[Developer] -->|npm run lint| Lint
+  Dev --> BuildScript[./deploy/build.sh]
+  Lint --> BuildScript
+  BuildScript --> Docker[Docker buildx
multi-stage] + Docker --> Image[registry.halla-aho.net
thalla/lomavuokraus-web] + Image --> Push[./deploy/push.sh] + Push --> DeployStg[./deploy/deploy-staging.sh] + Push --> DeployProd[./deploy/deploy-prod.sh] + DeployStg --> K8sStg[kubectl apply
rollout (staging)] + DeployProd --> K8sProd[kubectl apply
rollout (prod)] +
+
+
Edit the Mermaid block to reflect pipeline changes; no external tooling required.
+
+

Build Inputs

- -
-

Pipeline Diagram

-

For visuals, edit/export docs/drawio/architecture.drawio or create a dedicated pipeline page in draw.io.

-
+ diff --git a/docs/drawio/architecture.drawio b/docs/drawio/architecture.drawio deleted file mode 100644 index 6619d7a..0000000 --- a/docs/drawio/architecture.drawio +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/drawio/infra.drawio b/docs/drawio/infra.drawio deleted file mode 100644 index c127fc2..0000000 --- a/docs/drawio/infra.drawio +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/index.html b/docs/index.html index 7dd8381..39a36fb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,10 +8,10 @@

Lomavuokraus Documentation

-
Docs tracked in git, not deployed with the app.
+
Diagram-first docs rendered with Mermaid; tracked in git, not deployed with the app.
-
+

Contents

-
-
-

Notes

+ +
+

How diagrams work

    -
  • Docs live in docs/ (tracked, not shipped).
  • -
  • Sequence diagrams: PlantUML sources in docs/plantuml.
  • -
  • Architecture/infra diagrams: draw.io sources in docs/drawio.
  • -
  • Generate locally: PlantUML CLI/JAR, draw.io desktop/CLI exports.
  • +
  • All diagrams use Mermaid (rendered in-browser via CDN; no extra tooling needed).
  • +
  • Graph definitions live inline in the HTML for quick edits.
  • +
  • Docs live in docs/; they are tracked but not shipped with the app.
-
+
+ diff --git a/docs/infra.html b/docs/infra.html index 03958f7..2f464fa 100644 --- a/docs/infra.html +++ b/docs/infra.html @@ -8,11 +8,35 @@

Infrastructure Overview

-
- Hetzner k3s cluster, Traefik ingress, cert-manager TLS, private registry, staging/prod namespaces. -
+
Hetzner k3s cluster, Traefik ingress, cert-manager TLS, private registry, staging/prod namespaces.
+
+

Traffic flow

+
+
+graph LR
+  User[User Browser] -->|HTTPS| Traefik[Traefik Ingress
IngressClass traefik] + Traefik -->|Host: lomavuokraus.fi
staging.lomavuokraus.fi| Service[Service
port 80 -> 3000] + Service --> Pod[Next.js Pods (2)] + Pod --> DB[(PostgreSQL
46.62.203.202)] + Pod --> SMTP[smtp.sohva.org] + subgraph Cluster [k3s Cluster hel1 cx22 157.180.66.64] + Traefik + Service + Pod + CertMgr[cert-manager] + Secret[Secrets: lomavuokraus-web-secrets] + CM[ConfigMap: lomavuokraus-web-config] + end + CertMgr -->|TLS| Traefik + Registry[registry.halla-aho.net/thalla/lomavuokraus-web] -->|pull| Pod + DNS[lomavuokraus.fi
staging.lomavuokraus.fi
api.lomavuokraus.fi] --> Traefik +
+
+
Mermaid renders directly in the browser; edit the graph in this file to update.
+
+

Cluster & Namespaces

- -
-

Traffic Flow Diagram

-

Source: docs/drawio/infra.drawio (edit with draw.io, export PNG locally).

-
+ diff --git a/docs/plantuml/auth-register-login.puml b/docs/plantuml/auth-register-login.puml deleted file mode 100644 index 8e1b32b..0000000 --- a/docs/plantuml/auth-register-login.puml +++ /dev/null @@ -1,19 +0,0 @@ -@startuml -title User registration, verification, login, approval -actor User -participant "Next API" as API -database Postgres as DB -participant SMTP as Mail -actor Admin - -User -> API: POST /api/auth/register\n(email, password, name) -API -> DB: create User (status=PENDING)\ncreate VerificationToken -API -> Mail: send verification email -User -> API: POST /api/auth/verify (token) -API -> DB: set emailVerifiedAt -Admin -> API: POST /api/admin/users/approve -API -> DB: set status=ACTIVE, approvedAt -User -> API: POST /api/auth/login -API -> DB: validate password + status -API --> User: session_token cookie (JWT) -@enduml diff --git a/docs/plantuml/auth-register-login.svg b/docs/plantuml/auth-register-login.svg deleted file mode 100644 index 8b4e09b..0000000 --- a/docs/plantuml/auth-register-login.svg +++ /dev/null @@ -1 +0,0 @@ -User registration, verification, login, approvalUser registration, verification, login, approvalUserNext APIPostgresSMTPAdminUserUserNext APINext APIPostgresPostgresSMTPSMTPAdminAdminPOST /api/auth/register(email, password, name)create User (status=PENDING)create VerificationTokensend verification emailPOST /api/auth/verify (token)set emailVerifiedAtPOST /api/admin/users/approveset status=ACTIVE, approvedAtPOST /api/auth/loginvalidate password + statussession_token cookie (JWT) \ No newline at end of file diff --git a/docs/plantuml/listing-create-approve.puml b/docs/plantuml/listing-create-approve.puml deleted file mode 100644 index 5396aa8..0000000 --- a/docs/plantuml/listing-create-approve.puml +++ /dev/null @@ -1,18 +0,0 @@ -@startuml -title Listing creation and admin approval -actor Owner -participant "Next API" as API -database Postgres as DB -actor Admin -actor User - -Owner -> API: POST /api/listings\n(slug, details, images) -API -> DB: create Listing\nstatus=PENDING (or PUBLISHED if auto) -Admin -> API: GET /api/admin/pending -API -> DB: fetch pending listings -Admin -> API: POST /api/admin/listings/approve\n(action=approve|reject|remove) -API -> DB: update status, timestamps -User -> API: GET /listings/[slug] -API -> DB: fetch translation\nstatus=PUBLISHED and not removed -API --> User: render listing -@enduml diff --git a/docs/plantuml/listing-create-approve.svg b/docs/plantuml/listing-create-approve.svg deleted file mode 100644 index e9d3880..0000000 --- a/docs/plantuml/listing-create-approve.svg +++ /dev/null @@ -1 +0,0 @@ -Listing creation and admin approvalListing creation and admin approvalOwnerNext APIPostgresAdminUserOwnerOwnerNext APINext APIPostgresPostgresAdminAdminUserUserPOST /api/listings(slug, details, images)create Listingstatus=PENDING (or PUBLISHED if auto)GET /api/admin/pendingfetch pending listingsPOST /api/admin/listings/approve(action=approve|reject|remove)update status, timestampsGET /listings/[slug]fetch translationstatus=PUBLISHED and not removedrender listing \ No newline at end of file diff --git a/docs/plantuml/listing-removal.puml b/docs/plantuml/listing-removal.puml deleted file mode 100644 index 14dddc6..0000000 --- a/docs/plantuml/listing-removal.puml +++ /dev/null @@ -1,18 +0,0 @@ -@startuml -title Listing removal by owner or moderator -actor Owner -participant "Next API" as API -database Postgres as DB -actor Moderator - -Owner -> API: POST /api/listings/remove (listingId) -API -> DB: verify owner or moderator\nfetch listing -API -> DB: set status=REMOVED\npublished=false\nremovedAt/by -Moderator -> API: POST /api/admin/listings/approve\n(action=remove) -API -> DB: same status change if via admin path -Owner -> API: GET /api/listings/mine -API -> DB: fetch listings for owner (includes REMOVED) -Public -> API: GET /listings/[slug] -API -> DB: filter out removed listings -API --> Public: not found if removed -@enduml diff --git a/docs/plantuml/listing-removal.svg b/docs/plantuml/listing-removal.svg deleted file mode 100644 index e3a0259..0000000 --- a/docs/plantuml/listing-removal.svg +++ /dev/null @@ -1 +0,0 @@ -Listing removal by owner or moderatorListing removal by owner or moderatorOwnerNext APIPostgresModeratorPublicOwnerOwnerNext APINext APIPostgresPostgresModeratorModeratorPublicPublicPOST /api/listings/remove (listingId)verify owner or moderatorfetch listingset status=REMOVEDpublished=falseremovedAt/byPOST /api/admin/listings/approve(action=remove)same status change if via admin pathGET /api/listings/minefetch listings for owner (includes REMOVED)GET /listings/[slug]filter out removed listingsnot found if removed \ No newline at end of file diff --git a/docs/plantuml/profile-update.puml b/docs/plantuml/profile-update.puml deleted file mode 100644 index 5422bc4..0000000 --- a/docs/plantuml/profile-update.puml +++ /dev/null @@ -1,10 +0,0 @@ -@startuml -title Profile update (name/password) -actor User -participant "Next API" as API -database Postgres as DB - -User -> API: PATCH /api/me\n(name?, password?) -API -> DB: update name/passwordHash\n(email immutable) -API --> User: updated profile payload -@enduml diff --git a/docs/plantuml/profile-update.svg b/docs/plantuml/profile-update.svg deleted file mode 100644 index 7bb6c2d..0000000 --- a/docs/plantuml/profile-update.svg +++ /dev/null @@ -1 +0,0 @@ -Profile update (name/password)Profile update (name/password)UserNext APIPostgresUserUserNext APINext APIPostgresPostgresPATCH /api/me(name?, password?)update name/passwordHash(email immutable)updated profile payload \ No newline at end of file diff --git a/docs/sequences.html b/docs/sequences.html index fb51e09..eadf56d 100644 --- a/docs/sequences.html +++ b/docs/sequences.html @@ -8,40 +8,102 @@

Sequence Diagrams

-
PlantUML sources for key flows; render locally.
+
Mermaid-rendered flows for the most important user journeys.

User Registration & Verification

-

PlantUML: docs/plantuml/auth-register-login.puml

- User registration and verification sequence +
+
+sequenceDiagram
+  participant U as User
+  participant W as Web (Next.js)
+  participant DB as Postgres
+  participant Mail as SMTP
+
+  U->>W: Submit registration form (email, password)
+  W->>DB: Create pending user + verification token
+  W->>Mail: Send verification email with token link
+  U-->>Mail: Opens email
+  U->>W: Click verify link
+  W->>DB: Mark email verified (status = verified, awaiting approval)
+  Admin->>W: Approves user
+  W->>DB: Update status = approved
+  U->>W: Login (email/password)
+  W->>DB: Validate credentials, create session token
+  W-->>U: Set session cookie
+          
+

Listing Creation & Approval

-

PlantUML: docs/plantuml/listing-create-approve.puml

- Listing creation and approval sequence +
+
+sequenceDiagram
+  participant Host as Host (logged in)
+  participant W as Web/API
+  participant DB as Postgres
+  participant Mod as Moderator
+
+  Host->>W: Open "New listing" and submit details (address, amenities, images)
+  W->>DB: Save listing (status = PENDING)
+  Mod->>W: Review pending listing
+  W->>DB: Approve -> status = PUBLISHED
+  Host-->>W: Listing appears in "My listings" and public browse
+  Public->>W: Browse latest/map; fetch listing translation + cover image
+          
+

Listing Removal by Owner/Moderator

-

PlantUML: docs/plantuml/listing-removal.puml

- Listing removal sequence +
+
+sequenceDiagram
+  participant Owner as Owner/Moderator
+  participant W as Web/API
+  participant DB as Postgres
+
+  Owner->>W: Click "Remove" on listing
+  W->>Owner: Confirm removal
+  Owner-->>W: Confirm
+  W->>DB: Set removedAt timestamp, status = REMOVED
+  W-->>Owner: Show updated state in "My listings"
+  Public--xW: Listing hidden from browse/slug pages
+          
+

Profile Update (Name/Password)

-

PlantUML: docs/plantuml/profile-update.puml

- Profile update sequence +
+
+sequenceDiagram
+  participant User
+  participant W as Web/API
+  participant DB as Postgres
+
+  User->>W: Open profile page (requires session cookie)
+  W->>DB: Fetch user record (email immutable)
+  User->>W: Submit updated name and/or password
+  W->>DB: Update fields (hash password if provided)
+  W-->>User: Show "Profile updated"
+          
+

Rendering instructions

+ diff --git a/docs/style.css b/docs/style.css index af53da2..de95b44 100644 --- a/docs/style.css +++ b/docs/style.css @@ -80,3 +80,18 @@ ul { border-radius: 10px; background: #0b1220; } + +.mermaid { + background: #0b1220; + border: 1px solid #1f2937; + border-radius: 12px; + padding: 12px; +} + +.callout { + background: #0b1220; + border: 1px dashed #1f2937; + border-radius: 12px; + padding: 12px; + color: #cbd5e1; +}