Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 2m15s
326 lines
10 KiB
Markdown
326 lines
10 KiB
Markdown
# 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:**
|
|
|
|
```typescript
|
|
// 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:**
|
|
|
|
```typescript
|
|
// 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:**
|
|
|
|
```typescript
|
|
// 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:
|
|
|
|
```bash
|
|
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.
|
|
|
|
## Related Documentation
|
|
|
|
- [OVERVIEW.md](./OVERVIEW.md) - Subagent system overview
|
|
- [TESTER-GUIDE.md](./TESTER-GUIDE.md) - Testing strategies
|
|
- [DATABASE-GUIDE.md](./DATABASE-GUIDE.md) - Database development workflows
|
|
- [../adr/0034-repository-pattern-standards.md](../adr/0034-repository-pattern-standards.md) - Repository patterns
|
|
- [../adr/0035-service-layer-architecture.md](../adr/0035-service-layer-architecture.md) - Service layer architecture
|
|
- [../adr/0028-api-response-standardization.md](../adr/0028-api-response-standardization.md) - API response patterns
|
|
- [../development/CODE-PATTERNS.md](../development/CODE-PATTERNS.md) - Code patterns reference
|