Skip to content

Commit 699bbfd

Browse files
feat(log): Add wrapper function for standardized logging (#4061)
* feat(log): Add wrapper function for standardized logging * Add all routes to wrapper, handle background execution * fix lint * fix test * fix test missing url * fix lint * fix tests * fix build * fix(build): unmangle generic in admin outbox requeue route Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0e1ff0a commit 699bbfd

File tree

690 files changed

+24151
-22590
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

690 files changed

+24151
-22590
lines changed

.claude/rules/global.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Global Standards
22

33
## Logging
4-
Import `createLogger` from `sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`.
4+
Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`. Inside API routes wrapped with `withRouteHandler`, loggers automatically include the request ID.
5+
6+
## API Route Handlers
7+
All API route handlers must be wrapped with `withRouteHandler` from `@/lib/core/utils/with-route-handler`. Never export a bare `async function GET/POST/...` — always use `export const METHOD = withRouteHandler(...)`.
58

69
## Comments
710
Use TSDoc for documentation. No `====` separators. No non-TSDoc comments.

CLAUDE.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ You are a professional software engineer. All code must follow best practices: a
44

55
## Global Standards
66

7-
- **Logging**: Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`
7+
- **Logging**: Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`. Inside API routes wrapped with `withRouteHandler`, loggers automatically include the request ID — no manual `withMetadata({ requestId })` needed
8+
- **API Route Handlers**: All API route handlers (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) must be wrapped with `withRouteHandler` from `@/lib/core/utils/with-route-handler`. This provides request ID tracking, automatic error logging for 4xx/5xx responses, and unhandled error catching. See "API Route Pattern" section below
89
- **Comments**: Use TSDoc for documentation. No `====` separators. No non-TSDoc comments
910
- **Styling**: Never update global styles. Keep all styling local to components
1011
- **ID Generation**: Never use `crypto.randomUUID()`, `nanoid`, or `uuid` package. Use `generateId()` (UUID v4) or `generateShortId()` (compact) from `@sim/utils/id`
@@ -93,6 +94,41 @@ export function Component({ requiredProp, optionalProp = false }: ComponentProps
9394

9495
Extract when: 50+ lines, used in 2+ files, or has own state/logic. Keep inline when: < 10 lines, single use, purely presentational.
9596

97+
## API Route Pattern
98+
99+
Every API route handler must be wrapped with `withRouteHandler`. This sets up `AsyncLocalStorage`-based request context so all loggers in the request lifecycle automatically include the request ID.
100+
101+
```typescript
102+
import { createLogger } from '@sim/logger'
103+
import type { NextRequest } from 'next/server'
104+
import { NextResponse } from 'next/server'
105+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
106+
107+
const logger = createLogger('MyAPI')
108+
109+
// Simple route
110+
export const GET = withRouteHandler(async (request: NextRequest) => {
111+
logger.info('Handling request') // automatically includes {requestId=...}
112+
return NextResponse.json({ ok: true })
113+
})
114+
115+
// Route with params
116+
export const DELETE = withRouteHandler(async (
117+
request: NextRequest,
118+
{ params }: { params: Promise<{ id: string }> }
119+
) => {
120+
const { id } = await params
121+
return NextResponse.json({ deleted: id })
122+
})
123+
124+
// Composing with other middleware (withRouteHandler wraps the outermost layer)
125+
export const POST = withRouteHandler(withAdminAuth(async (request) => {
126+
return NextResponse.json({ ok: true })
127+
}))
128+
```
129+
130+
Never export a bare `async function GET/POST/...` — always use `export const METHOD = withRouteHandler(...)`.
131+
96132
## Hooks
97133

98134
```typescript

0 commit comments

Comments
 (0)