# Logical Architecture

## Component map

    flowchart LR
        Browser["Client browser"] -->|"HTTPS"| Traefik["Traefik ingress"]
        Traefik --> Varnish["Varnish cache\n(static + /api/images/*)"]
        Varnish --> Next["Next.js App Router\nSSR/ISR + API routes"]
        Next --> Auth["Auth/session module\n(JWT cookie)"]
        Next --> Prisma["Prisma ORM"]
        Prisma --> Postgres[(PostgreSQL\nlistings + images)]
        Next --> Mailer["SMTP mailer\nsmtp.lomavuokraus.fi (CNAME) + DKIM"]
        Admin["Admins & moderators"] --> Traefik

Edit the Mermaid block above to evolve the architecture.

## Domain model

    erDiagram
      USER ||--o{ LISTING : owns
      USER ||--o{ LISTING : approves
      LISTING ||--|{ LISTINGTRANSLATION : has
      LISTING ||--o{ LISTINGIMAGE : has

      USER {
        string id
        string email
        string passwordHash
        string role
        string status
        datetime emailVerifiedAt
        datetime approvedAt
        datetime rejectedAt
        datetime removedAt
      }
      LISTING {
        string id
        string status
        datetime approvedAt
        datetime rejectedAt
        datetime removedAt
        string country
        string region
        string city
        float latitude
        float longitude
      }
      LISTINGTRANSLATION {
        string id
        string slug
        string title
        string locale
        string teaser
      }
      LISTINGIMAGE {
        string id
        string url
        string data
        string mimeType
        int size
        string altText
        boolean isCover
        int order
      }

## Key notes

- Web: Next.js app (App Router), server-rendered pages, client hooks for auth state.
- API routes: Authentication, admin approvals, listings CRUD (soft-delete), profile update.
- Data: Postgres via Prisma (models: User, Listing, ListingTranslation, ListingImage, VerificationToken); listing images stored as bytes + metadata and served through `/api/images/:id`.
- Caching: Varnish sidecar caches `/api/images/*` (24h) and `/_next/static` assets (7d) before requests reach Next.js.
- Mail: SMTP (smtp.lomavuokraus.fi CNAME to smtp.sohva.org) + DKIM signing for verification emails.
- Auth: Email/password, verified+approved requirement, JWT session cookie (`session_token`), roles.