Skip to content

Prescription ​

Responsibility and model ​

Prescription owns doctor-authored clinical documents and shared global diagnosis, advice and investigation labels, plus structured chief complaint/history catalogs. Clinical documents include drafts, ordered clinical sections, structured medication orders, issuance snapshots, cancellation, and prescription-derived patient history. The doctor owns the document; organization_id is its context. Patient profiles and professional doctor details remain provider-owned data.

Current implementation ​

The clinical document Huma contracts validate requests and return 501 for valid input. No lifecycle transitions, clinical document database writes, author permissions, organization sharing, or snapshot persistence are implemented. Previous in-memory PUT/DELETE mutations have been replaced in the mounted API by PATCH and explicit issue/cancel actions. Legacy domain/adapter files retained in source do not make those earlier routes active.

Diagnosis, advice, and investigation catalogs have working PostgreSQL-backed CRUD APIs. These routes are global and do not require authentication, authorization, organization context, or audit writes.

Prescription generation suggestions ​

SuggestionDiagnosis, SuggestionAdvice, and SuggestionInvestigation are separate entities, each with its own public contract, repository interface, PostgreSQL adapter, CRUD use cases and HTTP handler. Their existing tables remain separate; no schema migration is needed for the entity split.

Each catalog is available at /api/v1/prescriptions/suggestions/{catalog}, where catalog is diagnosis, advice, or investigation.

MethodPath suffixBehavior
POSTcollectionCreate an entry; returns 201
GETcollectionList/search entries; returns 200
GET/{entityId}Get an entry; returns 200
PATCH/{entityId}Update its label; returns 200
DELETE/{entityId}Permanently delete it; returns 200 with data: {}

The detail path parameter is specific to each entity: suggestionDiagnosisId, suggestionAdviceId or suggestionInvestigationId.

POST and PATCH accept only {"label":"Example phrase"}. An entry contains only id and label; IDs are server-generated UUIDs. Labels are trimmed, nonblank, and limited to 500 characters. Duplicate labels within the same catalog, ignoring case, return 409. Missing entries return 404; invalid input returns 422.

GET collections support q (a case-insensitive literal substring, up to 255 characters), limit (default 20, maximum 100), and cursor. Results are ordered by label and ID ascending and use {"message":"...","status_code":200,"data":[{"id":"...","label":"..."}],"pagination":{"next_cursor":"..."}}. The next cursor is an empty string on the final page, and empty results contain data: []. Cursors are bound to their catalog and search query. Unknown query/body fields, including the old text field, are rejected.

Apply the tables with go run ./tools/cli database migrate --service prescription. The three active label rx_*_suggestions tables each contain only id and label and use goose_prescription_version for migration history. New catalogs start empty; populate them with POST requests. Catalog mutations do not rewrite clinical document entries or their existing API contracts. Offline schema generation works without a database; suggestion requests then return 503.

Clinical workflows ​

Patient and prescription workflows details draft creation and edits, ordered clinical content, medication/follow-up validation, issuance, cancellation, privacy, and history. Intended rules keep drafts private to the author, share issued/canceled history within the organization, and retain immutable patient/doctor display snapshots on issuance. History derives only from issued/canceled prescriptions, excluding private drafts and unrelated lab records.

Medicine-linked medication data can reference the global catalog while retaining the prescription's clinical instructions. Contract and example validation is implemented; looking up catalog records and enforcing stateful clinical rules remains future work.

Examples and verification ​

Download the complete prescription example. This fixture is copied from source during docs generation and is an intended payload rather than an actual persisted record.

json
{
  "patient_id": "patient_123",
  "encounter_date": "2026-10-08",
  "visit_reason": "Fever and cough",
  "specialty_id": "general-medicine",
  "notes": "Review at follow-up",
  "complaints": [
    {
      "id": "cc1",
      "concept_id": "fever",
      "label": "Fever",
      "duration": {
        "value": 3,
        "unit": "day"
      },
      "details": {
        "onset": "sudden",
        "course": "intermittent",
        "severity": "moderate",
        "location": "generalized",
        "laterality": "bilateral",
        "character": "febrile",
        "radiation": "none",
        "pattern": "evening",
        "aggravating_factors": [
          "activity"
        ],
        "relieving_factors": [
          "rest"
        ],
        "associated": [
          {
            "concept_id": "cough",
            "label": "Cough",
            "polarity": "present",
            "raw_text": "dry cough"
          }
        ],
        "custom_details": [
          {
            "id": "detail1",
            "raw_text": "worse at night",
            "normalized_value": "night",
            "attribute": "pattern",
            "concept_id": "nocturnal",
            "confidence": 0.9,
            "source": "clarification-custom",
            "status": "structured",
            "source_question_id": "q1",
            "was_custom_answer": true,
            "include_in_paper": false
          }
        ]
      }
    }
  ],
  "history": [
    {
      "id": "h1",
      "concept_id": "diabetes",
      "label": "Diabetes",
      "polarity": "present",
      "duration": {
        "value": 8,
        "unit": "year"
      },
      "value": "treated",
      "emphasis": "allergy"
    }
  ],
  "observations": [
    {
      "id": "o1",
      "type": "bp",
      "label": "Blood pressure",
      "value": "120/80",
      "unit": "mmHg"
    }
  ],
  "investigations": [
    {
      "id": "i1",
      "code": "CBC",
      "label": "Complete blood count"
    }
  ],
  "diagnoses": [
    {
      "id": "d1",
      "concept_id": "urti",
      "label": "URTI"
    }
  ],
  "medications": [
    {
      "id": "m1",
      "medication_id": "med_1",
      "display_name": "Medicine A",
      "form": "tablet",
      "strength": "500 mg",
      "sig": {
        "frequency": "1-0-1",
        "duration": {
          "value": 5,
          "unit": "day"
        },
        "meal_relation": "after",
        "timing": [
          "morning",
          "evening"
        ],
        "instruction": "With water"
      }
    },
    {
      "id": "m2",
      "display_name": "Custom medication",
      "sig": {
        "duration": {
          "ongoing": true
        },
        "instruction": "Continue the existing directions"
      }
    }
  ],
  "advice": [
    {
      "id": "a1",
      "phrase_id": "rest",
      "text": "Rest"
    }
  ],
  "follow_up": {
    "value": 3,
    "unit": "day",
    "label": "After 3 days",
    "formatted_date": "11 October 2026"
  }
}

Future clinical document tests must cover author-only writes, organization isolation, issuance requirements, immutable snapshots, version races, cancellation history, transactional persistence, and post-commit events. Existing contract tests cover schemas, local validation, PATCH presence, rich content round trips, and 501 responses. Suggestion tests cover all routes, field validation, PostgreSQL CRUD, catalog isolation, Unicode labels, search, cursor traversal, deletion, duplicate races, and migration rollback/replay. Run PostgreSQL tests with PRESCRIPTION_TEST_DATABASE_URL or AUTH_TEST_DATABASE_URL pointing to a dedicated local test database.

Code reference ​

See public clinical contracts, module, and use cases.

Structured clinical input catalogs ​

The clinical input workflow provides Doctor-only authenticated GETs and permission-protected Admin CRUD for chief complaints and all twelve history categories. Shared domain contracts/ports use pkg/types/domain for models/validation and pkg/types/ports for the two clinical services and repositories; their implementations remain here. New catalog writes commit atomically with Audit. The legacy history HTTP operations are removed, while rx_history_suggestions remains private for recovery.

Documentation follows the source. Planned contracts are marked explicitly.