{"openapi":"3.1.0","info":{"title":"API Tournéo","version":"1.0.0","description":"API REST de lecture/écriture : clientèle, contacts, notes, rapports de visite, rendez-vous, opportunités, tournées, étiquettes et données publiques d'entreprises. Authentification : `Authorization: Bearer <clé>` (clés créées dans Paramètres → API, droits lecture ou lecture+écriture)."},"servers":[{"url":"https://tourneo.jecasolutions.fr"}],"tags":[{"name":"companies","description":"Établissements de la clientèle (CRM)"},{"name":"contacts","description":"Interlocuteurs"},{"name":"notes","description":"Notes"},{"name":"reports","description":"Rapports de visite, prospection, rendez-vous, appel ou tournée. Les réponses aux champs personnalisés du modèle (Paramètres → Rapports) sont dans `fields` (clé technique → valeur) ; `checklist` est une liste { label, done }."},{"name":"appointments","description":"Rendez-vous"},{"name":"opportunities","description":"Opportunités commerciales"},{"name":"tours","description":"Tournées commerciales"},{"name":"tour_stops","description":"Arrêts de tournée"},{"name":"tags","description":"Statuts et étiquettes"},{"name":"pipeline_stages","description":"Étapes du pipeline"},{"name":"activities","description":"Journal d'activité (lecture seule)"},{"name":"users","description":"Utilisateurs de l'organisation (lecture seule)"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"status":{"type":"integer"},"details":{}}}}}}},"paths":{"/api/v1/companies":{"get":{"tags":["companies"],"summary":"Lister — Établissements de la clientèle (CRM)","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"updated_at.desc"},"description":"colonne.asc|desc — colonnes : id, name, enseigne, siret, city, postal_code, category, priority, potential, owner_id, status_tag_id, next_action_at, last_visit_at, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans name, enseigne, city, siret"},{"name":"status_tag_id","in":"query","schema":{"type":"string"},"description":"Statut commercial (id d'étiquette)"},{"name":"category","in":"query","schema":{"type":"string"},"description":"Type de magasin (boulangerie, fleuriste…)"},{"name":"siret","in":"query","schema":{"type":"string"},"description":"SIRET exact"},{"name":"city","in":"query","schema":{"type":"string"},"description":"Ville"},{"name":"owner_id","in":"query","schema":{"type":"string"},"description":"Commercial"},{"name":"updated_since","in":"query","schema":{"type":"string"},"description":"Modifiés depuis (ISO 8601)"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["companies"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"siret":{"anyOf":[{"type":"string","pattern":"^\\d{14}$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"enseigne":{"type":["string","null"]},"naf":{"type":["string","null"]},"category":{"type":["string","null"]},"address":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"city":{"type":["string","null"]},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"phone":{"type":["string","null"]},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"website":{"type":["string","null"]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status_tag_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"potential":{"type":["number","null"]},"priority":{"type":"integer","minimum":1,"maximum":3},"hidden":{"type":"boolean"},"next_action_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"opening_hours":{}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/companies/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["companies"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["companies"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"siret":{"anyOf":[{"type":"string","pattern":"^\\d{14}$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"enseigne":{"type":["string","null"]},"naf":{"type":["string","null"]},"category":{"type":["string","null"]},"address":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"city":{"type":["string","null"]},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"phone":{"type":["string","null"]},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"website":{"type":["string","null"]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"status_tag_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"potential":{"type":["number","null"]},"priority":{"type":"integer","minimum":1,"maximum":3},"hidden":{"type":"boolean"},"next_action_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"opening_hours":{}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["companies"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts":{"get":{"tags":["contacts"],"summary":"Lister — Interlocuteurs","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"created_at.desc"},"description":"colonne.asc|desc — colonnes : id, first_name, last_name, email, company_id, is_primary, created_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans first_name, last_name, email"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["contacts"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"is_primary":{"type":"boolean"}},"required":["company_id"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["contacts"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["contacts"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"job_title":{"type":["string","null"]},"phone":{"type":["string","null"]},"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"is_primary":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["contacts"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/notes":{"get":{"tags":["notes"],"summary":"Lister — Notes","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"created_at.desc"},"description":"colonne.asc|desc — colonnes : id, company_id, author_id, kind, pinned, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans body"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"},{"name":"kind","in":"query","schema":{"type":"string"},"description":"note | appel | email | reunion | interne"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["notes"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"body":{"type":"string","minLength":1},"kind":{"type":"string","enum":["note","appel","email","reunion","interne"]},"pinned":{"type":"boolean"}},"required":["company_id","body"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/notes/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["notes"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["notes"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"body":{"type":"string","minLength":1},"kind":{"type":"string","enum":["note","appel","email","reunion","interne"]},"pinned":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["notes"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reports":{"get":{"tags":["reports"],"summary":"Lister — Rapports de visite, prospection, rendez-vous, appel ou tournée","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"visited_at.desc"},"description":"colonne.asc|desc — colonnes : id, company_id, tour_id, author_id, kind, outcome, interest, visited_at, next_action_at, order_amount, quote_amount, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans title, summary, needs, objections, competitors, next_step, contact_name"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"},{"name":"tour_id","in":"query","schema":{"type":"string"},"description":"Tournée"},{"name":"appointment_id","in":"query","schema":{"type":"string"},"description":"Rendez-vous"},{"name":"author_id","in":"query","schema":{"type":"string"},"description":"Auteur (commercial)"},{"name":"kind","in":"query","schema":{"type":"string"},"description":"visite | prospection | rendez_vous | appel | tournee | autre"},{"name":"outcome","in":"query","schema":{"type":"string"},"description":"positif | neutre | negatif | sans_suite"},{"name":"from","in":"query","schema":{"type":"string"},"description":"Date de visite ≥ (ISO 8601)"},{"name":"to","in":"query","schema":{"type":"string"},"description":"Date de visite ≤ (ISO 8601)"},{"name":"follow_up_before","in":"query","schema":{"type":"string"},"description":"Relance prévue avant (ISO 8601)"},{"name":"updated_since","in":"query","schema":{"type":"string"},"description":"Modifiés depuis (ISO 8601)"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["reports"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"tour_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"tour_stop_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"appointment_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"author_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"kind":{"type":"string","enum":["visite","prospection","rendez_vous","appel","tournee","autre"]},"outcome":{"anyOf":[{"type":"string","enum":["positif","neutre","negatif","sans_suite"]},{"type":"null"}]},"interest":{"anyOf":[{"type":"integer","minimum":0,"maximum":5},{"type":"null"}]},"title":{"type":["string","null"]},"summary":{"type":["string","null"]},"body":{"type":["string","null"]},"contact_name":{"type":["string","null"]},"contact_role":{"type":["string","null"]},"needs":{"type":["string","null"]},"objections":{"type":["string","null"]},"competitors":{"type":["string","null"]},"next_step":{"type":["string","null"]},"next_action_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"next_action_type":{"type":["string","null"]},"order_amount":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"quote_amount":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"duration_minutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}]},"topics":{"maxItems":50,"type":"array","items":{"type":"string"}},"checklist":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"done":{"type":"boolean"}},"required":["label","done"],"additionalProperties":false}},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"visited_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["kind"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reports/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["reports"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["reports"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"tour_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"tour_stop_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"appointment_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"author_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"kind":{"type":"string","enum":["visite","prospection","rendez_vous","appel","tournee","autre"]},"outcome":{"anyOf":[{"type":"string","enum":["positif","neutre","negatif","sans_suite"]},{"type":"null"}]},"interest":{"anyOf":[{"type":"integer","minimum":0,"maximum":5},{"type":"null"}]},"title":{"type":["string","null"]},"summary":{"type":["string","null"]},"body":{"type":["string","null"]},"contact_name":{"type":["string","null"]},"contact_role":{"type":["string","null"]},"needs":{"type":["string","null"]},"objections":{"type":["string","null"]},"competitors":{"type":["string","null"]},"next_step":{"type":["string","null"]},"next_action_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"next_action_type":{"type":["string","null"]},"order_amount":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"quote_amount":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"duration_minutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":1440},{"type":"null"}]},"topics":{"maxItems":50,"type":"array","items":{"type":"string"}},"checklist":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"done":{"type":"boolean"}},"required":["label","done"],"additionalProperties":false}},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"lat":{"anyOf":[{"type":"number","minimum":-90,"maximum":90},{"type":"null"}]},"lng":{"anyOf":[{"type":"number","minimum":-180,"maximum":180},{"type":"null"}]},"visited_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["reports"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/appointments":{"get":{"tags":["appointments"],"summary":"Lister — Rendez-vous","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"starts_at.asc"},"description":"colonne.asc|desc — colonnes : id, title, starts_at, ends_at, status, owner_id, company_id, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans title, location"},{"name":"from","in":"query","schema":{"type":"string"},"description":"Début après (ISO 8601)"},{"name":"to","in":"query","schema":{"type":"string"},"description":"Début avant (ISO 8601)"},{"name":"owner_id","in":"query","schema":{"type":"string"},"description":"Commercial"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"},{"name":"status","in":"query","schema":{"type":"string"},"description":"planifie | confirme | realise | annule"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["appointments"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"contact_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"location":{"type":["string","null"]},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"status":{"type":"string","enum":["planifie","confirme","realise","annule"]}},"required":["title","starts_at","ends_at"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/appointments/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["appointments"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["appointments"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"contact_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"title":{"type":"string","minLength":1},"description":{"type":["string","null"]},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"location":{"type":["string","null"]},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"status":{"type":"string","enum":["planifie","confirme","realise","annule"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["appointments"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/opportunities":{"get":{"tags":["opportunities"],"summary":"Lister — Opportunités commerciales","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"updated_at.desc"},"description":"colonne.asc|desc — colonnes : id, title, amount, probability, expected_close_date, stage_id, owner_id, company_id, position, closed_at, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans title"},{"name":"stage_id","in":"query","schema":{"type":"string"},"description":"Étape"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"},{"name":"owner_id","in":"query","schema":{"type":"string"},"description":"Commercial"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["opportunities"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"stage_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string","minLength":1},"amount":{"type":"number"},"probability":{"anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"expected_close_date":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"description":{"type":["string","null"]}},"required":["stage_id","title"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/opportunities/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["opportunities"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["opportunities"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"stage_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string","minLength":1},"amount":{"type":"number"},"probability":{"anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"expected_close_date":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"description":{"type":["string","null"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["opportunities"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tours":{"get":{"tags":["tours"],"summary":"Lister — Tournées commerciales","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"date.desc"},"description":"colonne.asc|desc — colonnes : id, name, date, status, owner_id, start_time, total_distance_m, total_duration_s, created_at, updated_at"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Recherche dans name"},{"name":"from","in":"query","schema":{"type":"string"},"description":"Date ≥ (AAAA-MM-JJ)"},{"name":"to","in":"query","schema":{"type":"string"},"description":"Date ≤"},{"name":"owner_id","in":"query","schema":{"type":"string"},"description":"Commercial"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Statut"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["tours"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"start_time":{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},"start_address":{"type":["string","null"]},"start_lat":{"type":["number","null"]},"start_lng":{"type":["number","null"]},"end_address":{"type":["string","null"]},"end_lat":{"type":["number","null"]},"end_lng":{"type":["number","null"]},"return_to_start":{"type":"boolean"},"status":{"type":"string","enum":["brouillon","planifiee","en_cours","terminee"]},"settings":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"report":{"type":["string","null"]}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tours/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["tours"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["tours"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"owner_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"start_time":{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},"start_address":{"type":["string","null"]},"start_lat":{"type":["number","null"]},"start_lng":{"type":["number","null"]},"end_address":{"type":["string","null"]},"end_lat":{"type":["number","null"]},"end_lng":{"type":["number","null"]},"return_to_start":{"type":"boolean"},"status":{"type":"string","enum":["brouillon","planifiee","en_cours","terminee"]},"settings":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"report":{"type":["string","null"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["tours"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tour_stops":{"get":{"tags":["tour_stops"],"summary":"Lister — Arrêts de tournée","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"position.asc"},"description":"colonne.asc|desc — colonnes : id, tour_id, position, status, priority, eta, etd, visited_at, label, created_at"},{"name":"tour_id","in":"query","schema":{"type":"string"},"description":"Tournée"},{"name":"status","in":"query","schema":{"type":"string"},"description":"a_faire | visite | absent | reporte"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["tour_stops"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tour_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"label":{"type":"string","minLength":1},"address":{"type":["string","null"]},"lat":{"type":"number"},"lng":{"type":"number"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"visit_minutes":{"type":"integer","minimum":1,"maximum":600},"window_start":{"anyOf":[{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},{"type":"null"}]},"window_end":{"anyOf":[{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},{"type":"null"}]},"priority":{"type":"integer","minimum":1,"maximum":3},"locked":{"type":"boolean"},"status":{"type":"string","enum":["a_faire","visite","absent","reporte"]},"outcome":{"type":["string","null"]},"visited_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["tour_id","label","lat","lng"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tour_stops/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["tour_stops"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["tour_stops"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tour_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"company_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"label":{"type":"string","minLength":1},"address":{"type":["string","null"]},"lat":{"type":"number"},"lng":{"type":"number"},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"visit_minutes":{"type":"integer","minimum":1,"maximum":600},"window_start":{"anyOf":[{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},{"type":"null"}]},"window_end":{"anyOf":[{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$"},{"type":"null"}]},"priority":{"type":"integer","minimum":1,"maximum":3},"locked":{"type":"boolean"},"status":{"type":"string","enum":["a_faire","visite","absent","reporte"]},"outcome":{"type":["string","null"]},"visited_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["tour_stops"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tags":{"get":{"tags":["tags"],"summary":"Lister — Statuts et étiquettes","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"position.asc"},"description":"colonne.asc|desc — colonnes : id, name, kind, position, created_at"},{"name":"kind","in":"query","schema":{"type":"string"},"description":"status | label"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["tags"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"kind":{"type":"string","enum":["status","label"]},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"icon":{"type":["string","null"]}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tags/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["tags"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["tags"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"kind":{"type":"string","enum":["status","label"]},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"icon":{"type":["string","null"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["tags"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pipeline_stages":{"get":{"tags":["pipeline_stages"],"summary":"Lister — Étapes du pipeline","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"position.asc"},"description":"colonne.asc|desc — colonnes : id, name, position, probability"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["pipeline_stages"],"summary":"Créer (objet ou tableau de 100 max)","x-scope":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1},"color":{"type":"string"},"probability":{"type":"integer","minimum":0,"maximum":100},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"is_won":{"type":"boolean"},"is_lost":{"type":"boolean"}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Créé"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pipeline_stages/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["pipeline_stages"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["pipeline_stages"],"summary":"Modifier","x-scope":"write","requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1},"color":{"type":"string"},"probability":{"type":"integer","minimum":0,"maximum":100},"position":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"is_won":{"type":"boolean"},"is_lost":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK"},"422":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["pipeline_stages"],"summary":"Supprimer","x-scope":"write","responses":{"200":{"description":"Supprimé"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/activities":{"get":{"tags":["activities"],"summary":"Lister — Journal d'activité (lecture seule)","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"created_at.desc"},"description":"colonne.asc|desc — colonnes : id, type, company_id, user_id, created_at"},{"name":"company_id","in":"query","schema":{"type":"string"},"description":"Établissement"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Type"},{"name":"since","in":"query","schema":{"type":"string"},"description":"Depuis (ISO 8601)"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/activities/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["activities"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/users":{"get":{"tags":["users"],"summary":"Lister — Utilisateurs de l'organisation (lecture seule)","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"order","in":"query","schema":{"type":"string","example":"created_at.asc"},"description":"colonne.asc|desc — colonnes : id, email, full_name, role, created_at"},{"name":"role","in":"query","schema":{"type":"string"},"description":"admin | manager | commercial"}],"responses":{"200":{"description":"Liste paginée"},"401":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/users/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["users"],"summary":"Lire","responses":{"200":{"description":"OK"},"404":{"description":"Erreur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tours/{id}/optimize":{"post":{"tags":["tours"],"summary":"Optimiser une tournée (ordre, horaires, itinéraire)","x-scope":"write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"enum":["optimize","recompute"]}}}}}},"responses":{"200":{"description":"Tournée recalculée"}}}},"/api/v1/tours/{id}/ics":{"get":{"tags":["tours"],"summary":"Calendrier iCalendar de la tournée","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/calendar"}}}},"/api/v1/etablissements":{"get":{"tags":["données publiques"],"summary":"Rechercher des établissements (SIRENE) par texte ou par zone","parameters":[{"name":"q","in":"query","schema":{"type":"string"}},{"name":"lat","in":"query","schema":{"type":"number"}},{"name":"lng","in":"query","schema":{"type":"number"}},{"name":"radius_km","in":"query","schema":{"type":"number","maximum":50}},{"name":"categories","in":"query","schema":{"type":"string"},"description":"Codes séparés par des virgules (voir /api/v1/categories)"}],"responses":{"200":{"description":"Établissements"}}}},"/api/v1/etablissements/{siret}":{"get":{"tags":["données publiques"],"summary":"Fiche entreprise complète : identité, dirigeants, finances, BODACC","parameters":[{"name":"siret","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/categories":{"get":{"tags":["données publiques"],"summary":"Types de magasins et codes NAF associés","security":[],"responses":{"200":{"description":"OK"}}}}}}