Files
accounted/components/RecaptHideWidget.tsx
T
Jakob Wennberg 4a6c473cc4 fix(bookkeeping): allow EF förlängt räkenskapsår on first-period edit + hide Recapt widget (#481)
* fix(bookkeeping): allow EF förlängt räkenskapsår on first-period edit + hide Recapt widget

PATCH /api/bookkeeping/fiscal-periods/[id] rejected enskild firma first
fiscal periods extended into the next calendar year (e.g. 2020-10-04 →
2021-12-31, 15 mån) even though BFL 3 kap. permits up to 18 months when
the EF starts after 1 juli. Validator and DB trigger already supported
this; only the API check ignored isFirstPeriod. Move the isFirstPeriod
calculation above the EF rule and split it into "end must be 31 dec
(always)" + "start must be 1 jan (only when not first period)". Brings
the API into agreement with the frontend's validateFirstPeriod logic.

Also mount RecaptHideWidget in the root layout, which calls
window.recapt('feedback', { widget: 'hide' }) once the SDK is ready.
The floating bubble no longer appears in the bottom-right; Recapt's
identify and programmatic feedback APIs continue to work unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(bookkeeping): address PR-481 review — standard guards, shared helpers, 18-month cap regression

- Use shared createMockRequest / createMockRouteParams from tests/helpers.ts
- Add 401 (unauthenticated), 400 (malformed body), 404 (unknown period)
- Rename "mid-month startdatum" case to "not 1 januari" (request sends 2026-02-01, a month boundary, not mid-month — the rule rejects any non-Jan-1)
- Add defense-in-depth case proving validatePeriodDuration rejects a 24-month EF first period (BFL 3 kap. 18-month cap), since the new EF end-date guard runs before duration validation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(bookkeeping): lock in EF subsequent-period end-date guard

The start-must-be-1-jan + end-must-be-31-dec guards together force EF
subsequent periods to a 12-month span. validatePeriodDuration's 18-month
universal cap doesn't enforce this on its own — only the route's per-EF
guards do. Add a regression test so a future refactor of the EF block
can't silently allow a 13-month subsequent period (e.g. 2026-01-01 →
2027-01-31), addressing PR-481 swedish-compliance review finding #1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 14:31:01 +02:00

39 lines
877 B
TypeScript

'use client'
import { useEffect } from 'react'
/**
* Hides Recapt's floating feedback bubble while keeping the SDK active so
* `window.recapt('identify', ...)` and programmatic `window.recapt('feedback',
* { message })` calls continue to work. Mounted globally in the root layout.
*/
export function RecaptHideWidget() {
useEffect(() => {
let attempts = 0
const maxAttempts = 50
const hide = (): boolean => {
if (typeof window.recapt !== 'function') return false
try {
window.recapt('feedback', { widget: 'hide' })
} catch {
// best-effort
}
return true
}
if (hide()) return
const interval = setInterval(() => {
attempts++
if (hide() || attempts >= maxAttempts) {
clearInterval(interval)
}
}, 100)
return () => clearInterval(interval)
}, [])
return null
}