Commit Graph

4 Commits

Author SHA1 Message Date
Replit Agent 5dab20a526 Task #741: تغيير اسم التطبيق إلى «المراسم والعلاقات العامة»
- ar.json protocol.title: «العلاقات العامة والمراسم» → «المراسم والعلاقات العامة».
- en.json protocol.title: "Public Relations & Protocol" → "Protocol & Public Relations".
- Dev DB: UPDATE apps (slug='protocol', id 11015) name_ar/name_en to new order.
- scripts/src/seed.ts: protocol app entry updated to the new names.
- lib/db/scripts/pre-push-cleanup.ts: new idempotent step renaming the
  protocol apps row on every push so production gets the new tile name.
  Verified by running the script against dev DB ("already up to date").
- pnpm --filter @workspace/tx-os exec tsc --noEmit clean; architect review passed.
2026-07-09 10:04:39 +00:00
Replit Agent 86b2d64f5c Task #735: booking reference digits-only (no letters)
- makeBookingReference in artifacts/api-server/src/routes/protocol.ts now
  returns `${year}-${pad4(id)}` instead of `RB-${year}-${pad4(id)}`.
- Backfilled 7 existing dev DB rows: stripped "RB-" prefix via
  regexp_replace; verified 0 rows contain letters, unique/NOT NULL intact.
- lib/db/scripts/pre-push-cleanup.ts updated (architect-review finding):
  NULL backfill now uses digits-only format, plus a new idempotent
  normalization step that strips legacy "RB-" prefixes on every push.
- Frontend unchanged: bookingNumber() already strips non-digits; details
  card and public booking success page display the raw reference which is
  now digits-only. ilike search still works.
- tsc clean for tx-os and lib/db; API workflow restarted.
2026-07-09 09:17:43 +00:00
Replit Agent b38e2f9a90 Task #670: revamp public room-booking form (protocol)
Public booking form now captures department, meeting type (internal/
external), meeting purpose, and a repeatable "key attendees" table
(name + position + side). External meetings require the entity name
(reuses requesterOrg). "عدد الحضور" relabeled to "العدد المتوقع للحضور".
Added a static red disclaimer note about possible cancellation.

Every booking (public + internal) now gets a unique, NOT NULL, searchable
reference (RB-{year}-{pad4(id)}) shown on the success screen. Staff can
search the admin bookings list by reference OR phone.

Changes:
- lib/db schema: department, meetingType, purpose, keyAttendees (jsonb),
  bookingReference (NOT NULL + unique) + requesterPhone index; new
  enums/types. Applied via drizzle push; existing rows backfilled.
- api-server: extended public booking schema + refine (org required when
  external); reserveBookingId (nextval on the serial sequence) so the
  reference is written in a single INSERT and can never be null; GET
  /protocol/bookings accepts a `q` param filtering by reference OR phone
  (server-side, indexed, case-insensitive).
- tx-os public form rewritten; admin card shows new fields; admin search
  box now debounced and wired to the API `q` param (server-side filtering)
  with an empty state.
- ar/en i18n keys under protocol.bookings.

Deploy safety / backfill:
- lib/db pre-push-cleanup (runs before every drizzle push, dev + deploy)
  now backfills booking_reference for any pre-existing rows
  (RB-{year(created_at)}-{pad4(id)}) BEFORE the NOT NULL + unique
  constraint is enforced, so pushing the constraint on a populated table
  can never fail. Idempotent: only updates NULL rows.

Verification:
- Public booking POST returns a reference; external-without-org rejected
  (400); DB has zero null references after push. Re-running push logs
  "No protocol_room_bookings booking_reference to backfill" (idempotent).
- Pre-existing push.ts / executive-meetings.ts typecheck errors are
  unrelated to this task (files untouched).
2026-07-07 12:38:03 +00:00
riyadhafraa a8467f810b Task #148: Make pnpm --filter @workspace/db run push work without manual SQL
## Original task
`pnpm --filter @workspace/db run push` was failing with a duplicate-key
error on `app_permissions` (and a missing FK on
`executive_meeting_notifications`) because legacy data in the dev DB
violates constraints the schema now declares. Devs had to drop into psql
to fix it, which made bootstrapping painful and left
`role_permission_audit` reliant on hand-applied SQL.

## Changes
- Added `lib/db/scripts/pre-push-cleanup.ts`, an idempotent cleanup that:
  - Collapses duplicate `app_permissions` rows to one per
    `(app_id, permission_id)` so the composite PK can be added.
  - Deletes orphan `executive_meeting_notifications` rows so the new
    `ON DELETE CASCADE` FK can be added.
  - Skips both checks when the tables don't exist yet (fresh DB
    no-op).
- Wired the script into `lib/db/package.json` so both `push` and
  `push-force` run cleanup first (`pnpm run pre-push-cleanup && drizzle-kit push ...`).
- Added `tsx` to `lib/db` devDependencies (catalog version) so the
  package can run the cleanup without leaning on another workspace.
- Updated `replit.md` Deployment / Migration Runbook to reflect that
  cleanup is now automatic — no manual SQL required in any environment.

## Verification
- `pnpm --filter @workspace/db run push` now collapses 2 duplicate
  groups + removes 1978 orphan notifications, then succeeds with
  `[✓] Changes applied`.
- Re-running push is idempotent: second run reports no duplicates and
  no orphans, then succeeds.
- `pnpm --filter @workspace/db run push-force` (used by
  `scripts/post-merge.sh`) was also verified end-to-end.
- Confirmed `app_permissions` now has the composite PK,
  `executive_meeting_notifications` has the cascade FK, and
  `role_permission_audit` matches the schema.

## Notes
- A pre-existing unrelated typecheck error in
  `artifacts/api-server/src/routes/executive-meetings.ts` (font
  settings `scope` overload) was confirmed to exist on `main` before
  any changes here and is out of scope for this task.
- Proposed follow-up #213 to move from `push`/`push-force` to
  versioned `drizzle-kit migrate` so legacy-data backfills are checked
  in instead of living in a generic pre-push script.

Replit-Task-Id: 2efc4e22-0c65-48a1-b573-319474698b96
2026-04-30 12:07:19 +00:00