Files

2.5 KiB

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

return {
  success: true,
  reason: "Operation completed successfully",
  // additional fields
};

Batch Query Pattern

const items = await db
  .select()
  .from(itemTable)
  .where(inArray(itemTable.parentId, parentIds));

const itemsByParent = groupBy(items, "parentId");

Logging Pattern

logger.info("Operation completed", {
  operationId,
  userId,
  itemCount: items.length,
});

Error Pattern

if (!resource) {
  throw new ORPCError("NOT_FOUND", { message: "Resource not found" });
}