---
description: Dyolink project context — stack, org types, git safety, verification
alwaysApply: true
---

# Dyolink overview

Monorepo: `backend/` (NestJS + Prisma), `frontend/` (Next.js + next-intl), `infrastructure/` (Docker).

## Domain

- **CLINIC** orgs: patients, appointments, treatment, staff.
- **LAB** orgs: cases, tasks, lab workflows.
- Tab access: `TAB_*_READ` / `TAB_*_EDIT` in `backend/src/common/permissions.ts`. EDIT implies READ.

## Agent behavior

- Read `AGENTS.md` and file-scoped rules before large changes.
- **Never commit or push** unless the user explicitly asks.
- Prefer minimal diffs; reuse existing components and API patterns.
- After cross-cutting changes: `backend` → `npm run build`; `frontend` → `npx tsc --noEmit`.

## i18n

All user-visible strings: `frontend/messages/en.json`, `fa.json`, `nl.json` — add keys to **all three**.

Dates/times/numbers: `frontend/src/lib/i18n/format.ts` + `useLocale()`. **Form date fields:** `AppDateInput` only (no native `<input type="date">`); wire format `YYYY-MM-DD`. **Filter selects:** `FORM_SELECT_CLASS` from `components/shared/formSelectStyles.ts` (chevron via `globals.css`). **Tables:** `components/ui/shared/Table.tsx` — use `text-start`/`text-end`/`text-center`, never physical `text-left`/`text-right`. Treatment/Appointments headers: `ScheduleDayPicker` `compact`. Skill: `.cursor/skills/i18n-formatting/SKILL.md`.

## Treatment / appointment colors

Treatment-type colors and labels: `components/shared/treatmentTypeDisplay.ts` + `catalog-type-colors.ts`. UI badges: `components/ui/treatment/TreatmentTypeBadge.tsx`. **Prosthesis** colors/labels: `components/treatment/prosthesisTypeDisplay.ts` — use on lab Cases/Tasks/Today charts.

## Today dashboard

CLINIC + LAB KPIs/charts in `modules/today/today.service.ts`. Deep links: `components/today/today-deep-links.ts`. Task KPIs need `TAB_TASKS_READ` (no owner bypass). Skill: `.cursor/skills/today-dashboard/SKILL.md`.

## Lab case share link

QR + URL for **sent** cases; focus page `/lab-case/[token]`. Auth redirect via `postAuthRedirect.ts` + `useEnterAppWhenAuthenticated` (not inside `login()`). Skill: `.cursor/skills/lab-case-share-link/SKILL.md`.

## API errors

Logical failures: `AppException(ErrorCode.X)` → `errors.X` in en/fa/nl. UI: `getUserFacingError`. Unexpected 500s / client crashes: GlitchTip via Sentry SDKs (`SENTRY_DSN` / `NEXT_PUBLIC_SENTRY_DSN`). Skill: `.cursor/skills/api-errors/SKILL.md`. Appointments/working hours: client IANA `timeZone` (never Node local `getHours()`).

## Notifications (inbox + live tabs)

Header bell: `UserNotification` + Socket.IO. Same `notification.created` also drives sidebar tab badges and soft list refresh on **currently open** Cases/Tasks/Treatment/Orgs pages. Skills: `.cursor/skills/notifications-inbox/SKILL.md`, `.cursor/skills/tab-badges/SKILL.md`.
