Types relationnels
RELATION, USERS, DEPENDENT_RELATION, MORPH_RELATION, MANY_TO_MANY, PRIMARY_M2M_REFERENCE, PIPELINE
RELATION
Relation classique entre deux objets via cle etrangere. Supporte deux modes :
BELONGS_TO_ONE
L'objet source contient une cle etrangere (FK) vers l'objet cible. C'est le cote "N" d'une relation 1:N.
| Propriete | Valeur |
|---|---|
| SQL | UUID (colonne {champ}_id) |
| Indexable | Oui (index automatique) |
| FK | ON DELETE CASCADE si requis, ON DELETE SET NULL sinon |
Operateurs de filtre : equals, not_equals, in, not_in, is_null, is_not_null
{
relationType: 'BELONGS_TO_ONE',
targetObjectName: 'companies', // Objet cible
targetFieldName: 'contacts', // Champ inverse auto-genere sur la cible
targetFieldLabel: 'Contacts' // Label du champ inverse
}Le suffixe _id est ajoute automatiquement au nom de colonne. Un champ company cree une colonne company_id. Le champ inverse HAS_MANY est genere automatiquement sur l'objet cible.
HAS_MANY
Cote inverse d'un BELONGS_TO_ONE. Virtuel : pas de colonne physique. Les resultats sont calcules par requete.
| Propriete | Valeur |
|---|---|
| SQL | Aucune colonne (virtuel) |
Company.contacts → SELECT * FROM contacts WHERE company_id = {company.id}USERS
Relation speciale vers les utilisateurs du workspace. Cree une cle etrangere vers workspace_users.
| Propriete | Valeur |
|---|---|
| SQL | UUID (colonne {champ}_id) |
| Indexable | Oui (index automatique) |
Operateurs de filtre : equals, not_equals, in, not_in, is_null, is_not_null
{
relationType: 'BELONGS_TO_ONE', // Force automatiquement
targetObjectName: 'workspace_users', // Force automatiquement
defaultToSessionUser: true // Pre-remplit avec l'utilisateur connecte
}DEPENDENT_RELATION
Relation dont les options dependent d'un autre champ du meme objet. Typiquement utilise pour les etapes de pipeline filtrees par pipeline.
| Propriete | Valeur |
|---|---|
| SQL | UUID (colonne {champ}_id) |
| Indexable | Oui |
| FK | ON DELETE SET NULL ON UPDATE CASCADE |
Operateurs de filtre : equals, not_equals, in, not_in, is_null, is_not_null
{
relationType: 'BELONGS_TO_ONE',
targetObjectName: 'pipeline_steps',
dependsOn: 'pipeline_id', // Champ parent (obligatoire)
filterField: 'pipeline_id', // Champ de filtre sur la cible (obligatoire)
dependencyMode: 'strict' // 'strict' = filtre dur, 'suggest' = priorisation souple
}MORPH_RELATION
Relation polymorphe : un champ peut pointer vers plusieurs types d'objets differents. Chaque objet cible recoit sa propre colonne FK, toutes liees par un identifiant morphId commun.
| Propriete | Valeur |
|---|---|
| SQL | 1 colonne UUID par objet cible |
| FK | ON DELETE SET NULL ON UPDATE CASCADE par cible |
| Nommage | {champ}_{cible}_id (ex : linked_to_contacts_id) |
Operateurs de filtre : equals, not_equals, is_null, is_not_null
Exemple : un champ linked_to avec 3 cibles cree 3 colonnes :
"linked_to_contacts_id" UUID -- FK → contacts
"linked_to_companies_id" UUID -- FK → companies
"linked_to_opportunities_id" UUID -- FK → opportunitiesTous les champs partagent le meme morphId. Un seul est rempli a la fois. Utilise pour les taches et notes qui peuvent etre liees a differents types d'objets.
MANY_TO_MANY
Relation N:N via table de jonction auto-generee. Pas de colonne sur les objets source ou cible.
| Propriete | Valeur |
|---|---|
| SQL | Aucune colonne sur les tables parentes |
| Stockage | Table de jonction dediee |
| FK jonction | ON DELETE CASCADE ON UPDATE CASCADE |
Operateurs de filtre : equals, not_equals, in, not_in, is_null, is_not_null
Table de jonction
Nommage : {source}_{champ}_target (ex : contacts_companies_target)
Structure :
CREATE TABLE "contacts_companies_target" (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID NOT NULL, -- FK → contacts (CASCADE)
company_id UUID, -- FK → companies (CASCADE)
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
deleted_at TIMESTAMP DEFAULT NULL
)Un index unique composite est cree automatiquement sur (source_id, target_id).
Champs de jonction
La table de jonction peut contenir des champs additionnels :
junctionFields: [
{ name: 'position', type: 'TEXT', label: 'Poste' },
{ name: 'is_primary', type: 'BOOLEAN', label: 'Contact principal' }
]Options avancees
| Option | Description |
|---|---|
allowLinkFromTarget | Autoriser la creation/suppression de liens depuis le cote cible (defaut : true) |
closedAtColumnName | Nom d'une colonne TIMESTAMP pour marquer la fin d'une relation |
sticky | Auto-extension : ajoute automatiquement une colonne FK quand un nouvel objet est cree |
Multi-cible
Une seule table de jonction peut lier un objet source a plusieurs types d'objets cibles. Chaque cible a sa propre colonne FK (nullable), et une seule est remplie par ligne.
PRIMARY_M2M_REFERENCE
Reference virtuelle vers l'entree "principale" (is_primary = true) d'une relation MANY_TO_MANY.
| Propriete | Valeur |
|---|---|
| SQL | Aucune colonne (virtuel) |
| Lecture seule | Depend du referenceType |
Deux variantes :
display: affiche la valeur du champ standard de l'objet cible principal (lecture seule)junction_field: affiche/edite un champ specifique de la ligne de jonction principale
{
relationType: 'PRIMARY_M2M_REFERENCE',
sourceM2MField: 'companies', // Champ M2M source
referenceType: 'display', // ou 'junction_field'
junctionFieldName: 'position', // Si 'junction_field'
junctionTable: 'contacts_companies_target'
}PIPELINE
Type special pour les pipelines de vente. Type composite : cree 3 colonnes SQL.
| Propriete | Valeur |
|---|---|
| Colonne pipeline | UUID ({champ}_id) — FK vers pipelines |
| Colonne etape | UUID ({champ}_step_id) — FK vers pipeline_steps |
| Colonne cloture | TIMESTAMP ({champ}_closed_at) |
| FK | ON DELETE SET NULL ON UPDATE CASCADE pour les deux FK |
| Indexable | Oui (2 index automatiques) |
Schema SQL : pour un champ pipeline, trois colonnes sont creees :
"pipeline_id" UUID -- FK → pipelines
"pipeline_step_id" UUID -- FK → pipeline_steps
"pipeline_closed_at" TIMESTAMP{
pipelineObject: 'pipelines', // Table des pipelines
stepsObject: 'pipeline_steps', // Table des etapes
stepsFilterField: 'pipeline_id', // Filtre etapes par pipeline
pipelineColumnName: 'pipeline_id',
stepColumnName: 'pipeline_step_id',
closedAtColumnName: 'pipeline_closed_at',
closedAtLabel: 'Date de cloture'
}La vue Kanban est optimisee pour afficher les etapes de pipeline comme colonnes.