feat(executive-meetings): grant executive_ceo mutate + audit + push notify (Task #561)

User request: السماح للرئيس (executive_ceo) بإنشاء/تعديل/تأجيل/حذف
الاجتماعات، استلام إشعارات Push للتذكير، والاطلاع على سجل التدقيق —
مع إبقاء إعدادات الخطوط/الشعار حصرية على مدير المكتب التنفيذي.

Changes (3 lines added, backend-only):

1. artifacts/api-server/src/routes/executive-meetings.ts
   - Added "executive_ceo" to MUTATE_ROLES (line 120) → POST/PATCH/DELETE
     on meetings now accepted for the CEO role.
   - Added "executive_ceo" to ADMIN_AUDIT_ROLES (line 130) → /audit
     endpoint now reachable; canViewAudit=true in the bootstrap payload.
   - EM_ADMIN_ROLES intentionally untouched, so font-settings and global
     PDF brand assets remain admin + executive_office_manager only.

2. artifacts/api-server/src/lib/executive-meeting-scheduler.ts
   - Added "executive_ceo" to EM_NOTIFY_ROLES (line 18) → CEO users with
     an active Web Push subscription now receive the LEAD_MINUTES=5
     pre-meeting reminder push.

Frontend requires no changes: it gates buttons on canMutate /
canViewAudit booleans returned by the bootstrap endpoint (lines
617-619), which flip to true automatically for the CEO role.

Verification: API workflow restarted clean, scheduler started OK,
/api/executive-meetings and /alert-state respond 304/200.

NOT pushed to Gitea: Tailscale link to desktop-11cj93j is still down
from this sandbox (HTTP=000). Task #560's earlier VAPID fix
(629069b1) is also still pending push. Both will go up together when
the tunnel recovers, or the user can apply the same one-line edits
on the Mac and rebuild the api container.
This commit is contained in:
riyadhafraa
2026-05-17 10:07:57 +00:00
parent 42b881355b
commit 0f71ae4102
2 changed files with 7 additions and 1 deletions
@@ -10,7 +10,11 @@ import { getUserIdsForRoleNames } from "./executive-meeting-notify";
const TICK_MS = 60_000;
const LEAD_MINUTES = 5;
const EM_NOTIFY_ROLES = ["admin", "executive_office_manager"] as const;
const EM_NOTIFY_ROLES = [
"admin",
"executive_ceo",
"executive_office_manager",
] as const;
function pad2(n: number): string {
return String(n).padStart(2, "0");
@@ -117,12 +117,14 @@ const FONT_SIZE_MAX = 22;
const MUTATE_ROLES = [
"admin",
"executive_ceo",
"executive_office_manager",
"executive_coord_lead",
] as const;
const EM_ADMIN_ROLES = ["admin", "executive_office_manager"] as const;
const ADMIN_AUDIT_ROLES = [
"admin",
"executive_ceo",
"executive_office_manager",
"executive_coord_lead",
] as const;