Ekylibre repose sur PostgreSQL 13 étendu par PostGIS 2.5 pour les données géospatiales. Le schéma compte plus de 300 modèles ActiveRecord organisés en domaines métier : production végétale, animale, comptabilité, ventes, achats, ressources humaines.
| Domaine | Modèles clés | Tables racines |
|---|---|---|
| Production végétale |
Activity, LandParcel, Intervention, Plant, Cultivation
|
activities, land_parcels, interventions
|
| Production animale |
AnimalGroup, Animal, IntegrationTask
|
animal_groups, animals
|
| Comptabilité |
Account, JournalEntry, FiscalYear
|
accounts, journal_entries, fiscal_years
|
| Ventes / Achats |
Sale, Purchase, Invoice, Payment
|
sales, purchases, parcels (livraisons) |
| Stock |
Inventory, Product, ProductMovement
|
inventories, products, product_movements
|
| Tiers |
Entity, EntityAddress
|
entities |
| Référentiels | Lexicon::* |
schémas lexicon (variétés, intrants, équipements) |
Le lexicon est une base nomenclaturale agricole partagée (variétés, intrants, équipements, taxonomies). Il contient plus de 20 millions d'items servant de référence pour tous les tenants.
bin/rake lexicon:load (voir Setup app §6).lexicon-version (rechargement automatique en prod si la version change)lexicon (partagé entre tenants)Chaque ferme est un tenant isolé via la gem apartment :
acme, closeriedesterres, demo)public contient les tables système et le lexicon
acme.example.com → Apartment::Tenant.switch!('acme')
Lister les tenants :
bundle exec rails runner "puts Apartment::Tenant.list"
Créer un tenant :
# Native
bin/rake tenant:init TENANT=my-farm
# Docker prod
./docker/prod/scripts/tenant-init.sh my-farm admin@my-farm.com 'MotDePasse!'
Les entités géolocalisées (parcelles, observations, points GPS) utilisent les types PostGIS :
geometry(MultiPolygon, 4326) pour les surfaces (parcelles, zones d'observation)geometry(Point, 4326) pour les points (traces GPS, observations ponctuelles)Requêtes spatiales typiques :
-- Interventions sur une parcelle donnée
SELECT i.* FROM interventions i
JOIN land_parcels p ON ST_Intersects(i.geometry, p.shape)
WHERE p.id = 42;
-- Surface totale en hectares d'une activité
SELECT SUM(ST_Area(shape::geography) / 10000)
FROM land_parcels WHERE activity_id = 7;
Cette page est un point d'entrée. Pour le détail du schéma complet, les diagrammes ERD et les invariants métier :
docs/development/db.md dans le repo Ekylibre (en cours d'enrichissement)docs/development/algo/interventions.md
docs/guides/helpers.md, docs/guides/components.md
docs/api/openapi-v2.yaml
bundle exec rails c
# Bascule sur un tenant
Apartment::Tenant.switch!('demo')
# Compter les modèles
Plant.count
Intervention.where('started_at > ?', 1.month.ago).count
# Inspecter le lexicon
Lexicon::Variety.count
Lexicon::ProductionNature.where(name: 'wheat').first
# Dev native
psql -U ekylibre eky_development
# Dev Docker
psql -h localhost -p 5431 -U ekylibre eky_development
# Prod Docker
docker compose -f docker/prod/docker-compose.yml exec db \
psql -U ekylibre eky_production
Puis dans psql :
-- Lister les tenants
\dn
-- Bascule sur un tenant
SET search_path TO acme, public;
-- Tables du tenant
\dt
Pour les changements de schéma à venir, voir docs/planning/v6-brainstorm.md dans le repo Ekylibre.
Cette documentation est open-source. Aidez-nous à l'améliorer en ouvrant une issue ou une pull request.