* feat: add script to import Skatteverket monthly tax tables as fallback TypeScript module
- Implemented a new script `import-tax-tables.ts` to parse fixed-width TXT tax tables from Skatteverket (SKV 434).
- The script generates a TypeScript module for emergency fallback when the Skatteverket open-data API is unavailable.
- Supports command-line argument for specifying the year and handles parsing of B-rows only.
- Outputs a structured TypeScript file containing tax data for specified years.
* feat: gate salary module behind dev-only flag
Temporarily disable the Lön module in production while the feature is
being completed. Sidebar entries ("Löner", "Anställda") still render but
are not clickable and show a "Kommer snart" badge. Middleware redirects
/salary* to / and returns 404 on /api/salary/* so the feature can't be
reached by direct URL. All gates check NODE_ENV === 'development' so
local dev keeps full access for continued development.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: refactor bank file import wizard to streamline column mapping and enhance CSV handling
* fix: bump migration timestamp to avoid collision with logos_bucket
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: enhance AGI generation and salary entry calculations with improved status checks and error handling
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { createClient } from '@/lib/supabase/server'
|
|
import { NextResponse } from 'next/server'
|
|
import { lookupTaxFromApi, TaxTableUnavailableError } from '@/lib/salary/tax-tables'
|
|
|
|
export async function GET(request: Request) {
|
|
const supabase = await createClient()
|
|
const { data: { user } } = await supabase.auth.getUser()
|
|
if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
|
|
const { searchParams } = new URL(request.url)
|
|
const year = parseInt(searchParams.get('year') || new Date().getFullYear().toString())
|
|
const tableNumber = parseInt(searchParams.get('table') || '0')
|
|
const column = parseInt(searchParams.get('column') || '1')
|
|
const income = parseFloat(searchParams.get('income') || '0')
|
|
|
|
if (!tableNumber || tableNumber < 29 || tableNumber > 42) {
|
|
return NextResponse.json({ error: 'Skattetabell måste vara 29-42' }, { status: 400 })
|
|
}
|
|
|
|
try {
|
|
const { taxAmount, source } = await lookupTaxFromApi(tableNumber, column, income, year)
|
|
return NextResponse.json({
|
|
data: {
|
|
year,
|
|
tableNumber,
|
|
column,
|
|
income,
|
|
taxAmount,
|
|
source: source === 'api' ? 'skatteverket_api' : 'local_fallback',
|
|
},
|
|
})
|
|
} catch (err) {
|
|
if (err instanceof TaxTableUnavailableError) {
|
|
return NextResponse.json({ error: err.message }, { status: 503 })
|
|
}
|
|
throw err
|
|
}
|
|
}
|