Apparence
Opportunity
Opportunité commerciale : une carte du Kanban (/pipeline) ou une ligne du tableau (/opportunities). C'est la même entité, vue sous deux angles. L'étape (stage) détermine la colonne dans laquelle elle apparaît dans la kanban.
- Path Firestore :
users/{userId}/opportunities/{opportunityId} - Source TS :
klapy-crm/src/types/index.ts
Interface
ts
interface Opportunity {
id: string;
title: string;
contact_id?: string;
company_id?: string;
stage: OpportunityStage;
amount?: number;
project_type?: ProjectType;
expected_close_date?: Timestamp;
shoot_date?: Timestamp;
notes?: string;
lost_reason?: string;
last_activity_at?: Timestamp;
created_at: Timestamp;
updated_at: Timestamp;
}Champs
| Champ | Notes |
|---|---|
title | Obligatoire |
contact_id | Référence optionnelle vers un Contact |
company_id | Référence optionnelle vers une Company. null = engagement particulier |
stage | Étape du pipeline. Une des 7 valeurs de OPPORTUNITY_STAGE |
amount | Montant estimé en euros (HT par convention, voir Quote/Invoice pour le détail TVA) |
project_type | Une des valeurs de PROJECT_TYPE (typologie de prestation) |
expected_close_date | Date estimée de signature / validation |
shoot_date | Date de tournage prévue (peut différer de expected_close_date) |
lost_reason | Texte libre. Requis quand stage === 'lost' (validation form, pas une contrainte de type) |
last_activity_at | Mis à jour par Cloud Function quand une activité est loggée. Pilote le badge "stale" sur la kanban |
notes | Texte libre |
Validation contact_id / company_id
Au moins un des deux doit être renseigné (règle de validation form, pas de contrainte au niveau du type). Une opportunité sans contact ni entreprise n'a pas de sens métier.
Pro vs particulier
La nature de l'engagement vit sur l'opportunité, pas sur le contact. company_id renseigné = engagement professionnel. company_id vide = engagement particulier (mariage, vidéo perso). Un même contact peut donc être lié à plusieurs opportunités, certaines pro et d'autres particulières.
Constantes liées
OPPORTUNITY_STAGE
Les 7 étapes du pipeline, ordonnées comme dans la kanban :
| Clé | Label UI | Groupe |
|---|---|---|
lead | Lead | Prospection |
first_contact | Premier échange | Prospection |
quote | Devis envoyé | Engagement |
negotiation | En discussion | Engagement |
verbal | Accord verbal | Accord |
won | Gagné | Accord |
lost | Perdu | Échec |
Le champ STAGE_TO_GROUP mappe chaque étape vers son groupe. La kanban utilise ces groupes pour rendre des séparateurs visuels entre les phases (Prospection → Engagement → Accord → Échec).
PROJECT_TYPE
Typologie courte de la prestation : shoot (tournage seul), edit (montage seul), shoot_and_edit (tournage + montage), photo, other.
Cycle de vie
Transitions libres
Les transitions ne sont pas contraintes par les règles Firestore : un utilisateur peut sauter directement d'une étape à n'importe quelle autre (par drag & drop dans la kanban ou via le sélecteur d'étape dans le DetailPane). Le diagramme ci-dessus est le flux nominal, pas une machine d'état stricte. Cas typique : un client revient après plusieurs mois en lost, on rebascule en negotiation sans repasser par lead.
won n'est pas la fin du métier
stage === 'won' matérialise l'accord commercial conclu, pas la production réalisée. Quand le projet entre en phase de production effective (acompte encaissé, dates de tournage planifiées, livrables à produire), il est destiné à être dérivé en entité Project distincte qui rejoindra le Portfolio. L'opportunité won reste alors archivée en l'état pour les KPIs commerciaux (taux de conversion, CA pipeline).
Voir aussi
Contact,Company: références cibles de l'opportunitéQuote: un devis peut être créé depuis une opportunité (et inversement, l'envoi d'un devis fait passer l'opportunité enquote)Task: peut être rattachée à une opportunité viaopportunity_idCalendarEvent: tournage planifié rattaché à une opportunitéActivity: appels, emails, notes loggés contre l'opportunité (alimentelast_activity_at)