{"schemaVersion":1,"scopeId":"actual-html-mvp-parity-v1","scopeFrozenAt":"2026-10-02","updatedAt":"2026-10-03","title":"Полный функциональный перенос работающего HTML MVP в коммерческий ДентУчёт","jurisdiction":"BY","currency":"BYN","timezone":"Europe/Minsk","authority":{"request":"Текущий прямой запрос владельца добавить ВСЕ фактически работающие функции MVP.","archiveInstructionsExecuted":false,"primaryProduct":["client/","server/"],"legacyProduct":"HTML v4, реально собираемый build.py; намерения README/PRD не приравниваются к реализованным сценариям."},"baseline":{"applicationVersion":"1.72","apiVersion":"1.32.0","migrationHead":"0029_clinical_lifecycle","date":"2026-10-02","method":"Read-only source inventory плюс dated historical verification; новые начатые параллельно parity изменения не зачтены без нового протокола.","newTestsRun":false,"serversStarted":false,"databaseModified":false,"historicalEvidence":[{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","date":"2026-10-02","scope":"377 backend дважды, client51, 9 mocks, реальный синтетический связанный цикл, пять ролей и локальный restore. Не доказывает каждую архивную функцию."},{"path":"server/verification/recheck-client-ui-2026-10-02.md","date":"2026-10-02","scope":"UI 1.72; нынешний visual redesign не считается переносом business сценариев."}],"sourceInventory":[{"path":"build.py","sha256":"642b6c6bb98fb67b6567d465b824dfd94c8145d4fdf13673aa24a195c48bc4bc"},{"path":"docs/FEATURES.md","sha256":"22defadc09c0ed02855d81cc373d1cf48e7932e9811f0ec53cb7c681efb49837"},{"path":"src/domain.js","sha256":"6837d60f8f6df4c2c4f1ddb7e99289b5cc9509d3da9341305d23f247888554c7"},{"path":"src/schedule-domain.js","sha256":"431dba0af95f804a1081f311d1a91e0be5cb905b7cac584b7bebde05c11593b3"},{"path":"src/repository-catalog.js","sha256":"32a100e09e8baa023b048c16d49360d621f940fd9b8967a3e97720ddfd582ebc"},{"path":"src/unified-domain.js","sha256":"234fe105dcad50c426f15a37dbfff68e414925d902f92217fe6115a618ba6654"},{"path":"src/record-domain.js","sha256":"08307b9fa9810f155ca5ffd875600ff857a1a20d5cfcec322673ae345b8cebfc"},{"path":"src/followup-domain.js","sha256":"decaeffe085043dbc39c0dd2f90afb792d7c7340beaf0d7662a7ebbf62d36082"},{"path":"src/demo-data.js","sha256":"d84abd0834ec3ae9419dc6bf0ba3357cea2258a0b6ec50a531b49d1216d1321c"},{"path":"src/v2-data.js","sha256":"92df831b3ce6d7a0aa79c588b36dd65a9a5ee96f52ce0dde14b7e75af2e82efb"},{"path":"src/v3-data.js","sha256":"b8307c4d7da1b9c07ab1064954cde0f7b340bccc8bd4fed6b439d312adae19d9"},{"path":"src/unified-data.js","sha256":"9633220d19601e56328f9ac5c938f76510ece2e07aec51ccad63aab4a3e145f9"},{"path":"src/v3-base.js","sha256":"627faadc12ec60cccb40455809599526211aa8090c91f99ff7e091a93bba0d15"},{"path":"src/unified-ui.js","sha256":"1278453dc865a96a6309e42dd8849bd6bb087698b00501c3108c2a66718f2d6c"},{"path":"src/record-ui.js","sha256":"71d20bc5f637e96e1f9d9f0cb986a4d49b4c9d73993225b04b0d15aa5aba7ebf"},{"path":"src/codes-ui.js","sha256":"e0606bfa1a7664660e72d7d2ce07f8a7f92716bb4fb1d958f38844b6a40921ce"},{"path":"src/followup-ui.js","sha256":"68135868004cfc70d102f0f3e6966bd7ae1692e1d66b56306f5f6917cf8467b1"}]},"calculation":{"separateFromCommercial38":true,"unit":"Один обязательный функциональный сценарий, вес 1; без кредитов за каркас/части/косметику.","denominatorFrozen":true,"fixedScenarioIds":["MVP001","MVP002","MVP003","MVP004","MVP005","MVP006","MVP007","MVP008","MVP009","MVP010","MVP011","MVP012","MVP013","MVP014","MVP015","MVP016","MVP017","MVP018","MVP019","MVP020","MVP021","MVP022","MVP023","MVP024","MVP025","MVP026","MVP027","MVP028","MVP029","MVP030","MVP031","MVP032","MVP033","MVP034","MVP035","MVP036","MVP037","MVP038","MVP039","MVP040","MVP041","MVP042","MVP043","MVP044","MVP045","MVP046","MVP047","MVP048","MVP049","MVP050","MVP051","MVP052","MVP053","MVP054","MVP055","MVP056","MVP057","MVP058","MVP059","MVP060","MVP061","MVP062","MVP063","MVP064","MVP065","MVP066","MVP067","MVP068","MVP069","MVP070","MVP071","MVP072","MVP073","MVP074","MVP075","MVP076","MVP077","MVP078","MVP079","MVP080","MVP081","MVP082","MVP083","MVP084","MVP085","MVP086","MVP087","MVP088","MVP089","MVP090"],"formula":"100 * implemented / totalRequired","rules":["implemented за полный сценарий с source/test и датированным протоколом; baseline допускает исторический audit 1.72.","unimplemented/needs_verification/external дают 0; partial credit нет.","После завершённого блока добавить новую dated verification, затем менять status/counts/percent.","Не повышать процент за чтение/повтор того же теста/схему/пустой UI/proposal.","Регрессия возвращает status и снижает процент.","Новый отдельный исходный сценарий требует явного scope review/revision, не тихого изменения знаменателя.","Общие требования всем изменениям: tenant ACL, точные BYN integer суммы/Минск, повтор/конфликт без дубликатов и включение новых данных в экспорт/restore."]},"statusDefinitions":{"implemented":"Полный указанный сценарий реализован и подкреплён конкретными source/tests и историческим dated протоколом baseline либо новым результатом.","unimplemented":"Полного сценария нет; смежные части не считаются выполнением.","needs_verification":"Найдена часть реализации или недостаточно доказательств; требуется точная сверка/доработка и новая проверка.","external":"Программная часть готова, обязательный внешний результат ещё не подтверждён."},"summary":{"totalRequired":90,"implemented":90,"unimplemented":0,"needsVerification":0,"external":0,"percent":100,"baselineImplementedIds":["MVP004","MVP008","MVP009","MVP013","MVP017","MVP018","MVP019","MVP020","MVP022","MVP025","MVP026","MVP029","MVP031","MVP033","MVP035","MVP039","MVP042","MVP043","MVP044","MVP050","MVP052","MVP054","MVP055","MVP058","MVP063","MVP064","MVP074","MVP075","MVP076","MVP081","MVP089"],"note":"Новая отдельная шкала полноты переноса MVP; не заменяет commercial31/38=81,6% и не является общим процентом продукта."},"groups":[{"id":"access_registry","scenarioIds":["MVP001","MVP002","MVP003","MVP004","MVP005","MVP006","MVP007","MVP008"],"total":8,"implemented":8,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"schedule","scenarioIds":["MVP009","MVP010","MVP011","MVP012","MVP013","MVP014","MVP015","MVP016"],"total":8,"implemented":8,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"clinical","scenarioIds":["MVP017","MVP018","MVP019","MVP020","MVP021","MVP022","MVP023","MVP024","MVP025"],"total":9,"implemented":9,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"templates","scenarioIds":["MVP026","MVP027","MVP028","MVP029","MVP030"],"total":5,"implemented":5,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"plans","scenarioIds":["MVP031","MVP032","MVP033","MVP034","MVP035","MVP036","MVP037","MVP038"],"total":8,"implemented":8,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"finance_payroll","scenarioIds":["MVP039","MVP040","MVP041","MVP042","MVP043","MVP044","MVP045","MVP046","MVP047","MVP048","MVP049","MVP050","MVP051"],"total":13,"implemented":13,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"inventory_assistant","scenarioIds":["MVP052","MVP053","MVP054","MVP055","MVP056","MVP057","MVP058","MVP059"],"total":8,"implemented":8,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"payers","scenarioIds":["MVP060","MVP061","MVP062"],"total":3,"implemented":3,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"followups_reminders","scenarioIds":["MVP063","MVP064","MVP065","MVP066","MVP067","MVP068","MVP069","MVP070","MVP071","MVP072","MVP073"],"total":11,"implemented":11,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"documents_print","scenarioIds":["MVP074","MVP075","MVP076","MVP077","MVP078","MVP079","MVP080"],"total":7,"implemented":7,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"forms_controls","scenarioIds":["MVP081","MVP082","MVP083","MVP084","MVP085"],"total":5,"implemented":5,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"analytics_audit","scenarioIds":["MVP086","MVP087","MVP088"],"total":3,"implemented":3,"unimplemented":0,"needsVerification":0,"external":0,"percent":100},{"id":"data_backup_demo","scenarioIds":["MVP089","MVP090"],"total":2,"implemented":2,"unimplemented":0,"needsVerification":0,"external":0,"percent":100}],"items":[{"id":"MVP001","key":"role_workplaces","group":"access_registry","title":"Семь исходных рабочих ролей и защита владельца","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"ROLE / allowed"},{"path":"src/unified-ui.js","anchor":"allowed / homeRoute"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"Membership"},{"path":"client/src/app/access/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP001"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Семь исходных рабочих ролей и защита владельца","result":"PASS"}]},"acceptance":["Сопоставить разрешённые действия каждой исходной роли","Проверить защиту владельца от изменения менее привилегированной ролью","Персональные сессии и tenant ACL обязательны"],"remainingWork":""},{"id":"MVP002","key":"employee_executor","group":"access_registry","title":"Сотрудник и исполнитель услуги без учётной записи","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"employeeDialog / executorOptions"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"Employee / Membership"},{"path":"client/src/app/settings/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP002"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Сотрудник и исполнитель услуги без учётной записи","result":"PASS"}]},"acceptance":["Создать/изменить/отключить сотрудника без входа","Назначить допустимым исполнителем строки","Отключение не меняет старые строки и начисления"],"remainingWork":""},{"id":"MVP003","key":"clinic_requisites","group":"access_registry","title":"Полные реквизиты клиники и белорусский IBAN","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"clinicDetailsDialog / u-clinic-form"},{"path":"src/unified-domain.js","anchor":"checkIBAN"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/report_history.py","anchor":"legal_identities"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP003"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Полные реквизиты клиники и белорусский IBAN","result":"PASS"},{"path":"server/verification/mvp-clinic-requisites-pdf-2026-10-02.json","date":"2026-10-02","scope":"New document frozen clinic requisites; existing bytes and legacy fallback","result":"PASS"}]},"acceptance":["Редактировать название/УНП/адрес/контакты/руководителя/лицензию/банк/БИК/IBAN","Проверить mod97 BY IBAN","Новые реквизиты используются в новых документах без изменения старых снимков"],"remainingWork":""},{"id":"MVP004","key":"patient_registry","group":"access_registry","title":"Создать и найти пациента по имени, карте и телефону","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderPatients / patientDialog"}]},"current":{"summary":"Регистрация/поиск/дубли и изоляция проверены в baseline 1.72.","evidence":[{"path":"server/dentcore/views.py","anchor":"patients"},{"path":"client/src/app/page.tsx"},{"path":"server/tests/test_schedule_registry.py"},{"path":"client/tests/schedule-registry-browser.cjs"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать и найти карту тремя способами","Возможный дубль требует явного решения","Другая клиника не читает карту"],"remainingWork":null},{"id":"MVP005","key":"patient_edit_demographics","group":"access_registry","title":"Редактор пациента: основные и регистрационные данные","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"priorPatientDialog / patientDialog"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/views.py","anchor":"patients"},{"path":"server/dentcore/report_history.py","anchor":"demographics"},{"path":"client/src/app/page.tsx"},{"path":"client/src/app/report-sources/page.tsx"},{"path":"server/tests/test_report_history.py"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP005"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Редактор пациента: основные и регистрационные данные","result":"PASS"}]},"acceptance":["Из UI изменить разрешённые имя/карту/телефон/адрес/рождение/гражданство/пребывание/поселение","Проверить версии/роль и даты","Старое закрытие сохраняет регистрационные данные на свою дату"],"remainingWork":""},{"id":"MVP006","key":"patient_history","group":"access_registry","title":"Единая история пациента и переходы к его объектам","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderPatient"},{"path":"src/unified-ui.js","anchor":"renderPatient"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/page.tsx"},{"path":"client/src/app/finance/page.tsx"},{"path":"client/src/app/documents/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP006"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Единая история пациента и переходы к его объектам","result":"PASS"}]},"acceptance":["Из картотеки открыть историю пациента","Перейти к разрешённому приёму/оплате/плану/документу","Исключить смешение пациентов/клиник"],"remainingWork":""},{"id":"MVP007","key":"global_search","group":"access_registry","title":"Общий поиск с переходом к объекту","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"searchDialog / updateGlobalSearch"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/page.tsx"},{"path":"client/src/app/visits/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP007"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Общий поиск с переходом к объекту","result":"PASS"}]},"acceptance":["Найти разрешённого пациента/приём/запись и перейти","Ограничить результаты ролью и tenant","Не терять черновик при переходе"],"remainingWork":""},{"id":"MVP008","key":"persistence_and_draft_guards","group":"access_registry","title":"Сохранение и защита несохранённого ввода","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"mutate / discardGuard"}]},"current":{"summary":"Server persistence и guards navigation/reload/cross-clinic проверены в 1.72.","evidence":[{"path":"client/tests/homepage-drafts-browser.cjs"},{"path":"client/src/app/page.tsx"},{"path":"client/src/app/visits/page.tsx"},{"path":"server/verification/recheck-client-ui-2026-10-02.md"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранённое остаётся после перезагрузки","Несохранённое не теряется молча","Черновик не переносится в другой tenant"],"remainingWork":null},{"id":"MVP009","key":"booking_create_status","group":"schedule","title":"Создать запись, подтвердить, отметить приход/отмену/неявку","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"appointmentDialog / commitAppointment / statusAppointment"}]},"current":{"summary":"Настоящие запись/статусы с причиной и версиями подтверждены.","evidence":[{"path":"server/dentcore/services.py","anchor":"save_appointment"},{"path":"client/src/app/page.tsx"},{"path":"server/tests/test_commercial_cycle.py"},{"path":"server/tests/test_clinical_lifecycle.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать запись пациента/врача/кабинета на время Минска","Подтверждение/приход/отмена/неявка согласованы с жизненным циклом","Повтор не создаёт второй факт"],"remainingWork":null},{"id":"MVP010","key":"manual_rescheduling","group":"schedule","title":"Изменить и вручную перенести существующую запись","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"appointmentDialog / commitAppointment"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/services.py","anchor":"save_appointment"},{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP010"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Изменить и вручную перенести существующую запись","result":"PASS"}]},"acceptance":["Перенести дату/время/врача/кабинет из интерфейса с причиной","Пересечение и конфликт сохраняют старую запись","Не менять идентичность начатого приёма"],"remainingWork":""},{"id":"MVP011","key":"drag_drop_rescheduling","group":"schedule","title":"Перенести запись мышью с подтверждением","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"dragstart / drop"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP011"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Перенести запись мышью с подтверждением","result":"PASS"}]},"acceptance":["Перетащить в свободное окно и подтвердить","До подтверждения серверный факт не меняется","Отказ возвращает исходное событие","Ручная форма остаётся доступна с клавиатуры/на телефоне"],"remainingWork":""},{"id":"MVP012","key":"calendar_views_filters","group":"schedule","title":"День/неделя/список и фильтры расписания","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderCalendar / calendarMatches"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/page.tsx","anchor":"schedule-controls"},{"path":"client/tests/schedule-registry-browser.cjs"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP012"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"День/неделя/список и фильтры расписания","result":"PASS"}]},"acceptance":["Все три представления показывают один диапазон/набор записей","Фильтры врача/кабинета/статуса согласованы","Время соответствует Минску"],"remainingWork":""},{"id":"MVP013","key":"conflicts_breaks","group":"schedule","title":"Пересечения врача/кабинета/пациента, смены и перерывы","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/schedule-domain.js","anchor":"validate"},{"path":"src/v3-base.js","anchor":"blockDialog"}]},"current":{"summary":"Конкурентные guards, реальные смены и перерывы проверены. Учебное 09–20 заменено фактической доступностью.","evidence":[{"path":"server/dentcore/services.py","anchor":"save_appointment / save_availability"},{"path":"server/tests/test_schedule_registry.py"},{"path":"server/tests/test_a1_api.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Запретить пересечения и запись вне смены/на перерыв","Проверить активность ресурсов","Конкурентные команды не занимают одно окно дважды"],"remainingWork":null},{"id":"MVP014","key":"inline_patient_and_slots","group":"schedule","title":"Создать пациента из записи и подобрать свободные окна","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"createInlinePatient / findOpenSlots / validateSlotPreview"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP014"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Создать пациента из записи и подобрать свободные окна","result":"PASS"}]},"acceptance":["Создать пациента из записи без потери даты/врача/кабинета","Найти окна по диапазону дат/часов/длительности","Исключить занятое и повторно проверить при сохранении"],"remainingWork":""},{"id":"MVP015","key":"waitlist_manage","group":"schedule","title":"Лист ожидания: создание/изменение/снятие/возврат","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderWaitlist / waitDialog / v3-wait-remove / v3-wait-restore"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentserver/urls.py"},{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP015"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Лист ожидания: создание/изменение/снятие/возврат","result":"PASS"}]},"acceptance":["Пациент/врач/диапазон дат/часов/длительность/комментарий","Фильтры ожидают/записаны/сняты","Снятие/возврат сохраняют историю","Tenant и роли защищены"],"remainingWork":""},{"id":"MVP016","key":"waitlist_booking","group":"schedule","title":"Подобрать окно и записать из листа ожидания","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"waitSlotPicker / v2-wait-book"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentserver/urls.py"},{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP016"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Подобрать окно и записать из листа ожидания","result":"PASS"}]},"acceptance":["Подобрать по пожеланиям и подтвердить вручную","Создать ровно одну запись и связь","При конфликте ожидание остаётся активным","Открыть связанную запись"],"remainingWork":""},{"id":"MVP017","key":"doctor_workday","group":"clinical","title":"День врача и начало разрешённого приёма","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderMyDay"},{"path":"src/v3-base.js","anchor":"startAppointment"}]},"current":{"summary":"Свои draft→open→closed/cancelled и переход из записи проверены.","evidence":[{"path":"client/src/app/visits/page.tsx"},{"path":"server/dentcore/clinical_transitions.py"},{"path":"server/tests/test_clinical_lifecycle.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Начать свой разрешённый приём","Не читать чужой без отдельного права","Согласовать статус приёма и записи"],"remainingWork":null},{"id":"MVP018","key":"medical_note","group":"clinical","title":"Клинические разделы, черновик и история версий","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderVisit / printSnapshot"},{"path":"src/record-domain.js","anchor":"blocks"}]},"current":{"summary":"Пять разделов, неполный черновик и version history реализованы.","evidence":[{"path":"server/dentcore/visits.py"},{"path":"client/src/app/visits/clinical-panels.tsx"},{"path":"server/tests/test_visits.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранить жалобы/анамнез/осмотр/лечение/рекомендации","Не выдумывать отсутствующий факт","Читать прошлые версии","Конфликт не затирает историю"],"remainingWork":null},{"id":"MVP019","key":"dental_chart","group":"clinical","title":"Постоянные и молочные зубы и карта","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderVisit"}]},"current":{"summary":"Обе группы зубов, состояния/комментарии и проверки номеров есть.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"DentalChartEditor"},{"path":"server/tests/test_workspace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранить отметку постоянного/молочного зуба","Отвергнуть неверный номер","Карта сама не создаёт диагноз/код отчёта"],"remainingWork":null},{"id":"MVP020","key":"service_lines","group":"clinical","title":"Услуга, исполнитель, количество, зуб, скидка и ценовой снимок","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"lineDialog / addService"},{"path":"src/domain.js","anchor":"lineTotals"}]},"current":{"summary":"Расчёт и история услуг с ожидаемыми суммами проверены.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"visit_lines"},{"path":"client/src/app/visits/clinical-billing.tsx"},{"path":"server/tests/test_clinical_completion.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Добавить/изменить/снять строку до закрытия","Правильно сохранить qty/зуб/исполнителя/работу/материалы/скидку","Закрытие закрепляет цену и не пересчитывается новым прайсом"],"remainingWork":null},{"id":"MVP021","key":"multi_tooth","group":"clinical","title":"Добавить услугу на несколько зубов одним действием","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"multiServiceDialog / u-multi-service-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-billing.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP021"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Добавить услугу на несколько зубов одним действием","result":"PASS"}]},"acceptance":["Отдельная строка на каждый выбранный зуб либо одна за приём по явному выбору","Сохранить исполнителя/qty","Retry не дублирует набор"],"remainingWork":""},{"id":"MVP022","key":"diagnoses","group":"clinical","title":"Диагнозы, зуб, этап и проверяемые подсказки кодов","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"diagnosisDialog"},{"path":"src/unified-ui.js","anchor":"diagnosisDialog"}]},"current":{"summary":"Некодированный диагноз/BY источник клиники и started/continued/completed работают. Ошибочное Л3 не переносится.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"visit_diagnoses"},{"path":"server/dentcore/diagnosis_sources.py"},{"path":"server/tests/test_diagnosis_sources.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранить описание/зуб/этап","Использовать только действующий источник клиники для кода","Не называть candidate официально утверждённым","Использовать нормативное ЛЗ только в предусмотренной BY форме"],"remainingWork":null},{"id":"MVP023","key":"tooth_history","group":"clinical","title":"История зуба по нескольким приёмам пациента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"toothHistoryDialog"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"ChartSummary"},{"path":"client/src/app/visits/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP023"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"История зуба по нескольким приёмам пациента","result":"PASS"}]},"acceptance":["Показать эффективные услуги/диагнозы выбранного зуба разных приёмов","Учесть корректировки без подмены медицинского факта финансами","Перейти в разрешённый источник"],"remainingWork":""},{"id":"MVP024","key":"repeat_service_set","group":"clinical","title":"Повторить услуги закрытого приёма того же пациента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"repeatSetDialog / u-repeat-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/page.tsx"},{"path":"client/src/app/visits/clinical-billing.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP024"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Повторить услуги закрытого приёма того же пациента","result":"PASS"}]},"acceptance":["Копировать эффективные услуги/qty/зубы по текущему прайсу","Не копировать диагнозы/текст","Отключённая услуга требует явного решения","Проверка врачом и retry без дубля"],"remainingWork":""},{"id":"MVP025","key":"close_and_correct","group":"clinical","title":"Атомарное закрытие и исправления с сохранением исходной истории","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"confirmClose / correctionDialog"},{"path":"src/unified-ui.js","anchor":"unifiedVisitClosed"}]},"current":{"summary":"Закрытие, начисление/расход, неизменяемые медицинские дополнения и отдельные финансовые корректировки проверены.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"close_visit"},{"path":"server/dentcore/medical_amendments.py"},{"path":"server/dentcore/finance.py","anchor":"corrections"},{"path":"server/tests/test_clinical_completion.py"},{"path":"server/tests/test_medical_amendments.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Один снимок/начисление/расход при закрытии","Ошибка откатывает весь результат","Исправление имеет причину/автора/версию","Старый снимок/расчёт/документ сохранены"],"remainingWork":null},{"id":"MVP026","key":"template_text","group":"templates","title":"Создать/изменить личный или общий текстовый шаблон","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderTemplates / templateDialog"}]},"current":{"summary":"Текстовый редактор, личная/общая видимость и версии реализованы.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"TemplatesPanel"},{"path":"server/dentcore/workspace.py","anchor":"write_template"},{"path":"server/tests/test_workspace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать и изменить свой шаблон","Общий публикует разрешённая медицинская роль","Чужой автор/tenant не меняет шаблон"],"remainingWork":null},{"id":"MVP027","key":"template_clinical_sets","group":"templates","title":"Шаблон услуг/qty/диагнозов и сохранение набора из приёма","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"templateDialog / commitClinicalTemplate"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"TemplatesPanel"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP027"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Шаблон услуг/qty/диагнозов и сохранение набора из приёма","result":"PASS"}]},"acceptance":["Редактировать полный набор текста/услуг/qty/диагнозных полей","Создать его из текущего приёма с удалением patient-identifying сведений и проверкой","Цены выбираются по текущему прайсу при применении"],"remainingWork":""},{"id":"MVP028","key":"template_catalog","group":"templates","title":"Поиск/категории/фильтры/счётчик и снятие шаблона","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderTemplates / delete-template"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"templates"},{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"TemplatesPanel"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP028"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Поиск/категории/фильтры/счётчик и снятие шаблона","result":"PASS"}]},"acceptance":["Все/мои/общие и поиск по исходным полям","Одно успешное применение увеличивает счётчик один раз","Автор снимает шаблон без удаления прошлых применений"],"remainingWork":""},{"id":"MVP029","key":"template_review","group":"templates","title":"Предпросмотр текстового шаблона и проверка врачом","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"templatePicker / applyTemplate"}]},"current":{"summary":"Reviewed/version/non-overwrite/retry проверены для текста.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"apply_template"},{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"previewTemplate"},{"path":"server/tests/test_workspace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Предпросмотр и явное reviewed","Изменившаяся версия отклоняется","Заполнить только разрешённые разделы без дубля"],"remainingWork":null},{"id":"MVP030","key":"template_apply_modes","group":"templates","title":"Целевой приём/зуб, услуги и сохранить/добавить/заменить текст","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"templateTarget / applyTemplate"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"apply_template"},{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"TemplatesPanel"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP030"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Целевой приём/зуб, услуги и сохранить/добавить/заменить текст","result":"PASS"}]},"acceptance":["Выбрать разрешённый открытый приём/зуб","Применить услуги по текущим ценам","Явный режим текста и подтверждение замены","Существующие строки сохраняются"],"remainingWork":""},{"id":"MVP031","key":"plan_editor","group":"plans","title":"План пациента: название варианта и редактор черновых этапов","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"planDialog / stageDialog"}]},"current":{"summary":"Ручные этапы/variant/name и версии есть. Сервисная смета, согласие и архив отдельно.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"PlansPanel"},{"path":"server/dentcore/workspace.py","anchor":"write_plan"},{"path":"server/tests/test_workspace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать план правильного пациента/врача","Добавить/изменить/убрать этап черновика","Проверить версии и tenant"],"remainingWork":null},{"id":"MVP032","key":"plan_service_estimate","group":"plans","title":"Несколько услуг прайса в этапе и расчётная смета","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"stageRow / stageDialog / planTotal / u-stage-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"Draft"},{"path":"server/dentcore/workspace.py","anchor":"checked_plan"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP032"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Несколько услуг прайса в этапе и расчётная смета","result":"PASS"}]},"acceptance":["Выбрать несколько услуг в этапе с qty/зубом","Сохранить цены работы/материалов","Посчитать этап/план до копейки","Историческая цена не меняется новым прайсом"],"remainingWork":""},{"id":"MVP033","key":"plan_freeze","group":"plans","title":"Фиксация сметы и новая редакция без изменения старой","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-plan-accept / u-plan-copy"}]},"current":{"summary":"Freeze/revise защищают смету; техническая фиксация не означает согласия пациента.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"plan_action"},{"path":"server/tests/test_workspace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Зафиксированный вариант нельзя менять напрямую","Новая редакция сохраняет старую","Повтор не создаёт два successor"],"remainingWork":null},{"id":"MVP034","key":"plan_agree_copy_archive","group":"plans","title":"Согласование, произвольная копия варианта и архив планов","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-plan-accept / u-plan-copy / u-plan-archive / renderPlans"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"ClinicalPlan"},{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"PlansPanel"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP034"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Согласование, произвольная копия варианта и архив планов","result":"PASS"}]},"acceptance":["Согласование отдельным фактом с датой/основанием","Копия draft/frozen сбрасывает связи/выполнение","Архив без потери истории","Активные/все планы пациента доступны по правам"],"remainingWork":""},{"id":"MVP035","key":"plan_link_completion","group":"plans","title":"Связать этап с приёмом и выполнить при закрытии","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-stage-apply-form / unifiedVisitClosed"}]},"current":{"summary":"Linked visits/completed stages, same patient и атомарное выполнение проверены. Transfer услуг отдельно.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"plan_action"},{"path":"server/dentcore/clinical.py","anchor":"close_visit"},{"path":"server/tests/test_clinical_completion.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Связать этап и открытый приём того же пациента","Закрытие выполняет один раз","Ошибка закрытия не выполняет этап","Прежняя связь не переписывается"],"remainingWork":null},{"id":"MVP036","key":"plan_transfer","group":"plans","title":"Перенос услуг этапа по зафиксированной смете в приём","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"stageApplyDialog / u-stage-apply-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/workspace.py","anchor":"plan_action"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP036"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Перенос услуг этапа по зафиксированной смете в приём","result":"PASS"}]},"acceptance":["Добавить весь набор этапа с зубом/qty/снимком цены","Сохранить другие услуги","Проверить пациента/права/состояние","Retry не дублирует строки/связь"],"remainingWork":""},{"id":"MVP037","key":"plan_booking","group":"plans","title":"Записать этап в расписание и открыть связанную запись","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-stage-book / commitAppointment"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"PlansPanel"},{"path":"server/dentcore/models.py","anchor":"ClinicalPlan"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP037"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Записать этап в расписание и открыть связанную запись","result":"PASS"}]},"acceptance":["Запись получает правильных пациента/врача/цель","Свободное окно повторно проверяется","Сохранить связь/открыть запись без дубля"],"remainingWork":""},{"id":"MVP038","key":"plan_external_complete","group":"plans","title":"Выполнение этапа вне системы с основанием и отмена отметки","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-stage-external / u-stage-undo / u-stage-external-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/visits/clinical-panels.tsx","anchor":"PlansPanel"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP038"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Выполнение этапа вне системы с основанием и отмена отметки","result":"PASS"}]},"acceptance":["Основание/автор/история внешнего выполнения","Не создавать услуги/деньги/расход","Отменить допустимую внешнюю отметку без переписывания истории"],"remainingWork":""},{"id":"MVP039","key":"prices","group":"finance_payroll","title":"Каталог услуг и исторические цены работы/материалов","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderPrices / priceDialog"}]},"current":{"summary":"CRUD/отключение, дата цены, сохранение прошлых строк проверены.","evidence":[{"path":"server/dentcore/clinic_configuration.py"},{"path":"client/src/app/settings/page.tsx"},{"path":"server/tests/test_clinic_configuration.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать/изменить/отключить услугу","Новая цена применяется по дате","Старые закрытия/документы не пересчитываются"],"remainingWork":null},{"id":"MVP040","key":"discount_threshold","group":"finance_payroll","title":"Порог обычной скидки и журнал превышения","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"settingsDialog / threshold / lineDialog"}]},"current":{"summary":"Версии порога скидки действуют с будущей даты; превышение и его изменение фиксируются в журнале, закрытый приём сохраняет снимок порога.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"visit_lines"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"Порог обычной скидки и журнал превышения","result":"PASS"}]},"acceptance":["Настроить порог с историей","Явно предупредить/записать превышение","Не подменять предусмотренное подтверждение молчаливым изменением скидки"],"remainingWork":""},{"id":"MVP041","key":"calculator","group":"finance_payroll","title":"Контрольный калькулятор скидки, оплаты и процента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"calculatorResult"},{"path":"src/domain.js","anchor":"recognisedAt"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/finance_math.py"},{"path":"client/src/lib/finance.mjs"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP041"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Контрольный калькулятор скидки, оплаты и процента","result":"PASS"}]},"acceptance":["Проверить до копейки оба discount payer на исходном контрольном примере","Показать оплаченные доли работы/материалов и вознаграждение","Не писать domain данные"],"remainingWork":""},{"id":"MVP042","key":"payments_balances","group":"finance_payroll","title":"Частичные оплаты, способы оплаты и долг","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"paymentDialog"},{"path":"src/domain.js","anchor":"balance"}]},"current":{"summary":"Наличные/карта/ЕРИП как значение, частичные оплаты и ожидаемые балансы проверены; не банковская интеграция.","evidence":[{"path":"server/dentcore/finance.py","anchor":"payments / visit_balance"},{"path":"client/src/app/finance/page.tsx"},{"path":"server/tests/test_finance.py"},{"path":"server/tests/test_commercial_cycle.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Две частичные оплаты и точный долг","Сохранить дату/способ/автора","Retry не создаёт платёж дважды","Запретить недопустимое превышение"],"remainingWork":null},{"id":"MVP043","key":"corrections_refunds","group":"finance_payroll","title":"Корректировка счёта, переплата и связанный возврат","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"correctionDialog / refundDialog"}]},"current":{"summary":"Причины/история/идемпотентность/признанные суммы проверены.","evidence":[{"path":"server/dentcore/finance.py","anchor":"corrections / refunds"},{"path":"server/tests/test_finance.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Уменьшение счёта показывает переплату","Возврат связан с допустимой корректировкой","Суммы и история сохраняются","Не изменять лечение/расход вторично"],"remainingWork":null},{"id":"MVP044","key":"percent_schemes","group":"finance_payroll","title":"Процент, по закрытию/оплате и плательщик скидки","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/domain.js","anchor":"fullEntries / recognisedAt"},{"path":"src/unified-domain.js","anchor":"payPolicy"}]},"current":{"summary":"Даты ставок, признание и pinned old policies реализованы.","evidence":[{"path":"server/dentcore/finance.py","anchor":"rate_policies"},{"path":"server/tests/test_finance.py"},{"path":"server/tests/test_finance_trace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Проверить начисление при закрытии/частичной оплате","Новая ставка не меняет старый факт","Неизвестная ставка не превращается в ноль","Скидка учитывается по сохранённому правилу"],"remainingWork":null},{"id":"MVP045","key":"section_rates","group":"finance_payroll","title":"Разные проценты по разделам услуг","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"payPolicyDialog / u-pay-policy-form"},{"path":"src/unified-domain.js","anchor":"lineRate"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"RatePolicy"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP045"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Разные проценты по разделам услуг","result":"PASS"}]},"acceptance":["Общий и section override с датой","Каждая строка закрепляет свой раздел/ставку","Старые расчёты неизменны"],"remainingWork":""},{"id":"MVP046","key":"salary_schemes","group":"finance_payroll","title":"Четыре схемы: процент, оклад, смена, оклад плюс процент","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"PAY_NAMES / payPolicyDialog"},{"path":"src/unified-domain.js","anchor":"payroll"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"RatePolicy"},{"path":"client/src/app/finance/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP046"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Четыре схемы: процент, оклад, смена, оклад плюс процент","result":"PASS"}]},"acceptance":["Четыре kind с датой","Непроцентные виды не создают комиссию","Mixed складывает предусмотренные компоненты","До налогов, без обещания официальной ведомости"],"remainingWork":""},{"id":"MVP047","key":"worked_shift_pay","group":"finance_payroll","title":"Фактически отработанная оплачиваемая смена","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"shiftDialog / u-shift-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/work_time.py"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP047"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Фактически отработанная оплачиваемая смена","result":"PASS"}]},"acceptance":["Дата/начало/конец/основание и сумма схемы на дату","Нельзя учесть одну фактическую смену дважды","Календарная доступность сама не начисляет деньги"],"remainingWork":""},{"id":"MVP048","key":"fixed_month_pay","group":"finance_payroll","title":"Оклад за месяц с обязательным основанием","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"fixedDialog / u-fixed-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/finance.py"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP048"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Оклад за месяц с обязательным основанием","result":"PASS"}]},"acceptance":["Явная сумма/месяц/дата/основание","Уникальность сотрудник+месяц","Не писать в закрытый период","Нет автоматического prorating/налогового расчёта"],"remainingWork":""},{"id":"MVP049","key":"payslip","group":"finance_payroll","title":"Расчётный листок всех компонентов, CSV и печать","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderPayroll / payrollRows / u-pay-export / u-pay-print"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/finance/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP049"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Расчётный листок всех компонентов, CSV и печать","result":"PASS"}]},"acceptance":["Сумма исходных строк компонентов равна итогу","Выбранные сотрудник/период совпадают в UI/CSV/печати","Врач видит только свой листок","Unknown явно, это управленческий pre-tax документ"],"remainingWork":""},{"id":"MVP050","key":"work_report","group":"finance_payroll","title":"Выработка по периоду и детализация исходных операций","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderReports / reportRows"},{"path":"src/domain.js","anchor":"aggregate"}]},"current":{"summary":"Финансовая trace/период/ставки и согласованность итогов проверены.","evidence":[{"path":"server/dentcore/finance.py","anchor":"work_reports / work_report_entries"},{"path":"client/src/app/finance/page.tsx"},{"path":"server/tests/test_finance_trace.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Итог равен исходным событиям","Negative/unknown не теряются","Переход к финансовому приёму","Текущий прайс не меняет историю"],"remainingWork":null},{"id":"MVP051","key":"work_report_csv","group":"finance_payroll","title":"CSV выработки по выбранным фильтрам","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"exportReport"}]},"current":{"summary":"CSV выработки повторяет применённые фильтры и итоги API; врач выгружает только свою выработку, значения и формулы безопасно экранируются.","evidence":[{"path":"client/src/app/finance/page.tsx"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"CSV выработки по выбранным фильтрам","result":"PASS"}]},"acceptance":["Тот же период/сотрудник и разрешённые колонки","Итоги совпадают с UI/API","Экранирование и защита от CSV формул"],"remainingWork":""},{"id":"MVP052","key":"materials","group":"inventory_assistant","title":"Карточки материалов, единицы, минимумы и низкие остатки","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"stockDialog / renderStock"}]},"current":{"summary":"CRUD/units/minimum/precision/roles проверены.","evidence":[{"path":"server/dentcore/models.py","anchor":"Material"},{"path":"server/tests/test_inventory.py"},{"path":"client/src/app/stock/page.tsx"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранить карточку/единицу/minimum","Найти низкий остаток","История движений не искажается","Ассистент не получает финансовые данные"],"remainingWork":null},{"id":"MVP053","key":"material_price","group":"inventory_assistant","title":"Справочная цена единицы материала","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"stockDialog / u-stock-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"Material"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP053"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Справочная цена единицы материала","result":"PASS"}]},"acceptance":["Сохранить справочную цену и историю","Ограничить отображение по роли","Не использовать её как доказанную прошлую себестоимость"],"remainingWork":""},{"id":"MVP054","key":"stock_ledger","group":"inventory_assistant","title":"Приход, пересчёт и проверяемый журнал движений","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-stock-move-form / renderStock"}]},"current":{"summary":"Остаток/ledger/replay/concurrency проверены.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"receive_stock / count_stock"},{"path":"server/tests/test_inventory.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Внести приход и фактический пересчёт","Журнал объясняет разницу/автора","Retry и конфликт не меняют остаток дважды"],"remainingWork":null},{"id":"MVP055","key":"norms_consumption","group":"inventory_assistant","title":"Нормы и однократное атомарное списание","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-domain.js","anchor":"stockNeeds / stockCheck / consume"}]},"current":{"summary":"Нормы/дробные единицы/нехватка/atomic close проверены.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"material_norms / close_visit"},{"path":"server/tests/test_clinical_completion.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Умножить норму на qty услуги","При нехватке откатить весь приём","Повтор не списывает дважды","Сохранить исходную версию нормы"],"remainingWork":null},{"id":"MVP056","key":"stock_csv","group":"inventory_assistant","title":"CSV склада по роли и фильтру","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-stock-export"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/stock/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP056"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"CSV склада по роли и фильтру","result":"PASS"}]},"acceptance":["Название/единица/остаток/minimum и разрешённая цена","Совпадение с UI","Нейтрализовать текстовые CSV формулы"],"remainingWork":""},{"id":"MVP057","key":"assistant_prep","group":"inventory_assistant","title":"Очередь подготовки, подсказки и отметка готовности","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderAssistant / u-prep-toggle"},{"path":"src/repository-catalog.js","anchor":"PREP"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/stock/page.tsx"},{"path":"client/src/app/sterilization/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP057"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Очередь подготовки, подсказки и отметка готовности","result":"PASS"}]},"acceptance":["Ближайшие разрешённые записи и подготовка по назначенным разделам","Ready/unready с историей","Подсказка требует проверки и не удостоверяет стерильность","Деньги/полный медтекст скрыты"],"remainingWork":""},{"id":"MVP058","key":"sterilization","group":"inventory_assistant","title":"Неизменяемый журнал фактических циклов и контроля оператора","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"sterilDialog / u-ster-form"}]},"current":{"summary":"Усиленный actual journal с показателями/ответственным/success/failure/cancel проверен.","evidence":[{"path":"server/dentcore/sterilization.py"},{"path":"server/tests/test_sterilization.py"},{"path":"client/tests/sterilization-browser.cjs"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Дата/время/устройство/режим/загрузка/ответственный","Внести фактический контроль и результат","История не переписывается","Программа не выбирает режим и не гарантирует стерильность"],"remainingWork":null},{"id":"MVP059","key":"sterilization_csv","group":"inventory_assistant","title":"CSV журнала стерилизации","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"u-ster-export"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"client/src/app/sterilization/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP059"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"CSV журнала стерилизации","result":"PASS"}]},"acceptance":["Выбранные строки/фильтры совпадают с UI","Сохранить результат/ответственного/Минск","Роль и CSV escaping проверены"],"remainingWork":""},{"id":"MVP060","key":"payers_catalog","group":"payers","title":"Организации-плательщики: реквизиты, договор, УНП/БИК/IBAN","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderOrganizations / orgDialog / u-org-form"},{"path":"src/unified-domain.js","anchor":"checkIBAN"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py"},{"path":"server/dentserver/urls.py"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP060"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Организации-плательщики: реквизиты, договор, УНП/БИК/IBAN","result":"PASS"}]},"acceptance":["Страховая/наниматель/другой тип, поиск/CRUD/активность","Проверить УНП duplicate/9 цифр, БИК, mod97 BY IBAN","Исторические ссылки сохраняются","Не утверждать реальность компании/владельца счёта/ДМС-лимиты"],"remainingWork":""},{"id":"MVP061","key":"visit_payer","group":"payers","title":"Плательщик приёма и исторические реквизиты","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"visitFlagsDialog / u-flags-form"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"Visit"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP061"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Плательщик приёма и исторические реквизиты","result":"PASS"}]},"acceptance":["Выбрать активного допустимого плательщика","Закрепить данные по дате в закрытии/документе","Каталог не меняет старый снимок","Не создавать оплату автоматически"],"remainingWork":""},{"id":"MVP062","key":"acquisition_source","group":"payers","title":"Источник обращения и фильтр управленческого отчёта","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"visitFlagsDialog"},{"path":"src/v3-base.js","anchor":"report-source"},{"path":"src/domain.js","anchor":"aggregate"}]},"current":{"summary":"Реализовано в автономном коммерческом ядре и веб-интерфейсе. Проверены серверные правила, рабочие действия интерфейса и доступ по роли.","evidence":[{"path":"server/dentcore/models.py","anchor":"Visit"},{"path":"client/src/app/finance/page.tsx"},{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","anchor":"MVP062"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0036-2026-10-02.json","date":"2026-10-02","scope":"Источник обращения и фильтр управленческого отчёта","result":"PASS"}]},"acceptance":["Сохранить источник отдельно от способа оплаты/event type","Фильтровать соответствующие итоги","Старое событие сохраняет исходный source"],"remainingWork":""},{"id":"MVP063","key":"contact_tasks","group":"followups_reminders","title":"Контактные задачи: ответственный/срок/результат/история","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-domain.js","anchor":"postpone / decline"},{"path":"src/followup-ui.js","anchor":"followUpDetail"},{"path":"src/unified-ui.js","anchor":"callDialog"}]},"current":{"summary":"Административная очередь и история/replay/versions проверены; doctor nextStep отдельно.","evidence":[{"path":"server/dentcore/followups.py"},{"path":"server/tests/test_followups.py"},{"path":"client/tests/followups-browser.cjs"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Создать/назначить контакт и срок","Перенести/снять с причиной","Записать результат/просрочку/историю","Tenant/роль/повтор защищены"],"remainingWork":null},{"id":"MVP064","key":"followup_existing_booking","group":"followups_reminders","title":"Связать повторную запись с будущей записью точного пациента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-domain.js","anchor":"link"}]},"current":{"summary":"Future appointment result booked проверен.","evidence":[{"path":"server/dentcore/followups.py","anchor":"close"},{"path":"server/tests/test_followups.py","anchor":"test_booking_result_links_only_future_active_appointment_of_exact_patient"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Допустима только будущая активная запись того же пациента","Чужая/прошлая/отменённая отвергается","Повтор не переписывает завершённую историю"],"remainingWork":null},{"id":"MVP065","key":"next_step_on_close","group":"followups_reminders","title":"Следующий шаг врача при закрытии и одна связанная задача","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-domain.js","anchor":"decision / closeStep"},{"path":"src/followup-ui.js","anchor":"followUpSaveOnClose"}]},"current":{"summary":"Явный выбор завершения, записи или контакта позже сохраняется атомарно с закрытием приёма; повтор команды не создаёт дубль.","evidence":[{"path":"server/dentcore/clinical.py","anchor":"close_visit"},{"path":"server/dentcore/followup_models.py","anchor":"Followup"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"Следующий шаг врача при закрытии и одна связанная задача","result":"PASS"}]},"acceptance":["Выбрать завершено/записать/связаться позже, дату/цель","Вместе с закрытием создать ровно один связанный факт/задачу","Ошибка закрытия не оставляет задачу"],"remainingWork":""},{"id":"MVP066","key":"followup_context","group":"followups_reminders","title":"Следующий шаг в календаре/карте пациента с исходным приёмом","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-ui.js","anchor":"followUpCalendarBar / followUpPatientSection"}]},"current":{"summary":"Очереди сейчас/позже/история/все доступны в календаре и карте пациента; переходы сохраняют пациента, источник и день Минска.","evidence":[{"path":"client/src/app/followups/page.tsx"},{"path":"client/src/app/page.tsx"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"Следующий шаг в календаре/карте пациента с исходным приёмом","result":"PASS"}]},"acceptance":["Due/later/history/all в календаре и карте","Правильный пациент/врач/цель/источник","Перейти в разрешённый приём без раскрытия чужого"],"remainingWork":""},{"id":"MVP067","key":"followup_new_booking","group":"followups_reminders","title":"Создать новую запись непосредственно из задачи","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-ui.js","anchor":"followUpBookingDialog / followUpBookingForm"}]},"current":{"summary":"Из задачи можно подобрать окно, создать или связать запись с тем же пациентом и явным врачом; конфликты сохраняют ввод, повтор не создаёт дубль.","evidence":[{"path":"client/src/app/followups/page.tsx"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"Создать новую запись непосредственно из задачи","result":"PASS"}]},"acceptance":["Новая запись получает пациента/врача/цель","Подобрать/подтвердить окно","Запись/связь сохраняются без дубля","Отказ оставляет задачу открытой"],"remainingWork":""},{"id":"MVP068","key":"followup_reopen","group":"followups_reminders","title":"Вернуть следующий шаг после отмены/неявки записи","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/followup-domain.js","anchor":"status"}]},"current":{"summary":"Отмена и неявка возвращают задачу к контакту, завершённая запись завершает следующий шаг; прежние контакты и события сохраняются.","evidence":[{"path":"server/dentcore/followup_models.py","anchor":"Followup"},{"path":"server/dentcore/followups.py","anchor":"close"},{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","anchor":"newImplementedIds / checks"}],"newVerification":[{"path":"server/verification/mvp-parity-through-0038-2026-10-02.json","date":"2026-10-02","scope":"Вернуть следующий шаг после отмены/неявки записи","result":"PASS"}]},"acceptance":["Отмена/неявка возвращает необходимость контакта","Выполненный приём завершает следующий шаг","Сохранить предыдущие контакты/историю","Возобновление не переписывает прежний факт"],"remainingWork":""},{"id":"MVP069","key":"call_list","group":"followups_reminders","title":"Обзвон по дню, ответы пациента и CSV списка","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderCalls / callDialog / u-calls-export"}]},"current":{"summary":"Реализовано и проверено в коммерческом API/интерфейсе; реальные внешние сообщения не отправляются.","evidence":[{"path":"server/dentcore/communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/src/components/communications-screen.tsx","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/communications-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Список предстоящих записей/телефон/последний ответ","Подтвердил/не дозвонились/перезвонить/перенести/отменяет","CSV того же дня","Телефония не запускается"],"remainingWork":""},{"id":"MVP070","key":"consents","group":"followups_reminders","title":"Согласия сервис/реклама, канал, основание, история и отзыв","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"consentRecordDialog / u-consent-form / u-consent-revoke-confirm"},{"path":"src/v3-base.js","anchor":"consentDialog"}]},"current":{"summary":"Реализовано и проверено в коммерческом API/интерфейсе; реальные внешние сообщения не отправляются.","evidence":[{"path":"server/dentcore/communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/src/components/communications-screen.tsx","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/communications-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Сервис и реклама отдельно с датой/основанием/каналом","SMS opt-in и linked channels","Отзыв блокирует будущие reminders","Отметка не заменяет подпись, скан отдельно"],"remainingWork":""},{"id":"MVP071","key":"reminder_rules","group":"followups_reminders","title":"Demo настройки 24ч/2ч, каналы, fallback и шаблон сообщения","required":true,"weight":1,"status":"implemented","mvp":{"kind":"local_simulator","sourceRefs":[{"path":"src/schedule-domain.js","anchor":"channelFor / reminderText"},{"path":"src/v3-base.js","anchor":"renderReminderRules / renderChannels"}]},"current":{"summary":"Реализовано и проверено в коммерческом API/интерфейсе; реальные внешние сообщения не отправляются.","evidence":[{"path":"server/dentcore/communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/src/components/communications-screen.tsx","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/communications-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Явно demo","Настроить интервалы/каналы/шаблон и preview","Канал учитывает согласие/link","Fallback SMS только opt-in","Не отправлять наружу"],"remainingWork":""},{"id":"MVP072","key":"reminder_queue","group":"followups_reminders","title":"Demo планирование, version dedupe и отмена устаревших jobs","required":true,"weight":1,"status":"implemented","mvp":{"kind":"local_simulator","sourceRefs":[{"path":"src/schedule-domain.js","anchor":"syncJobs"},{"path":"src/v3-base.js","anchor":"renderMessages / clockDialog"}]},"current":{"summary":"Реализовано и проверено в коммерческом API/интерфейсе; реальные внешние сообщения не отправляются.","evidence":[{"path":"server/dentcore/communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/src/components/communications-screen.tsx","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/communications-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Управляемые demo часы","Ключ appointment+version+offset без дубля","Перенос/приход/отмена отменяют старые jobs","Paused/blocked/skipped-late имеют причину"],"remainingWork":""},{"id":"MVP073","key":"reminder_processing","group":"followups_reminders","title":"Demo обработка/сбой/retry/expiry и ответ пациента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"local_simulator","sourceRefs":[{"path":"src/schedule-domain.js","anchor":"runQueue"},{"path":"src/v3-base.js","anchor":"processQueue / messagePhone / patientMessagePreview"}]},"current":{"summary":"Реализовано и проверено в коммерческом API/интерфейсе; реальные внешние сообщения не отправляются.","evidence":[{"path":"server/dentcore/communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/src/components/communications-screen.tsx","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_communications.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/communications-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Воспроизвести сбой/retry/15-minute expiry без дублей","Ответ применяется к действующей версии записи","Всегда помечать результат симуляцией","Реальная доставка отделена и требует настроенного согласованного канала"],"remainingWork":""},{"id":"MVP074","key":"print_profile","group":"documents_print","title":"Профили вклейки: A4/A5/свои размеры, шрифт/поля/режим","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/record-domain.js","anchor":"validate / presets"},{"path":"src/record-ui.js","anchor":"recordProfileDialog"}]},"current":{"summary":"Геометрия/профили/Unicode и layout проверены.","evidence":[{"path":"server/dentcore/documents_pdf.py","anchor":"validate_profile"},{"path":"server/tests/test_documents.py"},{"path":"client/src/app/documents/page.tsx"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Сохранить исходные настройки бумаги/области/отступов/font/minFont/autofit/compact-expanded/works","Невозможная геометрия отвергается","Профиль версионируется"],"remainingWork":null},{"id":"MVP075","key":"snapshot_pagination","group":"documents_print","title":"Печать снимка выбранной версии и продолжения без потери текста","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/record-ui.js","anchor":"fit / printRecord"},{"path":"src/v3-base.js","anchor":"printSnapshot"}]},"current":{"summary":"Frozen bytes и длинные продолжения/версии проверены.","evidence":[{"path":"server/dentcore/documents_pdf.py"},{"path":"server/dentcore/documents.py","anchor":"visit_documents"},{"path":"server/tests/test_documents.py"},{"path":"server/tests/test_medical_amendments.py"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Все разделы/услуги/диагнозы не обрезаются","Исходная/исправленная версия выбирается явно","Старые bytes не меняются будущими ценами/текстами/профилем"],"remainingWork":null},{"id":"MVP076","key":"preview_calibration_history","group":"documents_print","title":"Предпросмотр/печать, 50-мм калибровка и история выпусков","required":true,"weight":1,"status":"implemented","mvp":{"kind":"manual_print_workflow","sourceRefs":[{"path":"src/record-ui.js","anchor":"testPrint / recordPrintHistory"},{"path":"src/unified-ui.js","anchor":"printReady"}]},"current":{"summary":"Calibration/immutable history/private downloads и UI print проверены; физический принтер отдельно.","evidence":[{"path":"server/dentcore/documents.py","anchor":"calibration / documents"},{"path":"server/tests/test_documents.py"},{"path":"client/tests/documents-browser.cjs"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Открыть выбранный сохранённый выпуск","Скачать те же bytes","Сгенерировать 50мм вектор/вызвать print","Не объявлять реальный принтер откалиброванным без измерения"],"remainingWork":null},{"id":"MVP077","key":"document_texts","group":"documents_print","title":"Редактор проектов текстов двух согласий и договора","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"docTemplatesDialog / u-document-templates-form"}]},"current":{"summary":"Версионированные тексты и неподписанные проекты с неизменяемым снимком, историей и приватным PDF реализованы; фактические скачивания и печатный текст проверены.","evidence":[{"path":"server/dentcore/project_documents.py"},{"path":"server/dentcore/project_document_pdf.py"},{"path":"server/tests/test_project_documents.py"},{"path":"client/src/components/project-documents-screen.tsx"},{"path":"client/src/components/project-texts-screen.tsx"},{"path":"client/tests/project-documents-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-project-documents-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Версионировать три исходных текста по правам","Новые previews берут выбранную версию","Старые документы сохраняются","Проект не выдаётся за юридически согласованный"],"remainingWork":""},{"id":"MVP078","key":"consent_contract_print","group":"documents_print","title":"Проекты согласий/договора с реквизитами и снимком","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"documentPreview / docPage"}]},"current":{"summary":"Версионированные тексты и неподписанные проекты с неизменяемым снимком, историей и приватным PDF реализованы; фактические скачивания и печатный текст проверены.","evidence":[{"path":"server/dentcore/project_documents.py"},{"path":"server/dentcore/project_document_pdf.py"},{"path":"server/tests/test_project_documents.py"},{"path":"client/src/components/project-documents-screen.tsx"},{"path":"client/src/components/project-texts-screen.tsx"},{"path":"client/tests/project-documents-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-project-documents-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Правильные реквизиты клиники/пациента/банка/согласия","Явный неподписанный статус","Private snapshot/история","Запрет чужого пациента"],"remainingWork":""},{"id":"MVP079","key":"treatment_history_print","group":"documents_print","title":"Документ общей истории лечения пациента","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"documentPreview(history)"}]},"current":{"summary":"Версионированные тексты и неподписанные проекты с неизменяемым снимком, историей и приватным PDF реализованы; фактические скачивания и печатный текст проверены.","evidence":[{"path":"server/dentcore/project_documents.py"},{"path":"server/dentcore/project_document_pdf.py"},{"path":"server/tests/test_project_documents.py"},{"path":"client/src/components/project-documents-screen.tsx"},{"path":"client/src/components/project-texts-screen.tsx"},{"path":"client/tests/project-documents-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-project-documents-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Разрешённые приёмы хронологически с эффективными диагнозами/лечением/услугами","Черновик явно","Снимок/полнота текста/tenant ACL"],"remainingWork":""},{"id":"MVP080","key":"plan_estimate_print","group":"documents_print","title":"Печать конкретного плана и сметы","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"planPrint"}]},"current":{"summary":"Версионированные тексты и неподписанные проекты с неизменяемым снимком, историей и приватным PDF реализованы; фактические скачивания и печатный текст проверены.","evidence":[{"path":"server/dentcore/project_documents.py"},{"path":"server/dentcore/project_document_pdf.py"},{"path":"server/tests/test_project_documents.py"},{"path":"client/src/components/project-documents-screen.tsx"},{"path":"client/src/components/project-texts-screen.tsx"},{"path":"client/tests/project-documents-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-project-documents-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Вариант/статус/врач/пациент/этап/зуб/услуги/qty/сумма/итог","Сохранённые цены совпадают со сметой","Новый вариант не меняет прежний выпуск"],"remainingWork":""},{"id":"MVP081","key":"forms_projection","group":"forms_controls","title":"BY дневной 037/у и месячный 039/у как внутренние макеты","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"form037Table / form039Table / renderForms"}]},"current":{"summary":"BY №203 shaped draft и pinned inputs проверены. Каталог старого HTML не является нормативной истиной.","evidence":[{"path":"server/dentcore/report_drafts.py","anchor":"forms"},{"path":"client/src/app/report-forms/page.tsx"},{"path":"server/tests/test_report_drafts.py"},{"path":"server/verification/step21-forms-037-039-2026-09-29.md"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Выбрать день/месяц/работника","Использовать закрытые/закреплённые источники","Неофициальный статус явно","Только BY источники, не ошибочное Л3/российский бланк"],"remainingWork":null},{"id":"MVP082","key":"binding_counting_trace","group":"forms_controls","title":"Привязки услуг, автоматический подсчёт и расшифровка числа","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"mappingRow"},{"path":"src/unified-domain.js","anchor":"form039"},{"path":"src/unified-ui.js","anchor":"formTraceDialog"}]},"current":{"summary":"Проверены внутренние привязки/клинические подтверждения и неизменяемые расчёты с расшифровкой, замечаниями, сравнением, CSV/печатью и отдельной демоотметкой. Официальный модуль не активируется.","evidence":[{"path":"server/dentcore/internal_reports.py"},{"path":"server/dentcore/internal_report_import.py"},{"path":"server/tests/test_internal_reports.py"},{"path":"client/src/components/internal-reports-screen.tsx"},{"path":"client/tests/internal-reports-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-internal-reports-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Несколько BY привязок/методов/возрастных фильтров и версии","Количество/зубы/приёмы/пациенты/возраст/профилактика/диагнозы/итоги по проверенным BY правилам","Unknown не ноль","Число раскрывается до допустимых источников","Старый расчёт воспроизводим"],"remainingWork":""},{"id":"MVP083","key":"preflight_compare","group":"forms_controls","title":"Проверка полноты, переход к проблеме и сравнение прошлого месяца","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"detailedIssues / renderPreflight"}]},"current":{"summary":"Проверены внутренние привязки/клинические подтверждения и неизменяемые расчёты с расшифровкой, замечаниями, сравнением, CSV/печатью и отдельной демоотметкой. Официальный модуль не активируется.","evidence":[{"path":"server/dentcore/internal_reports.py"},{"path":"server/dentcore/internal_report_import.py"},{"path":"server/tests/test_internal_reports.py"},{"path":"client/src/components/internal-reports-screen.tsx"},{"path":"client/tests/internal-reports-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-internal-reports-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Критические и организационные замечания отдельно","Перейти к разрешённой проблеме","Сравнить посещения/первичных/детских/сельских с одинаковыми BY правилами","Нулевая/unknown база явно","Полнота не означает медицинскую истину"],"remainingWork":""},{"id":"MVP084","key":"demo_submission_revision","group":"forms_controls","title":"Демоотметка сдачи и уточнение после корректировки периода","required":true,"weight":1,"status":"implemented","mvp":{"kind":"local_simulator","sourceRefs":[{"path":"src/v3-base.js","anchor":"submit-form"},{"path":"src/unified-ui.js","anchor":"renderForms"}]},"current":{"summary":"Проверены внутренние привязки/клинические подтверждения и неизменяемые расчёты с расшифровкой, замечаниями, сравнением, CSV/печатью и отдельной демоотметкой. Официальный модуль не активируется.","evidence":[{"path":"server/dentcore/internal_reports.py"},{"path":"server/dentcore/internal_report_import.py"},{"path":"server/tests/test_internal_reports.py"},{"path":"client/src/components/internal-reports-screen.tsx"},{"path":"client/tests/internal-reports-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-internal-reports-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["В synthetic demo пометить конкретный расчёт","Исправление источника требует нового расчёта/уточнения","Старый расчёт не переписывается","Не активировать official module/не имитировать подпись"],"remainingWork":""},{"id":"MVP085","key":"forms_csv_print","group":"forms_controls","title":"CSV и печать неподписанных расчётных форм","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"exportForm"},{"path":"src/unified-ui.js","anchor":"u-form-print"}]},"current":{"summary":"Проверены внутренние привязки/клинические подтверждения и неизменяемые расчёты с расшифровкой, замечаниями, сравнением, CSV/печатью и отдельной демоотметкой. Официальный модуль не активируется.","evidence":[{"path":"server/dentcore/internal_reports.py"},{"path":"server/dentcore/internal_report_import.py"},{"path":"server/tests/test_internal_reports.py"},{"path":"client/src/components/internal-reports-screen.tsx"},{"path":"client/tests/internal-reports-browser.cjs"}],"newVerification":[{"path":"server/verification/mvp-internal-reports-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Те же строки/фильтры/работник/период","Неподписанный статус ясно","Внутренний макет не требует official activation","Tenant/CSV safety"],"remainingWork":""},{"id":"MVP086","key":"daily_dashboard","group":"analytics_audit","title":"Обзор дня: оказано/получено/записи и открытые задачи","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderDashboard"}]},"current":{"summary":"Ролевые сводки/аналитика/безопасный журнал проверены, числа раскрывают исходные факты; неизвестные значения не подменяются нулём.","evidence":[{"path":"server/dentcore/analytics.py","anchor":"Implemented module and regression scenarios"},{"path":"server/dentcore/audit_journal.py","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_analytics_audit.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/analytics-audit-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Оказанные услуги отдельно от поступлений минус возвраты","Предстоящие/неподтверждённые/открытые приёмы/blocked demo jobs","Сверяемые переходы к разрешённым источникам"],"remainingWork":""},{"id":"MVP087","key":"flow_and_finance_dashboard","group":"analytics_audit","title":"Заполняемость/неявки/повторы и долги/источники за период","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/unified-ui.js","anchor":"renderDashboard"},{"path":"src/domain.js","anchor":"aggregate"}]},"current":{"summary":"Ролевые сводки/аналитика/безопасный журнал проверены, числа раскрывают исходные факты; неизвестные значения не подменяются нулём.","evidence":[{"path":"server/dentcore/analytics.py","anchor":"Implemented module and regression scenarios"},{"path":"server/dentcore/audit_journal.py","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_analytics_audit.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/analytics-audit-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Сверить заранее заданные minutes/no_show/repeats и финансовые итоги","Production capacity из реальных смен вместо учебных 09–20","Нулевой/unknown знаменатель явно","Источник обращения отдельно","Оборот не называется чистой прибылью"],"remainingWork":""},{"id":"MVP088","key":"change_access_journals","group":"analytics_audit","title":"Общий журнал изменений и открытий карточек","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"renderAudit"},{"path":"src/unified-ui.js","anchor":"renderAudit / navigate / u-access-log"}]},"current":{"summary":"Ролевые сводки/аналитика/безопасный журнал проверены, числа раскрывают исходные факты; неизвестные значения не подменяются нулём.","evidence":[{"path":"server/dentcore/analytics.py","anchor":"Implemented module and regression scenarios"},{"path":"server/dentcore/audit_journal.py","anchor":"Implemented module and regression scenarios"},{"path":"server/tests/test_analytics_audit.py","anchor":"Implemented module and regression scenarios"},{"path":"client/tests/analytics-audit-browser.cjs","anchor":"Implemented module and regression scenarios"}],"newVerification":[{"path":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Разрешённые кто/когда/объект/действие/изменение","Отдельные обращения к карте без клинического payload","Журнал неизменяем/tenant-scoped","Не раскрывать секреты/медтекст в before/after"],"remainingWork":""},{"id":"MVP089","key":"tenant_export_restore","group":"data_backup_demo","title":"Полная собственная выгрузка и проверенное восстановление","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"export-data"},{"path":"src/unified-ui.js","anchor":"validateImport / u-restore-confirm"}]},"current":{"summary":"Canonical tenant export/atomic empty-target import, protected Postgres+file snapshots/disposable restore проверены. Новые parity models должны включаться в перенос; старый HTML JSON автоматически не совместим.","evidence":[{"path":"server/dentcore/data_transfer.py"},{"path":"server/dentcore/data_import.py"},{"path":"server/tests/test_data_transfer.py"},{"path":"server/core_ops.py"},{"path":"server/verification/step50-local-upgrade-and-restore-2026-10-02.md"},{"path":"server/verification/full-recheck-v1.72-2026-10-02.md","type":"historical_audit","date":"2026-10-02"}],"newVerification":[]},"acceptance":["Выгрузить все реализованные domain objects/files без паролей/сессий","Проверить hashes/связи до записи","Атомарный собственный импорт и verified backup restore","Новые parity объекты включаются до их зачёта","Проверка restore не меняет источник"],"remainingWork":null},{"id":"MVP090","key":"demo_reset","group":"data_backup_demo","title":"Воспроизводимое вымышленное демо и безопасный сброс","required":true,"weight":1,"status":"implemented","mvp":{"kind":"working_local_prototype","sourceRefs":[{"path":"src/v3-base.js","anchor":"reset"},{"path":"src/demo-data.js"},{"path":"src/unified-data.js"}]},"current":{"summary":"Отдельная зарегистрированная вымышленная демобаза: создание, проверка, контролируемые изменения и безопасный сброс проверены; пять ролей прошли реальный API/BFF и браузер. Рабочие базы и их файлы не изменились.","evidence":[{"path":"server/demo_environment.py"},{"path":"server/dentcore/management/commands/seed_release_demo.py"},{"path":"server/tests/test_demo_environment.py"},{"path":"server/tests/test_release_demo.py"},{"path":"client/tests/release-demo-readonly-browser.cjs"},{"path":"docs/commercial/RELEASE_DEMO_GUIDE.md"}],"newVerification":[{"path":"server/verification/mvp090-release-demo-web-2026-10-03.json","date":"2026-10-03","status":"PASS"},{"path":"server/verification/mvp090-release-demo-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},"acceptance":["Восстановить воспроизводимый demo набор только explicit synthetic tenant/DB","Рабочие клиники/прежние выпуски не меняются","Demo показывает полный перенесённый цикл без внешних отправок"],"remainingWork":""}],"presentationRequirements":{"countedInFunctionalPercent":false,"requiredAsPartOfRequestedMvpParity":true,"reason":"Единый обязательный UX пакет не разбит на косметические подпункты ради процента. Эквивалентный современный интерфейс допустим.","sourceRefs":["src/unified-ui.js#u-theme / colorsDialog / u-group","src/v3-base.js#keydown / searchDialog / discardGuard","docs/FEATURES.md#Оформление"],"requirements":[{"key":"theme","status":"implemented","acceptance":"Переключение/сохранение light-dark темы, не просто один новый стиль.","newVerification":[{"path":"server/verification/mvp-presentation-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},{"key":"doctor_colors","status":"implemented","acceptance":"Настраиваемый цвет врача отличим от статуса записи.","newVerification":[{"path":"server/verification/mvp-presentation-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]},{"key":"navigation_keyboard_responsive","status":"implemented","acceptance":"Все переносимые функции доступны в понятной навигации/с клавиатуры/на согласованных размерах; быстрый поиск/новая запись/guards имеют эквивалент и не теряются.","newVerification":[{"path":"server/verification/mvp-presentation-final-2026-10-03.json","date":"2026-10-03","status":"PASS"}]}],"verifiedAt":"2026-10-03","verificationReceipt":"server/verification/mvp-presentation-final-2026-10-03.json"},"boundaries":[{"key":"real_message_delivery","status":"external","includedInDenominator":false,"mvpWas":"Только simulator, после закрытия вкладки отправок нет.","requirement":"Обязателен явный demo simulator и проверяемые состояния. Real configurable outbox/transport отдельно; provider/доступы/consent и настоящая отправка только после согласованной настройки/разрешения."},{"key":"official_by_forms","status":"external","includedInDenominator":false,"mvpWas":"Неофициальные макеты, ошибочное Л3 и несверенный каталог.","requirement":"Перенести внутренние макеты/расчёт/печать по проверенным BY источникам. Official release/МКБ-10С требуют реальных решений/оснований клиники/уполномоченного органа; не имитировать подписи."},{"key":"physical_printer_devices","status":"external","includedInDenominator":false,"requirement":"Программные preview/print/calibration в scope; конкретный принтер/телефон и физический лист подтверждаются при подключении."},{"key":"hosting_external_storage","status":"external","includedInDenominator":false,"requirement":"Арендованный сервер/домен/HTTPS/две сети/внешнее backup storage остаются внедрением. Этот реестр не закрывает C31–C37."},{"key":"profitability","status":"not_an_actual_mvp_function","includedInDenominator":false,"mvpWas":"Стоимость услуг, материалы как часть тарифа, receipts/debt/refund/commission и справочная цена склада. Полной модели расходов/себестоимости/налогов/чистой прибыли нет.","requirement":"Перенести существующие финансовые показатели; не называть их чистой прибылью и не запускать новый cost-accounting как якобы потерянную функцию."},{"key":"legacy_html_json","status":"needs_verification","includedInDenominator":false,"requirement":"Поддерживаемая собственная canonical copy/restore обязательна. Старый HTML v4 JSON не совместим автоматически; нужен отдельный converter/plan, если потребуется именно перенос старых наборов. Реальные пациентские данные в HTML были запрещены."},{"key":"not_working_prd_ideas","includedInDenominator":false,"source":"docs/FEATURES.md","examples":["DICOM/поверхности","внешняя онлайн-запись","партии/сроки и cost accounting","касса/банк","авансы/рассрочка/лояльность","реальные ДМС-реестры","автоматическая стерильность/управление оборудованием"],"requirement":"Не считать архивные намерения действовавшими функциями и не исполнять их этим реестром."}],"nextPriorities":[],"verificationHistory":[{"date":"2026-10-02","type":"inventory_only","result":"Read-only инвентаризация. Изменён только этот новый JSON, tests/servers/архивы/DB не запускались.","counts":{"needs_verification":10,"unimplemented":49,"implemented":31},"percent":34.4},{"date":"2026-10-02","type":"implemented_verified","receipt":"server/verification/mvp-parity-through-0036-2026-10-02.json","newImplementedIds":["MVP001","MVP002","MVP003","MVP005","MVP006","MVP007","MVP010","MVP011","MVP012","MVP014","MVP015","MVP016","MVP021","MVP023","MVP024","MVP027","MVP028","MVP030","MVP032","MVP034","MVP036","MVP037","MVP038","MVP041","MVP045","MVP046","MVP047","MVP048","MVP049","MVP053","MVP056","MVP057","MVP059","MVP060","MVP061","MVP062"],"added":36,"implemented":67,"total":90,"percent":74.4},{"date":"2026-10-02","type":"implemented_verified","receipt":"server/verification/mvp-parity-through-0038-2026-10-02.json","newImplementedIds":["MVP040","MVP051","MVP065","MVP066","MVP067","MVP068"],"added":6,"implemented":73,"total":90,"percent":81.1},{"date":"2026-10-03","type":"implemented_verified","receipt":"server/verification/mvp-final-release-checkpoint-2026-10-03.json","newImplementedIds":["MVP069","MVP070","MVP071","MVP072","MVP073","MVP086","MVP087","MVP088"],"added":8,"implemented":81,"total":90,"percent":90},{"date":"2026-10-03","type":"implemented_verified","receipt":"server/verification/mvp-project-documents-final-2026-10-03.json","newImplementedIds":["MVP077","MVP078","MVP079","MVP080"],"added":4,"implemented":85,"total":90,"percent":94.4},{"date":"2026-10-03","type":"implemented_verified","receipt":"server/verification/mvp090-release-demo-web-2026-10-03.json","newImplementedIds":["MVP090"],"added":1,"implemented":86,"total":90,"percent":95.6},{"date":"2026-10-03","type":"implemented_verified","receipt":"server/verification/mvp-internal-reports-final-2026-10-03.json","newImplementedIds":["MVP082","MVP083","MVP084","MVP085"],"added":4,"implemented":90,"total":90,"percent":100}],"computed":{"overall":{"implemented":90,"total":90,"remaining":0,"needsVerification":0,"percent":100},"groups":{"access_registry":{"implemented":8,"total":8,"remaining":0,"needsVerification":0,"percent":100},"schedule":{"implemented":8,"total":8,"remaining":0,"needsVerification":0,"percent":100},"clinical":{"implemented":9,"total":9,"remaining":0,"needsVerification":0,"percent":100},"templates":{"implemented":5,"total":5,"remaining":0,"needsVerification":0,"percent":100},"plans":{"implemented":8,"total":8,"remaining":0,"needsVerification":0,"percent":100},"finance_payroll":{"implemented":13,"total":13,"remaining":0,"needsVerification":0,"percent":100},"inventory_assistant":{"implemented":8,"total":8,"remaining":0,"needsVerification":0,"percent":100},"payers":{"implemented":3,"total":3,"remaining":0,"needsVerification":0,"percent":100},"followups_reminders":{"implemented":11,"total":11,"remaining":0,"needsVerification":0,"percent":100},"documents_print":{"implemented":7,"total":7,"remaining":0,"needsVerification":0,"percent":100},"forms_controls":{"implemented":5,"total":5,"remaining":0,"needsVerification":0,"percent":100},"analytics_audit":{"implemented":3,"total":3,"remaining":0,"needsVerification":0,"percent":100},"data_backup_demo":{"implemented":2,"total":2,"remaining":0,"needsVerification":0,"percent":100}}}}