doc updates and test fixin
This commit is contained in:
310
docs/subagents/CODER-GUIDE.md
Normal file
310
docs/subagents/CODER-GUIDE.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# 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:
|
||||
|
||||
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
|
||||
- [../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
|
||||
Reference in New Issue
Block a user