Almafrica System Architecture — n8n Workflow Documentation
Recommended Reading Paths
Use the n8n workflow docs as a guided map instead of reading them all in one pass.
| If you are trying to... | Start with | Then continue to |
|---|---|---|
| Understand the whole platform quickly | Cross-Domain Flow Map | Quick Index |
| Understand authentication, sync, and platform behavior | 01 — Auth & Authorization | 02 — Data Sync Engine, 09 — Notifications & Communication, 10 — Integration Architecture |
| Follow field operations end to end | 03 — Farmer Management | 05 — Production Cycle, 08 — Quality Assessment, 06 — Warehouse & Stock |
| Understand buyer and commercial workflows | 04 — Client & Order Lifecycle | 06 — Warehouse & Stock, 09 — Notifications & Communication |
| Understand campaigns and data collection | 07 — Campaigns & Surveys | 02 — Data Sync Engine, 10 — Integration Architecture |
| Translate n8n concepts back into real code | n8n Node Type → Almafrica Component Mapping | Appendix A, Appendix B |
How to Read This Documentation
This documentation describes the Almafrica platform's architecture using n8n workflow concepts. Each business process is represented as a workflow with:
- Trigger nodes — what starts the process (user action, timer, event)
- Function nodes — business logic steps (services, validations)
- Decision nodes — conditional branching (IF/Switch)
- Data nodes — database reads/writes, API calls
- Output nodes — final results, notifications, state changes
Every workflow has an ID like WF-AUTH-01 for cross-referencing between sections.
Diagram Conventions
[Square brackets] = Action/Function nodes
{Curly braces} = Decision/IF nodes
((Double parens)) = Trigger nodes
[[Double square]] = Database nodes
>Asymmetric] = Output/Result nodes
Solid arrows (-->) indicate normal flow. Dotted arrows (-.->) indicate error/fallback paths.
Domain Groups
To keep the documentation easier to scan, the workflow set is organized into four groups:
- Start here: overview, system context, and workflow conventions
- Platform flows: authentication, sync, notifications, and integrations
- Operational domains: farmer, client/order, production, warehouse, and quality workflows
- Reference: node mappings and entity relationships
If you are onboarding a new teammate, the best order is: overview -> auth -> sync -> the operational domain they work on most.
System Context Diagram
graph TB
subgraph Actors
AGENT[Field Agent]
ADMIN[Administrator]
FARMER[Farmer/Client]
WH_OP[Warehouse Operator]
DATA_AGENT[Data Agent]
end
subgraph "Mobile App (Flutter)"
MOBILE[Mon Jardin App]
SQLITE[(SQLite v88)]
SYNC[Sync Engine]
end
subgraph "Backend API (.NET)"
API[ASP.NET Core API]
SIGNALR[SignalR Hub]
end
subgraph "Data Stores"
PG[(PostgreSQL)]
REDIS[(Redis Cache)]
end
subgraph "External Services"
DO[DigitalOcean Spaces]
FCM[Firebase Cloud Messaging]
AT[Africa's Talking SMS]
end
subgraph "Web Dashboard (Next.js)"
WEB[Admin Dashboard]
end
AGENT --> MOBILE
FARMER --> MOBILE
WH_OP --> MOBILE
DATA_AGENT --> MOBILE
ADMIN --> WEB
MOBILE --> SQLITE
MOBILE --> SYNC
SYNC -->|HTTP/REST| API
SYNC -->|WebSocket| SIGNALR
WEB -->|HTTP/REST| API
API --> PG
API --> REDIS
API --> DO
API --> FCM
API --> AT
SIGNALR -->|Permission broadcasts| MOBILE
Cross-Domain Flow Map
graph LR
subgraph AUTH["1. Auth & Authorization"]
LOGIN[Login]
PERMS[Permissions]
ROLES[Multi-Role Hub]
end
subgraph SYNC["2. Data Sync Engine"]
FULL[Full Sync]
INIT[Initial Sync]
SUBMIT[Submit Priority]
QUEUE[Offline Queue]
end
subgraph FARM["3. Farmer Management"]
REG[Registration]
VISIT[Visits]
CROPS[Crop Association]
end
subgraph CLIENT["4. Client & Orders"]
ONBOARD[Onboarding]
DEMAND[Crop Demands]
ORDER[Orders]
end
subgraph PROD["5. Production"]
CYCLE[Cycles]
HARVEST[Harvest]
end
subgraph STOCK["6. Warehouse"]
INTAKE[Stock Intake]
TRANSFER[Transfers]
LOSS[Loss Mgmt]
end
subgraph CAMP["7. Campaigns"]
SURVEY[Surveys]
RESPONSE[Responses]
end
subgraph QA["8. Quality"]
ASSESS[Assessments]
end
subgraph NOTIF["9. Notifications"]
PUSH[Push/SMS]
REALTIME[SignalR]
end
subgraph INTEG["10. Integrations"]
S3[DO Spaces]
SMS[Africa's Talking]
end
LOGIN --> PERMS --> ROLES
ROLES --> FARM & CLIENT & STOCK & CAMP
FARM --> SYNC
CLIENT --> SYNC
PROD --> SYNC
STOCK --> SYNC
CAMP --> SYNC
QA --> SYNC
HARVEST --> INTAKE
DEMAND --> ORDER --> STOCK
ASSESS --> INTAKE
PERMS --> REALTIME
ORDER --> PUSH
FARM --> S3
CAMP --> S3
LOGIN --> SMS
Mobile Offline Architecture
graph TB
subgraph "Presentation Layer"
UI[Screens & Providers]
end
subgraph "Data Layer"
REPO[Repositories]
REMOTE[Remote Datasources]
LOCAL[Local Datasources]
end
subgraph "Sync Layer"
SM[SyncManager]
SC[SyncCoordinator]
STRAT{Strategy Selector}
FULL_S[FullSyncStrategy]
INIT_S[InitialSyncStrategy]
SUB_S[SubmitPriorityStrategy]
OQP[OfflineQueueProcessor]
RETRY[RetryExecutorService]
end
subgraph "Storage"
SQLITE[(SQLite - 80+ tables)]
PREFS[(SharedPreferences)]
end
subgraph "Network"
CONN[ConnectivityService]
DIO[Dio HTTP Client]
SIG[SignalR Client]
end
UI --> REPO
REPO --> REMOTE & LOCAL
REMOTE --> DIO
LOCAL --> SQLITE
SM --> STRAT
STRAT --> FULL_S & INIT_S & SUB_S
FULL_S --> SC
SUB_S --> SC
SC --> REMOTE & LOCAL
OQP -->|10s interval| SQLITE
OQP --> DIO
RETRY -->|30s-5h backoff| OQP
CONN -->|connectivity change| SM
SIG -->|permission update| LOCAL
n8n Node Type → Almafrica Component Mapping
| n8n Node Type | Almafrica Component | Example |
|---|---|---|
| Webhook Trigger | API Controller endpoint | AuthController.Login → POST /api/auth/login |
| Schedule Trigger | Timer-based service | OfflineQueueProcessor (10s interval), Auto-pull heartbeat |
| Manual Trigger | User-initiated action | Tap "Sync Now", Submit form |
| HTTP Request | Mobile Dio HTTP call | FarmerRemoteDataSource.createFarmer() |
| Function | Application Service method | AuthService.LoginAsync(), FarmerService.CreateFarmerAsync() |
| IF | Conditional check | ConnectivityService.isConnected, user.requiresTwoFactor |
| Switch | Multi-branch routing | SyncRunMode.toStrategy(), ActiveRoleManager.dashboardFor(roles) |
| Set | DTO/Model transformation | Farmer.toJson(), FarmerDto.FromEntity() |
| Merge | Parallel join | SyncCoordinator merging farmer + client + demand results |
| Wait | Delay/backoff | ExponentialBackoffService.calculateDelay() (30s→5h) |
| Loop | Iterative processing | Master data sync (26 entity types), batch queue processing (5 items) |
| Error Trigger | Exception handler | GlobalExceptionHandler, Result pattern failure path |
| Database (Read) | SQLite SELECT / EF Core query | DatabaseHelper.query(), _context.Farmers.Where() |
| Database (Write) | SQLite INSERT/UPDATE / EF Core save | DatabaseHelper.insert(), _context.SaveChangesAsync() |
| S3 Upload | DigitalOcean Spaces | DigitalOceanSpacesService.UploadAsync() |
| S3 (Chunked) | Chunked upload service | ChunkedUploadService.uploadFile() |
| SignalR | Real-time hub | PermissionHub.SendPermissionsUpdated() |
| SMS Send | Africa's Talking | OtpService.SendOtpAsync() |
| Push Notification | FCM (stub) | PushNotificationService (no-op placeholder) |
| NoOp | Skip/passthrough | Strategy paths that skip certain sync phases |
| Code | Complex inline logic | Conflict resolution field diff, permission matrix evaluation |
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Backend API | ASP.NET Core (.NET 8) | REST API, business logic, auth |
| Backend DB | PostgreSQL | Primary relational store |
| Cache | Redis | Performance caching, session data |
| File Storage | DigitalOcean Spaces (S3) | Images, documents, attachments |
| Real-time | SignalR | Permission broadcast WebSocket |
| SMS/OTP | Africa's Talking | 2FA, notifications |
| Push | Firebase Cloud Messaging | Mobile push (stub) |
| Mobile | Flutter (Dart) | Offline-first field app |
| Mobile DB | SQLite (sqflite) | Local storage, 80+ tables |
| Mobile State | Provider | State management |
| Web | Next.js (React/TypeScript) | Admin dashboard |
| Deployment | Docker + Coolify | Container orchestration |
Quick Index
| I want to understand... | Go to |
|---|---|
| Platform login, permissions, and role routing | 01 — Auth & Authorization |
| Offline-first synchronization and retries | 02 — Data Sync Engine |
| Farmer capture, draft handling, and approvals | 03 — Farmer Management |
| Client onboarding, demand capture, and orders | 04 — Client & Order Lifecycle |
| Production tracking from planting to harvest | 05 — Production Cycle |
| Warehouse intake, transfer, loss, and stock history | 06 — Warehouse & Stock |
| Campaign publishing, surveys, and response collection | 07 — Campaigns & Surveys |
| Quality checks and stock-in assessment flows | 08 — Quality Assessment |
| OTP, push notifications, and SignalR communication | 09 — Notifications & Communication |
| External providers, storage, and operational integrations | 10 — Integration Architecture |
| How n8n node types map back to code | Appendix A |
| Cross-system entities and schema relationships | Appendix B |
Workflow ID Reference
| Prefix | Domain | Count |
|---|---|---|
| WF-AUTH | Authentication & Authorization | 7 |
| WF-SYNC | Data Sync Engine | 17 |
| WF-FARM | Farmer Management | 6 |
| WF-CLI | Client & Order Lifecycle | 6 |
| WF-PROD | Production Cycle | 5 |
| WF-STOCK | Warehouse & Stock | 7 |
| WF-CAMP | Campaigns & Surveys | 5 |
| WF-QA | Quality Assessment | 4 |
| WF-NOTIF | Notifications & Communication | 4 |
| Total | 61 workflows |