Frontend
React Native - Application mobile cross-platform (iOS & Android)
Notre architecture est composée de trois couches principales :
architecture-beta
group architecture(cloud)[Architecture]
service client(internet)[Frontend] in architecture
service api(server)[API] in architecture
service ia(server)[IA] in architecture
service db(database)[Donnees] in architecture
client:R -- L:api
api:R -- L:db
api:B -- T:ia Frontend
React Native - Application mobile cross-platform (iOS & Android)
Backend API
Laravel - API RESTful robuste et scalable
Service IA
LangGraph + Mistral AI - Traitement multimodal et génération de cartes
Données
PostgreSQL + S3 - Stockage relationnel et objets
Notre infrastructure est déployée sur des services cloud européens pour garantir la conformité RGPD :
flowchart LR
subgraph Client["Client"]
RN["React Native"]
end
subgraph DNS["DNS"]
API_DNS["api.mindlet.app"]
WS_DNS["ws.mindlet.app"]
end
subgraph Ingress["Nginx Ingress Controller"]
LB["Load Balancer"]
RT["Router"]
end
subgraph API["API Deployment"]
OCT["Laravel Octane"]
POD_API1["POD"]
POD_API2["POD"]
POD_API3["POD"]
end
subgraph WS["WS Deployment"]
REV["Laravel Reverb"]
POD_WS["POD"]
end
subgraph REDIS["Redis Service"]
REDIS_APP["Redis"]
POD_REDIS["POD"]
end
subgraph WORKERS["Worker supervisors"]
HZ["Laravel Horizon"]
POD_W1["POD"]
POD_W2["POD"]
POD_W3["POD"]
end
subgraph K8S["OVH Cloud Kubernetes Cluster"]
Ingress
API_SVC(("api-service"))
WS_SVC(("ws-service"))
API
WS
REDIS
WORKERS
end
subgraph Neon["Neon"]
PG[("PostgreSQL")]
end
subgraph Qdrant["Qdrant Cloud"]
VDB[("Vector DB")]
end
subgraph LangGraph["LangGraph Cloud"]
CARD["Card generation"]
EMB["Embeddings"]
end
RN --> API_DNS & WS_DNS
LB --> RT
API_DNS --> LB
WS_DNS --> LB
RT --> API_SVC & WS_SVC
OCT --> POD_API1 & POD_API2 & POD_API3
REV --> POD_WS
REDIS_APP --> POD_REDIS
HZ --> POD_W1 & POD_W2 & POD_W3
API_SVC --> API
WS_SVC --> WS
API <--> REDIS
WS <--> REDIS
WORKERS <--> REDIS
API --> PG & VDB & CARD & EMB | Composant | Service | Fournisseur |
|---|---|---|
| Orchestration | Kubernetes | OVHcloud |
| Load Balancer | Cloud Load Balancer | OVHcloud |
| Base de données | PostgreSQL Managed | Neon |
| Base vectorielle | Qdrant Managed | Qdrant Cloud |
| Stockage objets | VPS | Hetzner |
La couche prĂ©sentation est responsable de lâinterface utilisateur :
Cette couche ne contient aucune logique métier et se contente de :
La couche métier implémente toute la logique applicative :
API Laravel :
Service IA :
La couche données gÚre la persistance :
| Type | Technologie | Usage |
|---|---|---|
| Relationnel | PostgreSQL | Données structurées (users, collections, cards) |
| Vectoriel | Qdrant | Embeddings pour la recherche sémantique |
| Objets | MinIO | Fichiers (images, PDFs, médias) |
| Cache | Redis | Sessions, workers, cache applicatif |
flowchart LR
subgraph Frontend
MOB[React Native]
end
subgraph Backend
API[Laravel]
end
subgraph Service IA
IA[LangGraph]
end
MOB <-->|REST API JSON| API
API <-->|REST API JSON| IA Caractéristiques :
Notre architecture est conçue pour supporter une montée en charge :
| Utilisateurs | Instances API | Instances IA | DB Connections |
|---|---|---|---|
| 100 | 1 | 2 | 10 |
| 5 000 | 2 | 4 | 50 |
| 50 000+ | 4+ | 8+ | 200+ |
La base de donnĂ©es de Mindlet suit une modĂ©lisation rigoureuse qui distingue le niveau conceptuel (abstrait, indĂ©pendant de lâimplĂ©mentation) du niveau physique (concret, spĂ©cifique Ă PostgreSQL).
Le MCD reprĂ©sente les entitĂ©s mĂ©tier et leurs associations de maniĂšre abstraite, sans se soucier des dĂ©tails techniques dâimplĂ©mentation.
Caractéristiques :
Notation utilisée :
Cardinalités :
||--o{ : Un à plusieurs (1,N)||--|| : Un à un (1,1)}o--o{ : Plusieurs à plusieurs (N,M)Le MPD traduit le MCD en une structure de base de données réelle avec les spécificités du SGBD choisi (PostgreSQL).
Caractéristiques :
ĂlĂ©ments spĂ©cifiques au MPD :
uuid, jsonb, timestamptz, textNOT NULL, UNIQUE, CHECKdeleted_at pour suppression logiqueLe schéma de données de Mindlet comprend 35+ tables organisées en domaines fonctionnels :
| Domaine | Tables principales | Description |
|---|---|---|
| Utilisateurs | users, user_follows, user_friendships, user_achievements | Gestion des comptes, relations sociales et gamification |
| Collections | collections, collection_collaborators, tags, taggables | Organisation hiérarchique du contenu avec collaboration |
| Cartes | cards, card_progressions | Cartes dâapprentissage (9 types) et suivi de progression |
| Ătude | study_sessions | Sessions de rĂ©vision avec mĂ©triques |
| IA | ai_resource_batches, ai_resource_items, ai_resource_embeddings, ai_card_generations, user_ai_quotas | Pipeline de génération IA et gestion des quotas |
| Messagerie | conversations, messages, groups, conversation_participants | SystÚme de messagerie temps réel |
| Social | posts, post_reactions, post_mentions | Fil dâactualitĂ© et interactions |
| Organisations | organizations, organization_members, organization_invitations | Gestion des établissements |
| Auth | personal_access_tokens, social_accounts, roles, permissions | Authentification et autorisations |
Le diagramme ci-dessous présente les entités principales et leurs relations :
erDiagram
direction TB
USERS {
uuid id PK ""
string name ""
string email ""
timestamp email_verified_at ""
string password ""
string remember_token ""
timestamp created_at ""
timestamp updated_at ""
}
ORGANIZATIONS {
uuid id PK ""
string name ""
string slug ""
string description ""
timestamp created_at ""
timestamp updated_at ""
}
ORGANIZATION_MEMBERS {
uuid id PK ""
uuid organization_id FK ""
uuid user_id FK ""
string role ""
timestamp created_at ""
timestamp updated_at ""
}
ORGANIZATION_INVITATIONS {
uuid id PK ""
uuid organization_id FK ""
uuid inviter_id FK ""
string invitee_email ""
string token ""
timestamp expires_at ""
timestamp created_at ""
timestamp updated_at ""
}
COLLECTIONS {
uuid id PK ""
uuid owner_id FK ""
uuid parent_id FK ""
uuid organization_id FK ""
string title ""
string description ""
timestamp created_at ""
timestamp updated_at ""
}
COLLECTION_COLLABORATORS {
uuid id PK ""
uuid collection_id FK ""
uuid user_id FK ""
string role ""
timestamp created_at ""
timestamp updated_at ""
}
CARDS {
uuid id PK ""
uuid collection_id FK ""
string type ""
string front ""
string back ""
timestamp created_at ""
timestamp updated_at ""
}
CARD_PROGRESSIONS {
uuid id PK ""
uuid user_id FK ""
uuid card_id FK ""
timestamp last_reviewed_at ""
integer streak ""
timestamp created_at ""
timestamp updated_at ""
}
STUDY_SESSIONS {
uuid id PK ""
uuid user_id FK ""
uuid collection_id FK ""
string status ""
timestamp started_at ""
timestamp ended_at ""
timestamp created_at ""
timestamp updated_at ""
}
TAGS {
uuid id PK ""
string name ""
string color ""
timestamp created_at ""
timestamp updated_at ""
}
TAGGABLES {
bigint id PK ""
uuid tag_id FK ""
uuid taggable_id ""
string taggable_type ""
timestamp created_at ""
timestamp updated_at ""
}
USER_ACHIEVEMENTS {
uuid id PK ""
uuid user_id FK ""
string achievement_key ""
timestamp unlocked_at ""
timestamp created_at ""
timestamp updated_at ""
}
USER_FOLLOWS {
uuid id PK ""
uuid follower_id FK ""
uuid followed_id FK ""
timestamp created_at ""
}
USER_FRIENDSHIPS {
uuid id PK ""
uuid requester_id FK ""
uuid addressee_id FK ""
string status ""
timestamp created_at ""
timestamp updated_at ""
}
POSTS {
uuid id PK ""
uuid author_id FK ""
uuid collection_id FK ""
string content ""
timestamp published_at ""
timestamp created_at ""
timestamp updated_at ""
}
POST_MENTIONS {
uuid id PK ""
uuid post_id FK ""
uuid mentionable_id ""
string mentionable_type ""
timestamp created_at ""
timestamp updated_at ""
}
POST_REACTIONS {
uuid id PK ""
uuid post_id FK ""
uuid user_id FK ""
string kind ""
timestamp created_at ""
timestamp updated_at ""
}
CONVERSATIONS {
uuid id PK ""
string type ""
string topic ""
timestamp created_at ""
timestamp updated_at ""
}
DIRECT_CONVERSATIONS {
uuid id PK ""
uuid conversation_id FK ""
uuid user_one_id FK ""
uuid user_two_id FK ""
timestamp created_at ""
timestamp updated_at ""
}
GROUPS {
uuid id PK ""
uuid conversation_id FK ""
uuid owner_id FK ""
string name ""
string description ""
timestamp created_at ""
timestamp updated_at ""
}
CONVERSATION_PARTICIPANTS {
uuid id PK ""
uuid conversation_id FK ""
uuid user_id FK ""
timestamp joined_at ""
timestamp created_at ""
timestamp updated_at ""
}
MESSAGES {
uuid id PK ""
uuid conversation_id FK ""
uuid sender_id FK ""
string content ""
timestamp sent_at ""
timestamp created_at ""
timestamp updated_at ""
}
MESSAGE_REACTIONS {
uuid id PK ""
uuid message_id FK ""
uuid user_id FK ""
string kind ""
timestamp created_at ""
timestamp updated_at ""
}
GROUP_INVITATIONS {
uuid id PK ""
uuid group_id FK ""
uuid inviter_id FK ""
uuid invitee_id FK ""
string status ""
timestamp created_at ""
timestamp updated_at ""
}
AI_RESOURCE_BATCHES {
uuid id PK ""
uuid user_id FK ""
string status ""
timestamp created_at ""
timestamp updated_at ""
}
AI_RESOURCE_ITEMS {
uuid id PK ""
uuid batch_id FK ""
string resource_type ""
string file_hash ""
timestamp created_at ""
timestamp updated_at ""
}
AI_RESOURCE_EMBEDDINGS {
uuid id PK ""
uuid item_id FK ""
string embedding_type ""
timestamp created_at ""
timestamp updated_at ""
}
AI_CARD_GENERATIONS {
uuid id PK ""
uuid user_id FK ""
string generation_key ""
timestamp created_at ""
timestamp updated_at ""
}
USER_AI_QUOTAS {
uuid id PK ""
uuid user_id FK ""
integer monthly_quota ""
integer used ""
timestamp reset_at ""
timestamp created_at ""
timestamp updated_at ""
}
MEDIA {
bigint id PK ""
uuid model_id ""
string model_type ""
string file_name ""
string disk ""
string path ""
timestamp created_at ""
timestamp updated_at ""
}
SOCIAL_ACCOUNTS {
uuid id PK ""
uuid user_id FK ""
string provider ""
string provider_user_id ""
timestamp created_at ""
timestamp updated_at ""
}
PERSONAL_ACCESS_TOKENS {
bigint id PK ""
uuid tokenable_id ""
string tokenable_type ""
string name ""
string token ""
timestamp last_used_at ""
timestamp created_at ""
timestamp updated_at ""
}
PERMISSIONS {
bigint id PK ""
string name ""
string guard_name ""
timestamp created_at ""
timestamp updated_at ""
}
ROLES {
bigint id PK ""
string name ""
string guard_name ""
timestamp created_at ""
timestamp updated_at ""
}
MODEL_HAS_PERMISSIONS {
bigint permission_id FK ""
uuid model_id ""
string model_type ""
}
MODEL_HAS_ROLES {
bigint role_id FK ""
uuid model_id ""
string model_type ""
}
ROLE_HAS_PERMISSIONS {
bigint permission_id FK ""
bigint role_id FK ""
}
USERS||--o{COLLECTIONS:"owns"
COLLECTIONS|o--o{ORGANIZATIONS:"assigned_to"
USERS||--o{COLLECTION_COLLABORATORS:"collaborates"
COLLECTIONS||--o{COLLECTION_COLLABORATORS:"has_collaborator"
COLLECTIONS||--o{CARDS:"contains"
USERS||--o{CARD_PROGRESSIONS:"tracks"
CARDS||--o{CARD_PROGRESSIONS:"progress"
USERS||--o{STUDY_SESSIONS:"runs"
COLLECTIONS||--o{STUDY_SESSIONS:"studied_in"
TAGS||--o{TAGGABLES:"links"
COLLECTIONS|o--o{TAGGABLES:"tagged_collection"
CARDS|o--o{TAGGABLES:"tagged_card"
USERS||--o{USER_ACHIEVEMENTS:"earns"
USERS||--o{USER_FOLLOWS:"follower"
USER_FOLLOWS}o--||USERS:"followed"
USERS||--o{USER_FRIENDSHIPS:"requests"
USER_FRIENDSHIPS}o--||USERS:"friend"
USERS||--o{POSTS:"authors"
COLLECTIONS|o--o{POSTS:"feeds"
POSTS||--o{POST_REACTIONS:"receives_reaction"
USERS||--o{POST_REACTIONS:"reacts"
POSTS||--o{POST_MENTIONS:"mentions"
POST_MENTIONS}o--||USERS:"mention_target"
CONVERSATIONS||--o{MESSAGES:"contains"
USERS||--o{MESSAGES:"sends"
CONVERSATIONS||--o{CONVERSATION_PARTICIPANTS:"has_participant"
USERS||--o{CONVERSATION_PARTICIPANTS:"participates"
CONVERSATIONS||--||DIRECT_CONVERSATIONS:"direct_thread"
DIRECT_CONVERSATIONS||--o{USERS:"user_one"
DIRECT_CONVERSATIONS||--o{USERS:"user_two"
CONVERSATIONS||--||GROUPS:"group_thread"
GROUPS||--o{GROUP_INVITATIONS:"issues"
USERS||--o{GROUP_INVITATIONS:"invites"
GROUP_INVITATIONS}o--||USERS:"invited"
GROUPS||--o{CONVERSATION_PARTICIPANTS:"members"
MESSAGES||--o{MESSAGE_REACTIONS:"receives_reaction"
USERS||--o{MESSAGE_REACTIONS:"reacts"
USERS||--o{AI_RESOURCE_BATCHES:"submits_batch"
AI_RESOURCE_BATCHES||--o{AI_RESOURCE_ITEMS:"includes_item"
AI_RESOURCE_ITEMS||--o{AI_RESOURCE_EMBEDDINGS:"has_embedding"
USERS||--o{AI_CARD_GENERATIONS:"requests_generation"
USERS||--o{USER_AI_QUOTAS:"quota_records"
AI_RESOURCE_ITEMS}o--||MEDIA:"stored_media"
USERS||--o{SOCIAL_ACCOUNTS:"links_account"
USERS||--o{PERSONAL_ACCESS_TOKENS:"tokens"
PERMISSIONS||--o{ROLE_HAS_PERMISSIONS:"granted_to_role"
ROLES||--o{ROLE_HAS_PERMISSIONS:"aggregates_permission"
ROLES||--o{MODEL_HAS_ROLES:"assigned_to"
USERS||--o{MODEL_HAS_ROLES:"user_role"
PERMISSIONS||--o{MODEL_HAS_PERMISSIONS:"assigned_to"
USERS||--o{MODEL_HAS_PERMISSIONS:"user_permission"
ORGANIZATIONS||--o{ORGANIZATION_MEMBERS:"has_member"
USERS||--o{ORGANIZATION_MEMBERS:"membership"
ORGANIZATIONS||--o{ORGANIZATION_INVITATIONS:"issues_invite"
USERS||--o{ORGANIZATION_INVITATIONS:"invites" Le MPD ci-dessous montre lâimplĂ©mentation PostgreSQL avec les types de donnĂ©es, contraintes et index :

Types utilisés dans le schéma :
| Type | Usage | Exemple |
|---|---|---|
uuid | Clés primaires et étrangÚres | id, user_id, collection_id |
jsonb | Données flexibles indexables | cards.data, cards.config |
timestamptz | Horodatages avec timezone | created_at, updated_at |
text | ChaĂźnes de longueur variable | title, description, content |
varchar(n) | Chaßnes limitées | email, type, status |
boolean | Valeurs binaires | is_unlimited, exclude_from_embedding |
integer | Compteurs et quotas | daily_generations_used |
StratĂ©gie dâindexation :
-- Index sur les clĂ©s Ă©trangĂšres frĂ©quemment requĂȘtĂ©esCREATE INDEX idx_cards_collection_id ON cards(collection_id);CREATE INDEX idx_cards_type ON cards(type);
-- Index composite pour les requĂȘtes combinĂ©esCREATE INDEX idx_cards_collection_type ON cards(collection_id, type);
-- Index GIN pour les recherches JSONBCREATE INDEX idx_cards_data ON cards USING GIN (data);
-- Index partiel pour les enregistrements non supprimĂ©sCREATE INDEX idx_cards_active ON cards(collection_id) WHERE deleted_at IS NULL;Contraintes dâintĂ©gritĂ© :
-- Clé primaire UUIDPRIMARY KEY (id)
-- Clé étrangÚre avec cascadeFOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
-- UnicitéUNIQUE (user_id, card_id) -- Une progression par carte par user
-- VérificationCHECK (daily_generations_used >= 0)CHECK (visibility IN ('private', 'public', 'draft'))| Relation | Type | Description |
|---|---|---|
User â Collections | 1:N | Un utilisateur possĂšde plusieurs collections |
Collection â Cards | 1:N | Une collection contient plusieurs cartes |
User â Collections | N:M | Collaboration via collection_collaborators |
Card â CardProgressions | 1:N | Progression par utilisateur et par carte |
User â AiCardGenerations | 1:N | Historique des gĂ©nĂ©rations IA |
AiResourceBatch â Items â Embeddings | 1:N:N | Pipeline dâingestion des ressources |
Architecture conçue pour la performance, la scalabilité et la maintenabilité.