# Add Feature

> Adds a full vertical feature slice (Domain entity, Application layer, EF migration, API endpoints, React feature folder, routes, and tests) to an existing dotnet-vite-webapp-template app, mirroring features/auth. Use when the user invokes /add-feature, asks to add a new feature/module, or wants end-to-end CRUD or domain functionality in the webapp template.

- Skill: `manifold-works/add-feature` (Agent Skill)
- Install (CLI): `npx skillmds@latest add manifold-works/add-feature`
- Raw SKILL.md: https://api.skillmd.com/api/skills/manifold-works/add-feature/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Manifold-Works (https://skillmd.com/u/manifold-works)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/manifold-works/add-feature

---


# Add Feature

Primary extension path: backend + frontend + migration + tests in one slice.

**Read first:** [`~/.cursor/skills/webapp-shared/reference.md`](../webapp-shared/reference.md)

**Mirror:** `backend/` auth slice + `frontend/src/features/auth/` — do not invent new architecture.

## Prerequisites

- [ ] App already scaffolded (via `create-webapp` or manual clone + rename)
- [ ] Docker Compose running or host SDK available
- [ ] Working tree is the renamed app (not literal `AppName`)

## Gather inputs

| Input | Example | Notes |
|-------|---------|-------|
| Feature name | `Todos` | PascalCase backend; kebab/camel frontend |
| Entity fields | `Title: string`, `IsDone: bool` | Ask for types and required/optional |
| Operations | list, get, create, update, delete | Default CRUD unless user specifies |
| Auth | required / public | Default: `[Authorize]` like `/api/me` |

## Checklist

```
Add-feature progress:
- [ ] 1. Domain entity
- [ ] 2. Application (DTOs, interface, service)
- [ ] 3. Infrastructure (EF config, DbSet, implementation)
- [ ] 4. API endpoints under /api/{feature}
- [ ] 5. EF migration
- [ ] 6. Frontend feature folder + API client
- [ ] 7. Routes + pages in src/app
- [ ] 8. Backend + frontend tests
- [ ] 9. Smoke via Compose
```

## Step 1: Domain

Create `backend/src/{App}.Domain/Entities/{Entity}.cs`:

- Properties with private setters or init as per existing entities
- No EF or ASP.NET references
- Follow `RefreshToken.cs` style for conventions

## Step 2: Application

In `backend/src/{App}.Application/`:

- DTOs: `{Feature}Dtos.cs` (request/response records)
- Abstraction: `I{Feature}Service.cs` in `Abstractions/`
- Service logic in `{Feature}/{Feature}Service.cs` or feature folder

Application references **Domain only**.

## Step 3: Infrastructure

In `backend/src/{App}.Infrastructure/`:

- Add `DbSet<{Entity}>` to `Persistence/AppDbContext.cs`
- EF configuration (fluent API or attributes) in `Persistence/Configurations/` if used
- Implement `I{Feature}Service` in `{Feature}/`
- Register in `DependencyInjection.cs`: `services.AddScoped<I{Feature}Service, {Feature}Service>()`

## Step 4: API endpoints

In `backend/src/{App}.Api/Program.cs` (or dedicated endpoint file if template uses one):

- Map routes under `/api/{kebab-feature}` e.g. `/api/todos`
- Use minimal APIs matching auth style: try/catch, proper status codes
- Apply `[Authorize]` unless feature is public
- Validate input; return `{ error: "..." }` on bad requests like auth endpoints

Example shape:

```
GET    /api/todos       → list
GET    /api/todos/{id}  → get
POST   /api/todos       → create
PUT    /api/todos/{id}  → update
DELETE /api/todos/{id}  → delete
```

## Step 5: Migration

Follow `add-migration` skill or:

```bash
cd backend
dotnet ef migrations add Add{Entity} \
  --project src/{App}.Infrastructure \
  --startup-project src/{App}.Api \
  --output-dir Persistence/Migrations
```

Restart `api` container or run `database update`. Dev auto-applies on next API start.

## Step 6: Frontend feature

Create `frontend/src/features/{feature}/`:

| File | Purpose |
|------|---------|
| `{feature}Api.ts` | Typed fetch wrappers using shared HTTP client |
| `types.ts` | TS interfaces matching DTOs |
| `pages/` | List, detail, form components |
| `components/` | Feature-specific UI |

Use `frontend/src/shared/` HTTP client — it handles Bearer token + refresh. **Do not** store access tokens in `localStorage`.

Mirror `features/auth/` for error handling and loading states.

## Step 7: Routes

In `frontend/src/app/` router:

- Add routes for feature pages
- Protect routes with auth guard if backend requires authorization
- Add navigation link in layout if appropriate

## Step 8: Tests

**Backend** (`backend/tests/`):

- Domain/Application unit tests for service rules
- Api integration test: create entity via HTTP, assert response (mirror auth tests in `AppName.Api.Tests`)

**Frontend** (`frontend/tests/` or colocated):

- Vitest + Testing Library smoke test for main page render
- Mock API or use MSW if template provides it

## Step 9: Verify

```bash
docker compose up -d --build api web   # if code changed
cd backend && dotnet test
cd frontend && npm test -- --run
# Manual: exercise new UI at http://localhost:5173
```

## Layer rules (enforce)

| Layer | Allowed references |
|-------|-------------------|
| Domain | none |
| Application | Domain |
| Infrastructure | Application, Domain |
| Api | Application, Infrastructure |

## Do not

- Put EF or HTTP types in Domain/Application
- Create parallel folder structures outside `features/` on frontend
- Skip migration or tests unless user explicitly opts out
- Duplicate auth/refresh logic — use shared client

## Related skills

- Backend only → `add-entity`
- UI only (API exists) → `add-page`
- Schema change only → `add-migration`
- Run stack → `dev-webapp`

