Files
teatea-pension/.trellis/spec/backend/quality.md

82 lines
2.5 KiB
Markdown

# Pre-commit Checklist
Run through this checklist before committing backend code.
## Type Safety
- [ ] **No non-null assertions (`!`)** - Use local variables and conditionals for type narrowing
- [ ] **All API inputs have Zod schemas** - Defined in `types.ts`
- [ ] **All API outputs have Zod schemas** - Including `success` and `reason` fields
- [ ] **Enums imported from `@your-app/utils`** - Not from database package
## Database Operations
- [ ] **No `await` in loops** - Use `inArray` for batch queries
- [ ] **Batch inserts used** - Not individual inserts in loops
- [ ] **Conflict handling considered** - Use `onConflictDoUpdate` when appropriate
- [ ] **JSON columns cast properly** - `::jsonb` for jsonb functions
- [ ] **Raw SQL column names quoted** - Double quotes for camelCase columns
## Logging
- [ ] **No `console.log`** - Use `logger` from `@your-app/logs`
- [ ] **Structured logging used** - Pass objects, not string interpolation
- [ ] **Errors logged with context** - Include relevant IDs and stack traces
- [ ] **Sensitive data excluded** - No passwords, tokens, or PII in logs
## Performance
- [ ] **Parallel execution where possible** - Use `Promise.all` for independent operations
- [ ] **Concurrency control for external APIs** - Use `p-limit` for rate-limited APIs
- [ ] **Retry logic for rate limits** - Exponential backoff implemented
- [ ] **Caching considered** - For expensive or frequently accessed data
## Error Handling
- [ ] **Errors properly caught and logged** - With Sentry context when applicable
- [ ] **Appropriate error codes returned** - `NOT_FOUND`, `FORBIDDEN`, `BAD_REQUEST`, etc.
- [ ] **Batch operations handle partial failures** - Return detailed error information
## Code Organization
- [ ] **Code in correct location** - Procedures, lib, types in right directories
- [ ] **Reusable logic extracted** - Shared code in `lib/` directory
- [ ] **Naming conventions followed** - Schemas, types, functions named correctly
## Quick Reference
### Response Format
```typescript
return {
success: true,
reason: "Operation completed successfully",
// additional fields
};
```
### Batch Query Pattern
```typescript
const items = await db
.select()
.from(itemTable)
.where(inArray(itemTable.parentId, parentIds));
const itemsByParent = groupBy(items, "parentId");
```
### Logging Pattern
```typescript
logger.info("Operation completed", {
operationId,
userId,
itemCount: items.length,
});
```
### Error Pattern
```typescript
if (!resource) {
throw new ORPCError("NOT_FOUND", { message: "Resource not found" });
}
```