# Och'Idoma Agri Grid
A PHP 8.2 (no framework, custom MVC, PDO) foundation for a Benue State
agri-tech platform.
## Honest scope note
The original brief describes 14 major subsystems — IoT storage monitoring,
a buyer marketplace with AI matching, a cooperative digital bank, harvest
prediction, a barn-rental marketplace, transport pooling, live auctions,
a full USSD gateway, multilingual (Idoma/Tiv/Igede) voice AI, market-price
forecasting, reputation scoring, image-based disease detection, offline-first
sync, and an admin analytics suite. That is a multi-team, multi-month build,
not something any codebase — generated in one sitting or not — can honestly
call "complete and production-ready."
## Architecture for plugging in external services
Every external dependency — SMS, WhatsApp, Voice/TTS, and AI (OpenRouter or
any OpenAI-compatible endpoint) — is wired through a **service layer with
swappable adapters**, so activating a real provider is a one-line config
change with zero application-code changes:
- `config/integrations.php` (and `.env.example`) is the single place you
set driver names and API keys.
- `app/services/NotificationService.php` is the one entry point the whole
app calls for SMS/WhatsApp/voice alerts. It picks the right adapter
(`app/services/adapters/*Notifier.php` — Stub, AfricasTalking, Termii,
WhatsAppCloud) based on config, and logs every attempt to
`notification_log` regardless of driver.
- `app/services/AIService.php` is the one entry point for harvest
prediction, price forecasting, and disease diagnosis. Set
`AI_DRIVER=openrouter` + `OPENROUTER_API_KEY` and it calls real models
immediately (model per-task is configurable — vision model for photos,
text model for forecasts). Responses are cached in `ai_prediction_cache`.
- `app/services/TtsService.php` posts to `TTS_ENDPOINT` — point this at
your own trained Idoma/Tiv/Igede model server once you have one; the
contract (`{text, language} -> {audio_url}`) is documented in the file.
- `app/co …