8.7 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.
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:
- Add route in
src/routes/{domain}.routes.ts - Use
validateRequest(schema)middleware for input validation - Call service layer (never access DB directly from routes)
- Return via
sendSuccess()orsendPaginated() - 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:
- Add method to
src/services/db/{domain}.db.ts - Follow naming:
get*(throws),find*(returns null),list*(array) - Use
handleDbError()for error handling - Accept optional
PoolClientfor transaction support - 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:
- Create component in
src/components/or feature-specific folder - Follow Neo-Brutalism design patterns (ADR-012)
- Use existing design tokens from
src/styles/ - 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
anytypes 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 setupsql/initial_schema.sql- Fresh install schemasql/migrations/*.sql- Production changes
Working with the Coder Subagent
Before Starting
- Identify the scope - What exactly needs to change?
- Check existing patterns - Is there similar code to follow?
- Consider tests - Will you need the testwriter subagent too?
During Development
- Review changes incrementally - Don't wait until the end
- Ask for explanations - Understand why certain approaches are chosen
- Provide feedback - Tell the coder if something doesn't look right
After Completion
- Run tests in the dev container
- Run type-check:
npm run type-check - Review the changes before committing
- 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:
- Ask the coder to include tests: "Include unit tests for all new code"
- 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.
Related Documentation
- OVERVIEW.md - Subagent system overview
- TESTER-GUIDE.md - Testing strategies
- ../adr/0034-repository-pattern-standards.md - Repository patterns
- ../adr/0035-service-layer-architecture.md - Service layer architecture
- ../adr/0028-api-response-standardization.md - API response patterns