# Asase — Technical Specifications

> Named after **Asase Yaa**, the Akan earth goddess of fertility and sustenance.
> Asase is the food and agriculture operations intelligence domain for Ghana's
> complete food value chain, covering 19 business units from farm production
> through processing, cold chain, logistics, quality assurance, export, and
> market operations.

This document is the authoritative technical reference for everything
**implemented** in the `libs/asase/*` libraries and `apps/asase/*` applications.
Every entity, enum, function, table, and constant below is traceable to source
code in the repository.

The specification is organised from the foundational core outward: §1 gives the
top-level domain metrics, §2 lists all libraries, §3–§14 cover the core type
system in depth (branded IDs, enums, value objects, domain entities, services,
validation, utilities, errors, and constants), §15 documents the database schema
(36 tables, 27 PostgreSQL enum types), §16 covers infrastructure services, §17
catalogues the public API surface of each specialised library, and §18–§21 cover
applications, configuration, cross- domain integration, and external data
sources.

Use `features.md` for narrative explanations of what each library does and why.
Use this document to look up exact type signatures, enum values, function names,
and schema details.

---

## 1. Domain Overview

The table below summarises the domain's key properties. These counts are
anchored to the source — if you add a library or table, update these values to
keep the document coherent.

| Property          | Value                                                                                         |
| ----------------- | --------------------------------------------------------------------------------------------- |
| Domain name       | `asase`                                                                                       |
| Scope             | Ghana food and agriculture operations intelligence                                            |
| Library count     | 15 (`libs/asase/*`)                                                                           |
| Application count | 5 (`apps/asase/*`)                                                                            |
| Business units    | 19                                                                                            |
| Database          | PostgreSQL (Drizzle ORM, 36 tables in `@asase/core`, pgvector)                                |
| Language          | TypeScript (ESM)                                                                              |
| Validation        | Zod (`@asase/core`, `@asase/infrastructure`); plus hand-written `ValidationResult` validators |
| Testing           | Vitest                                                                                        |
| Build             | `@nx/js:tsc`                                                                                  |
| Geographic focus  | Ghana (16 administrative regions, 5 agro-ecological zones)                                    |
| Project tags      | `["scope:asase", "layer:domain", "type:lib"]`                                                 |

All library `package.json` files use `"name": "@asase/<lib>"`,
`"version": "0.1.0"`, `"type": "module"`. Most libraries depend on `@asase/core`
via `workspace:*`. `@asase/financials`, `@asase/connectors`, and `@asase/sota`
have no `@asase/core` dependency.

---

## 2. Library Inventory

All 15 domain libraries and the migration package are implemented. Three
libraries (`@asase/financials`, `@asase/connectors`, `@asase/sota`) have no
`@asase/core` dependency; all others depend on `@asase/core` via `workspace:*`.

| Package                 | Path                        | Status      | Responsibility                                                                                                                                                                                                                                                                                                    |
| ----------------------- | --------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@asase/core`           | `libs/asase/core`           | Implemented | Foundation: branded IDs, enums, value objects, entities, services, db-schema                                                                                                                                                                                                                                      |
| `@asase/crops`          | `libs/asase/crops`          | Implemented | Crop registry, variety recommendation, pest/disease, field ops, irrigation, soil, health, labour, mechanization, yield, intercropping, harvest loss, weather                                                                                                                                                      |
| `@asase/livestock`      | `libs/asase/livestock`      | Implemented | Livestock registry, vaccination, feed formulation, broiler/layer/hatchery, disease surveillance, mortality, house environment, distribution, aquaculture (fish farm, growth, feed, health, water quality)                                                                                                         |
| `@asase/infrastructure` | `libs/asase/infrastructure` | Implemented | Redis cache, MinIO storage, event bus, Prometheus metrics, PostGIS geospatial                                                                                                                                                                                                                                     |
| `@asase/processing`     | `libs/asase/processing`     | Implemented | Plant digital twin, scheduling, raw material receiving, BOM, batch execution, recipes, utility/energy monitoring, yield/waste, batch genealogy, nutritional labeling, OEE, predictive maintenance, SPC, cost of quality                                                                                           |
| `@asase/cold-chain`     | `libs/asase/cold-chain`     | Implemented | Facility registry, temperature monitoring, inventory, energy optimizer, backup power, transport fleet, grain storage, warehouse, inventory valuation, warehouse receipt (GCX), post-harvest loss, compliance docs, last-mile, route optimizer, excursion analytics                                                |
| `@asase/supply-chain`   | `libs/asase/supply-chain`   | Implemented | Procurement, outgrower, contract farming, import management, supplier risk, distribution network, vehicle routing, market channel, returns logistics, delivery proof, commodity price, price forecast, import parity, margin analysis, demand sensing                                                             |
| `@asase/quality`        | `libs/asase/quality`        | Implemented | HACCP, audit, CCP monitoring, PRP, water quality, pesticide residue, aflatoxin, LIMS, recall, environmental compliance, regulatory change, label compliance, organic/export/FDA certification, calibration                                                                                                        |
| `@asase/export`         | `libs/asase/export`         | Implemented | Commodity analyzer, market scanner, grading, volume forecaster, competitor tracker, trade documents, AfCFTA, EU regulation, customs duty, license manager, buyer CRM, dynamic pricing, contract negotiation, logistics optimizer, certification tracker                                                           |
| `@asase/inputs`         | `libs/asase/inputs`         | Implemented | Fertilizer blend optimizer, soil nutrient mapper, fertilizer cost, organic fertilizer advisor, subsidy tracker, seed performance/multiplication, agrochemical guidance, IPM advisor, agrochemical safety, input distribution, farmer credit, input bundle optimizer, import substitution, input quality assurance |
| `@asase/market-intel`   | `libs/asase/market-intel`   | Implemented | Commodity/farmgate price tracking, price forecasting, price transmission, cedi exposure, supply-demand modeling, competitor analysis, consumer trend, price elasticity, seasonality profiler, AfCFTA opportunity, regional trade flow, market entry, trade intelligence, policy impact simulator                  |
| `@asase/retail`         | `libs/asase/retail`         | Implemented | QSR location, franchise management, POS integrator, staff scheduling, quality audit, menu engineering, recipe cost, menu localizer, inventory waste, dynamic menu pricer, delivery logistics/platforms, institutional catering, central kitchen, customer loyalty                                                 |
| `@asase/financials`     | `libs/asase/financials`     | Implemented | Startup cost, unit economics, farm/processing economics, working capital, consolidated projection, capex planning, debt capacity, tax optimization, investor return, synergy valuation, scenario planner, benchmarking, FX risk, impact metrics                                                                   |
| `@asase/connectors`     | `libs/asase/connectors`     | Implemented | Cross-domain connectors to Brigid, Cybele, Freya, Saraswati, Maat, Aje                                                                                                                                                                                                                                            |
| `@asase/sota`           | `libs/asase/sota`           | Implemented | Satellite remote sensing, drone/precision agriculture, computer-vision grading, blockchain traceability + IoT cold chain, ML yield prediction + RL crop planning                                                                                                                                                  |
| `@asase/migrations`     | `libs/asase/migrations`     | Implemented | Drizzle migration runner, 11 migration files, 8 seed scripts, connection pool config                                                                                                                                                                                                                              |

### `@asase/core` Source Modules

`@asase/core` is the only library that other Asase libraries are allowed to
import directly. It is deliberately layered (see `architecture.md` §3) so that
each file carries only the imports it needs. The table below maps each source
file to its responsibility.

| Module          | File                      | Responsibility                                                                                                                                                                                                                                |
| --------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Types           | `types.ts`                | Branded IDs, brand creators, enums, value objects, entity interfaces                                                                                                                                                                          |
| Constants       | `constants.ts`            | Crop varieties, livestock breeds, regulatory bodies, season ranges, markets, food-safety standards, HS codes, exchange rates, storage temperatures, soil classifications, post-harvest loss rates, BU prefixes, region codes, max batch sizes |
| Business Units  | `business-units.ts`       | Per-unit config interfaces, discriminated union, type guards                                                                                                                                                                                  |
| Agro-ecology    | `agro-ecology.ts`         | Zone enum, 16 region profiles, region/zone queries                                                                                                                                                                                            |
| Measurement     | `measurement.ts`          | Phantom-typed mass/volume/area/temperature/humidity/currency units and conversions                                                                                                                                                            |
| Seasonality     | `seasonality.ts`          | Crop seasonality profiles, planting windows, harvest/input-schedule resolution                                                                                                                                                                |
| Stakeholders    | `stakeholders.ts`         | 8 stakeholder profile types, discriminated union, type guards, compliance helpers                                                                                                                                                             |
| Domain Entities | `domain-entities.ts`      | `CropVariety`, `FarmPlot`, `Facility` hierarchy, `Product`, `PricePoint`/`PriceTrend`                                                                                                                                                         |
| Domain Services | `domain-services.ts`      | `UnitConversionService`, `SeasonalCalendarService`, `GhanaRegulatoryService`, `GeolocationService`, `AuditTrailService`                                                                                                                       |
| Unit Data       | `unit-conversion-data.ts` | Shared mass/volume/area conversion-factor maps                                                                                                                                                                                                |
| DB Schema       | `db-schema.ts`            | Drizzle ORM: 27 `pgEnum` types, 36 tables, custom `vector` pgvector type                                                                                                                                                                      |
| Validation      | `validation.ts`           | Domain validators returning `ValidationResult`; COCOBOD cocoa grading                                                                                                                                                                         |
| Utils           | `utils.ts`                | Yield, harvest estimate, soil pH, currency, cold chain compliance, HS code, season, post-harvest loss, batch number, phone                                                                                                                    |
| Geo Utils       | `geo-utils.ts`            | Haversine distance, DMS conversion, midpoint, Ghana-bounds check                                                                                                                                                                              |
| Errors          | `errors.ts`               | `AsaseError` hierarchy                                                                                                                                                                                                                        |

---

## 3. Core Data Model (`@asase/core/types.ts`)

This section documents every type exported from `types.ts`. The file is the
vocabulary of the Asase domain: branded identifiers, enums, literal-union types,
value objects, and entity interfaces. Changes here affect every other library in
the domain.

### 3.1 Branded ID Types

Branded ID types prevent passing a `PlotId` where a `FarmId` is expected — the
TypeScript compiler rejects the assignment even though both are strings at
runtime. Each branded type comes with a factory constructor.

Each is `Brand<string, '<Name>'>` with a matching `create<Name>Id(id: string)`
constructor:

`FarmId`, `PlotId`, `CropId`, `LivestockId`, `BatchId`, `FacilityId`,
`ShipmentId`, `OrderId`, `SupplierId`, `CustomerId`, `WorkerId`.

Constructors: `createFarmId`, `createPlotId`, `createCropId`,
`createLivestockId`, `createBatchId`, `createFacilityId`, `createShipmentId`,
`createOrderId`, `createSupplierId`, `createCustomerId`, `createWorkerId`.

### 3.2 Enums

All enums use the `const` object + companion type pattern —
`(typeof X)[keyof typeof X]` — rather than TypeScript `enum` declarations, which
avoids the reverse-mapping overhead and keeps values tree-shakeable. The
`BusinessUnit` enum is the discriminant for the 19-member config union in
`business-units.ts`. The `Region` enum covers exactly Ghana's 16 administrative
regions in their official English spellings.

| Enum               | Values                                                                                                                                                                                                                                                                                                |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BusinessUnit`     | `bakery`, `cafe`, `processed_foods`, `plant_farms`, `aquaculture`, `cold_chain`, `export_processing`, `animal_feed`, `institutional_catering`, `agricultural_inputs`, `beverages`, `poultry`, `dairy`, `edible_oils`, `rice_milling`, `spices`, `cassava_processing`, `qsr_chains`, `fertilizer` (19) |
| `CropCategory`     | `cereal`, `legume`, `root_tuber`, `fruit`, `vegetable`, `oil_crop`, `spice`, `stimulant`, `fiber`, `fodder`                                                                                                                                                                                           |
| `GrowthStage`      | `dormant`, `germination`, `seedling`, `vegetative`, `flowering`, `fruiting`, `maturation`, `harvest`, `post_harvest`                                                                                                                                                                                  |
| `LivestockType`    | `cattle`, `poultry_broiler`, `poultry_layer`, `goat`, `sheep`, `pig`, `rabbit`, `fish_tilapia`, `fish_catfish`, `shrimp`, `snail`                                                                                                                                                                     |
| `ProcessingStage`  | `raw_material`, `cleaning`, `sorting`, `processing`, `packaging`, `storage`, `dispatch`                                                                                                                                                                                                               |
| `QualityGrade`     | `premium`, `grade_a`, `grade_b`, `grade_c`, `reject`                                                                                                                                                                                                                                                  |
| `StorageCondition` | `ambient`, `chilled`, `frozen`, `controlled_atmosphere`                                                                                                                                                                                                                                               |
| `TransportMode`    | `truck_refrigerated`, `truck_ambient`, `motorcycle`, `bicycle`, `rail`, `vessel`                                                                                                                                                                                                                      |
| `CurrencyCode`     | `GHS`, `USD`, `EUR`, `GBP`                                                                                                                                                                                                                                                                            |
| `Region`           | `Greater_Accra`, `Ashanti`, `Western`, `Central`, `Eastern`, `Northern`, `Upper_East`, `Upper_West`, `Volta`, `Bono`, `Bono_East`, `Ahafo`, `Savannah`, `North_East`, `Oti`, `Western_North` (16)                                                                                                     |
| `Season`           | `major_rainy`, `minor_rainy`, `harmattan`, `dry`                                                                                                                                                                                                                                                      |
| `UnitOfMeasure`    | `kg`, `tonnes`, `liters`, `pieces`, `bags_50kg`, `bags_100kg`, `crates`, `bunches`                                                                                                                                                                                                                    |

### 3.3 Literal-Union Types

These types are simpler than full enums — they are plain TypeScript
`type = 'a' | 'b' | 'c'` definitions used where the set of values is small and
does not need to be iterated programmatically.

| Type                   | Values                                                                                                                                |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `SoilPHClassification` | `strongly_acidic`, `moderately_acidic`, `slightly_acidic`, `neutral`, `slightly_alkaline`, `moderately_alkaline`, `strongly_alkaline` |
| `SoilType`             | `sandy`, `loamy`, `clay`, `sandy_loam`, `clay_loam`, `silt_loam`, `laterite`, `alluvial`, `savannah_ochrosol`, `forest_ochrosol`      |
| `IrrigationType`       | `rainfed`, `drip`, `sprinkler`, `furrow`, `flood`, `bucket`, `dam_fed`, `borehole`                                                    |
| `PlotStatus`           | `active`, `fallow`, `preparation`, `harvested`, `abandoned`                                                                           |
| `HealthStatus`         | `healthy`, `under_observation`, `sick`, `quarantined`, `treated`, `recovered`                                                         |
| `ShipmentStatus`       | `pending`, `loading`, `in_transit`, `at_checkpoint`, `delayed`, `delivered`, `returned`                                               |
| `AreaUnit` (types.ts)  | `hectares`, `acres`, `sq_meters`                                                                                                      |

### 3.4 Value Objects

Value objects carry domain semantics with their data. `Temperature` is always
stored in Celsius (never raw numbers); `SoilPH` carries its classification
alongside the raw value; `CurrencyAmount` always names its currency. All fields
are `readonly`. The helper functions below each table construct instances
safely.

| Interface         | Fields                                                                            | Notes                                  |
| ----------------- | --------------------------------------------------------------------------------- | -------------------------------------- |
| `GeoLocation`     | `latitude: number`, `longitude: number`, `altitude?: number`, `accuracy?: number` | All `readonly`                         |
| `Temperature`     | `celsius: number`                                                                 | Always stored in Celsius               |
| `Humidity`        | `percentage: number`                                                              | 0–100                                  |
| `SoilPH`          | `value: number` (0–14), `classification: SoilPHClassification`                    | Built by `createSoilPH(value)`         |
| `CurrencyAmount`  | `amount: number`, `currency: CurrencyCode`                                        |                                        |
| `DateRange`       | `start: Date`, `end: Date`                                                        |                                        |
| `PlotArea`        | `value: number`, `unit: AreaUnit`                                                 | `'hectares' \| 'acres' \| 'sq_meters'` |
| `YieldPerHectare` | `kgPerHectare: number`                                                            |                                        |

Value-object helpers: `temperatureFromCelsius`, `temperatureFromFahrenheit`,
`temperatureToFahrenheit`, `temperatureToKelvin`, `createSoilPH`,
`plotAreaToHectares`, `plotAreaToAcres`, `yieldToTonnesPerHectare`.

### 3.5 Domain Entity Interfaces

These are the core domain entity shapes stored in the database (via Drizzle,
§15) and passed between service layers. All fields are `readonly`. The entities
defined here are intentionally lean — they contain identifying and status data
only, with richer value objects in `domain-entities.ts` (§9) for use-cases that
need full detail.

**`Farm`** — `id: FarmId`, `name: string`, `ownerId: string`, `region: Region`,
`district: string`, `geoLocation: GeoLocation`, `plots: readonly PlotId[]`,
`totalArea: PlotArea`, `registrationNumber: string`, `createdAt: Date`,
`updatedAt: Date`.

**`Plot`** — `id: PlotId`, `farmId: FarmId`, `name: string`, `area: PlotArea`,
`soilType: SoilType`, `irrigationType: IrrigationType`,
`currentCrop: CropId | null`, `status: PlotStatus`.

**`CropCycle`** — `id: string`, `plotId: PlotId`, `cropId: CropId`,
`plantingDate: Date`, `expectedHarvestDate: Date`, `growthStage: GrowthStage`,
`variety: string`, `seedSource: string`.

**`LivestockBatch`** — `id: LivestockId`, `facilityId: FacilityId`,
`type: LivestockType`, `breed: string`, `quantity: number`, `entryDate: Date`,
`expectedExitDate: Date`, `healthStatus: HealthStatus`.

**`ProcessingBatch`** — `id: BatchId`, `facilityId: FacilityId`,
`stage: ProcessingStage`, `inputMaterials: readonly string[]`,
`outputProduct: string`, `startTime: Date`, `endTime: Date | null`,
`yieldKg: number`, `qualityGrade: QualityGrade`.

**`ColdChainReading`** — `id: string`, `facilityId: FacilityId`,
`sensorId: string`, `temperature: Temperature`, `humidity: Humidity`,
`timestamp: Date`, `isInRange: boolean`.

**`Shipment`** — `id: ShipmentId`, `origin: FacilityId`,
`destination: FacilityId`, `transportMode: TransportMode`,
`items: readonly ShipmentItem[]`, `departureTime: Date`, `eta: Date`,
`currentLocation: GeoLocation | null`, `status: ShipmentStatus`.

**`ShipmentItem`** — `productName: string`, `quantity: number`,
`unit: UnitOfMeasure`, `batchId: BatchId | null`.

**`MarketPrice`** — `id: string`, `commodity: string`, `market: string`,
`price: CurrencyAmount`, `unit: UnitOfMeasure`, `date: Date`, `source: string`.

**`QualityTest`** — `id: string`, `batchId: BatchId`, `testType: string`,
`result: string`, `grade: QualityGrade`, `testedBy: WorkerId`, `testedAt: Date`.

---

## 4. Business Unit Configuration (`@asase/core/business-units.ts`)

Each of Asase's 19 business units has unique operational parameters — a bakery
tracks oven count and flour source; a cold-chain unit tracks cubic metres of
refrigerated storage and refrigerated truck count; a poultry unit tracks broiler
birds per cycle and laying hens. Rather than using a single wide configuration
record with many nullable fields, the system uses a discriminated union: each
business unit has a dedicated config interface with only the fields it needs.

`BusinessUnitConfig` is a 19-member discriminated union keyed on `type`. Shared
supporting types:

- `FdaLicenceType` — `manufacturer`, `importer`, `exporter`, `retailer`,
  `distributor`, `warehouse`, `food_vendor`
- `QualityCertification` — `GhanaFDA`, `GSA`, `ISO_22000`, `HACCP`,
  `GLOBAL_GAP`, `FAIRTRADE`, `ORGANIC_GHANA`, `RAINFOREST_ALLIANCE`,
  `COCOBOD_CERT`, `AGOA_COMPLIANT`, `EU_ORGANIC`
- `MarketChannel` — `wholesale`, `retail`, `export`, `institutional`,
  `b2b_food_service`, `direct_consumer`
- `ColdStorageCapability` — `capacityCubicMeters`, `chilled`, `frozen`,
  `refrigerationUnits`

The 19 config interfaces (`BakeryConfig`, `CafeConfig`, `ProcessedFoodsConfig`,
`PlantFarmsConfig`, `AquacultureConfig`, `ColdChainConfig`,
`ExportProcessingConfig`, `AnimalFeedConfig`, `InstitutionalCateringConfig`,
`AgriculturalInputsConfig`, `BeveragesConfig`, `PoultryConfig`, `DairyConfig`,
`EdibleOilsConfig`, `RiceMillingConfig`, `SpicesConfig`,
`CassavaProcessingConfig`, `QsrChainsConfig`, `FertilizerConfig`) each carry a
`type` discriminant plus unit-specific fields. Examples:

- `BakeryConfig` — `ovenCount`, `dailyCapacityKg`, `flourSource`
  (`local_mill | imported | both`), `fdaLicenceType`, `certifications`,
  `channels`
- `PoultryConfig` — `broilerBirdsPerCycle`, `layingHens`, `eggsPerDay`,
  `slaughterCapacityPerHour`, `hasHatchery`, `certifications`, `channels`
- `ColdChainConfig` — `storageInstallations: ColdStorageCapability[]`,
  `refrigeratedTrucks`, `insulatedVans`, `transitInsuranceValueGhs`,
  `certifications` (no `channels`)

`BusinessUnitConfigMap` maps each `BusinessUnit` value to its config type;
`ConfigForBU<T>` indexes it.

**Type guards / helpers:** `isBakeryConfig`, `isCafeConfig`,
`isPlantFarmsConfig`, `isAquacultureConfig`, `isColdChainConfig`,
`isExportProcessingConfig`, `isPoultryConfig`, `isDairyConfig`,
`requiresColdChainTracking` (true for `cold_chain`, `export_processing`,
`dairy`, `aquaculture`), `requiresFdaLicence` (true except `plant_farms`,
`aquaculture`, `cold_chain`), `getMarketChannels`.

---

## 5. Agro-Ecology (`@asase/core/agro-ecology.ts`)

This module maps Ghana's 16 administrative regions to their agro-ecological
zones and encodes the seasonal planting calendar for each. Its central purpose
is to let the platform ask "given a GPS coordinate, what crops are appropriate
right now?" — answered by chaining `getRegionForCoordinate` → `getRegionProfile`
→ `getRecommendedCropsForRegion` and `getActiveSeasonWindow`.

`AgroEcologicalZone` const enum — `coastal_savanna`, `deciduous_forest`,
`forest_savanna_transition`, `guinea_savanna`, `sudan_savanna`.

`IrrigationNeed` — `high`, `moderate`, `low`, `minimal`.

`SeasonWindow` — `plantingStartMonth`, `plantingEndMonth`, `harvestStartMonth`,
`harvestEndMonth` (all `number`), `primaryCrops: readonly string[]`.

`GhanaRegionProfile` — `region`, `zone`, `rainfallRangeMm {min,max}`,
`temperatureRangeCelsius {min,max}`, `dominantSoilTypes`, `majorSeasonWindow`,
`minorSeasonWindow: SeasonWindow | null` (null for unimodal northern zones),
`drySeasonIrrigationNeed`, `valueChainsNotes`.

`GHANA_REGION_PROFILES` — a profile for all 16 regions. `REGION_TO_ZONE` maps
every region to its zone. Helpers: `getRegionsByZone`, `getRegionProfile`,
`isBimodalRegion`, `getActiveSeasonWindow`, `getRecommendedCropsForRegion`.

---

## 6. Measurement (`@asase/core/measurement.ts`)

The measurement module solves a real agricultural problem: Ghanaian markets use
local units (olonka, maxi-bag) alongside international SI units, and confusing
them in calculations produces wrong-order-of-magnitude errors. The phantom-typed
algebra ensures that a `Mass` value cannot be accidentally added to an `Area`
value, and that conversions go through a single canonical SI path.

Phantom-typed `Measurement<U, D>` over dimensions
`mass | volume | area | temperature | humidity | currency`. The unit enums below
define every valid unit for each dimension; the Ghana-specific conversion
factors following the table are the authoritative values used by all conversion
functions.

| Unit enum                 | Values                                                                                  |
| ------------------------- | --------------------------------------------------------------------------------------- |
| `MassUnit`                | `g`, `kg`, `t`, `lb`, `oz`, `mini_bag_50kg`, `maxi_bag_100kg`                           |
| `VolumeUnit`              | `ml`, `l`, `gal_us`, `m3`, `olonka`, `bowl`, `american_tin_small`, `american_tin_large` |
| `AreaUnit` (measurement)  | `sqm`, `ha`, `ac`, `sqkm`, `plot`                                                       |
| `TemperatureUnit`         | `C`, `F`, `K`                                                                           |
| `CurrencyMeasurementUnit` | `GHS`, `USD`, `EUR`, `GBP`                                                              |

Ghana-specific conversion factors: `olonka` = 2.5 L, `bowl` = 3.0 L,
`american_tin_small` = 0.375 L, `american_tin_large` = 0.8 L, `plot` = 0.3 ha,
`mini_bag_50kg` = 50 kg, `maxi_bag_100kg` = 100 kg.

Constructors/converters: `mass`, `convertMass`, `toKg`, `volume`,
`convertVolume`, `toLitres`, `area`, `convertArea`, `toHectares`, `temperature`,
`convertTemperature`, `humidity` (throws `RangeError` outside 0–100), `money`,
`formatQuantity`. `Quantity<U>` is a persisted `{ value, unit }` pair;
`MassQuantity`/`VolumeQuantity`/`AreaQuantity`/`TemperatureQuantity` are
aliases. (`measurement.ts`'s `AreaUnit` is re-exported as `FarmAreaUnit` from
the package barrel to avoid clashing with `types.ts`'s `AreaUnit`.)

---

## 7. Seasonality (`@asase/core/seasonality.ts`)

The seasonality module answers crop-calendar questions: "When should I plant
Jasmine 85 rice in a bimodal rainfall zone?", "When is the next planting window
for Obatanpa maize?", "Given a planting date for Afisiafi cassava, when is the
expected harvest?". It encodes profiles for nine key Ghana crop varieties and
exposes helper functions that take a crop key, planting date, and rainfall
pattern and return actionable calendar guidance.

`CropGrowthStage`, `RainfallPattern` (`bimodal | unimodal`), `CalendarMonth`
(`1`…`12`).

`PlantingWindow` — `season`, `startMonth`, `endMonth` (`CalendarMonth`),
`startDay`, `endDay` (`number`), `rainfallPattern`, `latenessRisk`
(`low | moderate | high`).

`CropDuration` — `minDays`, `maxDays`, `daysToFlowering`, `daysToHarvest`.

`InputApplicationWindow` — `inputType`, `daysAfterPlanting`, `windowDays`,
`rationale`.

`CropSeasonalityProfile` — `cropKey`, `name`, `plantingWindows`, `duration`,
`inputSchedule`, `postHarvestNotes`.

`CROP_SEASONALITY` — profiles keyed by crop (`MAIZE_OBATANPA`, `MAIZE_ABONTEM`,
`CASSAVA_AFISIAFI`, `RICE_JASMINE_85`, `COCOA_HYBRID`, `YAM_PONA`,
`GROUNDNUT_MANIPINTA`, `SOYBEAN_SARI_SOLIMO`, `TOMATO_PECTOMECH`).
`GHANA_SEASONALITY` — `SeasonalityDescriptor` for `bimodal` and `unimodal`.

Functions: `getPlantingWindowsForPattern(cropKey, pattern)`,
`estimateHarvestRange(cropKey, plantingDate)` → `{earliest, latest} | null`,
`resolveInputSchedule(cropKey, plantingDate)`,
`isInPlantingWindow(cropKey, date, pattern)`.

---

## 8. Stakeholders (`@asase/core/stakeholders.ts`)

The stakeholder model captures the full cast of actors in Ghana's agricultural
value chain as a discriminated union. Each actor type carries the identity
documents, licences, and operational fields that are specifically relevant to it
— a farmer profile carries MoFA farmer number and mobile money provider; a
regulator profile carries inspection authority and regulatory domain. The
compliance functions (`isFdaRegulated`, `requiresPprsdCompliance`) operate on
the union type, making regulatory gate-checks type-safe and precise.

Identity-document type aliases: `GhanaCardNumber`,
`TaxpayerIdentificationNumber`, `SsnitNumber`, `BusinessRegNumber`,
`MofaFarmerNumber` (all `string`).

`StakeholderContact` — `mobile`, `landline?`, `email?`, `address`, `district`,
`region`.

`StakeholderRole` discriminant — `farmer`, `processor`, `distributor`,
`retailer`, `exporter`, `input_supplier`, `financier`, `regulator`.

`Stakeholder` is a discriminated union of 8 profiles, each extending
`BaseStakeholder` (`id`, `role`, `name`, `contact`, `kycVerified`,
`onboardedAt`):

| Profile                | Key fields / sub-types                                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `FarmerProfile`        | `category` (`smallholder \| commercial \| outgrower \| cooperative_member`), `economicGroup` (`subsistence \| transition \| commercial_small \| commercial_medium \| commercial_large`), `mofaFarmerNumber?`, `ghanaCardNumber?`, `ssnitNumber?`, `primaryCommodity`, `totalFarmAreaHectares`, `outgrowerSchemeName?`, `hasCreditAccess`, `usesMobileMoney`, `mobileMoneyProvider?` (`MTN \| Vodafone \| AirtelTigo`), `dependants?` |
| `ProcessorProfile`     | `category` (`primary \| secondary \| tertiary`), `fdaLicenceNumber?`, `gsaCertification?`, `tin?`, `businessRegNumber?`, `monthlyCapacityTonnes`, `permanentEmployees`, `productCategories`, `haccpCertified`, `iso22000Certified`                                                                                                                                                                                                   |
| `DistributorProfile`   | `tier` (`national \| regional \| district \| last_mile`), `refrigeratedVehicles`, `ambientVehicles`, `distributionRegions`, `offersColdChain`, `annualTurnoverGhsBand`                                                                                                                                                                                                                                                               |
| `RetailerProfile`      | `retailerType` (`supermarket \| mini_mart \| market_stall \| hawker \| agro_dealer \| cooperative_shop`), `sellsFreshProduce`, `sellsAgrochemicals`, `pprsdDealerNumber?`, `avgMonthlySalesGhs?`                                                                                                                                                                                                                                     |
| `ExporterProfile`      | `gepaNumber?`, `fdaLicenceNumber?`, `exportLicenceNumber?`, `destinationMarkets` (`ExportDestination[]`), `productCategories`, `annualExportValueUsd?`, `agoaBeneficiary`                                                                                                                                                                                                                                                            |
| `InputSupplierProfile` | `supplierType` (`national_distributor \| regional_distributor \| agro_dealer \| manufacturer`), `pprsdNumber?`, `suppliesCertifiedSeeds`, `suppliesAgrochemicals`, `operatingRegions`, `subDealerCount?`                                                                                                                                                                                                                             |
| `FinancierProfile`     | `financierType` (`microfinance \| rural_bank \| commercial_bank \| fintech \| agri_insurer \| development_finance`), `bogLicenceNumber?`, `offersCropInsurance`, `offersMobileCredit`, `agriLoanPortfolioGhs?`                                                                                                                                                                                                                       |
| `RegulatorProfile`     | `bodyType` (`Ghana_FDA \| GSA \| PPRSD \| VSD \| COCOBOD \| GEPA \| GRA \| MOFA \| EPA \| NIA \| Local_Government`), `regulatoryDomain`, `website?`, `issuesExportCerts`, `hasInspectionAuthority`                                                                                                                                                                                                                                   |

`ExportDestination` — `EU`, `US`, `UK`, `ECOWAS`, `Middle_East`, `Asia`,
`Other`.

Type guards: `isFarmer`, `isProcessor`, `isDistributor`, `isRetailer`,
`isExporter`, `isInputSupplier`, `isFinancier`, `isRegulator`.
`isFdaRegulated(s)` — true for processor/retailer/exporter.
`requiresPprsdCompliance(s)` — true for input_supplier or a retailer that sells
agrochemicals. `getStakeholderDisplayName(s)` formats `"<name> (<RoleLabel>)"`.

---

## 9. Domain Entities (`@asase/core/domain-entities.ts`)

Where `types.ts` (§3.5) defines lean entity interfaces for the core operational
loop, `domain-entities.ts` defines richer value objects for use-cases that need
full detail: crop variety botanical classification and yield ranges, farm plot
GPS polygons and rotation history, the facility hierarchy (processing plants,
cold stores, abattoirs), products with nutritional composition and bill of
materials, and price trend analytics.

### 9.1 `CropVariety`

`id`, `name`, `localNames: CropLocalNames` (`twi?`, `ewe?`, `ga?`, `dagbani?`,
`hausa?`, `fante?`), `botanical: BotanicalClassification` (`kingdom` is the
literal `'Plantae'`, `family`, `genus`, `species`, `binomial`, `cultivar?`),
`category: CropCategory`, `cocobodCode?`, `mofaRegistrationNumber?`,
`optimalZones`, `optimalRegions`, `growingDays {min,max}`,
`yieldRange: YieldRange` (`minKgPerHa`, `typicalSmallholderKgPerHa`,
`attainableKgPerHa`, `maxKgPerHa`), `marketGrades: MarketGradeSpec[]` (`grade`,
`description`, `premiumPercent`), `ambientShelfLifeDays?`,
`coldStorageShelfLifeDays?`, `susceptibilities`, `resistances`,
`openPollinated`, `seedSavable`.

`CROP_VARIETY_CATALOG` — keyed entries `COCOA_HYBRID_CRIG`,
`MAIZE_OBATANPA_QPM`, `CASSAVA_AFISIAFI`, `YAM_PONA`.

### 9.2 `FarmPlot`

`id: PlotId`, `farmId: FarmId`, `name`, `gpsPolygon?: GpsPolygon` (array of
`[lon, lat]` pairs), `areaHectares`, `soilType`, `soilPhValue?`,
`lastSoilTestDate?`, `irrigationType`, `status`, `currentCropVarietyId?`,
`currentPlantingDate?`, `rotationHistory: CropRotationEntry[]`, `notes?`.
`CropRotationEntry` — `seasonYear`, `cropVarietyId`, `plantingDate`,
`harvestDate?`, `yieldKgPerHa?`, `qualityGrade?`, `inputCostGhs?`.

### 9.3 Facility Hierarchy

`FacilityCategory` — `processing_plant`, `cold_storage`, `dry_warehouse`,
`abattoir`, `hatchery`, `feed_mill`, `fish_farm`, `shrimp_farm`,
`retail_outlet`, `market_centre`, `agro_input_store`, `laboratory`.

`FacilityOperationalStatus` — `active`, `under_maintenance`, `suspended`,
`decommissioned`.

`FacilityBase` — `id: FacilityId`, `businessUnit`, `category`, `name`, `region`,
`district`, `latitude`, `longitude`, `fdaLicenceNumber?`, `epaPermitNumber?`,
`lastFdaInspectionDate?`, `fdaInspectionResult?`
(`pass | conditional_pass | fail`), `operationalStatus`, `registeredAt`.

`Facility` =
`ProcessingFacility | ColdStorageFacility | AbattoirFacility | FacilityBase`.
`ProcessingFacility` adds `throughputTonnesPerDay`, `productCategories`,
`haccpImplemented`, `floorAreaSqm`, `processingLineCount`. `ColdStorageFacility`
adds `storageCubicMeters`, `temperatureRangeCelsius`, `refrigerationUnitCount`,
`hasBlastFreezer`, `backupGeneratorKva?`. `AbattoirFacility` adds
`vsdLicenceNumber?`, `slaughterCapacityPerDay`, `speciesSlaughtered`,
`anteMortemInspection`, `postMortemInspection`.

### 9.4 `Product`

`id`, `sku`, `name`, `description`, `businessUnit`, `facilityId?`,
`lotTrackingEnabled`, `activeLotIds`, `billOfMaterials: BomEntry[]`,
`nutritionalComposition?: NutritionalComposition`, `shelfLife: ShelfLifeParams`,
`gsaStandardReference?`, `fdaProductNumber?`, `cocobodGrade?`, `allergens`,
`organicCertified`, `halalCertified`, `salesUnit`, `netWeightGrams`,
`retailPriceGhs?`, `exportEligible`, `createdAt`, `updatedAt`.

`BomEntry` — `materialName`, `quantityPerUnit`, `unit`, `allergenRelevant`.
`NutritionalComposition` — per-100g `energyKcal`, `proteinG`, `fatG`,
`carbohydrateG`, `fibreG`, `sodiumMg`, optional `sugarG`, `calciumMg`, `ironMg`,
`vitaminCMg`. `ShelfLifeParams` — `ambientDays`, `chilledDays?`, `frozenDays?`,
`criticalWaterActivity?`.

`generateSku(businessUnitPrefix, categoryCode, sequence)` →
`"{PREFIX}-{CATEGORY}-{0000}"`.

### 9.5 `PricePoint` / `PriceTrend`

`PriceSource` — `ghana_commodity_exchange`, `esoko`, `mofa_market_survey`,
`market_field_visit`, `trader_report`, `export_contract`, `futures_cbot`,
`futures_ice`, `internal_transaction`.

`PricePoint` — `commodity`, `market`, `region`, `price`, `currency`, `unit`,
`source`, `observedAt`, `qualityGrade?`, `priceType`
(`wholesale | retail | farm_gate | export_fob`), `notes?`.

`PriceTrend` — `commodity`, `market`, `periodDays`, `openingPrice`,
`closingPrice`, `minPrice`, `maxPrice`, `meanPrice`, `changePercent`,
`volatilityPercent` (coefficient of variation), `observationCount`, `currency`,
`unit`.

`computePriceTrend(prices, commodity, market)` returns `PriceTrend | null` (null
when fewer than 2 matching points). `getLatestPrice(prices, commodity, market)`
returns the most recent matching `PricePoint`.

---

## 10. Domain Services (`@asase/core/domain-services.ts`)

Domain services wrap the lower-level modules (measurement, seasonality,
agro-ecology, geo-utils) behind stateful class APIs that support dependency
injection. A class that needs to convert units, look up planting windows, check
regulatory requirements, resolve coordinates, or record audit events imports the
appropriate service class and instantiates it — or receives it via constructor
injection for testing.

### 10.1 `UnitConversionService`

`convertMass(value, from, to)`, `convertVolume`, `convertArea` (all return
`ConversionResult<U>` with
`inputValue/inputUnit/outputValue/outputUnit/ conversionFactor`); `toKg`,
`toLitres`, `toHectares`; `bagCount(weightKg, bagSizeKg?: 50 | 100)` →
`{ fullBags, remainderKg }`; `pricePerKg(pricePerUnit, unit)`; `formatMass`,
`formatArea`.

### 10.2 `SeasonalCalendarService`

`getRainfallPattern(region)` — `unimodal` for guinea/sudan savanna, else
`bimodal`. `getPlantingAdvice(cropKey, region, date)` → `PlantingAdvice | null`
(`isWithinWindow`, `nextWindowStart?`, `daysUntilNextWindow?`, `latenessRisk?`,
`estimatedHarvestRange?`, `inputSchedule`). `getCropsInWindow(region, date)`,
`buildAnnualCalendar(region, fromDate)` (12-month planting calendar).

### 10.3 `GhanaRegulatoryService`

`getFoodSafetyStandard(commodity)` → `FoodSafetyResult | null` (matched against
`FOOD_SAFETY_STANDARDS`). `getRegulatoryBodies()` returns `REGULATORY_BODIES`.
`getExportRequirements(market: 'EU' | 'US' | 'UK' | 'ECOWAS' | 'Other')` returns
phytosanitary, aflatoxin (`maxAflatoxinPpbFresh/Processed`), and MRL
requirements per market. `getHsCode(commodity)` → entry from `HS_CODES`.
`getAgrochemicalRequirements(whoHazardClass: 'Ia' | 'Ib' | 'II' | 'III' | 'U')`
returns PPRSD/EPA registration, storage class, and PPE.

### 10.4 `GeolocationService`

Constructed with optional `customMarkets`; otherwise uses the 12-entry
`MAJOR_MARKETS` list. `getRegionForCoordinate(lat, lon)` — smallest-bounding-box
match over the 16 regions; `getZoneForCoordinate`;
`findNearestMarkets(lat, lon, topN = 3)` — Haversine ranking with road-distance
estimate (×1.3 factor) and travel hours (40 km/h); `locate(lat, lon)` →
`GeolocationResult`.

### 10.5 `AuditTrailService`

`AuditActorType` — `system`, `worker`, `manager`, `api_integration`,
`regulatory_inspector`. `ComplianceTag` — `EU_EXPORT`, `US_FDA`, `AGOA`,
`COCOBOD`, `GHANA_FDA`, `GSA_CERTIFIED`, `HACCP_CCP`, `ISO22000`, `GLOBAL_GAP`.

`AuditEvent` — `eventId`, `occurredAt`, `actor {type,id,name,ipAddress?}`,
`action`, `resourceType`, `resourceId`, `businessUnit`, `previousState?`,
`newState?`, `changedFields?`, `complianceTags`, `reason?`, `correlationId?`.

`AuditStorageAdapter` interface (`save`, `query`, `getById`) with
`InMemoryAuditAdapter`. `AuditTrailService` methods: `record`, `recordCreate`,
`recordUpdate` (computes `changedFields` by JSON diff), `query`, `getHistory`,
`getComplianceEvents`. Event IDs are `EVT-<timestamp>-<6-digit-seq>`.

---

## 11. Validation (`@asase/core/validation.ts`)

Validation functions return a `ValidationResult` — a plain
`{ valid: boolean, errors: readonly string[] }` object — rather than throwing.
This makes validation usable in bulk-import pipelines and API handlers alike:
callers inspect `valid` and accumulate `errors` without needing try/catch. All
Ghanaian domain-specific constraints (phone number formats, farm registration
patterns, cocoa grading thresholds) are encoded here rather than scattered
across application code.

`ValidationResult` — `{ valid: boolean, errors: readonly string[] }`.

The table below lists every validation function, its input parameters, and the
constraint it enforces.

| Function                                                                    | Behaviour                                                                                                |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ----- |
| `validateFarmRegistrationNumber(regNumber)`                                 | Matches `GH-<2 letters>-<2-4 letters>-<3-6 digits>` and validates the region code against `REGION_CODES` |
| `extractRegionFromRegistration(regNumber)`                                  | Returns `Region                                                                                          | null` |
| `validateGhanaCoordinates(location: GeoLocation)`                           | Lat 4.5–11.5, lon −3.3–1.2; flags negative/over-900 m altitude and negative accuracy                     |
| `validateCoordinates(location)`                                             | Generic lat −90…90, lon −180…180                                                                         |
| `validateTemperatureForStorage(temp, condition)`                            | Against `STORAGE_TEMPERATURE_RANGES`                                                                     |
| `validateTemperatureRange(temp, minCelsius, maxCelsius)`                    | Custom range                                                                                             |
| `validateMinimumGrade(actual, minimum)`                                     | `QualityGrade` rank order: `premium < grade_a < grade_b < grade_c < reject`                              |
| `isExportableGrade(grade)`                                                  | True for `premium` or `grade_a`                                                                          |
| `validateCocoaQuality(moisturePercent, defectivePercent, beanCountPer100g)` | Returns `{ grade, issues }` using `COCOA_GRADE_THRESHOLDS` (`grade_1`/`grade_2`/`substandard`/`reject`)  |
| `validateBatchSize(businessUnit, sizeKg)`                                   | Against `MAX_BATCH_SIZES`                                                                                |
| `validateCropCycleDates(plantingDate, expectedHarvestDate)`                 | Planting before harvest; cycle 30–2555 days                                                              |
| `validatePlantingDate(plantingDate, maxFutureDays = 365)`                   | Rejects dates beyond the planning horizon                                                                |
| `validateCurrencyAmount(amount, currency)`                                  | Non-negative, finite, supported currency                                                                 |
| `validateSoilPH(ph)`                                                        | 0–14                                                                                                     |
| `validateHumidity(percentage)`                                              | 0–100                                                                                                    |
| `validatePlotArea(value, unit)`                                             | Positive; unit in `hectares`/`acres`/`sq_meters`; sanity caps                                            |
| `validateGhanaPhoneNumber(phone)`                                           | `+233`/`233`/`0` prefix, `2x`/`5x` network code, 7-digit subscriber number                               |
| `validateBatchNumber(batchNumber)`                                          | `XX-XXXXX-YYYYMMDD-NNN`, with embedded-date sanity checks                                                |

`CocoaGradeThresholds` — `maxMoisturePercent`, `maxDefectivePercent`,
`minBeanCount100g`, `maxBeanCount100g`. `COCOA_GRADE_THRESHOLDS` keys:
`grade_1`, `grade_2`, `substandard`.

---

## 12. Utilities (`@asase/core/utils.ts`)

`utils.ts` contains standalone calculation functions that do not need to be
stateful or injected. These cover the domain-specific computations used
frequently enough to warrant shared helpers: yield, harvest estimation, soil pH
classification, currency conversion, cold chain compliance scoring, post-harvest
loss rates, batch number generation, and phone number formatting. The
`estimateHarvestDate` function applies regional climate factors (+5% days for
NORTHERN zones, +2% for TRANSITIONAL) to account for the shorter growing season
in southern Ghana versus the north.

`calculateYieldPerHectare(totalYieldKg, area)`, `compareYieldToTypical`,
`estimateHarvestDate(varietyKey, plantingDate, region)` (midpoint of growing
days × regional climate factor: +5 % NORTHERN, +2 % TRANSITIONAL),
`getGrowingPeriod`, `classifySoilPH`, `getCropSuitabilityForPH`,
`convertCurrency` (via GHS intermediary using `GHS_EXCHANGE_RATES`),
`formatCurrencyAmount`, `calculateColdChainCompliance` (percentage of readings
in range plus worst breach), `formatCommodityCode`, `isValidHSCode`,
`getSeasonForDate(date, region)`, `isPlantingWindow(date, region)`,
`calculatePostHarvestLoss(crop, storageCondition, durationDays)` (compound loss
from `POST_HARVEST_LOSS_RATES`), `generateBatchNumber`, `calculateBagCount`,
`getSuitableCropsForRegion`, `getVarietiesByCategory`,
`calculateTemperatureDeviation`,
`estimateWaterRequirement(cropCategory, growthStage, season)`,
`formatGhanaPhoneNumber`, `identifyGhanaOperator`
(`MTN`/`Vodafone`/`AirtelTigo`/`Glo`/`Other`).

---

## 13. Errors (`@asase/core/errors.ts`)

The error hierarchy uses a base `AsaseError` class that all domain-specific
errors extend. Each error carries a `code`, `statusCode` (suitable for HTTP
responses), optional `details`, a `timestamp`, and an `isOperational` flag that
distinguishes expected domain errors (crop cycle closed, cold chain breach,
export compliance failure) from unexpected programming errors. `AsaseError` is
self-contained — it does not depend on a shared error base class from outside
the domain.

`AsaseError` (base; `code`, `statusCode`, `details?`, `timestamp`,
`isOperational`, `toJSON()`) and its hierarchy:

```
AsaseError
├── CropCycleError                  (plotId?, cropId?)
│   ├── InvalidPlantingDateError
│   └── CropCycleClosedError
├── ColdChainBreachError            (getDeviationCelsius())
├── QualityFailureError
├── SupplyChainError                (shipmentId?, origin?, destination?)
│   ├── ShipmentDelayError          (delayHours)
│   └── RouteFailureError
└── ComplianceError                 (regulatoryBody?, standardCode?, violationType?)
    ├── FoodSafetyViolationError
    └── ExportComplianceError
```

`AsaseError` is self-contained — it does not depend on a shared error base.

---

## 14. Constants (`@asase/core/constants.ts`)

`constants.ts` holds the reference data that is stable enough to ship with the
domain library rather than require a database query: the crop variety catalog,
livestock breed list, regulatory bodies, seasonal ranges, market locations, food
safety standards, HS codes, exchange rates, storage temperature ranges, soil
classifications, post-harvest loss rates, business unit prefixes, region codes,
and batch size caps. These constants are the authoritative source for all
validation and calculation functions in the domain.

| Constant                     | Content                                                                                                                                                                                                                                                                                                                                                      |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CROP_VARIETIES`             | `CropVarietyInfo` for ~35 Ghana cultivars (cocoa, maize, rice, cassava, yam, plantain, oil palm, shea, groundnut, cowpea, soybean, tomato, pepper, ginger, cashew, mango, pineapple, coconut, sorghum, millet, okra, garden egg, onion, cotton, turmeric) — each with `localName`, `category`, `typicalYieldKgPerHa`, `growingDaysMin/Max`, `optimalRegions` |
| `LIVESTOCK_BREEDS`           | `LivestockBreedInfo` for ~21 breeds across cattle, poultry, goat, sheep, pig, fish, shrimp, rabbit, snail                                                                                                                                                                                                                                                    |
| `REGULATORY_BODIES`          | MoFA, FDA, GSA, COCOBOD, EPA, PPRSD, VSD, FC (Fisheries Commission), GEPA — each with `name`, `acronym`, `role`                                                                                                                                                                                                                                              |
| `SEASON_RANGES`              | `SOUTHERN`, `TRANSITIONAL`, `NORTHERN` cropping-season date ranges                                                                                                                                                                                                                                                                                           |
| `REGION_CLIMATE_ZONE`        | Each `Region` → `SOUTHERN`/`TRANSITIONAL`/`NORTHERN`                                                                                                                                                                                                                                                                                                         |
| `MARKET_LOCATIONS`           | 12 major markets (Makola, Agbogbloshie, Kumasi Central, Tamale, Techiman, Bolgatanga, Cape Coast, Ho, Sunyani, Tema Port, Takoradi Port, Wa) with GPS and commodities                                                                                                                                                                                        |
| `FOOD_SAFETY_STANDARDS`      | 10 GSA/FDA standards (`GS 34` maize, `GS 207` rice, `GS 52` cocoa, `GS 44` gari, `GS 972` shea butter, `GS 55` palm oil, `GS 955` fresh produce, `GS 175` groundnuts, `GS 215` dried fish, `GS 83` cassava flour)                                                                                                                                            |
| `HS_CODES`                   | 20 HS tariff codes for key agricultural exports                                                                                                                                                                                                                                                                                                              |
| `GHS_EXCHANGE_RATES`         | Reference rates: GHS→USD/EUR/GBP and USD/EUR/GBP→GHS                                                                                                                                                                                                                                                                                                         |
| `STORAGE_TEMPERATURE_RANGES` | Per `StorageCondition`: ambient 15–30 °C, chilled 0–5 °C, frozen −25…−18 °C, controlled_atmosphere 10–15 °C                                                                                                                                                                                                                                                  |
| `SOIL_CLASSIFICATIONS`       | 6 Ghana soil classes with optimal-pH range and suitable crops                                                                                                                                                                                                                                                                                                |
| `POST_HARVEST_LOSS_RATES`    | Monthly loss rates per commodity × storage condition                                                                                                                                                                                                                                                                                                         |
| `BUSINESS_UNIT_PREFIXES`     | Two-letter batch prefix per business unit                                                                                                                                                                                                                                                                                                                    |
| `REGION_CODES`               | Two-letter code per region (used by farm-registration validation)                                                                                                                                                                                                                                                                                            |
| `MAX_BATCH_SIZES`            | Daily capacity cap (kg) per business unit                                                                                                                                                                                                                                                                                                                    |

---

## 15. Persistence — Drizzle Schema (`@asase/core/db-schema.ts`)

The database schema is the persistence layer for the domain entities and
operational records defined in earlier sections. It uses the `asase_` table
prefix throughout to prevent name collisions with other Oshun domain schemas in
the shared PostgreSQL instance. The schema defines its own custom `vector`
Drizzle type backed by the `pgvector` PostgreSQL extension (`vector(1536)`
default dimension, JSON-serialised driver values), enabling semantic crop
variety search via 1536-dimension embeddings.

The schema uses the `asase_` table prefix throughout and defines a custom
`vector` Drizzle type backed by the PostgreSQL `pgvector` extension
(`vector(1536)` default, JSON-serialised driver values).

### 15.1 PostgreSQL Enums (27)

PostgreSQL enum types enforce valid values at the database level, independent of
application-layer validation. The 27 `pgEnum` types listed below mirror the
TypeScript enums in §3.2 — when a TypeScript enum value changes, the
corresponding PostgreSQL enum migration must also be applied. Each enum name
carries the `asase_` prefix.

`asase_business_unit`, `asase_crop_category`, `asase_growth_stage`,
`asase_livestock_type`, `asase_processing_stage`, `asase_quality_grade`,
`asase_storage_condition`, `asase_transport_mode`, `asase_currency_code`,
`asase_region`, `asase_season`, `asase_unit_of_measure`, `asase_soil_type`,
`asase_irrigation_type`, `asase_plot_status`, `asase_health_status`,
`asase_shipment_status`, `asase_facility_type`, `asase_order_status`,
`asase_alert_severity`, `asase_certification_status`, `asase_haccp_record_type`,
`asase_worker_role`, `asase_listing_status`, `asase_trade_status`,
`asase_sensor_status`, `asase_breeding_method`, `asase_feed_type`,
`asase_input_category`, `asase_safety_class`.

(`asase_business_unit`, `asase_crop_category`, `asase_growth_stage`,
`asase_quality_grade`, `asase_region`, `asase_season`, etc. mirror the
TypeScript enums in §3.2.)

### 15.2 Tables (36)

The 36 tables are grouped by the domain concern they serve. All tables use
`uuid` primary keys (`defaultRandom()`), timezone-aware `timestamp` columns for
`created_at` / `updated_at` / `deletedAt` (soft delete), `jsonb` for flexible
metadata, and named B-tree / unique indexes.

| Group               | Tables                                                                                                                       |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Crops               | `asase_crop_varieties`, `asase_farms`, `asase_plots`, `asase_crop_cycles`, `asase_planting_records`, `asase_harvest_records` |
| Livestock           | `asase_livestock_batches`, `asase_feeding_schedules`, `asase_health_records`, `asase_breeding_records`                       |
| Facility/Processing | `asase_facilities`, `asase_processing_batches`, `asase_bill_of_materials`, `asase_packaging_records`                         |
| Cold chain          | `asase_cold_storage_units`, `asase_temperature_sensors`, `asase_sensor_readings`, `asase_breach_alerts`                      |
| Supply chain        | `asase_suppliers`, `asase_purchase_orders`, `asase_shipments`, `asase_shipment_items`, `asase_delivery_tracking`             |
| Quality             | `asase_quality_standards`, `asase_quality_tests`, `asase_certifications`, `asase_haccp_records`                              |
| Market              | `asase_market_prices`, `asase_commodity_listings`, `asase_trading_records`, `asase_price_forecasts`                          |
| Operations          | `asase_business_unit_configs`, `asase_workers`, `asase_worker_assignments`, `asase_audit_log`                                |
| Inputs              | `asase_agricultural_inputs`                                                                                                  |

Tables use `uuid` primary keys (`defaultRandom()`), `timestamp` with timezone
`created_at`/`updated_at`/`deletedAt` (soft delete), `jsonb` columns for
flexible metadata, foreign keys with `onDelete` rules, and named B-tree / unique
indexes. `asase_crop_varieties` carries a
`vector('embedding', { dimensions: 1536 })` column for crop-similarity search.
`asase_farms` stores `registration_number` (unique), `region`, `district`, GPS
decimal columns, and `certifications` jsonb. `asase_plots` references
`asase_farms` (cascade) and `asase_crop_varieties` (set-null).

### 15.3 Migration Framework (`@asase/migrations`)

The `@asase/migrations` package owns all database lifecycle operations for the
Asase domain: applying schema migrations, seeding reference data, and managing
connection pools. It is the only package that talks to the database by path —
all other libraries receive a database connection via dependency injection. The
CLI (`migrate.ts`) exposes the standard `up`, `down`, `status`, `seed`, and
`reset` commands as npm scripts.

- 11 migration files (`20260101_000001`…`_000011`): create enums, crop tables,
  livestock tables, facility/processing tables, cold-chain tables, supply-chain
  tables, quality tables, market tables, ops tables, RLS policies, and the
  agricultural-inputs table. Exported as `ASASE_MIGRATIONS`.
- 8 seed scripts: business units, crop varieties, livestock breeds, facilities,
  quality standards, markets, suppliers, workers (`runAllSeeds` orchestrates
  them).
- `AsaseMigrationRunner` / `createAsaseMigrationRunner` with `runMigrations`,
  `rollbackMigration`, `getMigrationStatus`, `seedDatabase`.
- Connection pooling: `SENSOR_INGESTION_POOL`, `TRANSACTIONAL_POOL`,
  `REPORTING_POOL` presets, `createAsasePool`, `AsaseConnectionManager`,
  `PGBOUNCER_CONFIG_TEMPLATE`.
- CLI `migrate.ts` with commands `up`, `down`, `status`, `seed`, `reset` (npm
  scripts `migrate:up/down/status/seed/reset`, `drizzle:generate/push/ studio`).

---

## 16. Infrastructure Services (`@asase/infrastructure`)

`@asase/infrastructure` wraps shared Oshun platform services with Asase-
specific namespacing, type definitions, and configuration. It depends on
`@asase/core`, `@oshun/cache`, `@oshun/event-bus`, `@oshun/logging`,
`@oshun/metrics`, `ioredis`, and `zod`. All other Asase libraries that need
caching, storage, events, metrics, or geospatial queries import from
`@asase/infrastructure` — never directly from the underlying Oshun platform
packages.

Depends on `@asase/core`, `@oshun/cache`, `@oshun/event-bus`, `@oshun/logging`,
`@oshun/metrics`, `ioredis`, `zod`.

- **Cache** — `AsaseCacheClient`, `createAsaseCacheClient`, key helpers
  `asaseKey`/`asasePattern`, predefined TTL constants `ASASE_TTL`.
- **Storage** — `AsaseStorageService`, `ASASE_BUCKETS`, `BUCKET_CONFIGS`,
  `buildObjectKey`, `buildComplianceKey`; types include `MinioClientLike`,
  `PresignOptions`, `BucketInitResult`.
- **Events** — `createAsaseEventBus`, `ASASE_TOPICS`, `ASASE_TOPIC_PATTERNS`.
  Event types: `CropsCycleStartedEvent`, `CropsHarvestRecordedEvent`,
  `CropsPestAlertEvent`, `LivestockHealthAlertEvent`,
  `LivestockMortalityRecordedEvent`, `ColdChainBreachDetectedEvent`,
  `SupplyChainDelayDetectedEvent`, `QualityTestRecordedEvent`,
  `MarketPriceUpdatedEvent`. `AsaseEvent` is the union; `AsaseEventBase` is the
  shared base.
- **Metrics** — `AsaseMetricsService`, `createAsaseMetrics`; metric groups
  `CropMetrics`, `LivestockMetrics`, `ProcessingMetrics`, `ColdChainMetrics`,
  `SupplyChainMetrics`, `QualityMetrics`, `MarketMetrics`.
- **Geospatial** — `AsaseGeospatialService`, `GHANA_REGION_INFO`, `GEO_SQL`,
  `haversineDistanceKm`, `findRegionByCoordinate`, `sortByDistance`,
  `toPointWkt`, `toGeoJsonString`, `buildBufferSql`; types include
  `PlotBoundary`, `FacilityLocation`, `DeliveryRoute`, `MarketCatchmentArea`,
  `PgClientLike`.

---

## 17. Domain Library API Surface (Selected)

Each domain library exposes a curated `index.ts` barrel that re-exports the
public API. The lists below are representative entry points — the highest-value
exports that consumers are most likely to import. The full surface is in the
library source. For a narrative description of what each library does, see
`features.md`.

Each domain library exposes a curated `index.ts` barrel. The full surface is in
the library source; representative entry points:

- **`@asase/crops`** — `GHANA_CROP_REGISTRY`, `recommendVarieties`,
  `PEST_DISEASE_CATALOG`, `FieldActivityTracker`, `GHANA_INPUT_PRODUCTS` +
  `generateInputSchedule`, `GHANA_IRRIGATION_SCHEMES` +
  `estimateEToHargreaves`/`computeKcAtDas`/`generateIrrigationSchedule`,
  `LabourManager` + wage/compliance functions, `MechanizationScheduler`,
  `INTERCROPPING_MATRIX` + `generateRotationPlan`, `predictYield`,
  `CropHealthMonitor` + `computeNdvi`/`computeEvi`/`computeNdwi`,
  `SoilFertilityTracker` + `GHANA_SRID_THRESHOLDS`, `WeatherImpactAnalyzer`,
  `HarvestLossEstimator`.
- **`@asase/livestock`** — `GHANA_LIVESTOCK_BREEDS` + `LivestockRegistry` +
  `generateNlisId`, `GHANA_VACCINE_CATALOG` + `VaccinationManager`,
  `FeedFormulationEngine` + `formulateRation`, `DiseaseSurveillanceSystem` +
  `generateWahisNotification`, `MortalityMorbidityService` + `computeEpef`,
  `BroilerFlockTracker`, `LayerFarmManager` + `GHANA_EGG_GRADE_THRESHOLDS`,
  `HatcheryManager` + `computePasgarScore`, `HouseEnvironmentController` +
  `computeThi`, `PoultryDistributionOptimizer`, `FishFarmRegistry`,
  `WaterQualityMonitor`, `AquaFeedManager`, `AquaGrowthTracker`,
  `FishHealthManager`.
- **`@asase/processing`** — `ProcessingPlantRegistry`, `ProductionScheduler`,
  `RawMaterialReceivingService`, `BomExplosionService`, `BatchExecutionEngine`,
  `RecipeManager`, `UtilityMonitoringService`, `YieldWasteTracker`,
  `BatchGenealogyTracker`, `NutritionalLabelingEngine`, `OEEEngine`,
  `EnergyEfficiencyAnalytics`, `PredictiveMaintenanceService`, `SPCService`,
  `COQReportingService`.
- **`@asase/cold-chain`** — `ColdStorageFacilityRegistry`,
  `TemperatureMonitoringService`, `ColdRoomInventoryService`,
  `EnergyOptimizationEngine`, `BackupPowerManager`, `TransportFleetManager`,
  `GrainStorageMonitor`, `WarehouseManager`, `InventoryValuationEngine`,
  `WarehouseReceiptManager` (GCX), `PostHarvestLossEngine`,
  `ComplianceDocumentGenerator`, `LastMileColdChainTracker`,
  `ColdChainRouteOptimizer`, `ExcursionAnalyticsEngine`.
- **`@asase/supply-chain`** — `ProcurementEngine`, `OutgrowerSchemeManager`,
  `ContractFarmingService`, `ImportManagementService`, `SupplierRiskRegistry`,
  `DistributionNetworkOptimizer`, `VehicleRoutingEngine`,
  `MarketChannelService`, `ReturnsLogisticsService`, `DeliveryProofService`,
  `CommodityPriceService`, `PriceForecastEngine`, `ImportParityService`,
  `MarginAnalysisService`, `DemandSensingEngine`.
- **`@asase/quality`** — `HaccpPlanManager`, `AuditManagementService`,
  `CcpMonitoringService`, `PrpTracker`, `WaterQualityService`,
  `PesticideResidueService`, `AflatoxinManagementService`, `LimsService`,
  `RecallManagementService`, `EnvironmentalComplianceService`,
  `RegulatoryChangeMonitoringService`, `LabelComplianceService`,
  `OrganicCertificationService`, `ExportCertificationService`,
  `FdaRegistrationService`, `CalibrationService`.
- **`@asase/export`** — commodity analyzer, `ExportMarketScanner`,
  `CommodityGradingEngine`, `ExportVolumeForecaster`, `CompetitorExportTracker`,
  `TradeDocumentGenerator`, `AfCFTAComplianceEngine`, `EURegulationTracker`,
  `CustomsDutyCalculator`, `ExportLicenseManager`, `ExportBuyerCRM`,
  `DynamicPricingEngine`, `ContractNegotiationAssistant`,
  `ExportLogisticsOptimizer`, `QualityCertificationTracker`.
- **`@asase/inputs`** — `FertilizerBlendOptimizer`, `SoilNutrientMapper`,
  `FertilizerCostAnalyzer`, `OrganicFertilizerAdvisor`,
  `FertilizerSubsidyTracker`, `SeedPerformanceDatabase`,
  `SeedMultiplicationTracker`, `AgrochemicalGuidanceEngine`,
  `IntegratedPestManagementAdvisor`, `AgrochemicalSafetyModule`,
  `InputDistributionNetworkManager`, `FarmerCreditFacilitator`,
  `InputBundleOptimizer`, `ImportSubstitutionAnalyzer`, `InputQualityAssurance`.
- **`@asase/market-intel`** — `CommodityPriceTracker`, `FarmgatePriceMonitor`,
  `PriceForecastingEngine`, `PriceTransmissionAnalyzer`,
  `CediExposureCalculator`, `SupplyDemandModeler`, `CompetitorAnalysisEngine`,
  `ConsumerTrendAnalyzer`, `PriceElasticityCalculator`, `SeasonalityProfiler`,
  `AfCFTAOpportunityScanner`, `RegionalTradeFlowMapper`, `MarketEntryAssessor`,
  `TradeIntelligenceDashboard`, `PolicyImpactSimulator`.
- **`@asase/retail`** — `QSRLocationAnalyzer`, `FranchiseManagementSystem`,
  `RestaurantPOSIntegrator`, `StaffSchedulingOptimizer`, `QualityAuditSystem`,
  `MenuEngineeringAnalyzer`, `RecipeCostCalculator`, `MenuLocalizer`,
  `InventoryWasteTracker`, `DynamicMenuPricer`, `DeliveryLogisticsEngine`,
  `DeliveryPlatformIntegrator`, `InstitutionalCateringManager`,
  `CentralKitchenPlanner`, `CustomerLoyaltyEngine`.
- **`@asase/financials`** — `StartupCostEstimator`, `UnitEconomicsModeler`,
  `FarmEconomicsCalculator`, `ProcessingEconomicsAnalyzer`,
  `WorkingCapitalModeler`, `ConsolidatedProjectionEngine`,
  `CapexPlanningModule`, `DebtCapacityAnalyzer`, `TaxOptimizationModeler`,
  `InvestorReturnCalculator`, `SynergyValuationEngine`, `ScenarioPlanner`,
  `BenchmarkingModule`, `FXRiskQuantifier`, `ImpactMetricsCalculator`.
- **`@asase/connectors`** — Brigid (`IrrigationInfrastructureConnector`,
  `ProcessingFacilityDesignBridge`, `ColdChainInfrastructurePlanner`,
  `RuralRoadAssessmentLink`), Cybele (`ClimateAdaptationConnector`,
  `SoilHealthIntegrator`, `WaterResourceLinker`, `BiodiversityImpactAssessor`),
  Freya (`AgriculturalMarketplaceConnector`, `PaymentReconciliationBridge`,
  `SupplyChainFinanceLinker`), Saraswati (`FarmerTrainingContentGenerator`,
  `AgriculturalResearchBridge`), Maat (`FoodSafetyComplianceConnector`,
  `LandTenureIntegrator`), Aje (`AgriculturalLendingConnector`,
  `CommodityHedgingBridge`).
- **`@asase/sota`** — `SatelliteCropMonitor`, `CropAreaEstimator`,
  `DeforestationAlertSystem`, `FloodDroughtEarlyWarning`, `DroneSurveyPlanner`,
  `DroneSprayingController`, `PlantCountAnalyzer`, `CacaoBeanGrader`,
  `CashewKernelClassifier`, `GrainQualityAnalyzer`,
  `BlockchainTraceabilityLedger`, `SmartContractPaymentSystem`,
  `IoTColdChainMonitor`, `ColdChainAnalyticsDashboard`, `MLYieldPredictor`,
  `CropDiseasePredictor`, `RLCropPlanningAgent`, `RLResourceAllocator`.

---

## 18. Applications (`apps/asase/*`)

The five application packages are the consumer-facing surfaces of the domain.
They are implemented as TypeScript libraries (not Next.js or Express apps) —
each exposes module-level service classes and functions that can be composed by
an HTTP server, CLI, or other runtime. All five include Vitest specs.

All five applications are implemented as TypeScript libraries with `src/`
modules and Vitest specs.

| App                  | Path                     | Modules                                                                                                                    |
| -------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `@asase/api`         | `apps/asase/api`         | `api-gateway.ts`, `api-auth.ts`                                                                                            |
| `@asase/dashboard`   | `apps/asase/dashboard`   | `dashboard-shell.ts`, `kpi-view.ts`, `value-chain-viz.ts`, `alert-center.ts`, `reporting-engine.ts`                        |
| `@asase/field`       | `apps/asase/field`       | `field-data-capture.ts`, `farmer-registration.ts`, `mobile-advisory.ts`, `input-distribution.ts`, `harvest-procurement.ts` |
| `@asase/marketplace` | `apps/asase/marketplace` | `b2b-portal.ts`, `farmer-input-store.ts`                                                                                   |
| `@asase/processing`  | `apps/asase/processing`  | `processing-dashboard.ts`, `batch-traceability.ts`, `qc-workstation.ts`                                                    |

- **Dashboard** — `AsaseDashboardShell` (role-based sessions/permissions),
  `ConsolidatedKPIView` + `ASASE_BU_METRICS`, `ValueChainVisualization` (margin
  waterfall, bottleneck ranking, flow maps), `AlertManagementCenter`
  (`ESCALATION_RULES`, priority scoring, escalation), `ReportingEngine`
  (templates, scheduled reports).
- **Field** — `FieldDataCapture` (offline sync queue),
  `FarmerRegistrationModule` (biometric enrolment, household categorisation),
  `MobileAdvisorySystem` (weather/market/agronomic advisories, USSD menu text,
  channel selection), `InputDistributionTracker` (QR verification, stock),
  `HarvestProcurementModule` (weight capture, grading, payment initiation).
- **Marketplace** — B2B portal plus `FarmerInputStore` (catalog, cart, Mobile
  Money order flow: place → pay → dispatch → confirm).
- **Processing** — processing dashboard, batch traceability, QC workstation.
- **API** — `api-gateway.ts` and `api-auth.ts` (gateway + authentication).

---

## 19. Configuration

### Package Configuration

```json
{
  "name": "@asase/core",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "dependencies": { "drizzle-orm": "catalog:", "zod": "catalog:" },
  "devDependencies": { "vitest": "catalog:" }
}
```

### Project Tags

```json
["scope:asase", "layer:domain", "type:lib"]
```

### Environment Variables

```bash
# @asase/migrations connection (DATABASE_URL accepted as fallback)
ASASE_DATABASE_URL=postgresql://...
```

---

## 20. Cross-Domain Integration

Cross-domain integration is implemented entirely in `@asase/connectors` (see
§17). The connector pattern keeps domain boundaries clean: Asase never imports
from another Oshun domain library; instead, each connector owns typed payload
interfaces that translate Asase data into the vocabulary of the receiving
domain. The six domains Asase connects to, and the nature of each bridge:

- **Brigid** — engineering/infrastructure: Asase sends facility and irrigation
  requirements; Brigid returns engineering designs.
- **Cybele** — earth/environmental intelligence: Asase sends land-use and
  location data; Cybele returns climate and soil assessments.
- **Freya** — commerce/trade: Asase sends product listings and payment requests;
  Freya returns transaction records.
- **Saraswati** — knowledge/education: Asase sends agricultural practice data;
  Saraswati returns training content.
- **Maat** — governance/compliance: Asase sends compliance reports and
  land-tenure documents; Maat manages the regulatory lifecycle.
- **Aje** — financial intelligence: Asase sends farmer and commodity data; Aje
  returns lending scorecards and hedging structures.

Each connector is a class plus builder functions and typed payload interfaces.

---

## 21. External Data Sources

The domain references several Ghanaian institutional data sources whose
standards and formats are encoded directly in the codebase — not fetched at
runtime, but compiled into constants and validation rules. The table below
documents which external source backs each constant or validation.

| Source                      | Data referenced in code                                                         |
| --------------------------- | ------------------------------------------------------------------------------- |
| MoFA farm registry          | Farm registration number format and two-letter region codes (`REGION_CODES`)    |
| COCOBOD grading standards   | Cocoa quality thresholds (`COCOA_GRADE_THRESHOLDS`)                             |
| Ghana Standards Authority   | `FOOD_SAFETY_STANDARDS` (`GS …` specifications)                                 |
| Ghana Revenue Authority     | `HS_CODES` for export commodities; import-duty schedules in supply-chain/export |
| Bank of Ghana / forex       | `GHS_EXCHANGE_RATES` reference rates                                            |
| Ghana Meteorological Agency | Season date ranges (`SEASON_RANGES`) and agro-ecological profiles               |
| VSD / WOAH (OIE)            | Livestock disease profiles and WAHIS notification (`@asase/livestock`)          |
| GCX                         | Warehouse-receipt grading and fees (`@asase/cold-chain`)                        |
