utilities/seed-app.js
jtricerolph f1ce0f06d8 Fix TOU rate-window mismatch and enforce fallback-split validation
Rate windows were matched by substring (label.includes(key)), so
overlapping labels like "Day"/"Weekday" could silently cross-match to
the wrong rate. Switched to an exact match.

The "split must total 100%" check was advisory-only in the UI and
never validated server-side, letting a tariff save with a split that
doesn't sum to 100% and permanently mis-cost that meter's usage.
Enforced on both the API (POST/PATCH /api/tariffs) and the Save
button.

Also aligned the app's portal category to 'Hotel' (already correct in
auth/src/db.js) here and in stack-init/install-stack.sh, which had
both drifted to 'Operations'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 12:59:19 +00:00

45 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
// Run against the auth DB to (re-)register the utilities app and its
// capabilities. This mirrors the seed block already added to auth/src/db.js —
// use this for a manual re-seed without restarting the auth service.
// Usage: DATABASE_URL=postgresql://... node seed-app.js
import pg from 'pg'
const { Pool } = pg
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
await pool.query(`
INSERT INTO apps (slug, name, description, base_path, icon, theme_color, category, internal_host, internal_port)
VALUES ('utilities', 'Utilities', 'Meter readings, tariffs and energy cost tracking', '/utilities', 'Zap', '#1e6091', 'Hotel', '10.10.10.127', 3080)
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
base_path = EXCLUDED.base_path,
icon = EXCLUDED.icon,
theme_color = EXCLUDED.theme_color,
category = EXCLUDED.category,
internal_host = EXCLUDED.internal_host,
internal_port = EXCLUDED.internal_port
`)
// Seed capabilities — no default Staff grants, admin assigns via portal
await pool.query(`
INSERT INTO app_capabilities (app_id, slug, name, description, sort_order)
SELECT a.id, c.slug, c.name, c.description, c.sort_order
FROM apps a, (VALUES
('readings', 'Enter Readings', 'Enter manual meter readings and view reading history', 1),
('meters', 'Manage Meters', 'Create/edit categories, meters, locations and images', 2),
('tariffs', 'Manage Tariffs', 'Create/edit tariffs, rate windows, standing charges and CCL', 3),
('reports', 'View Reports', 'View consumption and cost reports', 4),
('estimates', 'View Estimates', 'View and adjust period cost estimates', 5),
('settings', 'Settings', 'App settings', 6)
) AS c(slug, name, description, sort_order)
WHERE a.slug = 'utilities'
ON CONFLICT (app_id, slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
sort_order = EXCLUDED.sort_order
`)
console.log('utilities app seeded.')
await pool.end()