import type { Request, Response, RequestHandler } from 'express'; import type { RequestContext } from './request-types.js'; /** * Context object passed to every route handler wrapped with `withRoute()`. */ export interface RouteContext { /** Original Express request */ req: Request; /** Original Express response */ res: Response; /** Request context with identity and logging */ ctx: RequestContext; /** Lowercased organization ID (guaranteed non-empty when requireOrgId is true) */ orgId: string; /** User ID from JWT (defaults to empty string) */ userId: string; } /** * Options for `withRoute()`. */ export interface WithRouteOptions { /** * Whether to require orgId on the request. * When true (default), returns 400 if orgId is missing. * Set to false for routes that don't need org context. */ requireOrgId?: boolean; } /** * Wrap an async route handler with standard boilerplate. * * Extracts context, orgId, userId from the request, validates orgId, * and catches errors. Typed `AppError` subclasses are automatically * mapped to the correct HTTP response. * * @param handler - Async function receiving a RouteContext * @param options - Configuration options * @returns Express RequestHandler * * @example * ```typescript * router.get('/:id', withRoute(async ({ req, res, ctx, orgId }) => { * const id = getParam(req.params, 'id'); * const result = await pipelineService.findById(id, orgId); * if (!result) throw new NotFoundError('Pipeline not found'); * return sendSuccess(res, 200, { pipeline: result }); * })); * ``` */ export declare function withRoute(handler: (rc: RouteContext) => Promise, options?: WithRouteOptions): RequestHandler;