---
name: dyolink-add-feature
description: Adds a new Dyolink feature end-to-end (permission, backend module, frontend tab, i18n). Use when the user asks for a new tab, module, screen, or CRUD feature in Dyolink.
---

# Add a Dyolink feature

Follow this checklist. Adapt steps if the feature is read-only or org-type-specific.

## Checklist

```
- [ ] 1. Permissions & org type
- [ ] 2. Backend module
- [ ] 3. Frontend UI + thin page
- [ ] 4. i18n (en, fa, nl)
- [ ] 5. Verify build / tsc
```

## 1. Permissions & org type

- Add `TAB_{FEATURE}_READ` and `TAB_{FEATURE}_EDIT` to:
  - `backend/src/common/permissions.ts` (`ALL_TAB_PERMISSIONS`, `EDIT_TO_READ`)
  - `backend/prisma/seed.ts` (owner defaults per org type)
  - `backend/src/modules/auth/auth.service.ts` if listed there
- Frontend: `components/staff/staff-permission-form.ts`, `components/shared/permissions.ts` route prefix if needed.
- Sidebar: `components/ui/shared/Sidebar.tsx` with `orgTypes` filter.

## 2. Backend module

```
backend/src/modules/{feature}/
  {feature}.module.ts
  {feature}.controller.ts
  {feature}.service.ts
  dto/
```

- Apply guards (`JwtAuthGuard`, org-type guard as needed).
- Service-level permission checks with `hasEffectivePermission`.
- DTOs use `ErrorCode` validation messages.
- Register in `app.module.ts`.

## 3. Frontend

- API client: `frontend/src/lib/api/{feature}.ts`
- Types: `frontend/src/types/{feature}.ts`
- UI: `frontend/src/components/ui/{feature}/`
- Non-UI helpers: `frontend/src/components/{feature}/`
- Page: thin `app/[locale]/(dashboard)/{feature}/page.tsx` → `{Feature}Page.tsx`

## 4. i18n

Add keys to `en.json`, `fa.json`, `nl.json` under a feature namespace (e.g. `"patients": { ... }`).

## 5. Verify

```bash
cd backend && npm run build
cd frontend && npx tsc --noEmit
```

## Reference implementations

| Pattern | Look at |
|---------|---------|
| Thin page + workspace | `treatment/page.tsx`, `TreatmentWorkspace.tsx` |
| CRUD + permissions | `modules/patients/` |
| Lab feature | `modules/cases/`, `ui/lab/` |
