Skip to content

KrinosAI — Software Requirements Specification (SRS)

Template ID: TPL-02-04 | Stage: 02-Requirements | Version: 0.3
Record: KAI-VORAL-SRS-001 — retrospective draft for Visionary Oral. Not approved.

Purpose: State every verifiable software requirement with a unique ID, so design, code and tests can trace to it.

Required inputs: Approved PRD; use cases; DPIA findings; risk-control measures; interface constraints.

Document control

Field Required entry
Document ID KAI-VORAL-SRS-001
Template used TPL-02-04 Software Requirements Specification (SRS) v0.3
Product / project / software version or commit SHA VORAL (Visionary Oral) / PRJ-001 / a6b4429e3165 (branch app_dev of AI-Dental-Project/Visionary_Oral)
Record status and version Draft v0.1
Author / technical reviewer / quality reviewer Claude Code (drafted with Claude Code for KrinosAI) / Tech Lead (name to be assigned) / Security & Privacy Officer (name to be assigned)
Created / updated / approved dates 2026-10-27 / 2026-10-27 / Pending
Applicable SOP and revision SOP-LC-02 v0.3
Related issue, commit, requirement and evidence links KAI-VORAL-BRF-001, KAI-VORAL-IRS-001, KAI-VORAL-CHR-001, KAI-VORAL-DEC-001; docs/lifecycle/_evidence/api-inventory-a6b4429.md
Approver and decision record Pending

Applicability and evidence baseline

Product / system boundary: Web app and API (dentalapp/), doctor/admin mobile app (mobile/), PDF Lambda (dentalapp/pdf-lambda/) at a6b4429e3165, and the external services they call (see KAI-VORAL-IRS-001). Related approved requirements, risks and change records: None approved. Related drafts are listed in document control. Retrospective record? Yes — follows the Retrospective Documentation Protocol (KrinosAI lifecycle pack, 05-References/). Items are labelled Observed (code or Git at a6b4429), Measured (dated run), Stated (named person, dated) or Not recorded. Requirements are written from the behaviour observed in code (what the system does today), plus the security/privacy controls the risk screen requires; requirements not met by today's code say so and cite the OPEN item. Acceptable evidence: an implementation reference (file:line at a commit SHA), a dated test record, a signed decision, a vendor agreement, or another independently verifiable artifact. Never invent approvals, clinical results, measurements or performance data.

1. System boundary and operating context

Element Inside / outside Notes
Web app and API (dentalapp/, Next.js) Inside 75 API route files — docs/lifecycle/_evidence/api-inventory-a6b4429.md
Doctor/admin mobile app (mobile/, Expo) Inside On-device ONNX detectors; offline queue
PDF Lambda (dentalapp/pdf-lambda/) Inside Renders the print page to PDF; stores in S3
ML service (Visionary_oral_ML, Hugging Face Space) Outside — integration Called with ML_BACKEND_URL
Clerk, MongoDB, Cloudflare R2, AWS S3/Lambda, OpenRouter, Groq, Resend, Cashfree, Expo EAS Outside — integrations See KAI-VORAL-IRS-001 §5
Clinical diagnosis, treatment planning, radiographs Outside — excluded KAI-VORAL-BRF-001 §4

2. Atomic functional requirements with REQ IDs

REQ ID Requirement Source Priority Verification
REQ-001 The system shall authenticate web and mobile users through Clerk and reject API calls without a valid session or bearer token with HTTP 401. dentalapp/src/lib/auth-helpers.js:20-27; mobile/src/lib/api/client.ts @ a6b4429 Must Test
REQ-002 The system shall resolve each user's role (admin, doctor, patient) from the profiles collection and route the user to the matching area. dentalapp/src/app/api/user/role/route.js; mobile/app/_layout.tsx @ a6b4429 Must Test
REQ-003 The system shall block a suspended doctor from doctor routes (HTTP 403 "Account suspended") and show the mobile "Account suspended" screen. dentalapp/src/lib/auth-helpers.js:72-74; dentalapp/src/app/api/user/role/route.js:34-41; mobile/src/lib/api/auth.ts @ a6b4429 Must Test
REQ-004 The mobile app shall re-check the account status when it returns to the foreground and every 2 minutes while online. mobile/app/_layout.tsx:162 @ a6b4429 Should Test
REQ-005 An admin shall be able to invite a doctor by email; the system shall create a Clerk invitation, record it and report whether the invitation email was sent. dentalapp/src/app/api/admin/doctors/route.js:208 @ a6b4429 Must Test
REQ-006 An admin shall be able to resend an invitation, including an expired one. dentalapp/src/app/api/admin/invitations/[invitationId]/resend-invitation/route.js:12 @ a6b4429 Should Test
REQ-007 A doctor who signs up without an invitation shall be stored with status "pending" and shall not use doctor features until an admin approves the account. dentalapp/src/app/api/onboarding/route.js:105; dentalapp/src/app/api/admin/doctors/[clerkId]/approve/route.js:14 @ a6b4429 Must Test
REQ-008 An admin shall be able to suspend and unsuspend a doctor, with the reason and the acting admin recorded. dentalapp/src/app/api/admin/doctors/[clerkId]/suspend/route.js:14; …/unsuspend/route.js:12 @ a6b4429 Must Test
REQ-009 An admin shall be able to set a doctor's offline access limit as days + hours + minutes (max 365 days) or remove it. dentalapp/src/app/api/admin/doctors/[clerkId]/offline-days/route.js:66 @ a6b4429 Must Test
REQ-010 A doctor shall be able to create, view, edit and delete their own patients; access to another doctor's patient shall be refused. dentalapp/src/app/api/patients/route.js:163; dentalapp/src/app/api/patients/[id]/route.js:127; verifyPatientOwnership in dentalapp/src/lib/auth-helpers.js @ a6b4429 Must Test
REQ-011 The mobile app shall let a doctor create and edit patients offline and send the changes when the backend is reachable. mobile/src/lib/offline/patientOutbox.ts:245 @ a6b4429 Must Test
REQ-012 The scan flow shall capture exactly three guided views: front, upper jaw, lower jaw. dentalapp/src/app/scan/page.js:23; mobile/src/features/scan/steps.ts:23,39,60 @ a6b4429 Must Inspection
REQ-013 Each captured photo shall pass a quality check (teeth found, coverage, centring, sharpness) and the user shall be asked to retake a photo that fails the minimums. mobile/src/ml/qualityGate.ts:14; mobile/src/ml/qualityDecision.ts:46; web dentalapp/src/app/api/validate-scan/route.js:8 @ a6b4429 Must Test
REQ-014 The mobile app shall save each captured photo to app storage before any upload, so a scan survives loss of connection. mobile/src/lib/offline/scanQueue.ts:29 @ a6b4429 Must Test
REQ-015 The system shall upload scan photos to object storage and attach them to one scan document per scan ID, retrying failed uploads. dentalapp/src/app/api/upload/route.js:121; mobile/src/lib/api/upload.ts:34; mobile/src/lib/offline/syncManager.ts:188 @ a6b4429 Must Test
REQ-016 Each patient shall have at most one report (scan) on the website flow. dentalapp/src/app/api/scans/route.js:99-111 @ a6b4429 Should Test
REQ-017 The system shall run the cavity, calculus, gum recession and swollen gums detectors on the front photo, and only cavity and calculus on upper- and lower-jaw photos. mobile/src/ml/analysis.ts:18-24; server dentalapp/src/app/api/analyze-gemini/route.js:641-650 @ a6b4429 Must Test
REQ-018 The mobile app shall run the detectors on the phone (ONNX) without internet, with a 120 s limit per detector step. mobile/src/ml/analysis.ts:123, DETECTOR_TIMEOUT_MS @ a6b4429 Must Test
REQ-019 The mobile app shall send on-device findings to the backend, which stores them on the matching photos of the scan owned by that doctor. dentalapp/src/app/api/scans/analysis/route.js:37 @ a6b4429 Must Test
REQ-020 The report shall show the three photos with detection boxes, counts per finding, a risk level per finding and an overall hygiene score computed by the fixed rules. dentalapp/src/lib/reportCalculations.js:9,173-175; mobile/report-renderer/entry.jsx:741 @ a6b4429 Must Test
REQ-021 The report shall include AI-generated personalized text based on the findings and the patient's stated concern. dentalapp/src/app/api/personalized-analysis/route.js:216-228,561 @ a6b4429 Should Inspection
REQ-022 The report shown for a scan taken on the phone shall be the same every time it is opened: the phone's full copy until the server copy of the same scan has all photos with findings. mobile/src/report/reportData.ts:182 @ a6b4429 Must Test
REQ-023 Users shall be able to download the report as a PDF (web via the PDF Lambda and download tokens; mobile generated on the phone). dentalapp/src/app/api/download-report/route.js:9; dentalapp/src/lib/download-tokens.js:13; mobile/src/report/savePdf.ts:56 @ a6b4429 Must Test
REQ-024 Reports and patient-facing pages shall be available in English, Hindi and Marathi according to the patient's preferred language. dentalapp/src/lib/i18n.js:35; dentalapp/src/translations/en.js, hi.js, mr.js @ a6b4429 Should Inspection
REQ-025 The mobile app shall keep reports available offline by saving patients' latest reports on the phone while online. mobile/src/report/precache.ts:77 @ a6b4429 Should Test
REQ-026 When a doctor's offline access limit runs out while offline, the mobile app shall lock; once back online it shall report this and the backend shall suspend the account until an admin unsuspends it. mobile/src/lib/offline/sessionGate.ts; dentalapp/src/app/api/user/offline-limit-exceeded/route.js:21 @ a6b4429 Must Test
REQ-027 The mobile app shall treat the device as online only when the backend answers (reachability checked against the backend). mobile/src/lib/netReachability.ts:15 @ a6b4429 Should Test
REQ-028 A doctor shall be able to view and edit clinic details and generate a patient-registration QR code; the mobile screen shall open from a saved copy without waiting for the network. dentalapp/src/app/api/clinic/generate-qr/route.js:6; mobile/app/(doctor)/clinic-info.tsx @ a6b4429 Should Test
REQ-029 A patient shall be able to self-register through a clinic QR code and take a scan in a time-limited public session tied to that clinic. dentalapp/src/app/api/public/patient-registration/route.js:30; dentalapp/src/app/api/public/create-scan-session/route.js:6 @ a6b4429 Should Test
REQ-030 Doctors shall be able to buy plans and subscriptions through Cashfree; payment status shall be updated from signed Cashfree webhooks. dentalapp/src/app/api/payments/create-order/route.js:8; dentalapp/src/app/api/billing/subscription/create/route.js:8; dentalapp/src/app/api/webhooks/cashfree/route.js:5 @ a6b4429 Should Test
REQ-031 Admins shall be able to see per-doctor usage (reports, images, AI and ML calls) and global statistics. dentalapp/src/app/api/admin/global-stats/route.js; dentalapp/src/app/api/admin/api-usage/route.js:6 @ a6b4429 Should Test
REQ-032 Users shall be able to raise support tickets and exchange messages with admins. dentalapp/src/app/api/support/route.js:20; dentalapp/src/app/api/support/messages/route.js @ a6b4429 Could Test
REQ-033 Doctors shall receive in-app notifications and milestone feedback prompts. dentalapp/src/app/api/doctor/notifications/route.js:6; dentalapp/src/lib/milestone-helpers.js:70 @ a6b4429 Could Inspection
REQ-034 Every API route that returns personal data, admin data or triggers paid AI calls shall require an authenticated and authorized caller. Required by the risk screen; not met by 20 routes in docs/lifecycle/_evidence/api-inventory-a6b4429.md (e.g. dentalapp/src/app/api/admin/patient-sample/route.js:5-11) — OPEN-026 Must Test
REQ-035 Secrets shall come only from environment variables or a vault: no credentials in the repository and no hard-coded fallback secrets. Required by the risk screen; not met: OPEN-007, OPEN-017 (dentalapp/src/lib/admin/session.js:4) Must Inspection
REQ-036 Photos and report files shall be served only to the scan's owner, an admin, or a holder of a valid time-limited token. dentalapp/src/app/api/image/route.js:19; dentalapp/src/app/api/scans/route.js:173-223 (public session) @ a6b4429 Must Test

3. Input and output specifications

REQ ID Data item Format / range Invalid input behavior
REQ-012 Scan photos JPEG from camera, cropped to the guide; front/upper/lower Quality gate asks for a retake (REQ-013)
REQ-010 Patient record firstName, lastName, phone, email, dob, gender, message, preferredLanguage (dentalapp/src/app/api/patients/route.js:102-112) HTTP 400 with a field error; mobile shows the server message
REQ-009 Offline limit Whole numbers: days 0–365, hours 0–23, minutes 0–59; total ≥ 1 minute and ≤ 365 days HTTP 400 "must be a whole number" / "at most 365 days" (…/offline-days/route.js)
REQ-019 Findings payload { scanId, views: { front, upper, lower: [{ class, confidence, box[4] }] } }, values clamped to 0–1 HTTP 400 if scanId or views missing (dentalapp/src/app/api/scans/analysis/route.js:42-46)
REQ-005 Invitation firstName, lastName, email (valid format), clinicName, optional phone HTTP 400 per field; 409 if the doctor or invitation already exists

4. Performance availability reliability constraints

REQ ID Requirement Condition
REQ-018 Each on-device detector step completes or fails within 120 s Per photo, per model (DETECTOR_TIMEOUT_MS)
REQ-015 Failed uploads are retried with growing delays up to 5 times MAX_RETRIES in mobile/src/lib/offline/syncManager.ts @ a6b4429
REQ-001 API calls time out after 75 s (allows a cold-started host) DEFAULT_TIMEOUT_MS in mobile/src/lib/api/client.ts @ a6b4429
REQ-028 Response-time and availability targets Proposed (Claude Code, for confirmation): API p95 ≤ 2 s; availability 99.5 %

5. Usability and accessibility needs

REQ ID Requirement
REQ-024 Patient-facing text in English, Hindi and Marathi
REQ-012 Each capture step shows instructions and a reference image before the camera opens (mobile/src/features/scan/steps.ts)
REQ-030 Accessibility requirements: Proposed (Claude Code, for confirmation): WCAG 2.1 AA for web pages; screen-reader labels and system text scaling in the app

6. Interfaces and security requirements

REQ ID Requirement
REQ-001 All non-public API routes require a Clerk session or bearer token
REQ-034 Every route returning personal/admin data or calling paid AI requires an authorized caller — not met today (OPEN-026)
REQ-035 No secrets in the repository; no fallback secrets — not met today (OPEN-007, OPEN-017)
REQ-036 Photos and PDFs only to owner, admin or valid token holder
REQ-030 Cashfree webhooks accepted only with a valid signature (CASHFREE_WEBHOOK_SECRET)

7. Error handling and negative behaviors

REQ ID Condition Required behavior
REQ-003 Account suspended HTTP 403 "Your account has been suspended"; mobile shows "Account suspended"
REQ-007 Account pending approval Doctor routes refuse ("Account waiting for approval"); mobile shows "Waiting for approval"
REQ-013 Photo fails quality minimums Retake requested; "Use anyway" offered when the check could not run
REQ-015 Upload fails Photo stays queued on the phone and is retried; after 5 failures the user can retry manually
REQ-005 Invitation email fails Invitation still saved; response says emailSent: false with the reason
REQ-026 Offline limit runs out offline App locks; suspension is reported when back online

8. Measurable verification criteria

REQ ID Pass criterion
REQ-001 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-002 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-003 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-004 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-005 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-006 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-007 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-008 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-009 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-010 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-011 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-012 Verified by inspection of code and UI at the release commit — OPEN-032
REQ-013 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-014 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-015 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-016 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-017 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-018 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-019 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-020 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-021 Verified by inspection of code and UI at the release commit — OPEN-032
REQ-022 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-023 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-024 Verified by inspection of code and UI at the release commit — OPEN-032
REQ-025 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-026 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-027 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-028 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-029 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-030 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-031 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-032 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-033 Verified by inspection of code and UI at the release commit — OPEN-032
REQ-034 Verified by test case(s) to be defined in stage 07 — OPEN-032
REQ-035 Verified by inspection of code and UI at the release commit — OPEN-032
REQ-036 Verified by test case(s) to be defined in stage 07 — OPEN-032

9. Baselining and change control

Baseline Date Approved by Change process
SRS baseline v0.1 (draft, retrospective) 2026-10-27 Product Owner (name to be assigned) Changes through a Requirements Change Request (KAI-VORAL-RCR-001) and the RTM

Open issues and decisions

ID Specific gap or decision Responsible owner Due date Blocks gate? Evidence required Status
OPEN-001 Tracker project ID, named requester and sponsor, and named reviewers are not recorded Product Owner 2026-11-10 (proposed) Yes Tracker entry; names with roles Open
OPEN-007 Credential files committed to Git: dentalapp/google-credentials.json, dentalapp/mongoDb_usernamePassword (contents not opened) Security & Privacy Officer 2026-10-31 (proposed) Yes Credentials rotated; files removed and purged from history; confirmation Open
OPEN-017 Admin session signing uses a hard-coded fallback secret when JWT_SECRET is unset (dentalapp/src/lib/admin/session.js:4) Backend Lead 2026-11-10 (proposed) Yes Code fix; secret confirmed set Open
OPEN-026 Critical: 20 API routes have no authentication check, incl. /api/admin/patient-sample (patient emails) and /api/admin/api-usage (doctor names and emails), support tickets/messages, and paid AI routes (/api/detect-gemini, /api/speech-to-text, /api/validate-scan) — see docs/lifecycle/_evidence/api-inventory-a6b4429.md Backend Lead 2026-10-31 (proposed) Yes Auth added to each route; re-run of the inventory shows none unprotected Open
OPEN-028 No nonfunctional targets (response time, availability, analysis time, offline period) are defined Product Owner 2026-11-30 (proposed) No Approved NFR targets Open
OPEN-030 No accessibility requirements or checks (contrast, screen readers, text size) Product Owner 2026-12-15 (proposed) No Accessibility requirements and a test record Open
OPEN-032 Design (DES) and test (TC) links for requirements are added by stages 03 and 07; requirements without them stay open Tech Lead 2026-12-15 (proposed) No RTM with DES and TC links Open

Review and approval

Review role Named individual Decision Date Signed / controlled record
Author Claude Code (drafted with Claude Code) Draft 2026-10-27 This file at the commit that adds it
Technical reviewer Tech Lead (name to be assigned) Pending Pending Pending
Quality / regulatory reviewer (if applicable) Qualified regulatory reviewer (name to be assigned) Pending Pending Pending
Authorized approver Product Owner (name to be assigned) Pending Pending Pending