Commit Graph

4 Commits

Author SHA1 Message Date
riyadhafraa 7a2ae8434d Update project documentation and code comments to remove platform-specific references
Refactor documentation files and code comments to remove references to Replit, specific task numbers, and other platform-specific identifiers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: fa18e5d4-a810-4bd5-8cde-2a60d64d9e3f
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/kI0sxlu
Replit-Helium-Checkpoint-Created: true
2026-05-14 06:23:49 +00:00
riyadhafraa de7973f35b Task #293: DB CHECK constraint for executive_meetings.row_color (defense-in-depth for #288)
Mirrors the API-side row-colour whitelist at the database layer so any
out-of-band write path (manual psql, future bulk-import jobs, restored
backups) cannot smuggle an unrenderable colour past the Zod guard
introduced in #288.

Changes:

- lib/db/src/schema/executive-meetings.ts: export new shared constant
  EXECUTIVE_MEETING_ROW_COLOR_KEYS (red/amber/green/blue/violet/gray)
  + ExecutiveMeetingRowColor union type. Add a Drizzle check()
  constraint named `executive_meetings_row_color_palette_check` that
  allows NULL or any of the six keys. The CHECK uses sql.raw to inline
  the palette as quoted SQL literals (PG CHECK definitions are DDL and
  reject parameter placeholders); safe because the keys come from a
  hardcoded compile-time constant of single-word identifiers, never
  user input. Generating the literal list from the same constant
  guarantees the API guard and the DB constraint stay in sync.

- artifacts/api-server/src/routes/executive-meetings.ts: import
  EXECUTIVE_MEETING_ROW_COLOR_KEYS from @workspace/db and rewire
  rowColorSchema to z.enum(EXECUTIVE_MEETING_ROW_COLOR_KEYS).nullable().
  Deletes the local ROW_COLOR_KEYS const so the palette has exactly
  one source of truth. No behaviour change at runtime.

- artifacts/api-server/tests/executive-meetings-row-color.test.mjs:
  append a focused defense-in-depth test that bypasses the API and
  asserts (a) NULL is allowed, (b) each of the six palette keys
  round-trips on raw UPDATE, (c) off-palette UPDATEs reject with PG
  SQLSTATE 23514 referencing the constraint by name, (d) the row
  keeps its previous colour after the rejected updates, and (e) raw
  INSERT with an off-palette value is rejected the same way.

Migration applied via pnpm --filter @workspace/db push (no destructive
prompts; existing rows are NULL or valid keys from #288 so the
constraint installs cleanly). All 7 tests in the row-color file pass.
Architect review: APPROVED, no critical findings.

The single pre-existing Reorder test failure in the wider suite is
unrelated to this change (Reorder does not touch row_color).
2026-05-01 15:41:21 +00:00
riyadhafraa 4d497606d4 Task #288: Share Executive Meetings row highlight colors across devices
Per-row highlight colors on the Executive Meetings daily schedule were
stored in each browser's localStorage, so a color set by the admin on
their laptop never reached the executive office or the big-screen
viewer. Move the color into a shared, server-stored field on the
meeting row so every viewer sees the same color in real time.

Schema
- Add nullable `row_color varchar(16)` to `executive_meetings`
  (lib/db/src/schema/executive-meetings.ts). Migration applied via
  `pnpm --filter @workspace/db push`.

API (artifacts/api-server/src/routes/executive-meetings.ts)
- Whitelist ROW_COLOR_KEYS = red/amber/green/blue/violet/gray.
- Extend meetingPatchSchema with optional `rowColor` (nullable enum).
- Existing PATCH /executive-meetings/:id picks it up, stamps
  updatedBy, writes the standard audit-log entry, and fires
  emitExecutiveMeetingsDaysChanged so other viewers' day query
  invalidates and re-fetches.
- Permission gating unchanged: requireMutate → executive_viewer 403.

Frontend (artifacts/tx-os/src/pages/executive-meetings.tsx)
- `rowColors` is now derived from the meetings query via useMemo.
  The localStorage write effect is removed.
- New async setRowColor() PATCHes the server and invalidates the day
  query (key ["/api/executive-meetings", date]).
- Best-effort migration of legacy localStorage colors:
  - drops invalid keys / unknown colors immediately,
  - skips ids the server already colored (no overwrite),
  - PATCHes ids in the currently loaded day,
  - PRESERVES ids for dates the user hasn't visited yet so they
    migrate when they do navigate there (architect review caught a
    data-loss bug in the first cut where unvisited-day entries were
    being deleted),
  - keeps failed PATCHes for retry, removes the localStorage key
    only once nothing is left,
  - in-flight Set prevents double-PATCH if the effect re-fires.

Tests
- New artifacts/api-server/tests/executive-meetings-row-color.test.mjs
  (6 specs) covers PATCH set / clear / invalid-key 400 / viewer 403 /
  realtime executive_meetings_changed socket event for the affected
  date / audit attribution. All pass.
- E2E (runTest) verified two browser contexts share the color
  without manual refresh.

Documentation
- replit.md: added "Task #288 — Shared row colours" section.

Drift / notes
- Pre-existing TS errors in admin.tsx and pre-existing isHighlighted /
  font_settings scope errors in executive-meetings.ts are unrelated
  to this change.
- Follow-up #293 proposed: add a DB-level CHECK constraint mirroring
  the API whitelist for defense-in-depth.
2026-05-01 15:32:38 +00:00
riyadhafraa ab5ec2e2e2 Add shared row highlighting to executive meeting scheduler
Implement shared row highlighting for executive meetings by adding a `rowColor` field to the database schema and API, and migrating existing per-device colors to the new shared field.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 273accfc-a301-41b9-bd20-c121cb4e79c7
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/g7BgHDL
Replit-Helium-Checkpoint-Created: true
2026-05-01 15:24:59 +00:00