feat(mileage): surface Körjournal in the nav behind a settings toggle (#1540)

* feat(mileage): surface Körjournal in the nav behind a settings toggle

The /mileage page shipped hidden: the route works but no nav row points at
it. Add company_settings.mileage_enabled (mirroring dimensions_enabled) with
a switch in Fönster -> Bokföring, and show the Arbeta nav row when the toggle
is on OR the company already has mileage_trips rows, the same hybrid gate as
webshop orders, so trips created via API/MCP can never become invisible
underlag. UI visibility only, never load-bearing for correctness.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(migrations): move mileage_enabled migration after already-applied 20260812153208

origin/main merged in 20260812153208 which prod has already applied; a new
file sorting before it risks an out-of-order db push abort.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-08-12 21:48:01 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 67febd5097
commit 45d7f1be4e
12 changed files with 191 additions and 6 deletions
+19
View File
@@ -97,6 +97,25 @@ describe('PUT /api/settings', () => {
expect(deadlineMocks.regenerate).not.toHaveBeenCalled()
})
it('accepts the mileage_enabled visibility toggle', async () => {
enqueueMany([
{ data: { entity_type: 'enskild_firma', onboarding_complete: true } }, // fetch oldSettings
{ data: { id: 's1', mileage_enabled: true } }, // update ... returning
{ data: null, count: 5 }, // deadlines count (has some -> no regen)
])
const request = createMockRequest('/api/settings', {
method: 'PUT',
body: { mileage_enabled: true },
})
const response = await PUT(request, { params: Promise.resolve({}) })
const { status, body } = await parseJsonResponse<{ data: { mileage_enabled: boolean } }>(response)
expect(status).toBe(200)
expect(body.data.mileage_enabled).toBe(true)
expect(deadlineMocks.regenerate).not.toHaveBeenCalled()
})
it('round-trips share capital fields and clears them with null', async () => {
const updates = { aktiekapital: 25000, antal_aktier: 500 }
enqueueMany([