# Airmid Domain — Technical Specifications

> **Airmid** — Evidence-Based Phytotherapy and Botanical Intelligence Platform

This document specifies what is actually implemented in the Airmid domain.
Airmid is a **pure library domain**: 19 TypeScript libraries under
`libs/airmid/`, with no applications and no standalone services. Every type,
schema, enum, event, endpoint definition, and database table described below is
traceable to source under `libs/airmid/`.

The document is organized to mirror how the code layers. It starts with the
shared foundation (`@airmid/core`) — the types, entities, errors, events, and
constants that every other library builds on — then covers the database schema,
the API layer, and finally a summary surface for each scientific library.
Reading this document alongside `features.md` gives a complete picture:
`features.md` explains what each module does and why; this document specifies
the exact types, enum values, table names, and function signatures involved.

The canonical planning backlog is **Phase 35** of `TODOS.md` (`35.1`–`35.20`).

---

## 1. Library Inventory

All 19 libraries are private workspace packages (`version: 0.1.0`,
`type: module`, source entry `./src/index.ts`). Every package depends on `zod`
(catalog). `@airmid/database` additionally depends on `knex` and (dev) `uuid`.
`@airmid/ml` additionally depends on `@airmid/api` (`workspace:*`). All packages
carry `vitest` as a dev dependency.

| Package                  | Path                         | Purpose                                                              |
| ------------------------ | ---------------------------- | -------------------------------------------------------------------- |
| `@airmid/core`           | `libs/airmid/core`           | Foundation types, branded IDs, enums, entities, errors, events       |
| `@airmid/ethno`          | `libs/airmid/ethno`          | Ethnobotanical knowledge — TCM, Ayurveda, Unani, Indigenous systems  |
| `@airmid/phytochem`      | `libs/airmid/phytochem`      | Computational phytochemistry — properties, drug-likeness, ADMET      |
| `@airmid/evidence`       | `libs/airmid/evidence`       | Trial integration, systematic review, GRADE grading, evidence search |
| `@airmid/interactions`   | `libs/airmid/interactions`   | Herb-drug interaction clinical decision support                      |
| `@airmid/docking`        | `libs/airmid/docking`        | Molecular docking, virtual screening, QSAR, molecular dynamics       |
| `@airmid/network`        | `libs/airmid/network`        | Network pharmacology — targets, PPI, pathway/GO enrichment           |
| `@airmid/formulation`    | `libs/airmid/formulation`    | Synergy analysis, extraction, stability, bioavailability             |
| `@airmid/microbiome`     | `libs/airmid/microbiome`     | Microbiome pharmacology — prebiotics, metabolites, dysbiosis         |
| `@airmid/precision`      | `libs/airmid/precision`      | Pharmacogenomics, genotype-response, biomarker integration           |
| `@airmid/quality`        | `libs/airmid/quality`        | DNA barcoding, spectroscopy, chromatography, chemometrics            |
| `@airmid/safety`         | `libs/airmid/safety`         | Adverse events, hepatotoxicity, nephrotoxicity, special populations  |
| `@airmid/regulatory`     | `libs/airmid/regulatory`     | Pharmacopoeia compliance, EMA/HMPC, FDA, global status, labeling     |
| `@airmid/sustainability` | `libs/airmid/sustainability` | Conservation status, sourcing, environmental impact, substitution    |
| `@airmid/ml`             | `libs/airmid/ml`             | Biomedical NLP, GNN, transformers, generative models                 |
| `@airmid/vision`         | `libs/airmid/vision`         | Plant identification — leaf, flower, bark, multi-organ matching      |
| `@airmid/clinical`       | `libs/airmid/clinical`       | FHIR, CDS Hooks, interaction alerts, patient education               |
| `@airmid/api`            | `libs/airmid/api`            | External DB connectors, ETL, OpenAPI spec, export/reporting          |
| `@airmid/database`       | `libs/airmid/database`       | PostgreSQL schema (Knex migrations + Zod schemas)                    |

Every Nx project carries the tags `scope:airmid`, `layer:domain`, `type:lib`.

---

## 2. Core Foundation Types (`@airmid/core`)

Defined in `libs/airmid/core/src/types.ts`. All branded ID types use a
`Brand<T, B>` nominal-typing helper and are validated against a UUID v4 pattern.
Branded types catch a common class of bug where a `CompoundId` is accidentally
passed where a `SpeciesId` is expected — the TypeScript compiler rejects such
assignments even though both are strings at runtime.

### 2.1 Branded ID Types

The following ID types are used as foreign keys throughout all domain entities
and events:

| Type             | Brand             | Zod schema             | Validation |
| ---------------- | ----------------- | ---------------------- | ---------- |
| `SpeciesId`      | `Brand<string,…>` | `SpeciesIdSchema`      | UUID v4    |
| `CompoundId`     | `Brand<string,…>` | `CompoundIdSchema`     | UUID v4    |
| `TrialId`        | `Brand<string,…>` | `TrialIdSchema`        | UUID v4    |
| `InteractionId`  | `Brand<string,…>` | `InteractionIdSchema`  | UUID v4    |
| `MonographId`    | `Brand<string,…>` | `MonographIdSchema`    | UUID v4    |
| `PathwayId`      | `Brand<string,…>` | `PathwayIdSchema`      | UUID v4    |
| `AdverseEventId` | `Brand<string,…>` | `AdverseEventIdSchema` | UUID v4    |

### 2.2 Chemical Identifier Types

Chemical identity management requires strict format validation — a corrupted CAS
number or InChIKey breaks cross-database linking. These types enforce the
official format rules for each identifier:

| Type                  | Definition       | Pattern / Notes                                                   |
| --------------------- | ---------------- | ----------------------------------------------------------------- |
| `CASNumber`           | branded `string` | `CAS_NUMBER_PATTERN` = `/^\d{2,7}-\d{2}-\d$/`                     |
| `SMILES`              | `string` alias   | Line notation of molecular structure                              |
| `InChIKey`            | `string` alias   | `INCHI_KEY_PATTERN` = `/^[A-Z]{14}-[A-Z]{10}-[A-Z]$/`             |
| `MolecularFormula`    | `string` alias   | Hill-system notation                                              |
| `AdministrationRoute` | union            | `'oral' \| 'sublingual' \| 'topical' \| 'inhalation' \| 'rectal'` |

### 2.3 Enumerations

All enumerations are TypeScript `enum`s with string values. They are used as
column types in the database schema (§8) and as discriminants in entity computed
properties throughout the domain. The full set of enums:

- **`TaxonomicRank`** — `Kingdom`, `Phylum`, `Class`, `Order`, `Family`,
  `Genus`, `Species`, `Subspecies`, `Variety`, `Cultivar`.
- **`CompoundClass`** — `Alkaloid`, `Flavonoid`, `Terpene`, `Terpenoid`,
  `Phenol`, `Polyphenol`, `Tannin`, `Saponin`, `Glycoside`, `Coumarin`,
  `Lignin`, `Steroid`, `EssentialOil`, `FattyAcid`, `Amino`, `Carbohydrate`,
  `Vitamin`, `Mineral`, `Other` (19 members).
- **`GRADEQuality`** — `High`, `Moderate`, `Low`, `VeryLow`.
- **`OxfordLevel`** — `Level1a`, `Level1b`, `Level2a`, `Level2b`, `Level3a`,
  `Level3b`, `Level4`, `Level5` (Oxford CEBM, March 2009).
- **`StudyDesign`** — `SystematicReview`, `MetaAnalysis`, `RCT`, `CohortStudy`,
  `CaseControl`, `CaseSeries`, `CaseReport`, `CrossSectional`, `InVitro`,
  `InVivo`, `ExVivo`, `Computational`.
- **`EvidenceStrength`** — `Strong`, `Moderate`, `Limited`, `Insufficient`,
  `Conflicting`.
- **`InteractionSeverity`** — `Contraindicated`, `Major`, `Moderate`, `Minor`,
  `Theoretical`.
- **`InteractionMechanism`** — `CYP450Inhibition`, `CYP450Induction`,
  `PGPInhibition`, `ProteinBindingDisplacement`, `PharmacodynamicSynergy`,
  `PharmacodynamicAntagonism`, `GIAbsorptionAlteration`, `RenalClearanceChange`,
  `Other`.
- **`AdverseReactionType`** — `Allergic`, `Hepatotoxic`, `Nephrotoxic`,
  `Neurotoxic`, `Dermatologic`, `GI`, `Cardiovascular`, `Respiratory`,
  `Hematologic`, `Endocrine`, `Other`.
- **`CausalityAssessment`** — `Certain`, `Probable`, `Possible`, `Unlikely`,
  `Conditional`, `Unassessable` (WHO-UMC categories).
- **`DosageForm`** — `Tincture`, `Decoction`, `Infusion`, `Capsule`, `Tablet`,
  `Extract`, `EssentialOil`, `Poultice`, `Salve`, `Syrup`, `Powder`, `Tea`,
  `Cream`, `Oil` (14 members).
- **`DosageUnit`** — `mg`, `g`, `mL`, `drops`, `cups`, `tablespoons`,
  `teaspoons`.
- **`PreparationType`** — `Aqueous`, `Ethanolic`, `Hydroethanolic`,
  `Supercritical`, `ColdPressed`, `SteamDistilled`, `Macerated`, `Fermented`.
- **`IUCNStatus`** — `NotEvaluated`, `DataDeficient`, `LeastConcern`,
  `NearThreatened`, `Vulnerable`, `Endangered`, `CriticallyEndangered`,
  `ExtinctInWild`, `Extinct`.
- **`CITESAppendix`** — `None`, `AppendixI`, `AppendixII`, `AppendixIII`.
- **`Pharmacopoeia`** — `USP`, `EP`, `BP`, `JP`, `CP`, `IP`, `WHO`, `ESCOP`,
  `CommissionE`, `HMPC`.
- **`RegulatoryStatus`** — `Approved`, `MonographPublished`, `TraditionalUse`,
  `DietarySupplement`, `Restricted`, `Banned`, `UnderReview`.

### 2.4 Plain Interfaces

The following plain interfaces are used as the raw-data input to entity class
constructors (§3). Each has a corresponding Zod schema that validates the data
at the boundary.

#### `TaxonomicClassification`

Represents a complete Linnaean classification from kingdom down to species, with
optional infraspecific ranks. All required string fields enforce `.min(1)`.

| Field        | Type     | Req. | Meaning                                        |
| ------------ | -------- | ---- | ---------------------------------------------- |
| `kingdom`    | `string` | ✓    | e.g. `"Plantae"`                               |
| `phylum`     | `string` | ✓    | e.g. `"Tracheophyta"`                          |
| `class`      | `string` | ✓    | e.g. `"Magnoliopsida"`                         |
| `order`      | `string` | ✓    | e.g. `"Malpighiales"`                          |
| `family`     | `string` | ✓    | e.g. `"Hypericaceae"`                          |
| `genus`      | `string` | ✓    | e.g. `"Hypericum"`                             |
| `species`    | `string` | ✓    | Specific epithet, e.g. `"perforatum"`          |
| `subspecies` | `string` |      | Infraspecific rank (trinomial nomenclature)    |
| `variety`    | `string` |      | Infraspecific variety rank                     |
| `cultivar`   | `string` |      | Cultivar name                                  |
| `authority`  | `string` | ✓    | Taxonomic authority (e.g. `"L."` for Linnaeus) |

Validated by `TaxonomicClassificationSchema` (Zod).

#### `BotanicalName`

Captures both the formal binomial name (enforced by regex to require
`Genus species` capitalization format) and the human-facing vernacular names and
synonyms used across databases:

| Field         | Type       | Req. | Meaning                         |
| ------------- | ---------- | ---- | ------------------------------- |
| `binomial`    | `string`   | ✓    | `"Genus species"` format        |
| `authority`   | `string`   | ✓    | Taxonomic authority             |
| `commonNames` | `string[]` | ✓    | Vernacular names                |
| `synonyms`    | `string[]` | ✓    | Other accepted scientific names |

Validated by `BotanicalNameSchema`. `binomial` must match
`/^[A-Z][a-z]+ [a-z]+$/`.

#### `DosageGuideline`

Structured dosage data with range bounds and frequency, enabling comparison
across traditional, clinical, and pharmacopoeial dose recommendations:

| Field                 | Type              | Req. | Meaning                        |
| --------------------- | ----------------- | ---- | ------------------------------ |
| `form`                | `DosageForm`      | ✓    | Pharmaceutical form            |
| `preparationType`     | `PreparationType` | ✓    | Extraction/preparation method  |
| `minDose`             | `number`          | ✓    | Minimum single dose (positive) |
| `maxDose`             | `number`          | ✓    | Maximum single dose (positive) |
| `unit`                | `DosageUnit`      | ✓    | Unit of measurement            |
| `frequency`           | `number`          | ✓    | Times per day (integer, 1–12)  |
| `duration`            | `number`          | ✓    | Duration in days (integer ≥ 0) |
| `specialInstructions` | `string`          |      | e.g. `"Take with food"`        |

Validated by `DosageGuidelineSchema`.

#### `CompoundProperties`

Captures the physicochemical descriptors used by drug-likeness filters and ADMET
prediction. The Lipinski Ro5 fields are all required; TPSA and rotatable bonds
are optional because they may not be available for all natural product
structures:

| Field                         | Type            | Req. | Meaning                             |
| ----------------------------- | --------------- | ---- | ----------------------------------- |
| `molecularWeight`             | `number`        | ✓    | Daltons (positive)                  |
| `logP`                        | `number`        | ✓    | Octanol-water partition coefficient |
| `hydrogenBondDonors`          | `number`        | ✓    | NH/OH groups (integer ≥ 0)          |
| `hydrogenBondAcceptors`       | `number`        | ✓    | N/O atoms (integer ≥ 0)             |
| `topologicalPolarSurfaceArea` | `number`        |      | TPSA in Å² (positive)               |
| `rotatableBonds`              | `number`        |      | Integer ≥ 0                         |
| `compoundClass`               | `CompoundClass` | ✓    | Classification                      |

Validated by `CompoundPropertiesSchema`.

#### `StudyMetadata`

Fields: `design` (`StudyDesign`), `sampleSize` (`number`), `blinding`
(`'none' \| 'single' \| 'double'`), `allocation`
(`'random' \| 'quasi-random' \| 'non-random'`), optional
`allocationConcealment`, `intentionToTreat`, `attritionRate`, `effectSize`,
`confidenceInterval` (`[number, number]`), `pValue`.

#### `InteractionRecord`

Fields: `herb` (`string`), `drug` (`string`), `mechanism`
(`InteractionMechanism`), `severity` (`InteractionSeverity`), `evidenceLevel`
(`EvidenceStrength`), `description` (`string`), optional `cyp450Enzymes`
(`string[]`). This is the shape used by the `COMMON_HERB_DRUG_INTERACTIONS`
constant and the core interaction helper functions.

---

## 3. Core Domain Entities (`@airmid/core`)

Defined in `libs/airmid/core/src/entities.ts`. Each entity is a class wrapping a
`Readonly<…Data>` raw-data interface, with constructor validation (throws plain
`Error` on invalid input), computed getters, and a `toJSON()` serializer. There
are **15 entity classes**, each with a matching `…Data` interface. The computed
getters are where domain logic lives — for example,
`ClinicalTrial.evidenceLevel` derives an Oxford evidence level from the study
design, blinding, and allocation fields.

### 3.1 `BotanicalSpecies`

Constructed from `BotanicalSpeciesData`: `id` (`SpeciesId`), `taxonomy`
(`TaxonomicClassification`), `botanicalName` (`BotanicalName`), `description`,
`nativeRegion` (`string[]`), `habitat`, `growthForm`, `plantPartsUsed`
(`string[]`), `iucnStatus` (`IUCNStatus`), `citesAppendix` (`CITESAppendix`),
`imageUrls` (`string[]`).

Computed: `binomialName`, `fullName`, `family`, `isEndangered`, `isCITESListed`,
`taxonomicPath`, `plantPartsUsed`. Methods: `belongsToFamily(family)`,
`hasMedicinalUse()`.

### 3.2 `PhytochemicalCompound`

Constructed from `PhytochemicalCompoundData`: `id` (`CompoundId`), `name`,
`iupacName`, `casNumber`, `smiles`, `inchiKey`, `molecularFormula`,
`molecularWeight`, `logP`, `compoundClass`, `hydrogenBondDonors`,
`hydrogenBondAcceptors`, `rotatableBonds`, `polarSurfaceArea`.

Computed: `molecularWeight`, `isLipinskiCompliant`, `drugLikenessScore` (0–5,
Lipinski Ro5 + Veber rotatable-bond extension), `compoundClassDescription`,
`hasValidCAS`, `hasValidSMILES`, `logPCategory`. Method: `isNaturalProduct()`.

### 3.3 `ClinicalTrial`

Constructed from `ClinicalTrialData`: `id` (`TrialId`), `title`, `registryId`,
`studyDesign`, `phase`, `population`, `sampleSize`, `duration`, `intervention`,
`control`, `primaryOutcome`, `results`, `conclusion`, `blinding`, `allocation`,
`attritionRate`, `effectSize`, `pValue`, `confidenceInterval`, `journal`,
`publicationDate`, `doi`, `speciesId`.

Computed: `isRCT`, `evidenceLevel` (Oxford level from study design + blinding +
allocation), `sampleSizeCategory`, `hasStatisticalSignificance`, `qualityScore`
(composite 0–100), `isBlinded`, `isRandomized`, `yearPublished`. Method:
`meetsInclusionCriteria(minSampleSize, maxPValue)`.

### 3.4 `EvidenceRecord`

Constructed from `EvidenceRecordData`: `id`, `speciesId`, `condition`,
`indication`, `gradeQuality`, `oxfordLevel`, `evidenceStrength`, `studyCount`,
`supportingTrialIds` (`TrialId[]`), `summary`, `recommendation`,
`lastReviewDate`.

Computed: `isHighQuality`, `recommendationStrength`, `needsMoreResearch`,
`isOutdated` (no review in > 5 years), `studyCountCategory`. Method:
`summarize()`.

### 3.5 `DrugHerbInteraction`

Constructed from `DrugHerbInteractionData`: `id` (`InteractionId`), `speciesId`,
`drugName`, `drugClass`, `severity`, `mechanism`, `description`,
`clinicalEvidence` (`EvidenceStrength`), `monitoringRequired`,
`monitoringParameters` (`string[]`), `managementGuideline`.

Computed: `isContraindicated`, `requiresMonitoring`, `affectsCYP450`,
`clinicalSignificance`, `safetyMargin`. Method: `generateClinicalWarning()`.

### 3.6 `AdverseEvent`

Constructed from `AdverseEventData`: `id` (`AdverseEventId`), `speciesId`,
`reactionType`, `description`, `severity`
(`'mild' \| 'moderate' \| 'severe' \| 'fatal'`), `causalityAssessment`,
`patientAge`, `patientSex` (`'male' \| 'female' \| 'other'`), `dose`,
`duration`, `outcome`, `concomitantMedications` (`string[]`), `reportSource`,
`reportDate`.

Computed: `isSeriousEvent`, `causalityStrength`, `isExpectedReaction`,
`requiresReporting`, `outcomeCategory`.

### 3.7 `TraditionalUse`

Constructed from `TraditionalUseData`: `id`, `speciesId`, `tradition`,
`indication`, `preparation`, `dosage`, `plantPart`, `region`,
`historicalPeriod`, `culturalContext`, `referenceSource`.

Computed: `tradition`, `hasScientificValidation` (always `false` — callers must
cross-reference `EvidenceRecord`), `geographicOrigin`, `historicalDepth`,
`preparationComplexity`.

### 3.8 `PharmacognosyMonograph`

Constructed from `MonographData`: `id` (`MonographId`), `speciesId`,
`pharmacopoeia`, `monographId`, `title`, `qualityMarkers`
(`QualityMarkerEntry[]` — `marker`, `minValue`, `maxValue`, `unit`),
`identityTests` (`string[]`), `purityTests` (`string[]`), `assayMethod`,
`storageConditions`, `shelfLifeMonths`, `lastRevisionDate`.

Computed: `pharmacopoeia`, `qualityMarkerCount`, `hasAssayMethod`,
`isCurrentEdition` (revised within 10 years), `shelfLifeMonths`. Method:
`meetsQualityStandard(marker, value)`.

### 3.9 `ProteinTarget`

Constructed from `ProteinTargetData`: `id`, `uniprotId`, `name`, `geneName`,
`organism`, `function`, `subcellularLocation`, `molecularWeight`,
`aminoAcidLength`, `bindingSites` (`BindingSiteEntry[]` — `name`, `residues`,
`type`: `'active_site' \| 'allosteric' \| 'cofactor' \| 'other'`),
`associatedPathways` (`string[]`), `associatedDiseases` (`string[]`),
`compoundIds` (`CompoundId[]`), `pdbIds` (`string[]`).

Computed: `hasValidUniprotId`, `hasStructuralData`, `bindingSiteCount`,
`hasActiveSite`, `isDrugTarget`, `sizeCategory`, `diseaseAssociationCount`,
`hasAllostericSite`.

### 3.10 `BiologicalPathway`

Constructed from `BiologicalPathwayData`: `id` (`PathwayId`), `name`, `keggId`,
`category`, `description`, `organismSpecific`, `nodeCount`, `edgeCount`,
`keyEnzymes` (`string[]`), `substrates`, `products`, `regulators`,
`associatedCompoundIds` (`CompoundId[]`), `associatedDiseases` (`string[]`).

Computed: `hasValidKeggId`, `complexityCategory`, `averageConnectivity`,
`hasCompoundInteractions`, `isDiseaseAssociated`, `isOrganismSpecific`,
`enzymeCount`.

### 3.11 `QualityMarker`

Constructed from `QualityMarkerData`: `id`, `speciesId`, `compoundId`,
`markerName`, `markerType`
(`'active_constituent' \| 'indicator' \| 'adulterant' \| 'contaminant'`),
`minConcentration`, `maxConcentration`, `unit`, `analyticalMethod`,
`pharmacopoeiaReference`, `acceptanceCriteria`.

Computed: `isActiveConstituent`, `isAdulterantMarker`, `isContaminantMarker`,
`concentrationRange`, `targetConcentration`. Methods:
`isWithinSpec(measuredValue)`, `deviationFromTarget(measuredValue)`.

### 3.12 `DNABarcode`

Constructed from `DNABarcodeData`: `id`, `speciesId`, `locus`, `sequence`,
`sequenceLength`, `gcContent` (0–1), `accessionNumber`, `primerForward`,
`primerReverse`, `referenceDatabase`, `similarityThreshold` (0–1),
`authenticates` (`boolean`).

Computed: `isStandardLocus` (ITS, ITS2, rbcL, matK, trnH-psbA),
`gcContentCategory`, `isValidForAuthentication`, `sequenceLengthCategory`,
`hasAccessionNumber`. Method: `isAboveThreshold(querySimilarity)`.

### 3.13 `SpectroscopicFingerprint`

Constructed from `SpectroscopicFingerprintData`: `id`, `speciesId`, `technique`
(`'HPLC' \| 'HPTLC' \| 'GC-MS' \| 'LC-MS' \| 'NMR' \| 'IR' \| 'UV-Vis' \| 'Raman'`),
`samplePreparation`, `instrumentParameters`, `peakCount`, `majorPeaks`
(`SpectroscopicPeak[]` — `position`, `intensity`, `assignment`),
`referenceStandard`, `similarityScore` (0–1), `isAuthentic`, `rawDataUrl`.

Computed: `isChromatographic`, `isSpectroscopic`, `complexityCategory`,
`passesAuthentication` (similarity ≥ 0.9 and `isAuthentic`), `dominantPeak`,
`hasRawData`.

### 3.14 `FormulationRecipe`

Constructed from `FormulationRecipeData`: `id`, `name`, `description`, `form`,
`preparationType`, `ingredients` (`FormulationIngredient[]` — optional
`speciesId`, `name`, `amount`, `unit`, optional `plantPart`, `role`:
`'primary' \| 'adjuvant' \| 'corrective' \| 'vehicle' \| 'preservative'`),
`instructions` (`string[]`), `totalVolume`, `totalVolumeUnit`, `shelfLifeDays`,
`storageConditions`, `indications` (`string[]`), `contraindications`
(`string[]`).

Computed: `ingredientCount`, `primaryIngredientCount`, `isSimple`,
`hasContraindications`, `shelfLifeCategory`, `primaryIngredients`,
`adjuvantIngredients`, `complexityCategory`, `stepCount`.

### 3.15 `ConservationStatus`

Constructed from `ConservationStatusData`: `id`, `speciesId`, `iucnStatus`,
`citesAppendix`, `populationTrend`
(`'increasing' \| 'stable' \| 'decreasing' \| 'unknown'`), `estimatedPopulation`
(`number | null`), `threatFactors` (`string[]`), `conservationActions`
(`string[]`), `assessmentDate`, `assessmentAuthority`, `range` (`string[]`),
`protectedAreaCoverage` (0–100), `sustainableHarvestingPossible` (`boolean`).

Computed: `isThreatened`, `isExtinct`, `isCITESListed`, `isPopulationDeclining`,
`urgencyLevel`, `canBeSustainablyHarvested`, `threatCount`,
`conservationActionCount`, `hasAdequateProtection`.

---

## 4. Core Errors (`@airmid/core`)

Defined in `libs/airmid/core/src/errors.ts`. Airmid errors carry structured
metadata beyond a simple message string — severity, a domain-specific error
code, and a freeform `details` record. This allows callers to handle errors
programmatically (e.g., escalating `Fatal` severity interactions differently
from `Warning` severity taxonomy errors).

### 4.1 `AirmidErrorSeverity`

Enum: `Info`, `Warning`, `Critical`, `Fatal`.

### 4.2 `AirmidErrorCode`

A template-literal union: `AIRMID_TAXONOMY_${string}`,
`AIRMID_COMPOUND_${string}`, `AIRMID_INTERACTION_${string}`,
`AIRMID_EVIDENCE_${string}`, `AIRMID_DOSAGE_${string}`,
`AIRMID_CONTRAINDICATION_${string}`, `AIRMID_QUALITY_${string}`,
`AIRMID_REGULATORY_${string}`.

### 4.3 Error Classes

`AirmidError` is the base class (`Error` subclass) carrying `code`, `severity`,
`details` (`Record<string, unknown>`), `timestamp`, and a `toJSON()` returning
`SerializedAirmidError`. The eight domain-specific subclasses map to the most
clinically significant error categories. Note that `ContraindicationError` and
`DosageExceedanceError` default to the highest severities — these represent
patient-safety critical conditions.

| Class                       | Default code                       | Default severity                               |
| --------------------------- | ---------------------------------- | ---------------------------------------------- |
| `InvalidTaxonomyError`      | `AIRMID_TAXONOMY_INVALID`          | `Warning`                                      |
| `CompoundNotFoundError`     | `AIRMID_COMPOUND_NOT_FOUND`        | `Warning`                                      |
| `InteractionWarningError`   | `AIRMID_INTERACTION_WARNING`       | `Critical`/`Warning` (by interaction severity) |
| `EvidenceConflictError`     | `AIRMID_EVIDENCE_CONFLICT`         | `Info`                                         |
| `DosageExceedanceError`     | `AIRMID_DOSAGE_EXCEEDED`           | `Critical`                                     |
| `ContraindicationError`     | `AIRMID_CONTRAINDICATION_DETECTED` | `Fatal`                                        |
| `QualityControlError`       | `AIRMID_QUALITY_FAILURE`           | `Critical`                                     |
| `RegulatoryComplianceError` | `AIRMID_REGULATORY_VIOLATION`      | `Critical`                                     |

Utilities: `isAirmidError(error)` (type guard), `formatAirmidError(error)`
(human-readable string with severity badge).

---

## 5. Core Domain Events (`@airmid/core`)

Defined in `libs/airmid/core/src/events.ts`. The `AirmidEventType` constant
object provides **13 event type strings**. There is no event bus in the domain;
`createAirmidEvent` builds typed event objects and `resetEventCounter` resets
the in-process ID counter. When the planned Oshun event bus integration is wired
in, these events will flow to other domains without any changes to the event
payloads.

Every event object (`AirmidEvent<T>`) carries `type`, `payload`, `timestamp`
(ISO 8601), `eventId`, and `source` (defaults to `'airmid-core'`).

| Event constant               | Event string                          | Payload type                        |
| ---------------------------- | ------------------------------------- | ----------------------------------- |
| `SpeciesRegistered`          | `airmid.species.registered`           | `SpeciesRegisteredPayload`          |
| `SpeciesUpdated`             | `airmid.species.updated`              | `SpeciesUpdatedPayload`             |
| `CompoundDiscovered`         | `airmid.compound.discovered`          | `CompoundDiscoveredPayload`         |
| `CompoundLinked`             | `airmid.compound.linked`              | `CompoundLinkedPayload`             |
| `InteractionIdentified`      | `airmid.interaction.identified`       | `InteractionIdentifiedPayload`      |
| `InteractionSeverityChanged` | `airmid.interaction.severity_changed` | `InteractionSeverityChangedPayload` |
| `AdverseEventReported`       | `airmid.adverse_event.reported`       | `AdverseEventReportedPayload`       |
| `AdverseEventAssessed`       | `airmid.adverse_event.assessed`       | `AdverseEventAssessedPayload`       |
| `EvidenceAdded`              | `airmid.evidence.added`               | `EvidenceAddedPayload`              |
| `EvidenceGradeChanged`       | `airmid.evidence.grade_changed`       | `EvidenceGradeChangedPayload`       |
| `QualityControlFailed`       | `airmid.quality_control.failed`       | `QualityControlFailedPayload`       |
| `RegulatoryStatusChanged`    | `airmid.regulatory.status_changed`    | `RegulatoryStatusChangedPayload`    |
| `ConservationStatusChanged`  | `airmid.conservation.status_changed`  | `ConservationStatusChangedPayload`  |

### 5.1 Payload Shapes

Each payload carries the minimum fields needed by downstream consumers to act on
the event without querying the database — for example,
`InteractionIdentifiedPayload` includes both `herb` and `drug` names so a
notification service can generate an alert without a separate lookup.

| Payload                             | Fields                                                                                                            |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `SpeciesRegisteredPayload`          | `speciesId`, `binomial`, `family`, `commonNames`                                                                  |
| `SpeciesUpdatedPayload`             | `speciesId`, `binomial`, `updatedFields`                                                                          |
| `CompoundDiscoveredPayload`         | `compoundId`, `name`, `compoundClass`, optional `molecularFormula`                                                |
| `CompoundLinkedPayload`             | `compoundId`, `speciesId`, `plantPart`, optional `concentrationRange`                                             |
| `InteractionIdentifiedPayload`      | `interactionId`, `herb`, `drug`, `mechanism`, `severity`                                                          |
| `InteractionSeverityChangedPayload` | `interactionId`, `herb`, `drug`, `previousSeverity`, `newSeverity`, `reason`                                      |
| `AdverseEventReportedPayload`       | `adverseEventId`, `substance`, `reactionType`, `description`, optional `patientAge`, `patientSex`                 |
| `AdverseEventAssessedPayload`       | `adverseEventId`, `substance`, `causality`, `assessedBy`                                                          |
| `EvidenceAddedPayload`              | `trialId`, `studyDesign`, `herb`, `indication`, `sampleSize`, `outcome` (`'positive' \| 'negative' \| 'neutral'`) |
| `EvidenceGradeChangedPayload`       | `herb`, `indication`, `previousGrade`, `newGrade`, `previousStrength`, `newStrength`, `reason`                    |
| `QualityControlFailedPayload`       | `product`, `testType`, `issue`, optional `batchNumber`, `contaminant`                                             |
| `RegulatoryStatusChangedPayload`    | `substance`, `jurisdiction`, `previousStatus`, `newStatus`, `effectiveDate`                                       |
| `ConservationStatusChangedPayload`  | `speciesId`, `binomial`, `previousStatus`, `newStatus`, `assessmentYear`                                          |

---

## 6. Core Constants and Reference Data (`@airmid/core`)

Defined in `libs/airmid/core/src/constants.ts`. These constants are the
hard-coded scientific reference data that does not change frequently and does
not belong in the database — enzyme identifiers, curated short interaction
lists, WHO-recognized herb lists, and pharmacological parameters.

- **`CYP450_ENZYMES`** — 12 major cytochrome P450 enzyme identifiers (`CYP3A4`,
  `CYP2D6`, `CYP2C9`, `CYP2C19`, `CYP1A2`, `CYP2E1`, `CYP2B6`, `CYP2A6`,
  `CYP2C8`, `CYP3A5`, `CYP3A7`, `CYP2J2`).
- **`COMMON_HERB_DRUG_INTERACTIONS`** — curated `InteractionRecord[]` covering
  St. John's Wort, Ginkgo, Panax ginseng, Kava, Valerian, Garlic, Echinacea,
  Milk thistle, Grapefruit, and Goldenseal.
- **`WHO_ESSENTIAL_MEDICINES_HERBS`** — 25 WHO-recognized medicinal plants, each
  `{ binomial, commonName, primaryUse }`.
- **`GRADE_QUALITY_FACTORS`** — five downgrade factors (risk of bias,
  inconsistency, indirectness, imprecision, publication bias) and three upgrade
  factors (large effect, plausible confounding, dose-response), each with a
  `maxReduction`/`maxIncrease`.
- **`THERAPEUTIC_CATEGORIES`** — 20 categories (Adaptogen, Analgesic, etc.),
  each `{ category, description, examples }`.
- **`ELEMENT_SYMBOLS`** — all 118 periodic-table element symbols, used for
  molecular-formula validation.
- **`BIOAVAILABILITY_ROUTES`** — five administration routes with typical
  bioavailability fractions.
- **`MEDICINAL_PLANT_FAMILIES`** — 10 major medicinal plant families with
  characteristic compounds and example genera.
- **`CYP450_COMPOUND_CLASS_PROFILES`** — maps 11 compound classes to the CYP
  enzymes each inhibits or induces.

---

## 7. Core Validation and Pharmacology Functions

The following utility modules in `@airmid/core` provide standalone functions
used throughout the domain. They operate on the plain interfaces and enums from
§2 rather than on entity class instances.

### 7.1 Validation (`libs/airmid/core/src/validation.ts`)

`validateCASNumber` (check-digit validation), `validateTaxonomy`,
`getRequiredRanksForLevel`, `validateDosage`, `validateSMILES`,
`validateMolecularFormula`, `validateEvidenceGrade`.

### 7.2 Pharmacology (`libs/airmid/core/src/pharmacology.ts`)

`calculateBioavailability`, `estimateHalfLife`, `classifyDrugLikeness` (returns
`LipinskiResult`), `calculateTherapeuticIndex`, `assessCYP450Risk` (returns
`CYP450RiskAssessment`), `calculateDoseEquivalence`.

### 7.3 Taxonomy (`libs/airmid/core/src/taxonomy.ts`)

`formatBinomial`, `parseBotanicalName` (returns `ParsedBotanicalName`),
`getPlantFamily`, `validateBinomialNomenclature`, `buildTaxonomicPath`,
`getCommonFamilies`.

### 7.4 Evidence (`libs/airmid/core/src/evidence.ts`)

`gradeEvidence`, `classifyStudyQuality`, `calculateEffectSize`,
`assessPublicationBias`, `generateEvidenceSummary`, `isRCTQuality`.

### 7.5 Interactions (`libs/airmid/core/src/interactions.ts`)

`assessInteractionRisk`, `getCYP450Profile`, `checkContraindications`,
`formatInteractionWarning`, `rankInteractionsBySeverity`,
`getMonitoringRecommendation`.

---

## 8. Database Schema (`@airmid/database`)

Located at `libs/airmid/database/src`. The library exports Zod schema modules
(`schema/`) and Knex migration functions (`migrations/`). It does **not** open
database connections — it provides schema definitions and migration runners that
a consuming application wires to a PostgreSQL connection.

The schema was designed with several production concerns in mind: `uuid-ossp`
for UUID generation, `pg_trgm` for full-text trigram search, an
`airmid_update_timestamp()` trigger for automatic `updated_at` maintenance,
soft-delete support via `deleted_at` columns, and 5 materialized views for
commonly aggregated queries that would otherwise require expensive joins.

### 8.1 Migrations

Six ordered migration files (timestamp-prefixed `20260318100001`–`…6`). They
must be applied in order — later migrations reference tables and enum types
created by earlier ones.

1. **`initial_setup`** — enables PostgreSQL extensions `uuid-ossp` and
   `pg_trgm`, creates the `airmid_update_timestamp()` trigger function, and
   creates **35 custom enum types** (`growth_form`, `plant_part`, `iucn_status`,
   `cites_appendix`, `compound_class`, `solubility_class`, `extraction_method`,
   `study_design`, `trial_phase`, `blinding_type`, `allocation_type`,
   `grade_quality`, `oxford_level`, `evidence_strength`, `interaction_severity`,
   `interaction_mechanism`, `clinical_evidence_level`, `adverse_reaction_type`,
   `adverse_event_severity`, `causality_assessment`, `adverse_event_outcome`,
   `patient_sex`, `medical_tradition`, `pharmacopoeia_source`,
   `regulatory_jurisdiction`, `regulatory_status_value`, `regulatory_category`,
   `marker_region`, `reference_database`, `spectroscopic_technique`,
   `activity_type`, `population_trend`, `harvest_sustainability`,
   `cultivation_status`, `airmid_audit_action`).
2. **`core_tables`** — `botanical_species`, `phytochemical_compounds`,
   `plant_compound_associations`, `clinical_trials`, `evidence_records`.
3. **`safety_tables`** — `drug_herb_interactions`, `adverse_event_reports`,
   `traditional_use_records`, `pharmacopoeia_monographs`, `regulatory_statuses`.
4. **`genomics_targets`** — `dna_barcodes`, `spectroscopic_fingerprints`,
   `protein_targets`, `compound_target_associations`, `biological_pathways`,
   `conservation_records`, `airmid_audit_logs`.
5. **`materialized_views`** — five materialized views
   (`mv_species_compound_evidence`, `mv_species_interaction_summary`,
   `mv_top_studied_species`, `mv_evidence_by_condition`,
   `mv_compound_activity_summary`), each with a unique index, refreshed with
   `REFRESH MATERIALIZED VIEW CONCURRENTLY`.
6. **`soft_delete`** — adds `deleted_at` columns, partial indexes, cascade
   triggers, and `soft_delete` / `restore` / `purge` helper functions.

Total: **17 base tables** plus 5 materialized views.

### 8.2 Tables (`createTable` calls)

The 17 tables are distributed across three migration files according to their
domain grouping:

| Table                          | Migration        |
| ------------------------------ | ---------------- |
| `botanical_species`            | core_tables      |
| `phytochemical_compounds`      | core_tables      |
| `plant_compound_associations`  | core_tables      |
| `clinical_trials`              | core_tables      |
| `evidence_records`             | core_tables      |
| `drug_herb_interactions`       | safety_tables    |
| `adverse_event_reports`        | safety_tables    |
| `traditional_use_records`      | safety_tables    |
| `pharmacopoeia_monographs`     | safety_tables    |
| `regulatory_statuses`          | safety_tables    |
| `dna_barcodes`                 | genomics_targets |
| `spectroscopic_fingerprints`   | genomics_targets |
| `protein_targets`              | genomics_targets |
| `compound_target_associations` | genomics_targets |
| `biological_pathways`          | genomics_targets |
| `conservation_records`         | genomics_targets |
| `airmid_audit_logs`            | genomics_targets |

### 8.3 Zod Schema Modules

`schema/index.ts` re-exports 15 modules: `common`, `botanical-species`,
`phytochemicals`, `plant-compounds`, `clinical-trials`, `evidence-records`,
`drug-interactions`, `adverse-events`, `traditional-use`, `pharmacopoeia`,
`regulatory`, `genomics`, `targets-pathways`, `conservation`, `audit`.

The `common.ts` module provides shared building blocks used across all other
schema modules: `UuidSchema` (UUID v4), `TimestampSchema` (ISO datetime, with or
without offset), `UrlSchema`, `DoiSchema`, `CasNumberSchema`, `InChIKeySchema`,
`PaginationSchema`, `SortDirectionSchema`, `SortSchema`,
`DateRangeFilterSchema`, `NumericRangeFilterSchema`, `JsonValueSchema`,
`JsonObjectSchema`, `StringArrayJsonSchema`.

Each entity module exports a row schema plus matching `…CreateInputSchema`
(omits `id`, `createdAt`, `updatedAt`) and `…UpdateInputSchema` (partial).
Example: `BotanicalSpeciesSchema` has fields `id`, `binomialName` (regex
`/^[A-Z][a-z]+ [a-z]+$/`), `genus`, `species`, `subspecies?`, `authority`,
`family`, `commonNames` (JSON array), `synonyms` (JSON array), `description`,
`nativeRegion`, `habitat`, `growthForm`, `plantPartUsed` (≥ 1), `iucnStatus`,
`citesAppendix`, `isEndemic`, `imageUrls`, `createdAt`, `updatedAt`.

Note a field naming divergence between the two layers: the database schema uses
singular `plantPartUsed` and adds `isEndemic`, while the core
`BotanicalSpeciesData` entity uses plural `plantPartsUsed` without `isEndemic`.
Consuming code must account for this mapping at the persistence boundary.

---

## 9. API Layer (`@airmid/api`)

Located at `libs/airmid/api/src`. `@airmid/api` does **not** run an HTTP server.
It provides: external bioinformatics database connectors, an ETL pipeline
framework, an OpenAPI 3.1 endpoint _specification_ (as data and a generator),
SMILES/SMARTS cheminformatics utilities, and data-export/reporting functions.

### 9.1 External Database Connectors

`EXTERNAL_DATABASE_CONFIGS` defines **10 external bioinformatics databases**,
each with `name` and `baseUrl`. The following table shows each database and its
base URL as configured in the library:

| Database                   | Base URL                                                   |
| -------------------------- | ---------------------------------------------------------- |
| PubMed/NCBI E-utilities    | `https://eutils.ncbi.nlm.nih.gov/entrez/eutils/`           |
| PubChem PUG REST           | `https://pubchem.ncbi.nlm.nih.gov/rest/pug/`               |
| ChEMBL                     | `https://www.ebi.ac.uk/chembl/api/data/`                   |
| UniProt                    | `https://rest.uniprot.org/uniprotkb/`                      |
| STRING                     | `https://string-db.org/api/`                               |
| KEGG REST                  | `https://rest.kegg.jp/`                                    |
| DrugBank                   | `https://go.drugbank.com/ws/`                              |
| ClinicalTrials.gov         | `https://clinicaltrials.gov/api/v2/`                       |
| WHO VigiBase               | `https://api.who-umc.org/vigibase/`                        |
| Natural Medicines Database | `https://api.naturalmedicines.therapeuticresearch.com/v1/` |

URL builders cover each database (e.g. `buildPubMedSearchURL`,
`buildPubMedFetchURL`, `buildPubChemPropertyURL`, `buildPubChemNameSearchURL`,
`buildPubChemSMILESSearchURL`, `buildChEMBLMoleculeURL`,
`buildChEMBLActivityURL`, `buildUniProtSearchURL`, `buildUniProtEntryURL`,
`buildSTRINGNetworkURL`, `buildSTRINGPartnersURL`, `buildSTRINGEnrichmentURL`,
`buildKEGGFindURL`, `buildKEGGListURL`, `buildKEGGLinkURL`,
`buildKEGGPathwayURL`, `buildClinicalTrialsSearchURL`). Response parsers
(`parseNCBIResponse`, `parsePubMedArticleXML`, `parsePubChemResponse`,
`parseChEMBLResponse`, `parseChEMBLActivities`, `parseUniProtResponse`,
`parseSTRINGResponse`, `parseKEGGResponse`, `parseKEGGCompoundList`) map raw
responses to typed objects. Retry support: `calculateExponentialBackoff`,
`DEFAULT_RETRY_CONFIG`, `isRetryable`, `isRateLimitError`,
`getEffectiveRateLimit` (3/s NCBI without key, 10/s with key), plus
`validateDatabaseURL` and `getDatabaseConfig`.

### 9.2 ETL Pipeline Framework

`PIPELINE_DEFINITIONS` defines **8 scheduled pipelines** (PubMed weekly, PubChem
monthly, ChEMBL monthly, ClinicalTrials.gov weekly, UniProt quarterly, STRING
quarterly, KEGG quarterly, VigiBase monthly). `TRANSFORMATION_RULES` defines
**18 transformation rules** (CAS check-digit validation, InChIKey format
validation, SMILES canonicalization, species-name resolution with 40+ mappings,
unit harmonization, cross-reference mapping, deduplication, confidence scoring).
Pipeline functions: `createPipeline`, `runETLExtraction`,
`runETLTransformation`, `runETLLoad`, `updatePipelineStatus`,
`calculateNextRun`, `getTransformationRulesForPipeline`. Data-integrity helpers:
`computeSHA256Hex`, `trackProvenance`, `verifyProvenanceChecksum`. Normalizers:
`normalizeCASNumber`, `normalizeAuthorName`, `normalizeOrganism`,
`resolveSpeciesName`, `canonicalizeSMILES`, `convertUnit`,
`convertToMicromolar`, `convertToDaltons`, `validateCASCheckDigit`,
`validateInChIKey`.

### 9.3 Cheminformatics Utilities

Two cheminformatics modules handle SMILES and SMARTS processing in TypeScript,
without external chemistry tool dependencies:

`smiles-canonical.ts` exports `parseSmiles`, `canonicalSmiles`,
`emitCanonicalSmiles`, `morganCanonicalRanks` (plus `Atom`, `Bond`, `Molecule`
types). `smarts.ts` exports `parseSmarts`, `matchSmarts`, `smartsMatchesSmiles`,
`findAllSmartsMatches`, `countSmartsMatches` (plus `SmartsAtomQuery`,
`SmartsBondQuery`, `SmartsPattern` types).

### 9.4 OpenAPI 3.1 Endpoint Specification

`AIRMID_API_ENDPOINTS` is a typed array of **44 OpenAPI 3.1 endpoint
definitions** across 12 resource tags. `generateOpenAPISpec()` assembles a
complete OpenAPI 3.1 document (info, servers, `bearerAuth` security scheme,
`ProblemDetail` schema, tags). This is a published _specification_ used by a
consuming application; the library itself does not serve these routes.

Authentication is a JWT Bearer token (`bearerAuth` security scheme) for all
secured endpoints. All errors follow RFC 7807 (`application/problem+json`);
standard responses for 400, 401, 403, 404, 429, and 500 are attached to every
secured endpoint.

| Method   | Path                                           | operationId                  | Tags                 | Auth | Rate-limit tier |
| -------- | ---------------------------------------------- | ---------------------------- | -------------------- | ---- | --------------- |
| `GET`    | `/api/v1/species`                              | `listSpecies`                | Species              | ✓    | basic           |
| `GET`    | `/api/v1/species/{id}`                         | `getSpeciesById`             | Species              | ✓    | basic           |
| `GET`    | `/api/v1/species/{id}/compounds`               | `getSpeciesCompounds`        | Species,Compounds    | ✓    | basic           |
| `GET`    | `/api/v1/species/{id}/interactions`            | `getSpeciesInteractions`     | Species,Interactions | ✓    | basic           |
| `GET`    | `/api/v1/species/{id}/evidence`                | `getSpeciesEvidence`         | Species,Evidence     | ✓    | basic           |
| `GET`    | `/api/v1/species/{id}/safety`                  | `getSpeciesSafety`           | Species,Safety       | ✓    | basic           |
| `GET`    | `/api/v1/species/search`                       | `searchSpecies`              | Species              | ✓    | basic           |
| `GET`    | `/api/v1/compounds`                            | `listCompounds`              | Compounds            | ✓    | basic           |
| `GET`    | `/api/v1/compounds/{id}`                       | `getCompoundById`            | Compounds            | ✓    | basic           |
| `GET`    | `/api/v1/compounds/{id}/targets`               | `getCompoundTargets`         | Compounds,Targets    | ✓    | basic           |
| `GET`    | `/api/v1/compounds/{id}/admet`                 | `getCompoundADMET`           | Compounds            | ✓    | pro             |
| `GET`    | `/api/v1/compounds/search`                     | `searchCompoundsByName`      | Compounds            | ✓    | basic           |
| `POST`   | `/api/v1/compounds/structure-search`           | `searchCompoundsByStructure` | Compounds            | ✓    | pro             |
| `POST`   | `/api/v1/interactions/check`                   | `checkInteractions`          | Interactions         | ✓    | basic           |
| `GET`    | `/api/v1/interactions/{id}`                    | `getInteractionById`         | Interactions         | ✓    | basic           |
| `GET`    | `/api/v1/interactions`                         | `listInteractions`           | Interactions         | ✓    | basic           |
| `GET`    | `/api/v1/evidence`                             | `listEvidence`               | Evidence             | ✓    | basic           |
| `GET`    | `/api/v1/evidence/{id}`                        | `getEvidenceById`            | Evidence             | ✓    | basic           |
| `GET`    | `/api/v1/evidence/search`                      | `searchEvidence`             | Evidence             | ✓    | basic           |
| `POST`   | `/api/v1/safety/assess`                        | `assessSafety`               | Safety               | ✓    | pro             |
| `GET`    | `/api/v1/safety/pregnancy/{species}`           | `getPregnancySafety`         | Safety               | ✓    | basic           |
| `GET`    | `/api/v1/safety/contraindications/{species}`   | `getContraindications`       | Safety               | ✓    | basic           |
| `GET`    | `/api/v1/safety/adverse-events`                | `getAdverseEvents`           | Safety               | ✓    | pro             |
| `POST`   | `/api/v1/clinical/cds-hooks`                   | `cdshooksRequest`            | Clinical             | ✓    | enterprise      |
| `POST`   | `/api/v1/clinical/interaction-check`           | `clinicalInteractionCheck`   | Clinical             | ✓    | pro             |
| `GET`    | `/api/v1/clinical/patient-education/{species}` | `getPatientEducation`        | Clinical             | ✓    | basic           |
| `GET`    | `/api/v1/targets`                              | `listTargets`                | Targets              | ✓    | basic           |
| `GET`    | `/api/v1/targets/{id}`                         | `getTargetById`              | Targets              | ✓    | basic           |
| `GET`    | `/api/v1/targets/{id}/network`                 | `getTargetNetwork`           | Targets              | ✓    | pro             |
| `GET`    | `/api/v1/pathways`                             | `listPathways`               | Pathways             | ✓    | basic           |
| `GET`    | `/api/v1/pathways/{id}`                        | `getPathwayById`             | Pathways             | ✓    | basic           |
| `POST`   | `/api/v1/pathways/enrichment`                  | `analyzePathwayEnrichment`   | Pathways             | ✓    | pro             |
| `POST`   | `/api/v1/reports/generate`                     | `generateReport`             | Reports              | ✓    | pro             |
| `GET`    | `/api/v1/reports/templates`                    | `listReportTemplates`        | Reports              | ✓    | basic           |
| `GET`    | `/api/v1/reports/{id}`                         | `getReportById`              | Reports              | ✓    | basic           |
| `POST`   | `/api/v1/export/species`                       | `exportSpecies`              | Export               | ✓    | pro             |
| `POST`   | `/api/v1/export/compounds`                     | `exportCompounds`            | Export               | ✓    | pro             |
| `GET`    | `/api/v1/export/fair-assessment`               | `getFAIRAssessment`          | Export               | ✓    | basic           |
| `POST`   | `/api/v1/webhooks`                             | `createWebhook`              | Webhooks             | ✓    | pro             |
| `GET`    | `/api/v1/webhooks`                             | `listWebhooks`               | Webhooks             | ✓    | pro             |
| `DELETE` | `/api/v1/webhooks/{id}`                        | `deleteWebhook`              | Webhooks             | ✓    | pro             |
| `GET`    | `/api/v1/status`                               | `getAPIStatus`               | Admin                | —    | free            |
| `GET`    | `/api/v1/stats`                                | `getDataStats`               | Admin                | ✓    | basic           |
| `GET`    | `/api/v1/rate-limit`                           | `getRateLimitStatus`         | Admin                | ✓    | free            |

### 9.5 Rate-Limit Tiers

`RATE_LIMIT_TIERS` defines **4 tiers**. The CDS Hooks endpoint requires
enterprise tier because it is called synchronously from within an EHR workflow
and needs to handle high-frequency clinical traffic.

| Tier         | Requests/day                                      | Requests/minute | Burst |
| ------------ | ------------------------------------------------- | --------------- | ----- |
| `free`       | 100                                               | 10              | 5     |
| `basic`      | 1,000                                             | 60              | 20    |
| `pro`        | 10,000                                            | 300             | 50    |
| `enterprise` | `Number.MAX_SAFE_INTEGER` (effectively unlimited) | 1,000           | 200   |

Rate-limit functions: `checkRateLimit`, `getRateLimitTier`. Request validation:
`validateRequest`. RFC 7807 helpers: `createProblemDetail`,
`createValidationError`. Cursor pagination (base64-encoded position):
`generateCursorPagination`, `encodeCursor`, `decodeCursor`.

### 9.6 Webhooks and API Documentation

`api-documentation.ts` exports `WEBHOOK_SPECIFICATIONS` (12 webhook event types
— `species.updated`, `species.created`, `compound.added`, `compound.updated`,
`interaction.discovered`, `interaction.updated`, `evidence.published`,
`evidence.retracted`, `safety.alert`, `pipeline.completed`, `pipeline.failed`,
`report.generated`), `getWebhookSpec`, `generateWebhookPayload`,
`verifyWebhookSignature` (HMAC-SHA256), `computeHMACSHA256`, plus
`generateTypeScriptClient`, `generateCodeExample`, `generateAllCodeExamples`.

### 9.7 Data Export and Reporting

`data-export.ts` exports `exportToJSON`, `exportToCSV` (RFC 4180),
`exportToXML`, `exportToRDFTurtle` (linked data), `exportToSDF` (cheminformatics
Structure-Data File), `escapeCSVField`, `escapeXML`. Reporting:
`REPORT_TEMPLATES` (6 templates), `listReportTemplates`, `generateReport`.
Open-data assessment: `assessFAIRCompliance` (Findable, Accessible,
Interoperable, Reusable scoring).

---

## 10. Scientific Library Surface

The remaining scientific libraries each expose a typed module surface through
`src/index.ts`. Rather than duplicating all field-level detail here (consult the
library source for exhaustive types), this section documents the headline data
magnitudes and key function names that define each library's public contract.

| Library                  | Headline implemented surface                                                                                                                                                                                                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@airmid/phytochem`      | `NATURAL_PRODUCTS_DATABASE` — 55 curated compound entries; molecular property calculation (logP, TPSA, QED, Fsp3); drug-likeness (Lipinski, Veber, Ghose, Egan, Muegge); ADMET prediction; toxicity prediction (Ames, hERG, hepatotoxicity, LD50, GHS); 3D structure; metabolite prediction |
| `@airmid/evidence`       | Trial integration, `createSystematicReview`/`performMetaAnalysis`, `ROB2_DOMAINS` (Cochrane RoB 2.0), GRADE grading (`computeGRADECertainty`, `GRADE_FACTORS`), forest plot data, publication-quality scoring, evidence search                                                              |
| `@airmid/interactions`   | `HERB_DRUG_INTERACTION_DATABASE` — 80+ herb-drug interaction entries; CYP450 profiling; transporter interactions; pharmacodynamic interaction analysis; `checkInteractions`, `predictInhibitionMagnitude`, `generatePatientCounseling`                                                      |
| `@airmid/safety`         | WHO-UMC causality, Naranjo ADR, RUCAM hepatotoxicity, Hy's Law, DILI pattern; nephrotoxicity; special-population safety (pregnancy 40+, pediatric 20+, geriatric 15+ herbs); 30+ toxic compounds; contamination assessment                                                                  |
| `@airmid/precision`      | CPIC CYP450 allele databases (9 genes); Activity Score; `GENOTYPE_RESPONSE_DATABASE` — 48 herb-gene-phenotype entries; 30 microbiome-herb interaction entries; 30+ biomarkers; personalized recommendation engine                                                                           |
| `@airmid/docking`        | AutoDock Vina scoring, protein preparation, binding-site detection, virtual screening, PAINS filtering, QSAR, inverse docking, molecular dynamics specification and trajectory analysis                                                                                                     |
| `@airmid/network`        | Target identification, PPI networks (STRING), network topology metrics, KEGG pathway enrichment, GO analysis, multi-layer network integration, synergy/disease-module mapping                                                                                                               |
| `@airmid/formulation`    | Synergy analysis (Chou-Talalay, Bliss, Loewe, HSA), antagonism detection, extraction optimization, stability/shelf-life prediction, bioavailability enhancement                                                                                                                             |
| `@airmid/microbiome`     | Prebiotic-effect database, microbial metabolite production, dysbiosis-correction protocols, herb-metabolism modeling, clinical integration                                                                                                                                                  |
| `@airmid/quality`        | DNA barcoding (`dna-barcoding-data` reference set), spectroscopic fingerprinting, chromatographic profiling, chemometrics, marker-compound quantification, adulteration detection                                                                                                           |
| `@airmid/regulatory`     | Pharmacopoeia compliance (USP, EP, BP, JP, CP, IP), EMA/HMPC monograph system, FDA/DSHEA, global jurisdiction status, labeling and claims classification                                                                                                                                    |
| `@airmid/sustainability` | IUCN conservation status, sustainable sourcing, cultivation alternatives, environmental impact (LCA-style), at-risk species substitution engine                                                                                                                                             |
| `@airmid/ml`             | Biomedical NLP, ADMET filtering, graph neural networks, molecular transformers, generative models, fragment database, molecular editor, explainable AI, advanced learning                                                                                                                   |
| `@airmid/vision`         | Leaf analysis, flower analysis, bark analysis, climate model, geographic filter, multi-organ species matcher                                                                                                                                                                                |
| `@airmid/clinical`       | FHIR integration, interaction alerts, evidence summaries, patient education, audit/compliance                                                                                                                                                                                               |
| `@airmid/ethno`          | Traditional medicine databases, indigenous knowledge, preparation methods, formulation principles, scientific validation                                                                                                                                                                    |

Each library's `types.ts` defines its own domain types, unions, and Zod schemas;
those types are not duplicated here — consult the library source for exhaustive
field-level detail.

---

## 11. Configuration

Airmid libraries are configured through their callers. There is no `.env` file
or environment-variable loader inside `libs/airmid/`. Configuration that _is_
expressed in code:

- **External database base URLs and rate limits** — `EXTERNAL_DATABASE_CONFIGS`
  in `@airmid/api` (the NCBI E-utilities client distinguishes a 3/s unkeyed rate
  limit from a 10/s keyed rate limit via `getEffectiveRateLimit`).
- **ETL pipeline schedules** — `PIPELINE_DEFINITIONS` in `@airmid/api`.
- **API rate-limit tiers** — `RATE_LIMIT_TIERS` in `@airmid/api`.
- **OpenAPI servers** — `generateOpenAPISpec()` lists production, staging, and
  local-development server URLs.
- **Database connection** — `@airmid/database` provides Knex migrations and Zod
  schemas only; the connection string is supplied by the migration runner /
  consuming application.

---

## 12. Technology Stack and Build

| Layer      | Technology                                    |
| ---------- | --------------------------------------------- |
| Language   | TypeScript (Node.js, ESM — `type: module`)    |
| Validation | Zod (catalog dependency in every package)     |
| Database   | PostgreSQL via Knex.js (`@airmid/database`)   |
| UUIDs      | `uuid` (dev dependency of `@airmid/database`) |
| Build      | Nx `@nx/js:tsc`                               |
| Test       | Vitest (`@nx/vite:test`)                      |
| Tags       | `scope:airmid`, `layer:domain`, `type:lib`    |

Cheminformatics algorithms (SMILES canonicalization, SMARTS substructure
matching, AutoDock Vina scoring, Needleman-Wunsch alignment, molecular property
formulas) are implemented in TypeScript; there is no Python subprocess or RDKit
dependency in the current code.

When Nx is unavailable (for example, due to duplicate project detection from
worktrees), use these direct invocations:

```bash
# Type check a library
cd libs/airmid/<library> && npx tsc --noEmit

# Run a library's tests
cd libs/airmid/<library> && npx vitest run

# Run all airmid tests
npx vitest run libs/airmid/
```

---

## 13. Acceptance Criteria

The following criteria must all pass. They are phrased as observable test
outcomes rather than code assertions, so they can be evaluated against any test
runner output.

- All 19 libraries type-check (`npx tsc --noEmit`) and pass their Vitest suites.
- Branded ID schemas reject non-UUID strings; `CAS_NUMBER_PATTERN` and
  `INCHI_KEY_PATTERN` reject malformed identifiers.
- Entity constructors throw on missing required fields and on out-of-range
  numeric inputs (e.g. `pValue` outside 0–1, `gcContent` outside 0–1).
- Domain-correctness tests assert known literature values (e.g. compound
  molecular weights, established herb-drug interaction severities) rather than
  shape-only assertions.
- Contraindicated interactions are never downgraded by clinical-decision logic.
- The 6 database migrations apply in order and create the 17 base tables, 5
  materialized views, and 35 enum types described in §8.
- `generateOpenAPISpec()` produces a valid OpenAPI 3.1 document covering all 44
  endpoints in §9.4.
