Feature Builder¶
Implements complete features full-stack (backend + frontend + tests).
Overview¶
| Attribute | Value |
|---|---|
| Name | feature-builder |
| Type | Implementation skill |
| Triggers | "implement feature", "build functionality", "add feature" |
| Output | Working feature code |
| Location | .claude/skills/feature-builder/ |
What It Does¶
The Feature Builder implements features end-to-end:
- Reads Gherkin scenarios - Understands acceptance criteria
- Creates backend endpoints - API routes, validation, logic
- Builds frontend UI - Components, forms, state
- Writes tests - Unit, integration tests
- Verifies against scenarios - Ensures criteria are met
Implementation Process¶
Step 1: Understand Requirements¶
Reads from:
- Gherkin scenarios (features/*.feature)
- Discovery document
- Existing code structure
Step 2: Backend Implementation¶
Creates/modifies: - Controller endpoints - Service business logic - DTOs for validation - Database queries
// src/extensions/Project/Project.controller.ts
@Controller('projects')
export class ProjectController {
@Post(':id/archive')
async archive(@Param('id') id: string) {
return this.projectService.archive(id);
}
}
// src/extensions/Project/Project.service.ts
@Injectable()
export class ProjectService {
async archive(id: string) {
const project = await this.findOne(id);
await this.taskService.archiveByProject(id);
return this.update(id, { status: 'archived' });
}
}
Step 3: Frontend Implementation¶
Creates/modifies: - Page components - Form handling - API integration - State management
// app/projects/[id]/page.tsx
export default async function ProjectPage({ params }) {
const project = await getProject(params.id);
return (
<div>
<ProjectHeader project={project} />
<TaskList projectId={params.id} />
<ArchiveButton projectId={params.id} />
</div>
);
}
Step 4: Test Implementation¶
Creates: - Step definitions - Unit tests - Integration tests
// tests/unit/project.service.spec.ts
describe('ProjectService', () => {
describe('archive', () => {
it('should archive project and all tasks', async () => {
const result = await service.archive('project-1');
expect(result.status).toBe('archived');
expect(taskService.archiveByProject).toHaveBeenCalled();
});
});
});
Step 5: Verification¶
Runs scenarios to verify:
Feature Types¶
CRUD Feature¶
For basic entity management: - List view with pagination - Detail view - Create form - Edit form - Delete confirmation
Workflow Feature¶
For multi-step processes: - State machine logic - Step-by-step UI - Progress tracking - Validation at each step
Integration Feature¶
For external systems: - API client setup - Webhook handlers - Error handling - Retry logic
File Locations¶
| Type | Backend Location | Frontend Location |
|---|---|---|
| Controller | src/extensions/Entity/ |
- |
| Service | src/extensions/Entity/ |
- |
| Page | - | app/entity/page.tsx |
| Component | - | components/entity/ |
| Test | test/ |
__tests__/ |
Code Patterns¶
Backend Service Pattern¶
@Injectable()
export class FeatureService {
constructor(
private entityRepo: EntityRepository,
private relatedService: RelatedService,
) {}
async create(dto: CreateDto): Promise<Entity> {
// Validate business rules
await this.validateRules(dto);
// Create entity
const entity = await this.entityRepo.create(dto);
// Side effects
await this.relatedService.onEntityCreated(entity);
return entity;
}
}
Frontend Form Pattern¶
'use client';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
export function CreateForm() {
const form = useForm({
resolver: zodResolver(schema),
defaultValues: { name: '', status: 'active' },
});
const onSubmit = async (data) => {
await createEntity(data);
router.push('/entities');
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* Form fields */}
</form>
</Form>
);
}
Validation Against Scenarios¶
The feature builder ensures code matches Gherkin:
Scenario: Create project with valid data
Given I am authenticated
When I create a project with name "My Project"
Then the project is created
And I see "Project created successfully"
↓ Becomes ↓
// Backend validates and creates
async create(dto) {
if (!dto.name) throw new ValidationError('Name required');
return this.repo.create(dto);
}
// Frontend shows success
const onSubmit = async (data) => {
await api.createProject(data);
toast.success('Project created successfully');
};
Invocation¶
Via Orchestrator¶
Called during Phase 8+ of /start-project for each feature.
Via Natural Language¶
"Implement the project archive feature"
"Build the user settings page"
"Add comments functionality to tasks"
Tips¶
Do¶
- Read scenarios before implementing
- Follow existing patterns
- Put code in
extensions/(notautogen/) - Write tests alongside code
- Verify with Gherkin after
Don't¶
- Modify
autogen/files - Skip validation
- Ignore error cases
- Forget multi-tenancy (
organization_id)
Related¶
- Test Generator (creates scenarios)
- Backend Bootstrapper (base structure)
- Schema Architect (data model)