PAWRISE CARE
🗺️

La carte interactive est sur desktop

Le cockpit d'architecture (briques, flux et parcours, à explorer en zoomant et en cliquant) est pensé pour les grands écrans. Les choix techniques justifiés ci-dessous, eux, se lisent partout.

Pawrise CareCockpit d'architecture
Flux Synchrone · aller-retour Événement · sens unique Contrôle Externe
Glissez pour déplacer · molette = zoom · cliquez un Epic/US pour rejouer son parcours
Parcours·
Choix techniques justifiés ↓

Choix techniques justifiés

L'architecture repose sur quelques décisions structurantes, chacune benchmarkée. On présente ici le besoin, les alternatives écartées, la décision et son trade-off : aucun choix n'est gratuit, chacun est assumé.

Rust pour les services métier

Besoin

Des services backend fiables et performants (ingestion temps réel, API, auth) sur une infra peu coûteuse.

Alternatives écartées

Node.js/NestJS, Python/FastAPI, Go/Gin, C#/ASP.NET, Rust/Axum (benchmark backend complet).

Décision

Rust (Axum) pour les services métier ; Python réservé au Care Engine (IA).

Trade-off assumé

Assumé : le benchmark montre un coût de développement environ 2,5× supérieur et seulement deux développeurs Rust dans l'équipe. On le choisit pour la performance, la sûreté mémoire (une classe entière de bugs disparaît), une empreinte serveur minimale et la montée en compétence. Garde-fous : périmètre Rust ciblé sur les services critiques, Python assumé pour l'IA, workspace Cargo partagé, et réintroduction ciblée d'un autre langage si un service devient un point chaud.

Découpage en services

Besoin

Faire évoluer et monter en charge chaque partie du système séparément, sans créer une constellation ingérable.

Alternatives écartées

Monolithe unique, microservices fins.

Décision

Un ensemble restreint de services dont les frontières suivent quatre critères : domaine métier (bounded context), runtime (Rust / Python), profil de charge et frontière de sécurité. Concrètement : OIDC isolé (sécurité), Core API (cœur transactionnel), Ingestion (flux MQTT haute fréquence), Téléconsult/Pool (avec état, WebSocket), Care Engine (runtime Python, cloisonné).

Trade-off assumé

Montée en charge et durcissement ciblés par service ; surcoût d'exploitation absorbé par Kubernetes, le GitOps et l'observabilité. On ne fragmente pas au-delà : un nouveau service ne naît que lorsqu'un des quatre critères le justifie, jamais par principe.

MQTT (EMQX) pour l'entrée IoT

Besoin

Recevoir la télémétrie de colliers sur batterie et réseau cellulaire instable.

Alternatives écartées

HTTP/REST, CoAP, passerelle maison.

Décision

Broker MQTT (EMQX) en point d'entrée, TLS et certificat par collier (step-ca).

Trade-off assumé

MQTT est le standard IoT : pub/sub léger, QoS, sessions persistantes, reconnexion et mode hors-ligne gratuits. Coût : un composant de plus à opérer dans le cluster.

Apache Kafka comme bus d'événements

Besoin

Découpler les services et ne perdre aucun événement (ingestion, projections, file de téléconsultation, audit).

Alternatives écartées

RabbitMQ, appels synchrones directs entre services.

Décision

Apache Kafka comme épine dorsale événementielle.

Trade-off assumé

Kafka offre haut débit, rétention des messages et un large écosystème de connecteurs. Coût : plus gourmand en RAM que RabbitMQ, ce qui dimensionne le cluster. Choix assumé pour la robustesse et l'évolutivité.

PostgreSQL + TimescaleDB + pgvector

Besoin

Stocker le métier transactionnel, les séries temporelles de télémétrie et les embeddings du corpus vétérinaire.

Alternatives écartées

MongoDB + InfluxDB + Qdrant, soit trois moteurs séparés.

Décision

Une seule famille PostgreSQL : TimescaleDB (séries temporelles) et pgvector (vectoriel) en extensions.

Trade-off assumé

Un seul moteur à opérer et sauvegarder, SQL vérifié à la compilation, open-source sans licence. Bascule possible vers Qdrant si la charge vectorielle l'exige (interface RAG abstraite).

Pipeline LangGraph déterministe (pas d'agent autonome)

Besoin

Un assistant IA dont chaque étape est testable et juridiquement défendable (non-diagnostic).

Alternatives écartées

Agent LLM autonome en boucle libre.

Décision

Pipeline LangGraph borné à 6 nœuds ; le LLM est cantonné dans une cage (ADR-001).

Trade-off assumé

Moins de flexibilité qu'un agent libre, mais la responsabilité juridique est portée par le pipeline. Un agent libre serait indéfendable face au Code rural. Détail sur la page Assistant IA.

Azure OpenAI EU + cascade + Cohere

Besoin

Un LLM de qualité en français, conforme RGPD, à coût maîtrisé.

Alternatives écartées

LLM hébergé hors UE, modèle unique pour tout le pipeline.

Décision

Azure OpenAI déployé en UE, cascade (un modèle par nœud) et reranker Cohere (ADR-002 / ADR-003).

Trade-off assumé

Data residency UE et coût d'environ 0,03 à 0,05 € par conversation. Dépendance à Microsoft, mitigée par une interface LLMProvider (bascule Mistral ou self-host). Budget détaillé sur la page Assistant IA.

Kubernetes auto-géré + GitOps

Besoin

Faire tourner les services et toutes leurs dépendances (bases, Kafka, broker MQTT, observabilité), scaler et déployer de façon reproductible, à coût maîtrisé et souverain.

Alternatives écartées

PaaS, Kubernetes managé d'emblée, simple docker-compose.

Décision

Cluster Kubernetes auto-géré (Terraform) sur Hetzner, déploiement GitOps via Argo CD.

Trade-off assumé

Le plus économique et souverain, mais le plus exigeant en opérations (sauvegarde etcd, mises à jour). Mitigé par l'Infrastructure as Code et un passage au managé EU au scale. Détail sur la page Cloud.

OIDC maison

Besoin

Identité, connexion et droits owner / vétérinaire, avec consentement RGPD.

Alternatives écartées

Auth0, Keycloak, Cognito.

Décision

Serveur OIDC maison (Rust).

Trade-off assumé

Choix de souveraineté et défi technique formateur, mais coûteux (environ 4 à 6 mois-homme) et sensible côté sécurité. Garde-fous : revue de sécurité et tests d'abus obligatoires avant la mise en production.