Files
flyer-crawler.projectium.com/docs/subagents/CODER-GUIDE.md
Torben Sorensen 45ac4fccf5
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 2m15s
comprehensive documentation review + test fixes
2026-01-28 16:35:38 -08:00

10 KiB

Coder Subagent Guide

The coder subagent is your primary tool for writing and modifying production Node.js/TypeScript code in the Flyer Crawler project. This guide explains how to work effectively with the coder subagent.

Quick Reference

Aspect Details
Primary Use Write/modify production TypeScript code
Key Files src/routes/*.routes.ts, src/services/**/*.ts, src/components/*.tsx
Key ADRs ADR-034 (Repository), ADR-035 (Services), ADR-028 (API Response)
Test Command podman exec -it flyer-crawler-dev npm run test:unit
Type Check podman exec -it flyer-crawler-dev npm run type-check
Delegate To db-dev (database), frontend-specialist (UI), testwriter (tests)

When to Use the Coder Subagent

Use the coder subagent when you need to:

  • Implement new features or functionality
  • Fix bugs in existing code
  • Refactor existing code
  • Add new API endpoints
  • Create new React components
  • Write service layer logic
  • Implement business rules

What the Coder Subagent Knows

The coder subagent has deep knowledge of:

Project Architecture

Routes -> Services -> Repositories -> Database
            |
       External APIs (*.server.ts)
  • Routes Layer: Request/response handling, validation, authentication
  • Services Layer: Business logic, transaction coordination, external APIs
  • Repositories Layer: Database access, query construction, error translation

Key Patterns

Pattern ADR Implementation
Error Handling ADR-001 handleDbError(), throw NotFoundError
Repository Methods ADR-034 get* throws, find* returns null, list* returns array
API Responses ADR-028 sendSuccess(), sendPaginated(), sendError()
Transactions ADR-002 withTransaction(async (client) => {...})

File Naming Conventions

Pattern Location Purpose
*.db.ts src/services/db/ Database repositories
*.server.ts src/services/ Server-only code (external APIs)
*.routes.ts src/routes/ Express route handlers
*.test.ts Colocated Unit tests

How to Request Code Changes

Good Request Examples

Specific and contextual:

"Use the coder subagent to add a new endpoint GET /api/stores/:id/locations
that returns all locations for a store, following the existing patterns
in stores.routes.ts"

With acceptance criteria:

"Use the coder subagent to implement the shopping list sharing feature:
- Add a share_token column to shopping_lists table
- Create POST /api/shopping-lists/:id/share endpoint
- Return a shareable link with the token
- Allow anonymous users to view shared lists"

Bug fix with reproduction steps:

"Use the coder subagent to fix the issue where flyer items are not
sorted by price on the deals page. The expected behavior is lowest
price first, but currently they appear in insertion order."

Less Effective Request Examples

Too vague:

"Make the code better"

Missing context:

"Add a feature to search things"

Multiple unrelated tasks:

"Fix the login bug, add a new table, and update the homepage"

Common Workflows

Adding a New API Endpoint

The coder subagent will follow this workflow:

  1. Add route in src/routes/{domain}.routes.ts
  2. Use validateRequest(schema) middleware for input validation
  3. Call service layer (never access DB directly from routes)
  4. Return via sendSuccess() or sendPaginated()
  5. Add tests in *.routes.test.ts

Example Code Pattern:

// src/routes/stores.routes.ts
router.get('/:id/locations', validateRequest(getStoreLocationsSchema), async (req, res, next) => {
  try {
    const { id } = req.params;
    const locations = await storeService.getLocationsForStore(parseInt(id, 10), req.log);
    sendSuccess(res, { locations });
  } catch (error) {
    next(error);
  }
});

Adding a New Database Operation

The coder subagent will:

  1. Add method to src/services/db/{domain}.db.ts
  2. Follow naming: get* (throws), find* (returns null), list* (array)
  3. Use handleDbError() for error handling
  4. Accept optional PoolClient for transaction support
  5. Add unit test

Example Code Pattern:

// src/services/db/store.db.ts
export async function listLocationsByStoreId(
  storeId: number,
  client?: PoolClient,
): Promise<StoreLocation[]> {
  const queryable = client || getPool();
  try {
    const result = await queryable.query<StoreLocation>(
      `SELECT * FROM store_locations WHERE store_id = $1 ORDER BY created_at`,
      [storeId],
    );
    return result.rows;
  } catch (error) {
    handleDbError(
      error,
      log,
      'Database error in listLocationsByStoreId',
      { storeId },
      {
        entityName: 'StoreLocation',
        defaultMessage: 'Failed to list store locations.',
      },
    );
  }
}

Adding a New React Component

The coder subagent will:

  1. Create component in src/components/ or feature-specific folder
  2. Follow Neo-Brutalism design patterns (ADR-012)
  3. Use existing design tokens from src/styles/
  4. Add unit tests using Testing Library

Example Code Pattern:

// src/components/StoreCard.tsx
import { Store } from '@/types';

interface StoreCardProps {
  store: Store;
  onSelect?: (store: Store) => void;
}

export function StoreCard({ store, onSelect }: StoreCardProps) {
  return (
    <div
      className="brutal-card p-4 cursor-pointer hover:translate-x-1 hover:-translate-y-1 transition-transform"
      onClick={() => onSelect?.(store)}
    >
      <h3 className="text-lg font-bold">{store.name}</h3>
      <p className="text-sm text-gray-600">{store.location_count} locations</p>
    </div>
  );
}

Code Quality Standards

The coder subagent adheres to these standards:

TypeScript

  • Strict TypeScript mode enabled
  • No any types unless absolutely necessary
  • Explicit return types for functions
  • Proper interface/type definitions

Error Handling

  • Use custom error classes from src/services/db/errors.db.ts
  • Never swallow errors silently
  • Log errors with appropriate context
  • Return meaningful error messages to API consumers

Logging

  • Use Pino logger (src/services/logger.server.ts)
  • Include module context in log child
  • Log at appropriate levels (info, warn, error)
  • Include relevant data in structured format

Testing

  • All new code should have corresponding tests
  • Follow testing patterns in ADR-010
  • Use mock factories from src/tests/utils/mockFactories.ts
  • Run tests in the dev container

Platform Considerations

Linux-Only Development

The coder subagent knows that this application runs exclusively on Linux:

  • Uses POSIX-style paths (/)
  • Assumes Linux shell commands
  • References dev container environment

Important: Any code changes should be tested in the dev container:

podman exec -it flyer-crawler-dev npm run test:unit

Database Schema Synchronization

When the coder subagent modifies database-related code, it will remind you:

Schema files must stay synchronized:

  • sql/master_schema_rollup.sql - Test DB setup
  • sql/initial_schema.sql - Fresh install schema
  • sql/migrations/*.sql - Production changes

Working with the Coder Subagent

Before Starting

  1. Identify the scope - What exactly needs to change?
  2. Check existing patterns - Is there similar code to follow?
  3. Consider tests - Will you need the testwriter subagent too?

During Development

  1. Review changes incrementally - Don't wait until the end
  2. Ask for explanations - Understand why certain approaches are chosen
  3. Provide feedback - Tell the coder if something doesn't look right

After Completion

  1. Run tests in the dev container
  2. Run type-check: npm run type-check
  3. Review the changes before committing
  4. Consider code review with the code-reviewer subagent

Common Issues and Solutions

Issue: Code Doesn't Follow Project Patterns

Solution: Provide examples of existing code that follows the desired pattern. The coder will align with it.

Issue: Missing Error Handling

Solution: Explicitly request comprehensive error handling:

"Include proper error handling using handleDbError and the project's
error classes for all database operations"

Issue: Tests Not Included

Solution: Either:

  1. Ask the coder to include tests: "Include unit tests for all new code"
  2. Use the testwriter subagent separately for comprehensive test coverage

Issue: Code Works on Windows but Fails on Linux

Solution: Always test in the dev container. The coder subagent writes Linux-compatible code, but IDE tooling might behave differently.