e271858a33eff874affc60a9454be3750517453c
Both found by the /orchestrate correctness critic against 15ddb9a, and both
verified by hand before fixing.
1. A picked tooth chip was dropped on Apply. pickCandidate ticked the teeth
row from `available`, which is memoised from `effective` — the value the
same handler is in the middle of changing. On "ترمیم برای دندون دو" the
backend returns no teeth, so `available.teeth` was false at pick time and
`prev.teeth` was false too; `false || false` stuck permanently. A variant
of the original live-test failure. Each branch now ticks the row it feeds
and returns, so nothing reads the stale memo.
2. Decision 41's type-row lock was missing. The treatmentType row was a plain
toggle, and applyVoiceResult derived `labDependent` from
`result.treatmentType` rather than the `detail.treatmentType` it writes —
so unticking the type row saved prosthesis lab rows on whatever type the
appointment purpose had seeded. Row gains a `locked` state, the type row
locks while the prosthesis row is ticked, Apply sends the forced tick, and
`labDependent` now comes from the detail being written.
Gates: backend 16 suites / 209 tests, frontend 37 Vitest tests,
tsc --noEmit clean, next build clean, ESLint 0 new warnings
(VoiceReviewSheet.tsx 0 issues; the 10 in TreatmentWorkspace.tsx are
pre-existing and unchanged in count).
Not covered by a test: both fixes live in component state logic, which the
chosen Vitest scope — pure helpers, no React, no DOM — cannot reach. §12's
manual checks cover them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dyolink
Monorepo: NestJS backend (backend/), Next.js frontend (frontend/), Docker stack under infrastructure/..
Local development: see backend/README.md and frontend/README.md.
Cursor AI: project conventions for agents are in AGENTS.md, .cursor/rules/, and .cursor/skills/.
Production deploy (https://nudentic.ir)
Full guide: infrastructure/DEPLOY.md
Git tag v1.0.1 → Gitea workflow .gitea/workflows/prod-tag-deploy.yml builds images (URLs baked for nudentic.ir), pushes to Gitea registry, SSH-deploys the Linux stack.
First-time SSL / Hub fallback: same DEPLOY.md.
Staging deploy (https://wixur.ir)
Full guide: infrastructure/STAGING-DEPLOY.md
Merge or push to master → Gitea Actions builds images → deploys to https://wixur.ir (Gitea: http://wixur.ir:3000).
Workflow: .gitea/workflows/registry-build-deploy.yml
Related paths
| Path | Role |
|---|---|
backend/Dockerfile |
API image |
frontend/Dockerfile |
Web image |
infrastructure/STAGING-DEPLOY.md |
Staging setup, CI variables, testing |
infrastructure/docker-compose.registry.yml |
Pull-only staging stack (registry images + nginx + postgres) |
infrastructure/deploy.registry.env.example |
Template for deploy.registry.env |
Description
Languages
TypeScript
97.4%
Shell
1.1%
CSS
0.8%
JavaScript
0.3%
Dockerfile
0.3%
Other
0.1%