openapi: 3.0.3 info: title: 'API Werise — Documentation' description: 'API Werise, le back-office de BabiMap : commerces, articles, adresses et commandes.' version: 1.0.0 servers: - url: 'http://172.20.10.4:8000' tags: - name: Administration description: "\nConnexion au back-office Werise." - name: Système description: '' - name: Utilisateurs description: '' components: securitySchemes: default: type: http scheme: bearer description: "Le jeton s'obtient à la connexion, via Laravel Sanctum." security: - default: [] paths: /api/admin/connexion: post: summary: Connexion operationId: connexion description: "Vérifie les identifiants et renvoie un couple de jetons. Le jeton d'accès\nest volontairement court : le client le rafraîchit avec `refreshToken`." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: token: … refreshToken: … expiresIn: 900 expiresAt: '2026-08-02T12:15:00+00:00' admin: id: 1 email: admin@werise.com properties: token: type: string example: … refreshToken: type: string example: … expiresIn: type: integer example: 900 expiresAt: type: string example: '2026-08-02T12:15:00+00:00' admin: type: object properties: id: type: integer example: 1 email: type: string example: admin@werise.com 401: description: '' content: application/json: schema: type: object example: message: 'Identifiants incorrects.' properties: message: type: string example: 'Identifiants incorrects.' 429: description: '' content: application/json: schema: type: object example: message: 'Trop de tentatives. Réessaie dans 60 secondes.' properties: message: type: string example: 'Trop de tentatives. Réessaie dans 60 secondes.' tags: - Administration requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: "L'adresse email de l'administrateur." example: admin@werise.com password: type: string description: 'Le mot de passe.' example: motdepasse required: - email - password security: [] /api/admin/rafraichir: post: summary: 'Rafraîchir le jeton' operationId: rafrachirLeJeton description: "Échange un jeton de rafraîchissement contre un nouveau couple de jetons.\nL'ancien jeton de rafraîchissement est invalidé au passage." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: token: … refreshToken: … expiresIn: 900 expiresAt: '2026-08-02T12:30:00+00:00' admin: id: 1 email: admin@werise.com properties: token: type: string example: … refreshToken: type: string example: … expiresIn: type: integer example: 900 expiresAt: type: string example: '2026-08-02T12:30:00+00:00' admin: type: object properties: id: type: integer example: 1 email: type: string example: admin@werise.com 401: description: '' content: application/json: schema: type: object example: message: 'Jeton de rafraîchissement invalide ou expiré.' properties: message: type: string example: 'Jeton de rafraîchissement invalide ou expiré.' tags: - Administration requestBody: required: true content: application/json: schema: type: object properties: refreshToken: type: string description: 'Le jeton de rafraîchissement reçu à la connexion.' example: architecto required: - refreshToken security: [] /api/admin/moi: get: summary: 'Administrateur connecté' operationId: administrateurConnect description: "Renvoie le compte associé au jeton d'accès." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: admin: id: 1 email: admin@werise.com properties: admin: type: object properties: id: type: integer example: 1 email: type: string example: admin@werise.com 401: description: '' content: application/json: schema: type: object example: message: 'Jeton invalide ou expiré.' expire: true properties: message: type: string example: 'Jeton invalide ou expiré.' expire: type: boolean example: true tags: - Administration security: [] /api/admin/deconnexion: post: summary: Déconnexion operationId: dconnexion description: 'Invalide les deux jetons du compte.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: Déconnecté. properties: message: type: string example: Déconnecté. tags: - Administration security: [] /api/admin/vue-ensemble: get: summary: "Vue d'ensemble" operationId: vueDensemble description: "Indicateurs du tableau de bord : cartes de tête, volumes de contenu,\ncourbe des inscriptions, répartition par catégorie, abonnements et\npaiements, file de modération." parameters: - in: query name: mois description: "Profondeur de la courbe d'inscriptions, entre 3 et 36." example: 12 required: false schema: type: integer description: "Profondeur de la courbe d'inscriptions, entre 3 et 36." example: 12 - in: query name: debut description: 'Premier mois de la courbe au format AAAA-MM. Prend le pas sur `mois`.' example: 2026-01 required: false schema: type: string description: 'Premier mois de la courbe au format AAAA-MM. Prend le pas sur `mois`.' example: 2026-01 - in: query name: fin description: 'Dernier mois de la courbe au format AAAA-MM. Par défaut le mois courant.' example: 2026-08 required: false schema: type: string description: 'Dernier mois de la courbe au format AAAA-MM. Par défaut le mois courant.' example: 2026-08 responses: 200: description: succès content: application/json: schema: type: object example: cartes: commercantsActifs: valeur: 12 evolution: '+3 ce mois' positif: true contenu: articles: valeur: 2 inscriptions: - mois: Juil periode: 2026-07 commercants: 4 utilisateurs: 9 categories: - nom: Restauration total: 3 pourcentage: 25 abonnements: actifs: 2 encaisseMois: 55000 moderation: total: 0 elements: [] source: false properties: cartes: type: object properties: commercantsActifs: type: object properties: valeur: type: integer example: 12 evolution: type: string example: '+3 ce mois' positif: type: boolean example: true contenu: type: object properties: articles: type: object properties: valeur: type: integer example: 2 inscriptions: type: array example: - mois: Juil periode: 2026-07 commercants: 4 utilisateurs: 9 items: type: object properties: mois: type: string example: Juil periode: type: string example: 2026-07 commercants: type: integer example: 4 utilisateurs: type: integer example: 9 categories: type: array example: - nom: Restauration total: 3 pourcentage: 25 items: type: object properties: nom: type: string example: Restauration total: type: integer example: 3 pourcentage: type: integer example: 25 abonnements: type: object properties: actifs: type: integer example: 2 encaisseMois: type: integer example: 55000 moderation: type: object properties: total: type: integer example: 0 elements: type: array example: [] source: type: boolean example: false tags: - Administration security: [] /api/admin/carte: get: summary: 'Carte des commerces' operationId: carteDesCommerces description: "Renvoie les commerces géolocalisés, les catégories servant de filtres et\nles compteurs de tête. Un commerce sans coordonnées est compté mais pas\nrenvoyé dans la liste : il n'a rien à faire sur une carte." parameters: [] responses: 200: description: succès content: application/json: schema: type: object example: centre: - 5.33 - -4.02 zoom: 13 stats: total: 8 cartographies: 5 actifs: 8 inactifs: 0 sansCoordonnees: 3 categories: - id: 1 nom: Restauration couleur: 'oklch(0.68 0.12 65)' commerces: 2 commerces: - id: 4 nom: ete adresse: Cocody telephone: '0700000000' lat: 5.39 lng: -3.98 actif: true categories: - 1 couleur: 'oklch(0.68 0.12 65)' categoriePrincipale: Restauration categoriesNoms: - Restauration photo: null note: 4.3 avis: 12 abonnes: 48 likes: 130 articles: 9 dernierAvis: texte: 'Très bon accueil.' note: 5 date: '2026-07-28T10:12:00Z' auteur: 'Awa K.' properties: centre: type: array example: - 5.33 - -4.02 items: type: number zoom: type: integer example: 13 stats: type: object properties: total: type: integer example: 8 cartographies: type: integer example: 5 actifs: type: integer example: 8 inactifs: type: integer example: 0 sansCoordonnees: type: integer example: 3 categories: type: array example: - id: 1 nom: Restauration couleur: 'oklch(0.68 0.12 65)' commerces: 2 items: type: object properties: id: type: integer example: 1 nom: type: string example: Restauration couleur: type: string example: 'oklch(0.68 0.12 65)' commerces: type: integer example: 2 commerces: type: array example: - id: 4 nom: ete adresse: Cocody telephone: '0700000000' lat: 5.39 lng: -3.98 actif: true categories: - 1 couleur: 'oklch(0.68 0.12 65)' categoriePrincipale: Restauration categoriesNoms: - Restauration photo: null note: 4.3 avis: 12 abonnes: 48 likes: 130 articles: 9 dernierAvis: texte: 'Très bon accueil.' note: 5 date: '2026-07-28T10:12:00Z' auteur: 'Awa K.' items: type: object properties: id: type: integer example: 4 nom: type: string example: ete adresse: type: string example: Cocody telephone: type: string example: '0700000000' lat: type: number example: 5.39 lng: type: number example: -3.98 actif: type: boolean example: true categories: type: array example: - 1 items: type: integer couleur: type: string example: 'oklch(0.68 0.12 65)' categoriePrincipale: type: string example: Restauration categoriesNoms: type: array example: - Restauration items: type: string photo: type: string example: null nullable: true note: type: number example: 4.3 avis: type: integer example: 12 abonnes: type: integer example: 48 likes: type: integer example: 130 articles: type: integer example: 9 dernierAvis: type: object properties: texte: type: string example: 'Très bon accueil.' note: type: integer example: 5 date: type: string example: '2026-07-28T10:12:00Z' auteur: type: string example: 'Awa K.' tags: - Administration security: [] '/api/admin/commerces/{id}': get: summary: "Détail d'un commerce" operationId: dtailDunCommerce description: "Toutes les informations que la base contient sur un commerce : fiche,\npropriétaire, catégories, photos, horaires, réseaux, statistiques et\ndernières activités." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: 'Jeton absent.' properties: message: type: string example: 'Jeton absent.' 404: description: '' content: application/json: schema: type: object example: message: 'Commerce introuvable.' properties: message: type: string example: 'Commerce introuvable.' tags: - Administration security: [] parameters: - in: path name: id description: 'Identifiant du commerce.' example: 4 required: true schema: type: integer /api/admin/paiements: get: summary: 'Liste des paiements' operationId: listeDesPaiements description: "Tous les encaissements d'abonnement, avec le client, la formule et la\npériode couverte. Filtrable et paginé." parameters: - in: query name: recherche description: "Filtre sur le client, l'email ou la formule." example: Vigivot required: false schema: type: string description: "Filtre sur le client, l'email ou la formule." example: Vigivot - in: query name: statut description: "Filtre sur l'état du paiement." example: paye required: false schema: type: string description: "Filtre sur l'état du paiement." example: paye - in: query name: moyen description: 'Filtre sur le moyen de paiement.' example: wave required: false schema: type: string description: 'Filtre sur le moyen de paiement.' example: wave - in: query name: debut description: 'Date de début au format AAAA-MM-JJ.' example: '2026-07-01' required: false schema: type: string description: 'Date de début au format AAAA-MM-JJ.' example: '2026-07-01' - in: query name: fin description: 'Date de fin incluse au format AAAA-MM-JJ.' example: '2026-08-31' required: false schema: type: string description: 'Date de fin incluse au format AAAA-MM-JJ.' example: '2026-08-31' - in: query name: page description: 'Numéro de page, à partir de 1.' example: 1 required: false schema: type: integer description: 'Numéro de page, à partir de 1.' example: 1 - in: query name: parPage description: 'Lignes par page, 100 au maximum.' example: 20 required: false schema: type: integer description: 'Lignes par page, 100 au maximum.' example: 20 responses: 200: description: succès content: application/json: schema: type: object example: resume: nombre: 2 montant: 55000 devise: FCFA paiements: - id: … montant: 50000 client: 'Vigivot Eddy' formule: Prenium statut: paye pagination: page: 1 parPage: 20 total: 2 pages: 1 filtres: statuts: - paye moyens: - wave properties: resume: type: object properties: nombre: type: integer example: 2 montant: type: integer example: 55000 devise: type: string example: FCFA paiements: type: array example: - id: … montant: 50000 client: 'Vigivot Eddy' formule: Prenium statut: paye items: type: object properties: id: type: string example: … montant: type: integer example: 50000 client: type: string example: 'Vigivot Eddy' formule: type: string example: Prenium statut: type: string example: paye pagination: type: object properties: page: type: integer example: 1 parPage: type: integer example: 20 total: type: integer example: 2 pages: type: integer example: 1 filtres: type: object properties: statuts: type: array example: - paye items: type: string moyens: type: array example: - wave items: type: string tags: - Administration security: [] /api/admin/commercants: get: summary: 'Liste des commerçants' operationId: listeDesCommerants description: "Tous les commerces inscrits, avec leur responsable et leur état.\nIl n'y a pas de validation à faire : un commerce existe dès son\ninscription, l'administration peut seulement le bloquer." parameters: - in: query name: recherche description: "Filtre sur le commerce, le responsable ou l'email." example: ali required: false schema: type: string description: "Filtre sur le commerce, le responsable ou l'email." example: ali - in: query name: etat description: '`actif` ou `bloque`.' example: bloque required: false schema: type: string description: '`actif` ou `bloque`.' example: bloque - in: query name: page description: 'Numéro de page, à partir de 1.' example: 1 required: false schema: type: integer description: 'Numéro de page, à partir de 1.' example: 1 - in: query name: parPage description: 'Lignes par page, 100 au maximum.' example: 20 required: false schema: type: integer description: 'Lignes par page, 100 au maximum.' example: 20 responses: 200: description: succès content: application/json: schema: type: object example: resume: total: 8 actifs: 8 bloques: 0 commercants: - id: 5 nom: 'CHez Ali' actif: true pagination: page: 1 parPage: 20 total: 8 pages: 1 properties: resume: type: object properties: total: type: integer example: 8 actifs: type: integer example: 8 bloques: type: integer example: 0 commercants: type: array example: - id: 5 nom: 'CHez Ali' actif: true items: type: object properties: id: type: integer example: 5 nom: type: string example: 'CHez Ali' actif: type: boolean example: true pagination: type: object properties: page: type: integer example: 1 parPage: type: integer example: 20 total: type: integer example: 8 pages: type: integer example: 1 tags: - Administration security: [] '/api/admin/commerces/{id}/blocage': patch: summary: 'Bloquer ou débloquer un commerce' operationId: bloquerOuDbloquerUnCommerce description: "Bascule `is_active`. Un commerce bloqué disparaît de l'app mobile ;\naucune donnée n'est supprimée, l'opération est réversible." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: id: 5 nom: 'CHez Ali' actif: false message: 'Commerce bloqué.' properties: id: type: integer example: 5 nom: type: string example: 'CHez Ali' actif: type: boolean example: false message: type: string example: 'Commerce bloqué.' 404: description: '' content: application/json: schema: type: object example: message: 'Commerce introuvable.' properties: message: type: string example: 'Commerce introuvable.' tags: - Administration requestBody: required: true content: application/json: schema: type: object properties: bloque: type: boolean description: '`true` pour bloquer, `false` pour réactiver.' example: true required: - bloque security: [] parameters: - in: path name: id description: 'Identifiant du commerce.' example: 5 required: true schema: type: integer /api/sante: get: summary: "État de l'API\n\nVérifie que l'API Werise répond. Utile pour les sondes de disponibilité." operationId: tatDeLAPIVrifieQueLAPIWeriseRpondUtilePourLesSondesDeDisponibilit description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: statut: ok service: werise-api properties: statut: type: string example: ok service: type: string example: werise-api tags: - Système security: [] /api/user: get: summary: "Utilisateur connecté\n\nRetourne l'utilisateur associé au jeton Sanctum envoyé dans l'en-tête `Authorization`." operationId: utilisateurConnectRetourneLutilisateurAssociAuJetonSanctumEnvoyDansLenTteAuthorization description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Utilisateurs security: []