Domain · Specifications

Airmid Domain — Technical Specifications

All 19 libraries are private workspace packages (version: 0.1.0,

13sections22 minread

On this page

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.135.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 enums 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:

  • TaxonomicRankKingdom, Phylum, Class, Order, Family, Genus, Species, Subspecies, Variety, Cultivar.
  • CompoundClassAlkaloid, Flavonoid, Terpene, Terpenoid, Phenol, Polyphenol, Tannin, Saponin, Glycoside, Coumarin, Lignin, Steroid, EssentialOil, FattyAcid, Amino, Carbohydrate, Vitamin, Mineral, Other (19 members).
  • GRADEQualityHigh, Moderate, Low, VeryLow.
  • OxfordLevelLevel1a, Level1b, Level2a, Level2b, Level3a, Level3b, Level4, Level5 (Oxford CEBM, March 2009).
  • StudyDesignSystematicReview, MetaAnalysis, RCT, CohortStudy, CaseControl, CaseSeries, CaseReport, CrossSectional, InVitro, InVivo, ExVivo, Computational.
  • EvidenceStrengthStrong, Moderate, Limited, Insufficient, Conflicting.
  • InteractionSeverityContraindicated, Major, Moderate, Minor, Theoretical.
  • InteractionMechanismCYP450Inhibition, CYP450Induction, PGPInhibition, ProteinBindingDisplacement, PharmacodynamicSynergy, PharmacodynamicAntagonism, GIAbsorptionAlteration, RenalClearanceChange, Other.
  • AdverseReactionTypeAllergic, Hepatotoxic, Nephrotoxic, Neurotoxic, Dermatologic, GI, Cardiovascular, Respiratory, Hematologic, Endocrine, Other.
  • CausalityAssessmentCertain, Probable, Possible, Unlikely, Conditional, Unassessable (WHO-UMC categories).
  • DosageFormTincture, Decoction, Infusion, Capsule, Tablet, Extract, EssentialOil, Poultice, Salve, Syrup, Powder, Tea, Cream, Oil (14 members).
  • DosageUnitmg, g, mL, drops, cups, tablespoons, teaspoons.
  • PreparationTypeAqueous, Ethanolic, Hydroethanolic, Supercritical, ColdPressed, SteamDistilled, Macerated, Fermented.
  • IUCNStatusNotEvaluated, DataDeficient, LeastConcern, NearThreatened, Vulnerable, Endangered, CriticallyEndangered, ExtinctInWild, Extinct.
  • CITESAppendixNone, AppendixI, AppendixII, AppendixIII.
  • PharmacopoeiaUSP, EP, BP, JP, CP, IP, WHO, ESCOP, CommissionE, HMPC.
  • RegulatoryStatusApproved, 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_tablesbotanical_species, phytochemical_compounds, plant_compound_associations, clinical_trials, evidence_records.
  3. safety_tablesdrug_herb_interactions, adverse_event_reports, traditional_use_records, pharmacopoeia_monographs, regulatory_statuses.
  4. genomics_targetsdna_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 limitsEXTERNAL_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 schedulesPIPELINE_DEFINITIONS in @airmid/api.
  • API rate-limit tiersRATE_LIMIT_TIERS in @airmid/api.
  • OpenAPI serversgenerateOpenAPISpec() 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.