Ctrl K
ComunidadGuías…

docs/shepherd-migration-support-plan.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Shepherd migration support plan

This document defines the public, vendor-level contract. Clinic archives,
filenames, values, identifiers, row errors, and mapping evidence never belong
in the repository, issues, pull requests, CI logs, or test fixtures.

## Goal

Move the operational record a clinic needs to work in OpenVPM while preserving
source identity and documenting every record that was imported, deferred,
reviewed manually, or excluded. The same pipeline must work for another
Shepherd clinic. Other PIMS vendors plug into the same normalized domain plan.

## Supported migration surface

The reusable Shepherd adapter now supports:

- owners, patients, vaccinations, and locked SOAP history with stable source
  identity;
- non-sending care reminders;
- billable services and active products, with imported product inventory
  explicitly untracked until a clinic enters a reviewed opening quantity;
- co-owner/contact history, historical appointments, prescriptions and fills,
  lab reports, financial documents, line items, payments, and allocations as a
  read-only migration archive; and
- allowlisted PDF, JPEG, PNG, and plain-text documents through checksum-verified
  managed storage. A document without an exact source relationship remains
  unlinked and visibly needs review.

The same normalized tables, source identities, retry semantics, review states,
and operator UI are clinic-independent. A new Shepherd clinic supplies a new
private manifest and reviewed coverage plan; it does not require clinic-specific
code or fixtures.

## Operational versus historical state

- Owners, patients, vaccinations, finalized notes, care reminders, services,
  and the untracked product catalog can support current clinic work after the
  practice review hold is released.
- Historical appointments never create upcoming calendar work.
- Imported prescriptions and fills are clinical history, not a new prescription
  or authorization to dispense.
- Financial documents and payments are historical evidence, not live invoices,
  receivables, credits, or opening balances.
- A product can be billed while inventory is untracked, but it cannot be used as
  clinic stock. Stock tracking starts only through an explicit opening-count
  action.
- Imported co-owners are client contacts. They receive no portal account,
  permission, consent, or communication access from the migration.

## Reusable domain boundaries

- Source adapters emit only normalized domain records; tenant rows never
  depend on Shepherd filenames or private archive paths.
- Every supported row carries a practice-scoped source identity and a
  deterministic payload fingerprint. An exact retry is convergent; the same
  source ID with changed content fails closed.
- A reviewed preview is bound to aggregate decisions and exact target versions
  before commit. The durable migration ledger contains only hashes, counts,
  source namespace, lifecycle state, and operator identity.
- Source rows that share an ambiguous name/code or patient relationship are
  deferred together. File order is never used to choose a winner.
- Care-reminder imports create internal staff work only. They cannot create a
  communication, restore consent, or schedule a provider send.
- Service imports cannot create products, change stock, create invoices, or
  mutate existing manual catalog rows.

## Deliberate exclusions

- Vendor authentication, credentials, runtime settings, audit logs, and staff
  accounts are never portable.
- Historical invoices and payments are reference-only until OpenVPM can prove
  the opening balance without altering live accounts receivable or inventory.
- A source lab panel is kept as a typed document when its structure cannot be
  represented by OpenVPM's scalar lab result without losing meaning.
- Communication history never restores SMS consent, provider delivery state,
  or an outbound send queue.
- Historical stock quantities, lots, and expirations are not trusted as current
  inventory. A clinic must verify and enter an opening count.
- Source diagnoses or procedures without an exact patient/event relationship are
  not synthesized into clinical events. Existing locked source notes remain the
  evidence until a reviewed adapter can preserve their semantics without
  duplication.
- Unlinked document bodies remain available only in the migration archive and
  require a human relationship review before being treated as patient evidence.

## Commit safety

- Put the practice under a recovery/review hold before the first write.
- Use one immutable bundle hash and a reviewed coverage-plan hash.
- Namespace every external identity by source and practice.
- Use deterministic entity IDs or an immutable entity-link receipt, plus a
  payload hash, so retrying is convergent and changed source data conflicts.
- Commit in dependency order with bounded transactions. Clinical content and
  its patient link commit together.
- Upload documents before linking them; require checksum, size, object version
  or ETag, and an `available` manifest state.
- Reconcile source, eligible, imported, deferred, excluded, and error counts.
  Those counts must add up exactly for every domain.
- Keep the hold until a reviewer checks owner/patient identity, medical
  timelines, reminders, medications, catalog behavior, documents, and the
  exception report in the application.

## Public-repository rules

- Tests use synthetic clinics and canary values only.
- Logs and evidence contain fixed reason codes, schema fingerprints, hashes,
  and aggregate counts. They contain no source paths, filenames, headers,
  record values, names, contact details, notes, or external IDs.
- Private operator manifests are owner-only files outside the repository.
- CI may run generated synthetic archives and a disposable Postgres drill. It
  must never access a clinic archive or production database.