From 6e5009b57f506b5671090b6db4b837c20680cfee Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Thu, 2 Jul 2026 14:36:06 +0000 Subject: [PATCH] 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 --- src/db.js | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/db.js b/src/db.js index afe43a5..bb2ab70 100644 --- a/src/db.js +++ b/src/db.js @@ -147,11 +147,14 @@ export async function initDb() { SELECT a.id, c.slug, c.name, c.description, c.sort_order FROM apps a CROSS JOIN (VALUES - ('count', 'Count cash ups', 'Create and edit draft daily cash ups', 1), - ('finalise', 'Finalise cash ups','Submit final, delete drafts, bulk-finalise', 2), - ('reports', 'View reports', 'Weekly / multi-day report, cash summary, debtors', 3), - ('floats', 'Manage floats', 'Float management and safe count', 4), - ('settings', 'Manage settings', 'App settings: Newbook config, GL columns, thresholds', 5) + ('count', 'Count cash ups', 'Create and edit draft daily cash ups', 1), + ('finalise', 'Finalise cash ups', 'Submit final, delete drafts, bulk-finalise', 2), + ('history', 'View history', 'View the cash up history list', 3), + ('reports', 'Weekly report', 'Weekly / multi-day report and debtors', 4), + ('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) WHERE a.slug = 'cashup' ON CONFLICT (app_id, slug) DO UPDATE SET @@ -160,10 +163,8 @@ export async function initDb() { sort_order = EXCLUDED.sort_order `) - // Non-breaking migration: grant the default Staff role every cashup capability - // except 'settings' (previously only is_admin could reach settings). Admins - // implicitly get all capabilities regardless. Only seeds when the Staff role - // has no cashup capabilities yet, so later admin tightening is never undone. + // Non-breaking initial seed: grant the default Staff role every cashup capability + // except 'settings' only when Staff has no cashup caps yet (first deploy). await pool.query(` INSERT INTO role_capabilities (role_id, capability_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 apps a ON a.id = ac.app_id 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 ( SELECT 1 FROM role_capabilities rc JOIN app_capabilities ac2 ON ac2.id = rc.capability_id @@ -180,6 +181,21 @@ export async function initDb() { 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 await pool.query(` INSERT INTO app_capabilities (app_id, slug, name, description, sort_order)