Repository Structure
Purpose
This document defines the mono-repo strategy for the Farmer1st platform, optimized for AI-first development and enabling "demo in a box" for sales teams.
Current State
Decision: Single Mono-Repo
All code, infrastructure, and GitOps manifests live in one repository.
github.com/farmer1st/farmer1st
Rationale
| Factor | Why Mono-Repo Wins |
|---|---|
| AI-first development | AI sees entire codebase; can reason about and modify related code atomically across services, apps, and infrastructure |
| Solo + AI team | No team boundaries to isolate; multi-repo overhead provides no benefit |
| Atomic changes | Change API + all consumers + deployment manifests in one commit |
| Demo in a box | Sales clones one repo, runs docker compose up, has full working stack |
| Refactoring | Rename a type → AI updates all references everywhere |
| No version hell | Everything is always compatible; no cross-repo version matrix |
| Simpler onboarding | One repo to clone, one set of tooling to learn |
Trade-offs Accepted
| Trade-off | Mitigation |
|---|---|
| Larger repository | Git is efficient; use sparse checkout if needed |
| Everyone sees everything | CODEOWNERS + branch protection for sensitive paths |
| Deployment history mixed with code | Git filtering, ArgoCD history, conventional commits |
| More complex CI | Path-based triggers, affected detection tooling |
Repository Structure
farmer1st/
│
├── apps/ # Frontend applications
│ ├── farmer-pwa/ # React PWA for farmers
│ │ ├── src/
│ │ ├── public/
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── vite.config.ts
│ │
│ └── stakeholder-portal/ # React portal for stakeholders
│ ├── src/
│ ├── public/
│ ├── Dockerfile
│ ├── package.json
│ └── vite.config.ts
│
├── services/ # Backend services (Python)
│ │
│ ├── user-management/ # User domain
│ │ ├── bff/ # GraphQL BFF
│ │ │ ├── src/
│ │ │ ├── tests/
│ │ │ ├── Dockerfile
│ │ │ └── pyproject.toml
│ │ ├── auth-service/
│ │ │ ├── src/
│ │ │ ├── tests/
│ │ │ ├── Dockerfile
│ │ │ └── pyproject.toml
│ │ ├── profile-service/
│ │ └── preferences-service/
│ │
│ ├── access-management/ # Access/relationships domain
│ │ ├── bff/
│ │ ├── invitation-service/
│ │ ├── fga-service/
│ │ └── entity-service/
│ │
│ ├── surveys/ # Surveys domain
│ │ ├── bff/
│ │ ├── survey-service/
│ │ ├── response-service/
│ │ └── analytics-service/
│ │
│ └── payments/ # Payments domain
│ ├── bff/
│ ├── points-service/
│ ├── payout-service/
│ └── provider-service/
│
├── packages/ # Shared code
│ ├── shared-types/ # Cross-service TypeScript/Python types
│ ├── api-clients/ # Generated API clients
│ ├── ui-components/ # Shared React components
│ └── common-utils/ # Shared utilities
│
├── platform/ # Platform service configurations
│ ├── supertokens/ # Auth server config
│ │ └── config.yaml
│ ├── openfga/ # Authorization model
│ │ ├── model.fga
│ │ └── tuples/
│ ├── temporal/ # Workflow definitions
│ │ └── ...
│ └── unleash/ # Feature flag setup
│ └── ...
│
├── infra/ # Infrastructure & deployment
│ │
│ ├── terraform/ # Cloud infrastructure (IaC)
│ │ ├── modules/ # Reusable TF modules
│ │ │ ├── vpc/
│ │ │ ├── eks/
│ │ │ ├── rds-postgresql/
│ │ │ ├── elasticache-redis/
│ │ │ ├── msk-kafka/
│ │ │ └── cloudflare-tunnel/
│ │ └── environments/ # Per-environment configs
│ │ ├── cloudflare/ # All CF resources
│ │ ├── aws-dev/
│ │ ├── aws-staging/
│ │ └── aws-prod/
│ │
│ ├── k8s/ # GitOps manifests (Kustomize)
│ │ ├── base/ # Base manifests
│ │ │ ├── user-management/
│ │ │ ├── access-management/
│ │ │ ├── surveys/
│ │ │ ├── payments/
│ │ │ └── platform/ # SuperTokens, OpenFGA, etc.
│ │ └── overlays/ # Environment-specific
│ │ ├── local/ # Local k8s (Kind/Minikube)
│ │ ├── dev/ # farmer1st.dev
│ │ ├── staging/ # farmer1st.tech
│ │ └── prod/ # farmer1st.org
│ │
│ └── docker/ # Local dev Dockerfiles
│ ├── postgres/
│ ├── redis/
│ └── kafka/
│
├── tools/ # Developer & sales tooling
│ │
│ ├── seed-data/ # Demo data scenarios
│ │ ├── scenarios/
│ │ │ ├── cocoa-cooperative/ # West Africa cocoa coop demo
│ │ │ │ ├── users.json
│ │ │ │ ├── farms.json
│ │ │ │ ├── cooperatives.json
│ │ │ │ ├── relationships.json # OpenFGA tuples
│ │ │ │ └── surveys.json
│ │ │ ├── coffee-brand/ # Coffee brand (Nestlé) demo
│ │ │ └── small-farm/ # Single farmer demo
│ │ └── seed.py # Seed script
│ │
│ └── scripts/ # Dev utilities
│ ├── setup.sh # First-time setup
│ ├── reset-db.sh # Reset local databases
│ └── generate-clients.sh # Generate API clients
│
├── .github/
│ ├── workflows/
│ │ ├── ci.yml # Lint, test, build
│ │ ├── deploy-dev.yml # Auto-deploy to dev
│ │ ├── deploy-staging.yml # Deploy to staging
│ │ └── deploy-prod.yml # Deploy to prod (manual)
│ ├── CODEOWNERS # Protect sensitive paths
│ └── dependabot.yml
│
├── docker-compose.yml # 🎯 Full stack local dev
├── docker-compose.override.yml # Local overrides (gitignored)
├── docker-compose.demo.yml # Demo-specific config
├── Makefile # Common commands
├── README.md
├── CLAUDE.md # AI assistant instructions
└── .gitignore
Domain to Folder Mapping
| Domain | Folder | K8s Namespace | Purpose |
|---|---|---|---|
| User Management | services/user-management/ |
user-management |
Users, auth, profiles, preferences |
| Access Management | services/access-management/ |
access-management |
Invitations, relationships, OpenFGA |
| Surveys | services/surveys/ |
surveys |
Survey creation, responses, analytics |
| Payments | services/payments/ |
payments |
Points, payouts, payment providers |
GitOps Strategy
Why GitOps Lives in the Mono-Repo
| Benefit | Description |
|---|---|
| AI context | AI sees code + deployment manifests together |
| Atomic changes | Code change + manifest update in one commit |
| No coordination | No "which version of service X goes with which GitOps commit?" |
| Simpler CI | One pipeline updates everything |
ArgoCD Configuration
ArgoCD points to subfolders within the mono-repo:
# Example: ArgoCD Application for surveys in prod
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: surveys-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/farmer1st/farmer1st.git
targetRevision: main
path: infra/k8s/overlays/prod/surveys
destination:
server: https://kubernetes.default.svc
namespace: surveys
syncPolicy:
automated:
prune: true
selfHeal: true
Path Protection
Sensitive paths are protected via CODEOWNERS:
# .github/CODEOWNERS
# Production deployments require platform team approval
/infra/k8s/overlays/prod/ @farmer1st/platform-team
/infra/k8s/overlays/staging/ @farmer1st/platform-team
# Terraform changes require platform team approval
/infra/terraform/ @farmer1st/platform-team
# Platform services require platform team approval
/platform/ @farmer1st/platform-team
Image Naming Convention
All container images go to GitHub Container Registry:
ghcr.io/farmer1st/farmer-pwa:v1.2.3
ghcr.io/farmer1st/stakeholder-portal:v1.2.3
ghcr.io/farmer1st/user-management-bff:v1.2.3
ghcr.io/farmer1st/auth-service:v1.2.3
ghcr.io/farmer1st/profile-service:v1.2.3
ghcr.io/farmer1st/surveys-bff:v1.2.3
ghcr.io/farmer1st/survey-service:v1.2.3
# ... etc
Local Development
See 12-local-development.md for the complete local development and demo strategy.
Quick start:
# Clone once
git clone git@github.com:farmer1st/farmer1st.git
cd farmer1st
# Start everything
make dev
# Or for sales demos
make demo scenario=cocoa-cooperative
CI/CD Flow
See 07-cicd-devops.md for complete CI/CD pipeline documentation.
High-level flow:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PR/Push │────►│ CI Build │────►│ Update k8s │
│ │ │ & Test │ │ overlays │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
┌──────────────┐ │
│ ArgoCD │◄────────────┘
│ Syncs │
└──────────────┘
Migration from Multi-Repo
If migrating from existing multi-repo structure:
- Create new mono-repo with folder structure
- Use
git subtreeor fresh copy to bring in each repo - Preserve meaningful git history where possible
- Update CI/CD pipelines
- Update ArgoCD application sources
- Archive old repositories
Open Questions
- Mono-repo tooling: Nx vs Turborepo vs plain Make?
- Python mono-repo tooling: uv workspaces?
- Shared library versioning within mono-repo?
- Branch strategy (trunk-based vs feature branches)?
Dependencies
- GitHub organization with mono-repo
- GHCR enabled for container images
- ArgoCD configured per EKS cluster
- Terraform Cloud workspaces
Last Updated: 2025-12-30