2c3e28ac79d6f1e4487c04bd45a2b4fba7a77664
applyVoiceResult decided what to write and wrote it, in one callback inside a
3200-line client component. Nothing could reach it — not exported, and rendering
its component means mocking next-intl, the i18n router and six axios modules.
Three of the five defects found in live use sat in that callback, while 209
green tests covered the helpers around it.
buildVoiceApplyPlan(result, selection, ctx) -> { detail, labCaseDraft } now
holds the decision and writes nothing. The callback keeps only what a component
must do: setDetails, the ref writes the in-flight save reads, and the order that
lets lab rows carry a real treatmentDetailId. newDetail and newLabCaseDraft move
to treatmentDetailRules.ts so the pure module can build a draft without
importing a component.
21 tests. Verified they bite by reverting each bug in place: reading
labDependent from result.treatmentType fails 1, merging the plain teeth list
onto a prosthesis detail fails 2.
One group asserts an invariant that belongs to the backend — every
toothProsthesis row naming a real tooth must be in detail.teeth, which is
TREATMENT_TOOTH_NOT_ON_DETAIL at treatments.service.ts:806. It spans two
processes, so neither side could state it alone before.
Not covered, still manual: the labCaseDraftsRef timing needs a real render.
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 (standalone + copy public/ for catalog icons) |
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%