|
| 1 | +# Feature Development Checklist |
| 2 | + |
| 3 | +Use this checklist when adding new features to Forest to ensure CLI/API parity. |
| 4 | + |
| 5 | +## Pre-Implementation |
| 6 | + |
| 7 | +- [ ] Define feature requirements clearly |
| 8 | +- [ ] Identify where the feature should be accessible (CLI only, API only, or both?) |
| 9 | +- [ ] Design the core function signature and return types |
| 10 | +- [ ] Plan error cases and validation |
| 11 | + |
| 12 | +## Implementation Order |
| 13 | + |
| 14 | +### 1. Core Business Logic |
| 15 | +- [ ] Create or update function in `src/core/*.ts` |
| 16 | + - [ ] Function is pure (no I/O formatting, no HTTP/CLI dependencies) |
| 17 | + - [ ] Returns typed data structures |
| 18 | + - [ ] Handles all business validation |
| 19 | + - [ ] Includes comprehensive error handling |
| 20 | + - [ ] Well-documented with JSDoc comments |
| 21 | + |
| 22 | +### 2. REST API (if applicable) |
| 23 | +- [ ] Create or update route in `src/server/routes/*.ts` |
| 24 | + - [ ] Calls core function (no business logic duplication) |
| 25 | + - [ ] Parses and validates query parameters/request body |
| 26 | + - [ ] Uses helper functions from `src/server/utils/helpers.ts` |
| 27 | + - [ ] Returns standard envelope format via `createSuccessResponse()` |
| 28 | + - [ ] Handles errors with `ForestError` classes |
| 29 | + - [ ] Sets appropriate HTTP status codes |
| 30 | + - [ ] Includes Swagger/OpenAPI documentation tags |
| 31 | +- [ ] Register route in `src/server/index.ts` |
| 32 | + - [ ] Import route module |
| 33 | + - [ ] Add `.use()` call to app |
| 34 | + - [ ] Add tag to Swagger documentation config |
| 35 | + |
| 36 | +### 3. CLI Command (if applicable) |
| 37 | +- [ ] Create or update command in `src/cli/commands/*.ts` |
| 38 | + - [ ] Calls core function (no business logic duplication) |
| 39 | + - [ ] Parses command-line arguments and flags |
| 40 | + - [ ] Provides human-readable text output (default) |
| 41 | + - [ ] Provides machine-readable JSON output (with `--json` flag) |
| 42 | + - [ ] Uses utilities from `src/cli/shared/utils.ts` |
| 43 | + - [ ] Handles errors with `handleError()` |
| 44 | +- [ ] Register command in `src/cli/index.ts` |
| 45 | + - [ ] Import command factory |
| 46 | + - [ ] Call `cli.command(createYourCommand(clerc))` |
| 47 | + |
| 48 | +### 4. Documentation |
| 49 | +- [ ] Update `CLAUDE.md` |
| 50 | + - [ ] Add command to command structure list (if new command) |
| 51 | + - [ ] Document any new patterns or utilities |
| 52 | + - [ ] Update examples if needed |
| 53 | +- [ ] Update README.md (if user-facing) |
| 54 | +- [ ] Add inline code comments for complex logic |
| 55 | + |
| 56 | +### 5. Testing |
| 57 | +- [ ] Test core function independently |
| 58 | + - [ ] Happy path with valid inputs |
| 59 | + - [ ] Error cases and edge cases |
| 60 | + - [ ] Boundary conditions |
| 61 | +- [ ] Test API endpoint (if applicable) |
| 62 | + - [ ] Valid requests return expected responses |
| 63 | + - [ ] Invalid requests return appropriate errors |
| 64 | + - [ ] Pagination works correctly (if applicable) |
| 65 | + - [ ] Filtering works correctly (if applicable) |
| 66 | + - [ ] Response format matches standard envelope |
| 67 | +- [ ] Test CLI command (if applicable) |
| 68 | + - [ ] Valid arguments produce expected output |
| 69 | + - [ ] Invalid arguments show helpful errors |
| 70 | + - [ ] Both text and JSON output formats work |
| 71 | + - [ ] Help text is clear and accurate |
| 72 | + |
| 73 | +### 6. Validation |
| 74 | +- [ ] CLI and API produce identical results for equivalent inputs |
| 75 | +- [ ] Error messages are consistent between CLI and API |
| 76 | +- [ ] Feature behavior is documented |
| 77 | +- [ ] No duplicate business logic between layers |
| 78 | + |
| 79 | +## Architecture Compliance |
| 80 | + |
| 81 | +### ✅ Good Patterns |
| 82 | +- Core function contains all business logic |
| 83 | +- CLI command calls core function, only handles formatting |
| 84 | +- API route calls core function, only handles HTTP concerns |
| 85 | +- Validation happens in both route/command AND core function |
| 86 | +- Errors use typed error classes (`ForestError` hierarchy) |
| 87 | + |
| 88 | +### ❌ Anti-Patterns to Avoid |
| 89 | +- Business logic implemented in CLI command or API route |
| 90 | +- Different validation logic in CLI vs API |
| 91 | +- Different error handling in CLI vs API |
| 92 | +- Direct database access from routes/commands (should go through core) |
| 93 | +- Copy-pasted code between CLI and API |
| 94 | + |
| 95 | +## Example: Semantic Search Feature |
| 96 | + |
| 97 | +**Core Function** (`src/core/search.ts`): |
| 98 | +```typescript |
| 99 | +export async function semanticSearchCore( |
| 100 | + query: string, |
| 101 | + options: SemanticSearchOptions = {}, |
| 102 | +): Promise<SemanticSearchResult> |
| 103 | +``` |
| 104 | + |
| 105 | +**API Route** (`src/server/routes/search.ts`): |
| 106 | +```typescript |
| 107 | +app.get('/api/v1/search/semantic', async ({ query }) => { |
| 108 | + const result = await semanticSearchCore(query.q, { ... }); |
| 109 | + return createSuccessResponse({ nodes: result.nodes, ... }); |
| 110 | +}); |
| 111 | +``` |
| 112 | + |
| 113 | +**CLI Command** (`src/cli/commands/search.ts`): |
| 114 | +```typescript |
| 115 | +export function createSearchCommand(clerc) { |
| 116 | + return clerc.defineCommand({ name: 'search' }, async ({ flags }) => { |
| 117 | + const result = await semanticSearchCore(flags.query, { ... }); |
| 118 | + printTextResults(result); // or JSON.stringify for --json |
| 119 | + }); |
| 120 | +} |
| 121 | +``` |
| 122 | + |
| 123 | +## Notes |
| 124 | + |
| 125 | +- If a feature only makes sense in one interface (CLI or API), that's okay! Not everything needs to be in both. |
| 126 | +- When in doubt, put logic in the core layer. It's easier to extract than to consolidate later. |
| 127 | +- Keep the API and CLI in sync by always implementing both at the same time when appropriate. |
0 commit comments