feat(portal): replace mock data with real session-driven API calls (#152)
Closes GRO-205. Reviewed and approved by CTO (The Dogfather) and QA (Lint Roller). cc @cpfarhood
This commit was merged in pull request #152.
This commit is contained in:
committed by
GitHub
parent
3834e45b66
commit
4746a63292
+20
-3
@@ -19,9 +19,10 @@ import { impersonationRouter } from "./routes/impersonation.js";
|
||||
import { settingsRouter } from "./routes/settings.js";
|
||||
import { searchRouter } from "./routes/search.js";
|
||||
import { calendarRouter } from "./routes/calendar.js";
|
||||
import { getDb, businessSettings } from "@groombook/db";
|
||||
import { setupRouter } from "./routes/setup.js";
|
||||
import { getDb, businessSettings, eq, staff } from "@groombook/db";
|
||||
import { authMiddleware } from "./middleware/auth.js";
|
||||
import { resolveStaffMiddleware, requireRole } from "./middleware/rbac.js";
|
||||
import { resolveStaffMiddleware, requireRole, requireRoleOrSuperUser, requireSuperUser } from "./middleware/rbac.js";
|
||||
import { devRouter } from "./routes/dev.js";
|
||||
import { adminSeedRouter } from "./routes/admin/seed.js";
|
||||
import { startReminderScheduler } from "./services/reminders.js";
|
||||
@@ -67,6 +68,17 @@ app.get("/api/branding", async (c) => {
|
||||
// Public iCal calendar feed — token auth in URL, no auth middleware required
|
||||
app.route("/api/calendar", calendarRouter);
|
||||
|
||||
// Public setup status — no auth required, must be registered before auth middleware
|
||||
app.get("/api/setup/status", async (c) => {
|
||||
const db = getDb();
|
||||
const [superUser] = await db
|
||||
.select({ id: staff.id })
|
||||
.from(staff)
|
||||
.where(eq(staff.isSuperUser, true))
|
||||
.limit(1);
|
||||
return c.json({ needsSetup: !superUser });
|
||||
});
|
||||
|
||||
// Protected API routes
|
||||
const api = app.basePath("/api");
|
||||
api.use("*", authMiddleware);
|
||||
@@ -82,8 +94,10 @@ api.route("/auth", authRouter);
|
||||
// Manager-only: admin settings, reports, invoices, impersonation
|
||||
// Staff CRUD: all roles may READ; manager-only for CREATE/UPDATE/DELETE
|
||||
api.on(["GET"], "/staff/*", requireRole("manager", "receptionist", "groomer"));
|
||||
api.use("/staff/*", requireRole("manager"));
|
||||
// Staff write routes: manager OR super-user (combined guard — avoids AND stacking)
|
||||
api.on(["POST", "PATCH", "DELETE"], "/staff/*", requireRoleOrSuperUser("manager"));
|
||||
api.use("/admin/*", requireRole("manager"));
|
||||
api.use("/admin/settings/*", requireSuperUser());
|
||||
api.use("/reports/*", requireRole("manager"));
|
||||
api.use("/invoices/*", requireRole("manager"));
|
||||
api.use("/impersonation/*", requireRole("manager"));
|
||||
@@ -123,6 +137,9 @@ api.on(
|
||||
);
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// Setup: POST /api/setup (authenticated) — requires staff context from auth middleware
|
||||
api.route("/setup", setupRouter);
|
||||
|
||||
api.route("/clients", clientsRouter);
|
||||
api.route("/pets", petsRouter);
|
||||
api.route("/services", servicesRouter);
|
||||
|
||||
Reference in New Issue
Block a user