The
apps/asase/area: five Nx "application" projects that implement the in-process domain logic for Asase, a Ghana-focused agricultural value-chain platform spanning field operations, processing, marketplace, executive dashboards, and an external data API.
What this area is#
Asase is the agri-value-chain product (the task IDs throughout the source —
56.15.x — place it as section 56.15 of the wider Oshun catalog). Its eight
commodity streams recur as a shared vocabulary across every project: cocoa,
maize, tilapia, chicken (poultry), rice, palm oil, cashew, and shea (see the
CommodityFlow union in apps/asase/dashboard/src/value-chain-viz.ts and
CommodityType in apps/asase/processing/src/processing-dashboard.ts). The
domain logic is deliberately Ghana-specific: regions enumerated in
apps/asase/api/src/api-gateway.ts (GHANA_REGIONS), prices in Ghana cedis
(...GhsPerTonne, ...GhsPerKg), mobile-money networks
(MTN_MoMo/Vodafone_Cash/AirtelTigo_Money), grain grading against Ghana
Grains Development Board thresholds, and field advisories localized into Twi,
Dagbani, and Ewe.
Despite each project.json carrying "projectType": "application" and the
type:app tag, these are not standalone deployable servers. Every package's
package.json sets "main": "./src/index.ts" and each src/index.ts is a pure
barrel of re-exports — there is no HTTP bootstrap, no main() that binds a
port, and no database client. They are in-process TypeScript domain-logic
packages: collections of strongly-typed, mostly-pure functions plus a few
stateful classes (e.g. AsaseAPIGateway, FieldDataCapture, ReportingEngine)
that hold their state in memory and expose a default* singleton. State lives
in Map/array fields, not in Postgres. This mirrors the "in-process and
Map-backed today" posture documented for the Freya domain.
The five projects partition the value chain end-to-end. @asase/field is the
upstream, offline-first mobile tier where farmers are registered and harvests
procured. asase-processing-app is the factory tier (production lines, batch
genealogy, lab QC). @asase/marketplace is the commercial tier (institutional
B2B sales downstream, input procurement back upstream to farmers).
@asase/dashboard is the management tier that aggregates KPIs and visualizes
the whole farm-gate-to-export chain. @asase/api is the external integration
tier that exposes commodity/weather/analytics data to third parties behind OAuth
and API-key auth.
These are substantial implementations, not scaffolds: each project is roughly
2,500–3,700 lines of source with 100–135 colocated Vitest cases (*.spec.ts).
The honest caveat is persistence and external integration — state is in-memory,
and the API's data endpoints are served by deterministic mock generators
(mockCommodityPrice, mockWeatherData, mockFarmAnalytics) backed by static
lookup tables rather than a live datastore.
How it fits the wider system#
The projects relate to each other by the value chain rather than by code
imports: each is self-contained and depends only on its own modules (cross-file
imports like harvest-procurement.ts reusing GPSCoordinate/SyncStatus from
field-data-capture.ts stay within a project). They share concepts — quality
grades (Grade_A…Reject), the commodity set, GHS pricing, mobile money — not
a shared runtime library, so today the integration between tiers is by
convention. Downstream consumers import a package's src/index.ts barrel: the
dashboard's value-chain and KPI views model the same node types the field and
processing tiers produce, and the marketplace's B2B grades line up with the
processing tier's QC output. The @asase/api tier is the documented external
boundary — its AccessTier (public/internal/partner/premium) and
UsageTier gates are what a partner integration would authenticate against.
Entity catalog (5)#
The 5 tracked Nx projects in asase, each a code-linked entity node — package, type, source path, declared targets, and its internal dependency graph (depends-on / used-by, resolved from the package manifests, §6/§8), read from the project graph. Grouped by architectural layer; walk the dependency links to travel the system. 5 of these carry an authored deep-dive (what / why / how it fits); the rest are generated scaffolds awaiting one.
unclassified (5)#
The external data API tier (apps/asase/api/src), exporting two modules
from index.ts: api-gateway.ts and api-auth.ts. The gateway
(AsaseAPIGateway) owns an in-memory APIEndpoint registry across seven data
domains (commodity_prices, weather, farm_analytics, supply_chain,
compliance, market_intelligence, financial), request routing
(processRequest, findEndpoint), envelope builders
(buildSuccessResponse/buildErrorResponse), and even a generated GraphQL SDL
string (buildGraphQLSchema). The auth layer (APIAuthenticationLayer)
implements OAuth-style client/token issuance, API-key generation and validation,
per-minute rate limiting (checkRateLimit/isRateLimited), tier-based scopes,
and usage analytics. Honest caveats: the data endpoints return values from
deterministic mock* generators over static tables (e.g. COMMODITY_DATA), not
a live source; and hashAPIKey is a custom deterministic positional-sum hash
(despite an APIKey.keyHash comment describing it as "SHA-256"), with key
material generated via randomHex — appropriate for in-memory demonstration,
not production secret storage.
The management/executive dashboard tier (apps/asase/dashboard/src), the
largest project here (~3,700 lines), composed of five modules surfaced through
index.ts. dashboard-shell.ts models roles, sessions, and per-module
visibility/permissions; kpi-view.ts consolidates business-unit metrics
(ASASE_BU_METRICS across farming/processing/distribution/services)
with weighted utilization and top/under-performer ranking; value-chain-viz.ts
builds margin waterfalls, commodity flow maps, and bottleneck rankings across
the seven ChainNode stages from farm_gate to retail; alert-center.ts
implements priority scoring (computePriorityScore), ESCALATION_RULES, and
the acknowledge/resolve/escalate lifecycle; and reporting-engine.ts provides
report templates, scheduling (getNextRunDate), and export-format/file-size
estimation. These are real domain computations over in-memory inputs, covered by
~120 spec cases.
buildDashboardPermissions11createDashboardSession11getRefreshIntervalSeconds11getVisibleModules11isModuleVisible11AsaseDashboardShell11defaultDashboardShell11aggregateKPIs23getTopPerformingBU23getUnderperformingBUs23computeWeightedUtilization23ConsolidatedKPIView23ASASE_BU_METRICS23defaultKPIView23 +29 moreThe upstream, offline-first mobile field application tier
(apps/asase/field/src), five modules behind index.ts.
field-data-capture.ts is offline-first: visit records, soil samples, crop
scouting, and an OfflineSyncQueue with pending/synced/conflict/failed
states and sync size estimation. farmer-registration.ts handles biometric
enrollment, plot geometry (GPS polygons, areaHa), and household classification
(classifyHousehold into subsistence→large-farmer bands). mobile-advisory.ts
builds weather/market/agronomic/pest advisories, selects a delivery channel
across in_app/sms/ussd/voice_ivr/whatsapp, generates USSD menu text,
and localizes English into Twi/Dagbani/Ewe via phrase-table regex substitution
(localizeText, honestly an approximate phrase-substitution scheme, not full
machine translation). input-distribution.ts tracks input inventory, QR
verification, and stock deduction; harvest-procurement.ts grades lots against
Ghana Grains Development Board moisture/foreign-matter/broken thresholds
(gradeByParameters) and computes net weight and mobile-money payments. ~135
spec cases.
computeVisitDurationMinutes5createVisitRecord5addSoilSample5addCropScouting5markSynced5stimateSyncSizeKb5getPendingVisits5getVisitsByFarm5buildSyncQueue5identifyActionRequired5FieldDataCapture5defaultFieldCapture5classifyHousehold34computeTotalFarmHa34 +48 moreThe commercial digital marketplace tier (apps/asase/marketplace/src), two
modules. b2b-portal.ts (task 56.15.4.1) connects processed Asase products to
institutional buyers — BuyerType spans exporters, processors, retailers, food
manufacturers, and NGOs — with ProductListings carrying spot and
30/90-day/annual-offtake contract pricing, Incoterms-style delivery options
(ex_works/fob_tema/cif_destination/door_delivery), and an order
lifecycle through to delivered. farmer-input-store.ts (task 56.15.4.2) is
the upstream-facing store where smallholders browse and order seeds,
fertilizers, and equipment, supporting MoFAD subsidy pricing, mobile-money
payment recording, cart/subtotal/delivery-fee computation, and a
cart→placed→delivered order flow. Because some symbol names overlap between the
two modules, index.ts re-exports the input-store surface under disambiguated
aliases (e.g. getInputProductCatalog, placeInputOrder). ~107 spec cases.
getInputProductCatalog22getProduct22filterByCrop22filterByCategory22getInStockProducts22buildCartItem22computeSubtotal22computeDeliveryFee22laceInputOrder22recordPayment22dispatchOrder22confirmDelivery22getOrdersByFarmer22computeStoreSummary22 +2 moreThe factory processing-plant interface tier (apps/asase/processing/src);
note this is the one project whose project.json name
(asase-processing-app) differs from its package name (@asase/processing).
Three modules: processing-dashboard.ts (56.15.3.1) models production lines,
equipment status (running/idle/maintenance/breakdown/startup), and
shift codes; batch-traceability.ts (56.15.3.2) is the most algorithmically
interesting — full lot genealogy with raw-material intake (aflatoxin ppb,
pesticide flags), stage records with yield/waste accounting, and a recall path
that walks the batch graph (getBatchLineage does BFS upward for ancestors and
downward for descendants, getAffectedBatches/buildRecallScope compute recall
blast radius); and qc-workstation.ts (56.15.3.3) implements lab QC against
QCSpecification parameters with test methods
(AOAC/ISO/AOCS/ASTM/FDA/GSA_GH), hold/release/reject/rework
decisions, and certificate-of-analysis generation. ~110 spec cases. State is
in-memory; there is no persistence layer.