Commit graph

149 commits

Author SHA1 Message Date
Hermes Agent
da54a67d9d chore: make dev Dockerfiles self-contained, add bindless dev override
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m26s
CI / E2E browser tests (pull_request) Successful in 4m14s
Why
---
The dev compose (docker-compose.yml) assumes the Docker daemon can bind-mount
the host repo (and several subpaths) at runtime, providing live source for
`gradle :backend:bootRun` and Vite HMR. That works on a normal Linux/macOS
host but breaks in:

  - Docker-in-Docker setups (e.g. the Hermes sandbox used for agent work)
  - rootless Docker with restricted mount paths
  - some CI runners

The failure mode is the daemon's mount namespace only sees compose-created
named-volume subdirs at the bind source, not the real repo files. The
backend then fails with `stat ./gradlew: no such file or directory` and
the frontend fails with `mount src=.../index.html, dst=.../index.html
... not a directory`. The image itself is empty of source — there are no
`COPY` lines in the dev Dockerfiles.

Approach
--------
Make the dev images self-sufficient by COPYing the source at build time.
The compose bind mount is kept (it's still the right thing for normal
local dev with HMR), but it's no longer load-bearing. The image works
standalone in any environment.

Add a separate `docker-compose.dev-bindless.yml` for environments where
host bind mounts can't be used (DinD, CI, restricted Docker). It uses
the same images (COPY'd source) but redefines the services with no
host bind mounts — only the named cache volumes remain, so gradle and
Vite caches persist between `up` cycles.

Compose merge semantics caveat: `volumes:` lists merge by concatenation,
not by entry replacement, so the bindless workflow can't be expressed as
a compose override on top of docker-compose.yml. A standalone file is
required.

Changes
-------
* docker/backend.Dockerfile
  - Add `COPY gradlew settings.gradle build.gradle ./`
  - Add `COPY gradle/ gradle/`
  - Add `RUN chmod +x gradlew`
  - Add `COPY backend/ backend/`
  - Add `EXPOSE 8080`
  - Keep ENTRYPOINT unchanged.
  - New image is runnable with `docker run bilhej-backend-dev` (no bind
    mount needed) and works under `docker compose up -d` on any host.

* docker/frontend.Dockerfile
  - Add comments documenting the two-stage COPY pattern (deps first for
    layer cache, then full source).
  - Keep the existing structure — it already COPYs the source, just
    wasn't being relied on. Now bind-mount failures (e.g. index.html
    type mismatch in DinD) don't kill the container; the COPY'd file
    is already in place.
  - Add `EXPOSE 3000` (was missing).

* .dockerignore
  - Expand to exclude everything that isn't strictly needed at build or
    run time: docs, scripts, git, editor config, build outputs, test
    results, logs, env files, docker-related metadata, etc.
  - Cuts the build context from ~MBs to ~800 KB (verified).
  - Image contents are now: gradlew + wrapper, build.gradle, settings,
    gradle/, backend/ (for backend image); package.json, package-lock,
    src/, public/, index.html, node_modules (for frontend image).

* docker-compose.dev-bindless.yml (new)
  - Standalone variant of docker-compose.yml with all host bind mounts
    removed. Same service definitions, same image tags, same env vars,
    same named cache volumes (pgdata, gradle-cache, backend-gradle-
    project, backend-build). Only differences: no `.:/app`, no
    `./frontend/src:/app/src`, no `./frontend/public:/app/public`, no
    `./frontend/index.html:/app/index.html`.
  - Usage: `docker compose -f docker-compose.dev-bindless.yml up -d`
    (no `--build` needed if images already exist; include `--build`
    on first run or after pulling changes).
  - Trade-off vs the default dev compose: image is "frozen" at build
    time, so editing source on the host doesn't trigger HMR. Edit +
    `docker compose up -d --build` (or just rebuild the relevant
    service) to pick up changes. Named cache volumes still keep
    gradle/npm caches warm across rebuilds.

* e2e compose (docker-compose.e2e.yml, docker/*.e2e.Dockerfile) —
  unchanged. They were already self-contained and continue to work as
  before. Verified by running the full 90/90 Playwright suite in 54s.

Compatibility with existing dev workflow
----------------------------------------
On a normal host where bind mounts work (the common case):

  - `docker compose up -d` (the existing command) keeps working
    unchanged. The bind mount on `.:/app` overlays the COPY'd source
    at runtime, so HMR and `gradle :backend:bootRun` hot-reload work
    exactly like before.
  - Image size grows (~50 MB backend, ~50 MB frontend on top of base
    image; ~200 MB including node_modules). Acceptable for dev.
  - First-time `docker compose build` is slightly slower because it
    has to COPY the source. Subsequent builds cache well: the COPY
    layer invalidates only when source files change.

Verified
--------
  - Hermes DinD sandbox: bindless dev stack (`docker-compose.dev-
    bindless.yml`) brings up postgres + mailpit + backend + frontend
    with no bind mounts. Spring Boot starts in ~6s, Vite dev server
    in ~700ms. Backend serves real API responses
    (`GET /api/vehicles/ABC123 -> 404 Inget fordon hittades`).
  - Hermes DinD sandbox: e2e stack runs all 90 Playwright tests in
    ~54s, identical to pre-patch behavior.
  - Docker image self-sufficiency: `docker run --rm bilhej-backend-dev`
    and `docker run --rm bilhej-frontend-dev` both work without any
    bind mounts.

Refs: project AGENTS.md (Docker section, gradle check pre-commit).
2026-06-17 09:44:18 +00:00
aa2cb7c4a0 Merge pull request 'Add production-only Umami analytics for bilhej.se.' (#9) from feature/umami-analytics into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m17s
CI / E2E browser tests (push) Successful in 3m28s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/9
2026-06-01 10:10:19 +00:00
737bc3dc64 Add production-only Umami analytics for bilhej.se.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m8s
CI / E2E browser tests (pull_request) Successful in 3m29s
Enable pageview tracking when VITE_UMAMI_WEBSITE_ID is set at frontend
build time (Forgejo secret + deploy workflow), with SPA route updates
and no script in local dev. Document setup in docs/umami-analytics.md,
extend integritetspolicy, and add admin Webbstatistik link in prod builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 12:02:14 +02:00
fa7e48fe02 Merge pull request 'Refactor admin fulfillment into focused modules.' (#8) from refactor/admin-fulfillment into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m5s
CI / E2E browser tests (push) Successful in 3m21s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/8
2026-05-28 12:48:44 +00:00
c7eeaf6a6b Refactor admin fulfillment into focused modules.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m9s
CI / E2E browser tests (pull_request) Successful in 4m1s
Extract AdminOrderWorkflowService and status rules API; split AdminPage
into composables and components; share order status constants; update tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 14:34:03 +02:00
0b2c58fa82 Merge pull request 'Add admin order fulfillment tracking.' (#7) from feature/admin-fulfillment-tracking into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m10s
CI / E2E browser tests (push) Successful in 3m24s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/7
2026-05-28 12:16:59 +00:00
aec7020621 Stabilize CI E2E: serial admin specs and no shared DB races.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m6s
CI / E2E browser tests (pull_request) Successful in 3m27s
Run admin-dashboard with other DB/Mailpit specs after parallel tests.
Stop admin-dashboard from mutating the sent seed order before fulfillment.
Wait longer for backend readiness in the E2E stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 08:47:16 +02:00
623433ba4d Format AdminPage.vue with Prettier.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m16s
CI / E2E browser tests (pull_request) Failing after 1m17s
No behavior change; satisfies frontend lint formatting.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 18:53:33 +02:00
c578463b10 Add mandatory pre-commit full check for agents and devs.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m6s
CI / E2E browser tests (pull_request) Failing after 1m8s
Document that ./gradlew check must pass before every commit. Add scripts
to run the same verification as CI and optionally install a git hook.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 13:43:35 +02:00
afa552e18b Run Mailpit E2E specs serially to stop flakes.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m7s
CI / E2E browser tests (pull_request) Failing after 1m17s
account-settings and password-reset called clearMailpit in parallel with
other tests, wiping emails before waitForEmailChangeToken could read them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 13:24:26 +02:00
2fa161f4fa Fix frontend tests after admin status error UX.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m4s
CI / E2E browser tests (pull_request) Failing after 1m9s
Align AdminDashboard unit test with API error messages shown in UI.
Stabilize account-settings E2E by relying on waitForEmailChangeToken only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 13:00:28 +02:00
5b5b44194d Fix V7 dev seed for H2 compatibility.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Failing after 2m15s
CI / E2E browser tests (pull_request) Failing after 1m34s
Remove PostgreSQL-only ON CONFLICT so Flyway succeeds in tests and local H2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 12:40:22 +02:00
1c9269699e Add admin order fulfillment tracking.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Failing after 1m50s
CI / E2E browser tests (pull_request) Failing after 1m38s
Register PostNord shipments, admin notes, and guarded status transitions
with customer emails. Expandable admin UI, V11 migration, serial E2E suite,
and AGENTS.md Docker-only E2E guidance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 12:21:17 +02:00
17fe67ae3f Merge pull request 'Make customer-facing UI usable on smartphones.' (#6) from feature/mobile-responsive into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m11s
CI / E2E browser tests (push) Successful in 56s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/6
2026-05-26 11:48:49 +00:00
144791b7e6 Fix deferred-payment E2E failures under parallel CI workers.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m8s
CI / E2E browser tests (pull_request) Successful in 1m2s
Remove the brittle filter-empty assertion from admin search helpers.
Run deferred-payment-admin in an isolated Playwright project with one
worker so serial tests keep shared order state. Stabilize unpaid-order
lookup by searching order id first, then plate text from the admin row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 13:45:16 +02:00
cf938501c5 Fix flaky admin plate search in deferred-payment E2E.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m9s
CI / E2E browser tests (pull_request) Failing after 1m2s
Merge admin lookup checks into one serial test, create the plate when
the order is created, and search using the plate shown in the admin row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 13:26:22 +02:00
4d3beeffb4 Stabilize deferred-payment admin E2E search assertions.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m22s
CI / E2E browser tests (pull_request) Failing after 1m6s
CI intermittently failed when searching admin orders by registration
number because the table was queried before data and filters settled.
Wait for the admin list to load, clear the search field between queries,
and use a longer timeout when expecting the matching row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 13:16:11 +02:00
7a95c1423c Make customer-facing UI usable on smartphones.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m22s
CI / E2E browser tests (pull_request) Failing after 1m3s
Mobile traffic was breaking on narrow viewports because the header nav
overflowed and several pages used desktop-only spacing. This adds a
shared phone breakpoint, a hamburger menu, and scroll-to-top on route
changes so footer and menu navigation always land at the top of the page.

- Add --page-gutter and max-width 639px rules in base.css
- AppHeader: hamburger panel on small screens; flat account links on mobile
- AppFooter: stack footer links vertically on phones
- Home, compose, edit order, orders, auth, and legal pages: tighter gutters
  and responsive layout (orders card actions stack; home grids single-column)
- Router scrollBehavior: scroll to top on navigation; restore on browser back
- Tests: AppHeader menu toggle, Router scrollBehavior, mobile Playwright checks

Admin page is intentionally unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 13:03:35 +02:00
71a3225a11 Merge pull request 'Add account settings dropdown and verified email change flow.' (#5) from feature/account-settings-dropdown into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m13s
CI / E2E browser tests (push) Successful in 53s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/5
2026-05-22 12:35:46 +00:00
b2aaeb5733 Merge origin/master into feature/account-settings-dropdown.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m24s
CI / E2E browser tests (pull_request) Successful in 1m31s
Resolve router conflict: keep /bekrafta-epost confirm route alongside
master's /om-oss about page and /om redirect.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 14:34:38 +02:00
3532e4d486 Add account settings dropdown and verified email change flow.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m9s
CI / E2E browser tests (pull_request) Successful in 1m55s
Replace the header "Byt lösenord" link with an Inställningar menu for
changing email or password. Email changes are two-step: request with
password, confirmation link to the new address, then password again on
confirm so a wrong inbox cannot take over the account.

- Backend: EmailChangeService, V10 email_change_tokens, confirm API
- Frontend: ChangeEmailPage, ConfirmEmailChangePage, header dropdown
- E2E: account-settings round-trips, Mailpit verification, wrong-password guard
- Flyway: V9 restore for dev DBs, CI migration checks, V10 for email tokens

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 14:33:06 +02:00
3f20656f04 Merge pull request 'feature/cancel-edit-pending-orders' (#4) from feature/cancel-edit-pending-orders into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m21s
CI / E2E browser tests (push) Successful in 56s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/4
2026-05-22 11:54:15 +00:00
a12e07ec1c Register routes for integritetspolicy and villkor legal pages.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m4s
CI / E2E browser tests (pull_request) Successful in 57s
- Add /integritetspolicy and /villkor to Vue Router
- Add Router tests confirming both public legal routes resolve

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 13:51:20 +02:00
ec62ba7673 Add användarvillkor page for Bilhej service terms.
- Create TermsOfServicePage covering Swish payment, letter content rules, and liability
- Describe edit/cancel before payment and refund expectations after posting
- Link to integritetspolicy and support contact in footer CTA
- Add TermsOfServicePage unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 13:51:20 +02:00
258f6f5a17 Add integritetspolicy page with Phase 0 privacy copy.
- Create PrivacyPolicyPage with sections on data, rights, and letter recipients
- Use plain Swedish without technical jargon or operational detail
- Link to kontakt page and mailto for privacy questions
- Add PrivacyPolicyPage unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 13:51:20 +02:00
bce2447238 Rework contact page emails and simplify mailto actions.
- Add support@bilhej.se for orders and technical issues
- Move complaints to klagomal@bilhej.se instead of personal Gmail
- Show one mailto chip per card instead of duplicate link and button
- Update ContactPage tests and production email checklist for all @bilhej.se addresses

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 13:51:20 +02:00
c0c32b718b Merge about page prose into hero and drop redundant section heading.
- Move the three explanatory paragraphs into the hero card under the lead
- Remove the separate "Vad vi gör" section that repeated the same framing
- Add a light divider between lead and body text for readability

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 13:51:11 +02:00
255095e6bd Document kontakt@bilhej.se receiving and fix stale contact address in requirements.
- Add production checklist section for Resend inbound on bilhej.se
- Note that mail is read in the Resend dashboard unless a webhook is added later
- Update GDPR letter footer example in REQUIREMENTS.md to kontakt@bilhej.se

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:59:49 +02:00
c0902d0494 Merge pull request 'feature/cancel-edit-pending-orders' (#3) from feature/cancel-edit-pending-orders into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m3s
CI / E2E browser tests (push) Successful in 54s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/3
2026-05-22 10:48:33 +00:00
081a1f90d3 Add expand/collapse for long letter previews on orders page.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 1m59s
CI / E2E browser tests (pull_request) Successful in 57s
- Truncate previews over 120 characters with a Visa mer toggle
- Allow per-order expand state on pending and completed cards
- Add styles for expanded preview and toggle button
- Cover long and short message behavior in OrdersPage tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:46 +02:00
162002dfb1 Fix printed letter footer contact address to kontakt@bilhej.se.
- Replace obsolete hej@bilhalsning.se in ComposePage GDPR footer
- Apply the same correction on EditOrderPage for edited orders

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:46 +02:00
60cb07fc89 Redesign contact page with separate support and complaint channels.
- Replace single placeholder mailto with two contact cards
- Show kontakt@bilhej.se for general questions and service issues
- Show jcamorling@gmail.com for complaints with clearer labeling
- Add tips section pointing users to Mina beställningar first
- Extend ContactPage tests for both email addresses

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:46 +02:00
758ace1b92 Redesign about page and move route to /om-oss.
- Replace placeholder about card with hero, prose, steps, and CTA
- Add primary route /om-oss with redirect from legacy /om
- Update footer tagline and Om oss link to match new URL
- Extend AboutPage and AppFooter tests for new content and routing

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:44 +02:00
139250b2ac Redesign homepage with clearer marketing sections and honest copy.
- Add structured use-case cards mapped to real letter templates
- Replace generic hero with bullets on traceability, anonymity, and timing
- Add three-step how-it-works flow with manual posting disclaimer
- Reframe trust section around convenience rather than hidden addresses
- Refresh layout with gradient heroes, icons, and consistent section styling

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:42 +02:00
aa2b4b4a16 Merge pull request 'Fix order cancellation by allowing cancelled in the database status constraint.' (#2) from feature/cancel-edit-pending-orders into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m13s
CI / E2E browser tests (push) Successful in 53s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/2
2026-05-22 09:54:07 +00:00
15d7b4ae4c Fix order cancellation by allowing cancelled in the database status constraint.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m26s
CI / E2E browser tests (pull_request) Successful in 1m18s
The cancel API returned 500 because ck_orders_status did not include cancelled.
Adds Flyway V9 and an E2E test for cancelling a pending order from /orders.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:53:25 +02:00
41cfea09a6 Merge pull request 'feature/cancel-edit-pending-orders' (#1) from feature/cancel-edit-pending-orders into master
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m17s
CI / E2E browser tests (push) Successful in 51s
Reviewed-on: https://srvr.nu/git/git/jocke/bilhej/pulls/1
2026-05-22 09:45:20 +00:00
ca5ce12812 Polish orders page UI for pending and completed cards.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m0s
CI / E2E browser tests (pull_request) Successful in 1m27s
Redesigns the order list so unpaid and paid orders share a consistent
card layout, with clearer payment context and labeled metadata users
need before paying via Swish.

- Split list into Obetalda/Tidigare sections with pending orders first
- Pending cards: preview box, labeled Beställnings-ID, price row, Betala 49 kr
- Completed cards: same header/preview layout, prominent Spåra brev button
- Replace em-dash pay label and update unit/E2E selectors

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:38:26 +02:00
3d0b7fe799 Allow users to edit or cancel unpaid orders before payment.
Adds backend endpoints and frontend edit page so pending orders can be updated or soft-cancelled without admin intervention.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:21:47 +02:00
082139d266 Fix Forgejo deploy form: add type string to version input.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 1m58s
CI / E2E browser tests (push) Successful in 1m22s
Forgejo workflow_dispatch requires an explicit input type; without it the
UI showed invalidinputtype. Clarify README: workflow ref vs version tag.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 09:38:14 +02:00
de86880a8f Fix prod SMTP STARTTLS for Resend password-reset mail.
Some checks failed
CI / E2E browser tests (push) Has been cancelled
CI / Lint, type check, unit tests, coverage (push) Has been cancelled
The docker profile disables mail.smtp.starttls for Mailpit; prod runs
docker+prod so Resend saw AUTH before STARTTLS (538). Re-enable auth and
STARTTLS in application-prod.yml.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 18:50:18 +02:00
ad195fd890 Wire production email secrets through Forgejo deploy.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m2s
CI / E2E browser tests (push) Successful in 1m16s
Deploy workflow now writes MAIL_* and APP_PUBLIC_BASE_URL from Actions
secrets into the server .env so Resend SMTP works after domain verify.
Document Resend-only setup, Forgejo secret names, and prod expose-token off.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 18:39:00 +02:00
86fb946e33 Add password reset, logged-in change password, and Mailpit email dev/E2E.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 2m2s
CI / E2E browser tests (push) Successful in 1m55s
Operators can fix prod admin passwords without email via Byt lösenord;
end users can use forgot-password when SMTP is configured. Local and CI
use Mailpit to capture outbound mail and verify reset links end-to-end.

- Backend: V8 password_reset_tokens, PasswordResetService, EmailService,
  POST /api/auth/forgot-password, reset-password, change-password
- Optional testToken in forgot-password response (docker profile only, for E2E)
- Frontend: ForgotPasswordPage, ResetPasswordPage, ChangePasswordPage,
  routes, login link, header Byt lösenord
- Mailpit (ghcr.io/axllent/mailpit:v1.28) in docker-compose + e2e stack
- E2E: password-reset.spec.ts + Mailpit API helper tests SMTP delivery
- Separate dev/e2e Docker image names to avoid overwriting bilhej-frontend
- Docs: README email section, production-email-checklist, .env.example
- Unit/integration tests for reset, change password, and Vitest page specs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 18:05:15 +02:00
45b2449b14 Add phased nginx setup for bilhej.se TLS on srvr.nu.
First-time host nginx setup needs HTTP-only vhost before certbot can
issue certs; the full bilhej.nginx.conf 443 block fails nginx -t until
those files exist.

- Add docker/bilhej.nginx.http.conf for ACME phase
- Reorder README one-time setup: HTTP vhost, certbot, then full config
2026-05-21 17:06:21 +02:00
fb9713d8d8 Fix prod deploy Flyway validation for removed dev seed migrations.
Some checks failed
CI / E2E browser tests (push) Has been cancelled
CI / Lint, type check, unit tests, coverage (push) Has been cancelled
Backend crashed on startup because the prod DB still records V6 (and
possibly V2/V4) from when seeds lived in db/migration, while prod only
loads schema migrations. ignore-migration-patterns alone did not prevent
validate failure on the runner.

- Run Flyway repair before migrate on the prod profile
- Add ProdFlywayConfigTest for repair-then-migrate order
- Document the V6 error in README deploy troubleshooting
2026-05-21 16:52:15 +02:00
61a7b8a40c Wire backend tests and coverage into ./gradlew check.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 1m52s
CI / E2E browser tests (push) Successful in 45s
Root check only ran frontend lint, unit tests, and E2E, so backend JUnit
and JaCoCo gates were skipped despite AGENTS.md documenting otherwise.

- Make check depend on :backend:check and frontendE2E as siblings
- Update AGENTS.md comment to match the real task order
2026-05-21 16:44:15 +02:00
db56fc58de Add deploy failure diagnostics and safer backend health check.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 1m52s
CI / E2E browser tests (push) Successful in 46s
Production deploy failed with no backend logs before rollback. Print
backend and postgres logs on failure, wait longer for JVM startup, and
probe /api/payment/swish-info instead of vehicle lookup (no external scrape).

- Document proof-first troubleshooting in README
- No volume reset workflow; fix only after reading job logs
2026-05-21 16:39:13 +02:00
d652a5b862 Fix deploy .env writing when secrets contain dollar signs.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 1m55s
CI / E2E browser tests (push) Successful in 48s
Docker Compose interpolates $VAR in .env files. Passwords like ...$A72y...
were truncated and the backend failed health checks, triggering rollback.

- Escape $ as $$ when writing production secrets to .env
- Document that deploy handles literal $ in Forgejo secrets
2026-05-21 16:17:36 +02:00
7731eb1155 Apply ESLint formatting fixes to admin and orders pages.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 3m46s
CI / E2E browser tests (push) Successful in 1m46s
Auto-fix from eslint src/ --fix after ./gradlew check touched these
files. No functional changes.
2026-05-21 16:00:53 +02:00
49b5a91f4a Include E2E browser tests in ./gradlew check.
Local verification should match Forgejo CI. Wire frontendE2E into check
and point it at docker-compose.e2e.yml with the same test env vars.

- Add frontendE2E to check after frontend unit tests
- Run docker-compose.e2e.yml directly from Gradle with CI secrets
- Update npm test:e2e:ci to use the e2e compose file
2026-05-21 15:58:09 +02:00