Fastify + pg backend, React/TS/Vite frontend. Categories (electric, gas, oil, water), meters with sub-metering rollup, tariffs with time-of-use rate windows, standing charges, Climate Change Levy and VAT, manual reading entry, consumption/cost reports, period cost estimates, and an API-key-gated /api/internal/* surface for the reports app's Directors Report. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
27 lines
1 KiB
JavaScript
27 lines
1 KiB
JavaScript
import { requireAuth, requireCap } from '../auth.js'
|
|
import { pool } from '../db.js'
|
|
|
|
export async function settingsRoutes(app) {
|
|
app.addHook('preHandler', requireAuth)
|
|
|
|
// GET /api/config — all config keys as a flat object (readable by anyone in
|
|
// the app since the estimates page needs the global default too)
|
|
app.get('/api/config', async () => {
|
|
const { rows } = await pool.query('SELECT key, value FROM config ORDER BY key')
|
|
return Object.fromEntries(rows.map(r => [r.key, r.value]))
|
|
})
|
|
|
|
// PUT /api/config/:key — update a single config key
|
|
app.put('/api/config/:key', { preHandler: requireCap('settings') }, async (req, reply) => {
|
|
const { key } = req.params
|
|
const { value } = req.body || {}
|
|
if (value === undefined) return reply.status(400).send({ error: 'value required' })
|
|
|
|
await pool.query(
|
|
`INSERT INTO config (key, value, updated_at) VALUES ($1, $2, NOW())
|
|
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()`,
|
|
[key, JSON.stringify(value)]
|
|
)
|
|
return { ok: true }
|
|
})
|
|
}
|