bf85d7066e
Schedule UI polish, full CRUD, Requests/Approvals/Tasks/Audit/PDF/Print/
Font Settings/Notifications-placeholder, audit logging on every mutation,
fine-grained RBAC, bilingual i18n.
Backend (artifacts/api-server/src/routes/executive-meetings.ts)
- All mutations transactional + audit-logged.
- Approve/reject/needs_edit use atomic UPDATE WHERE status='new' RETURNING;
race losers return 409 RACE_ALREADY_REVIEWED.
- applyApprovedRequest() applies reschedule / change_location / add_attendee /
remove_attendee / highlight / unhighlight / cancel_meeting / create / edit /
delete in-tx; effective-time validation throws APPLY_VALIDATION → 400.
- Approve auto-creates linked follow_up_<reqType> task with requestId set.
- Marking a task with requestId as 'completed' propagates request → 'done'
(in same tx, audit-logged).
- New endpoints: PUT /:id/attendees, POST /:id/duplicate,
GET/POST /pdf-archives.
Schema (lib/db/src/schema/executive-meetings.ts)
- executive_meeting_requests.meetingId nullable so 'create' requests work.
- pdf_archives table.
Frontend (artifacts/tx-os/src/pages/executive-meetings.tsx + new
executive-meetings-print.tsx, App.tsx route)
- Schedule polish: # column, RTL order, attendees widest, navy/white/gray,
red highlight only.
- Tabs: Manage / Requests / Approvals / Tasks / Audit / PDF / Notifications /
Font Settings.
- Requests form now sends STRUCTURED fields (meetingDate, startTime, endTime
for reschedule; location/url for change_location; name/title for
add_attendee; etc.) — previously sent only {note}, which prevented apply
from doing anything.
- Approve handler invalidates ALL ['/api/executive-meetings', *] keys + tasks.
- PDF tab lists archives; Archive snapshot button; Print opens new route.
i18n (en.json/ar.json)
- Full executiveMeetings.* key set including pdf.archive*, attendees.title/id.
Verified
- E2e regression: create meeting → reschedule request (structured) → approve
→ meeting moves to new date → task created → mark task complete → request
becomes 'done'. Negative case (start>end) → approve rejected.
- Architect final review: PASS, no severe blockers.
Out of scope per spec: real notification delivery, real PDF rendering, iCal,
mobile polish.
72 lines
1.1 KiB
Plaintext
72 lines
1.1 KiB
Plaintext
modules = ["nodejs-24", "postgresql-16", "python-3.11"]
|
|
|
|
[deployment]
|
|
router = "application"
|
|
deploymentTarget = "autoscale"
|
|
|
|
[deployment.postBuild]
|
|
args = ["pnpm", "store", "prune"]
|
|
env = { "CI" = "true" }
|
|
|
|
[workflows]
|
|
runButton = "Project"
|
|
|
|
[[workflows.workflow]]
|
|
name = "Project"
|
|
mode = "parallel"
|
|
author = "agent"
|
|
|
|
[[workflows.workflow.tasks]]
|
|
task = "workflow.run"
|
|
args = "test"
|
|
|
|
[[workflows.workflow]]
|
|
name = "test"
|
|
author = "agent"
|
|
|
|
[[workflows.workflow.tasks]]
|
|
task = "shell.exec"
|
|
args = "pnpm --filter @workspace/api-server test && pnpm --filter @workspace/tx-os test:e2e"
|
|
|
|
[workflows.workflow.metadata]
|
|
outputType = "console"
|
|
|
|
[agent]
|
|
stack = "PNPM_WORKSPACE"
|
|
expertMode = true
|
|
|
|
[postMerge]
|
|
path = "scripts/post-merge.sh"
|
|
timeoutMs = 120000
|
|
|
|
[[ports]]
|
|
localPort = 8080
|
|
externalPort = 8080
|
|
|
|
[[ports]]
|
|
localPort = 8081
|
|
externalPort = 80
|
|
|
|
[[ports]]
|
|
localPort = 8082
|
|
externalPort = 3003
|
|
|
|
[[ports]]
|
|
localPort = 8083
|
|
externalPort = 5173
|
|
|
|
[[ports]]
|
|
localPort = 25785
|
|
externalPort = 3000
|
|
|
|
[[ports]]
|
|
localPort = 25786
|
|
externalPort = 3002
|
|
|
|
[[ports]]
|
|
localPort = 25787
|
|
externalPort = 5000
|
|
|
|
[nix]
|
|
channel = "stable-25_05"
|