Selegic CRM Docs
ServerMiddleware & Lifecycle

Middleware List

Inventory of all request middleware and their responsibilities.

Core Middleware

sessionMiddleware

Location: lib/middleware/session.ts

Resolves user session from browser cookies:

export const sessionMiddleware: MiddlewareHandler = async (c, next) => {
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
  c.set("session", session?.session ?? null);
  c.set("user", session?.user ?? null);
  await next();
};

Sets: c.set("session", ...), c.set("user", ...)


tenantMiddleware

Location: lib/middleware/tenant.ts

Resolves organization and attaches tenant-scoped Prisma:

export const tenantMiddleware: MiddlewareHandler = async (c, next) => {
  // Handle API keys or x-tenant-id header
  // Resolve org from database
  c.set("prisma", tenantPrisma);
  c.set("org", orgSlug);
  await next();
};

Sets: c.set("prisma", ...), c.set("org", ...)


requireAuth

Location: lib/middleware/auth.ts

Simple guard that throws UnauthorizedError when no user:

export const requireAuth: MiddlewareHandler = async (c, next) => {
  const user = c.get("user");
  if (!user) {
    throw new UnauthorizedError("Authentication required");
  }
  await next();
};

lifecycleMiddleware

Location: lib/middleware/hooks.ts

Runs global lifecycle hooks:

export const lifecycleMiddleware: MiddlewareHandler = async (c, next) => {
  await lifecycleHooks.runBefore(c);
  await next();
  await lifecycleHooks.runAfter(c);
};

lifecycleMiddleware calls into:

  • lifecycleHooks.runBefore — Cross-cutting behavior (telemetry, feature flags)
  • lifecycleHooks.runAfter — Post-request processing

Registration

All middleware registered in routes/index.ts:

app.use("*", requestIdMiddleware)
   .use("*", sessionMiddleware)
   .use("*", tenantMiddleware)
   .use("*", requireAuth)
   .use("*", lifecycleMiddleware);

On this page