Task #521: shorten meetings page URL to /meetings
- artifacts/tx-os/src/App.tsx: serve the schedule at /meetings; add an ExecutiveMeetingsRedirect that rewrites /executive-meetings (and any /executive-meetings/* sub-path) to /meetings while preserving the query string and hash, so existing PDFs, emails, and bookmarks keep working with one transparent hop. - scripts/src/seed.ts: seed the apps row with route="/meetings" and update the expectedBuiltinRoutes drift guard to match. Add an idempotent UPDATE-by-slug after the apps insert so already-deployed rows (including any drift like /executive-meetings or /mms) get reconciled to /meetings on the next seed — safe because the slug is in BUILTIN_APP_SLUGS, meaning the SPA owns the route. - artifacts/tx-os/tests/meetings-route-redirect.spec.mjs: new spec verifying that /meetings loads, /executive-meetings?date=...#... is redirected with query+hash intact, and /api/apps now reports route="/meetings" for the executive-meetings slug. Out of scope (intentionally left untouched per task): API paths under /api/executive-meetings/*, React Query keys, DB tables, the apps slug "executive-meetings", page/component file names, the "Meetings" display name, and the executive_meetings:* permission name.
This commit is contained in:
+15
-2
@@ -218,7 +218,7 @@ async function main() {
|
||||
descriptionAr: "جدولة اجتماعات المكتب التنفيذي ومتابعتها",
|
||||
descriptionEn: "Schedule and track executive office meetings",
|
||||
iconName: "CalendarClock",
|
||||
route: "/executive-meetings",
|
||||
route: "/meetings",
|
||||
color: "#0B1E3F",
|
||||
isActive: true,
|
||||
isSystem: false,
|
||||
@@ -239,7 +239,7 @@ async function main() {
|
||||
notes: "/notes",
|
||||
"my-orders": "/my-orders",
|
||||
"orders-incoming": "/orders/incoming",
|
||||
"executive-meetings": "/executive-meetings",
|
||||
"executive-meetings": "/meetings",
|
||||
calendar: "/calendar",
|
||||
documents: "/documents",
|
||||
};
|
||||
@@ -258,6 +258,19 @@ async function main() {
|
||||
const insertedApps = await db.insert(appsTable).values(apps).onConflictDoNothing().returning();
|
||||
console.log("Apps created");
|
||||
|
||||
// Force the executive-meetings row onto the canonical /meetings route.
|
||||
// The slug is in BUILTIN_APP_SLUGS, so the SPA owns its route — any
|
||||
// drift in the DB (including legacy /executive-meetings or other
|
||||
// experimental values) would launch the home tile at a path that
|
||||
// has no React route and silently break the app. `onConflictDoNothing`
|
||||
// above skips updating existing rows, so this UPDATE is what carries
|
||||
// the route migration into already-deployed environments. The WHERE
|
||||
// by slug keeps it idempotent across re-seeds.
|
||||
await db
|
||||
.update(appsTable)
|
||||
.set({ route: "/meetings" })
|
||||
.where(eq(appsTable.slug, "executive-meetings"));
|
||||
|
||||
// Restrict admin app to users with apps:manage permission
|
||||
const allPerms = await db.select().from(permissionsTable);
|
||||
const appsManagePerm = allPerms.find((p) => p.name === "apps:manage");
|
||||
|
||||
Reference in New Issue
Block a user