Expand cashup caps: history, cash_summary, safe_count

Splits the old 'reports' cap into reports + cash_summary,
'floats' into floats + safe_count, and adds a new 'history' cap.
Existing installs get the three new caps added to the Staff role
via an additive per-cap seed so admin-managed configs are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-02 14:36:06 +00:00
parent b5d494a691
commit 6e5009b57f

View file

@ -149,9 +149,12 @@ export async function initDb() {
CROSS JOIN (VALUES CROSS JOIN (VALUES
('count', 'Count cash ups', 'Create and edit draft daily cash ups', 1), ('count', 'Count cash ups', 'Create and edit draft daily cash ups', 1),
('finalise', 'Finalise cash ups', 'Submit final, delete drafts, bulk-finalise', 2), ('finalise', 'Finalise cash ups', 'Submit final, delete drafts, bulk-finalise', 2),
('reports', 'View reports', 'Weekly / multi-day report, cash summary, debtors', 3), ('history', 'View history', 'View the cash up history list', 3),
('floats', 'Manage floats', 'Float management and safe count', 4), ('reports', 'Weekly report', 'Weekly / multi-day report and debtors', 4),
('settings', 'Manage settings', 'App settings: Newbook config, GL columns, thresholds', 5) ('cash_summary', 'Cash summary', 'Cash summary by denomination across date range', 5),
('floats', 'Manage floats', 'Float ledger: petty cash and change tin', 6),
('safe_count', 'Safe count', 'Safe cash count', 7),
('settings', 'Manage settings', 'App settings: Newbook config, GL columns, thresholds', 8)
) AS c(slug, name, description, sort_order) ) AS c(slug, name, description, sort_order)
WHERE a.slug = 'cashup' WHERE a.slug = 'cashup'
ON CONFLICT (app_id, slug) DO UPDATE SET ON CONFLICT (app_id, slug) DO UPDATE SET
@ -160,10 +163,8 @@ export async function initDb() {
sort_order = EXCLUDED.sort_order sort_order = EXCLUDED.sort_order
`) `)
// Non-breaking migration: grant the default Staff role every cashup capability // Non-breaking initial seed: grant the default Staff role every cashup capability
// except 'settings' (previously only is_admin could reach settings). Admins // except 'settings' only when Staff has no cashup caps yet (first deploy).
// implicitly get all capabilities regardless. Only seeds when the Staff role
// has no cashup capabilities yet, so later admin tightening is never undone.
await pool.query(` await pool.query(`
INSERT INTO role_capabilities (role_id, capability_id) INSERT INTO role_capabilities (role_id, capability_id)
SELECT r.id, ac.id SELECT r.id, ac.id
@ -171,7 +172,7 @@ export async function initDb() {
JOIN app_capabilities ac ON ac.app_id = (SELECT id FROM apps WHERE slug = 'cashup') JOIN app_capabilities ac ON ac.app_id = (SELECT id FROM apps WHERE slug = 'cashup')
JOIN apps a ON a.id = ac.app_id JOIN apps a ON a.id = ac.app_id
WHERE r.slug = 'staff' WHERE r.slug = 'staff'
AND ac.slug IN ('count', 'finalise', 'reports', 'floats') AND ac.slug IN ('count', 'finalise', 'history', 'reports', 'cash_summary', 'floats', 'safe_count')
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 FROM role_capabilities rc SELECT 1 FROM role_capabilities rc
JOIN app_capabilities ac2 ON ac2.id = rc.capability_id JOIN app_capabilities ac2 ON ac2.id = rc.capability_id
@ -180,6 +181,21 @@ export async function initDb() {
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
`) `)
// Additive migration: grant Staff the three new split caps individually if
// not already present (handles existing installs that already had the old caps).
await pool.query(`
INSERT INTO role_capabilities (role_id, capability_id)
SELECT r.id, ac.id
FROM roles r
JOIN app_capabilities ac ON ac.app_id = (SELECT id FROM apps WHERE slug = 'cashup')
WHERE r.slug = 'staff'
AND ac.slug IN ('history', 'cash_summary', 'safe_count')
AND NOT EXISTS (
SELECT 1 FROM role_capabilities rc WHERE rc.role_id = r.id AND rc.capability_id = ac.id
)
ON CONFLICT DO NOTHING
`)
// Seed hk-planner capabilities // Seed hk-planner capabilities
await pool.query(` await pool.query(`
INSERT INTO app_capabilities (app_id, slug, name, description, sort_order) INSERT INTO app_capabilities (app_id, slug, name, description, sort_order)