Files
cfw-autumn/server/src/honoMiddlewares/baseMiddleware.ts
John Yeo 98ba9f9841 feat: Add CTE utilities and enhance platform users endpoint
## CTE Utils System
- Created comprehensive CTE (Common Table Expression) builder utilities
- Supports declarative query building with automatic relation handling
- Smart strategy selection between JOIN+GROUP BY and subquery patterns
- Handles nested relations with automatic optimization
- Type-safe query construction with Drizzle ORM

## Platform Users Enhancements
- Refactored to use new CTE utils for cleaner query building
- Added analytics middleware to Hono pipeline
- Improved query param handling with queryStringArray helper
- Changed timestamps from ISO strings to milliseconds for consistency
- Extracted cleanOrgSlug utility function

## Other Improvements
- Added analytics middleware for Hono routes
- Enhanced base middleware with better context handling
- Fixed template literal linting in initHono.ts
- Updated logger for better structured logging
- Added test files for CTE development

## File Changes
- New: server/src/db/cteUtils/ - Complete CTE builder system
- New: server/src/honoMiddlewares/analyticsMiddleware.ts
- Modified: handleListPlatformUsers.ts - Refactored with CTE utils
- Modified: platformModels.ts - Updated types and validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 17:48:10 +01:00

77 lines
1.8 KiB
TypeScript

import {
ApiVersionClass,
AppEnv,
AuthType,
LATEST_VERSION,
} from "@autumn/shared";
import type { Context, Next } from "hono";
import { db } from "@/db/initDrizzle.js";
import { ClickHouseManager } from "@/external/clickhouse/ClickHouseManager.js";
import { logger } from "@/external/logtail/logtailUtils.js";
import type { HonoEnv } from "@/honoUtils/HonoEnv.js";
import { generateId } from "@/utils/genUtils.js";
/**
* Base middleware that sets up the request context
* Sets up: db, logger, clickhouseClient, id, timestamp
*/
export const baseMiddleware = async (c: Context<HonoEnv>, next: Next) => {
// const env = (c.req.header("app_env") as AppEnv) || AppEnv.Sandbox;
const id = c.req.header("rndr-id") || generateId("local_req");
const timestamp = Date.now();
const clickhouseClient = await ClickHouseManager.getClient();
const reqContext = {
id,
// env: c.req.header("app_env") || undefined,
method: c.req.method,
url: c.req.url,
timestamp,
};
const method = c.req.method;
const path = c.req.path;
let body = null;
if (method === "POST" || method === "PUT" || method === "PATCH") {
try {
body = await c.req.json();
} catch (_error) {}
}
// Create child logger
const childLogger = logger.child({
context: {
req: reqContext,
body,
query: c.req.query(),
},
});
// Set up the request context
c.set("ctx", {
// Core objects
db,
logger: childLogger,
clickhouseClient,
// Request info
id,
timestamp,
isPublic: false,
apiVersion: new ApiVersionClass(LATEST_VERSION),
// Auth (will be populated by auth middleware)
org: undefined as any,
features: [],
userId: undefined,
authType: AuthType.Unknown,
env: AppEnv.Sandbox, // maybe use app_env headers
});
childLogger.info(`${method} ${path}`);
await next();
};