The review sheet rendered the full dictation at the top of the modal, unconditionally. A raw transcript can carry the patient's spoken name — the spec said so itself in §9, while §10 said telemetry must never contain it. The transcript no longer reaches the browser by any route: - removed from the success response (VoiceExtractionResponse is now plain ResolvedExtraction, which never had the field) - removed from the error body. VOICE_EXTRACT_FAILED carried details.transcript for a salvage dialog that was never built, and ApiError['details'] is an array, so the shape never even matched — it was serialized onto the wire and dropped - removed from the sheet, and from VoiceExtractionResult. tsc proves that <p> was the only reader in the whole frontend It is logged instead: one info line per recording, written immediately after the emptiness check so a failed extraction still records it, and deliberately outside logTelemetry so that method's patient-free guarantee stays literally true. Accepted consequence, recorded in §10: patient words now persist in production server logs at default level, so whatever retention and access control applies to those logs applies to dictation. The repo's other sensitive-text path (openrouter.provider.ts) uses debug level with truncation; moving this line to debug is a one-word change. Transcript salvage is dropped rather than deferred, which settles §11 open item 16 by taking its second option. When extraction fails the clinician re-dictates; an operator can read the words in the log, the person who spoke them cannot. Spec: §7, §9 and §10 rewritten, item 16 resolved, decisions 51-53 added, and decisions 10 and 25 marked superseded so the log stops contradicting itself. No automated coverage for the response shape or the log line: there is no voice.service.spec.ts — the service is I/O orchestration and has never been unit tested. Removing the type field is what proves no reader survives. Gates: backend 216 tests, nest build, ESLint clean on the voice module; frontend tsc --noEmit clean, 52 Vitest tests, next build clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dyolink — Frontend (Next.js)
Prerequisites
- Node.js 20+ and npm
First-time setup
-
Clone the monorepo and go to the frontend app:
git clone <repository-url> dyolink cd dyolink/frontend -
Install dependencies
npm install -
Environment
Create
.env.localin this folder (not committed to git) with the public URLs your browser will use:NEXT_PUBLIC_APP_URL=http://localhost:3001 NEXT_PUBLIC_API_URL=http://localhost:3000/api NEXT_PUBLIC_APP_NAME=Dyolink- Adjust
NEXT_PUBLIC_API_URLif the Nest API runs on another host/port. - These values are baked in at build time for production images; for local dev, restart
npm run devafter changing them.
- Adjust
Run (development)
npm run dev
Open http://localhost:3001 (dev server uses port 3001 so it does not clash with the API on 3000).
Ensure the backend is running and NEXT_PUBLIC_API_URL matches its base URL (including /api if your API is mounted there).
After pulling latest main
git pull
npm install
Useful commands
| Command | Purpose |
|---|---|
npm run dev |
Development server (port 3001) |
npm run build |
Production build |
npm run start |
Serve production build (port 3000 — used inside Docker) |
npm run lint |
ESLint |
Docker
Image build and build-args (NEXT_PUBLIC_*) are documented in the repository root README.md.