# Fecly API — backend PHP / MySQL pour hébergement OVH mutualisé

API REST avec comptes réels par cabinet : chaque compte se connecte, gère
ses propres dossiers, dépose un relevé bancaire (texte libre, analysé par
l'API Claude, ou déjà structuré) et reçoit un export FEC (18 colonnes,
séparateur `|`), enregistré dans son historique.

Important : cet export **n'est pas un FEC officiel** au sens réglementaire
(article A47 A-1 du LPF) — le nom de fichier n'est notamment pas basé sur la
date de clôture d'exercice. C'est un export qui reprend la structure FEC afin
d'être importable dans n'importe quel logiciel de comptabilité.

Cette API est conçue pour être appelée directement depuis l'espace client
Fecly (page publique publiée via Claude) : voir "Brancher l'espace client"
plus bas.

## Prérequis

- Hébergement OVH mutualisé (Perso / Pro / Performance) — pas besoin de VPS
- PHP 8.1 ou supérieur (réglable dans le Manager OVH, onglet "Multisite" /
  "Configurer")
- Extensions PHP `curl` et `pdo_mysql` — activées par défaut chez OVH
- Une base de données MySQL / MariaDB créée depuis le Manager OVH

Aucune dépendance Composer : tout est en PHP natif pour rester simple à
déployer sur du mutualisé.

## Arborescence et placement des fichiers — point important

Sur un hébergement mutualisé OVH, **seul le dossier `www/` est accessible
depuis le web**. Tout le reste de votre espace (à la racine du compte
d'hébergement) ne l'est pas. Il faut donc déployer ainsi :

```
/ (racine de votre hébergement OVH, ex. via FTP/SFTP)
├── app/            ← classes PHP (NE PAS mettre dans www/)
├── sql/             ← schema.sql (NE PAS mettre dans www/)
├── .env             ← vos identifiants et clés (NE PAS mettre dans www/)
└── www/             ← seul dossier exposé publiquement
    ├── index.php
    └── .htaccess
```

En clair : uploadez `app/`, `sql/` et `.env` **à côté de** `www/`, pas
dedans. `www/index.php` les charge via des chemins relatifs
(`__DIR__ . '/../app/...'`), donc si votre `www/` correspond au dossier
racine web de votre offre OVH, ce schéma fonctionne tel quel.

## Étapes de déploiement — cas concret pour fecly.fr

Ce paquet est prêconfiguré pour être servi sur un sous-domaine dédié
**`api.fecly.fr`** (c'est la valeur déjà écrite dans `login.html`,
`signup.html` et `espace.html` : `API_BASE = "https://api.fecly.fr"`).
Un sous-domaine dédié à l'API, plutôt qu'un sous-dossier de `fecly.fr`,
évite tout conflit avec le site principal que vous déploierez peut-être
plus tard sur `fecly.fr` lui-même.

1. **Créer la base de données** : Manager OVH → Hébergements → votre offre →
   "Bases de données" → créer une base MySQL. Notez l'hôte, le nom de base,
   l'utilisateur et le mot de passe fournis.

2. **Importer le schéma** : ouvrez phpMyAdmin depuis le Manager OVH, allez
   dans l'onglet SQL de votre base, et exécutez le contenu de
   `sql/schema.sql` (quatre tables : `users`, `sessions`, `dossiers` et
   `exports`).

3. **Envoyer les fichiers par FTP** : connectez-vous avec votre client FTP
   (identifiants dans Manager OVH → Hébergements → FTP-SSH), placez-vous à
   la racine de votre espace d'hébergement, et déposez le dossier
   `fecly-api` tel quel (avec `app/`, `www/`, `sql/` et `.env` — voir étape
   4 — à l'intérieur). Vous obtenez par exemple :
   ```
   /fecly-api/app/...
   /fecly-api/www/index.php
   /fecly-api/www/.htaccess
   /fecly-api/sql/schema.sql
   /fecly-api/.env
   ```
   Seul `/fecly-api/www` sera exposé sur le web (étape 5) : `app/`, `sql/`
   et `.env` restent hors d'atteinte du navigateur.

4. **Configurer `.env`** : renommez `.env.example` en `.env` (il doit rester
   dans `fecly-api/`, au même niveau que `www/`), et renseignez :
   - `ANTHROPIC_API_KEY` — à générer sur https://console.anthropic.com/settings/keys
   - `DB_HOST`, `DB_NAME`, `DB_USER`, `DB_PASS` — fournis par OVH à l'étape 1
   - `CORS_ALLOW_ORIGIN` — laissez `*` (l'authentification se fait par jeton
     Bearer, pas par cookies, donc pas de risque CSRF)

5. **Créer le sous-domaine `api.fecly.fr`** : Manager OVH → votre domaine
   `fecly.fr` → "Multisite" (ou "Sous-domaines" selon l'interface) → "Créer
   un sous-domaine" → nom `api`, domaine `fecly.fr`. OVH vous demande le
   dossier à servir pour ce sous-domaine : indiquez `fecly-api/www` (le
   chemin relatif à la racine FTP où vous avez déposé les fichiers à
   l'étape 3). Le certificat HTTPS pour `api.fecly.fr` est généralement
   généré automatiquement par OVH après quelques minutes.

6. **Tester** : voir les exemples `curl` ci-dessous, en remplaçant
   `$API` par `https://api.fecly.fr`.

Si vous préférez finalement une autre organisation (un sous-dossier
`fecly.fr/api` plutôt qu'un sous-domaine, par exemple), c'est possible mais
demande d'adapter le routage Apache en conséquence — dans ce cas, changez
aussi la valeur d'`API_BASE` dans les trois pages web pour qu'elle
corresponde exactement à l'URL que vous choisissez.

## Brancher l'espace client (la page publique)

Les trois pages web du site (accueil, connexion, inscription, espace
client) sont publiées séparément via Claude. `login.html` et `signup.html`
appellent désormais réellement cette API (`/auth/login`, `/auth/register`)
et stockent le jeton reçu dans le `localStorage` du navigateur ;
`espace.html` l'utilise ensuite pour tous les appels (dossiers, import,
export, historique, téléchargement).

Dans chacun de ces trois fichiers, une constante en haut du `<script>`
pointe déjà vers `https://api.fecly.fr` :

```js
var API_BASE = "https://api.fecly.fr";
```

Si vous changez d'avis sur l'organisation de votre hébergement (autre
sous-domaine, sous-dossier de `fecly.fr`…), mettez cette constante à jour
dans les trois fichiers pour qu'elle corresponde exactement à l'URL où
pointe le dossier `www/` de `fecly-api` une fois déployé.

Un visiteur qui ouvre l'espace client sans être connecté (lien partagé
directement, sans passer par la page de connexion) reste dans un mode de
démonstration local, inchangé : ses dossiers ne sont pas sauvegardés sur
votre serveur. Dès qu'un compte réel est utilisé via les pages de connexion
ou d'inscription, l'espace client bascule automatiquement sur cette API.

## Sécurité

- La clé Anthropic (`ANTHROPIC_API_KEY`) ne quitte jamais le serveur : elle
  n'est utilisée que côté PHP, jamais envoyée au navigateur.
- Chaque compte a son propre mot de passe haché (`password_hash`, algorithme
  par défaut de PHP) et ses propres dossiers : un utilisateur ne peut ni
  lister, ni lire, ni modifier les dossiers ou exports d'un autre compte
  (toutes les requêtes sont filtrées par `user_id` côté serveur).
- L'authentification se fait par jeton de session opaque, envoyé dans
  l'en-tête `Authorization: Bearer <token>`, stocké haché (SHA-256) en base
  et expirant après 30 jours. Un jeton compromis peut être révoqué en
  vidant la table `sessions` pour l'utilisateur concerné.
- En cas d'erreur serveur, le détail est écrit dans les logs PHP
  (`error_log`) mais jamais renvoyé au client — seul un message générique
  est retourné, pour ne pas exposer de détails d'implémentation.
- Ne committez jamais `.env` dans un dépôt Git. `.env.example` est fourni à
  la place, sans valeurs réelles.

## Endpoints

`/auth/register` et `/auth/login` sont publics. Tous les autres endpoints
nécessitent l'en-tête : `Authorization: Bearer <token>` (obtenu via l'un de
ces deux endpoints).

### Créer un compte
```
POST /auth/register
Content-Type: application/json

{
  "prenom": "Camille",
  "nom": "Durand",
  "nom_entreprise": "Durand Conseil SARL",
  "email": "camille@cabinet.fr",
  "password": "un mot de passe d'au moins 8 caractères"
}
```
Réponse (201) : `{ "token": "...", "user": { ... } }`

### Se connecter
```
POST /auth/login
Content-Type: application/json

{ "email": "camille@cabinet.fr", "password": "..." }
```
Réponse (200) : `{ "token": "...", "user": { ... } }`

### Se déconnecter / profil courant
```
POST /auth/logout
GET  /auth/me
```

### Lister les dossiers du compte connecté
```
GET /dossiers
```

### Créer un dossier
```
POST /dossiers
Content-Type: application/json

{
  "nom": "Boulangerie Martin",
  "siren": "552100554"
}
```
Les paramètres FEC (comptes, journal…) sont optionnels à la création : des
valeurs par défaut sont utilisées, modifiables ensuite via `PUT`.

### Récupérer / modifier / supprimer un dossier
```
GET    /dossiers/{id}
PUT    /dossiers/{id}
DELETE /dossiers/{id}
```
Le `PUT` accepte n'importe quel sous-ensemble de : `nom`, `date_cloture`,
`journal_code`, `journal_lib`, `compte_banque`, `compte_banque_lib`,
`compte_contrepartie_credit`, `compte_contrepartie_credit_lib`,
`compte_contrepartie_debit`, `compte_contrepartie_debit_lib`.

### Extraire les transactions d'un relevé (sans enregistrer d'export)
```
POST /dossiers/{id}/extract
Content-Type: application/json

{ "statement_text": "01/03  VIR CLIENT DUPONT           +1250,00\n03/03  PRLV EDF                    -84,30\n..." }
```
Envoie le texte à l'API Claude pour extraction et renvoie la liste des
transactions détectées, sans générer ni sauvegarder de FEC — utile pour
laisser l'utilisateur relire/corriger avant de confirmer via
`POST /dossiers/{id}/exports`. Réponse :
```json
{ "transactions": [{ "date": "2026-03-01", "libelle": "VIR CLIENT DUPONT", "debit": 0, "credit": 1250 }] }
```

### Générer et enregistrer un export FEC à partir de transactions connues
```
POST /dossiers/{id}/exports
Content-Type: application/json

{
  "transactions": [
    { "date": "2026-03-01", "libelle": "VIR CLIENT DUPONT", "debit": 0, "credit": 1250, "compte_contrepartie": "706000" }
  ]
}
```
`compte_contrepartie` est optionnel ligne par ligne : à défaut, le compte de
contrepartie par défaut du dossier (selon le sens de l'opération) est
utilisé. Réponse (201) :
```json
{
  "export": {
    "id": 12,
    "file_name": "552100554_FEC_20260902.txt",
    "line_count": 4,
    "transaction_count": 2,
    "content": "JournalCode|JournalLib|EcritureNum|...\r\n..."
  }
}
```

### Déposer un relevé et recevoir directement un export FEC (extraction + génération en un appel)
```
POST /dossiers/{id}/convert
Content-Type: application/json

{ "statement_text": "01/03  VIR CLIENT DUPONT           +1250,00\n..." }
```
Équivalent à enchaîner `/extract` puis `/exports` sans étape de relecture
intermédiaire. Même forme de réponse que `/exports`.

### Historique des exports d'un dossier
```
GET /dossiers/{id}/exports
```

### Télécharger un export généré précédemment
```
GET /dossiers/{id}/exports/{exportId}/download
```
Renvoie le fichier en `text/plain` avec les en-têtes de téléchargement
appropriés (nom de fichier `SIREN_FEC_dateexport.txt`).

## Exemples curl

```bash
API=https://api.fecly.fr

# Créer un compte et récupérer un jeton
TOKEN=$(curl -s -X POST "$API/auth/register" -H "Content-Type: application/json" \
  -d '{"prenom":"Camille","nom":"Durand","nom_entreprise":"Durand Conseil SARL","email":"camille@cabinet.fr","password":"motdepasse123"}' \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

# Créer un dossier
curl -s -X POST "$API/dossiers" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"nom":"Boulangerie Martin","siren":"552100554"}'

# Déposer un relevé et récupérer le FEC (extraction + génération directe)
curl -s -X POST "$API/dossiers/1/convert" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"statement_text":"01/03 VIR CLIENT DUPONT +1250,00\n03/03 PRLV EDF -84,30"}'

# Télécharger un export
curl -s "$API/dossiers/1/exports/1/download" -H "Authorization: Bearer $TOKEN" -o export.txt
```

## Coûts

L'appel à l'API Claude est facturé par Anthropic à l'usage (tokens en
entrée/sortie), indépendamment de votre hébergement OVH. Le modèle par
défaut (`claude-haiku-4-5-20251001`) est le plus économique de la gamme
actuelle ; changez `ANTHROPIC_MODEL` dans `.env` si vous avez besoin de plus
de précision sur des relevés difficiles à lire.

## Pistes d'évolution

- Plusieurs collaborateurs par cabinet partageant les mêmes dossiers (table
  `users` actuellement = un compte = un cabinet).
- Réinitialisation de mot de passe par e-mail (le lien "Mot de passe
  oublié ?" de la page de connexion n'est pas encore relié).
- Dépôt direct de fichiers PDF/CSV plutôt que de texte collé (nécessiterait
  une extraction de texte côté serveur avant l'appel à l'API Claude).
- Limitation du nombre d'inscriptions / appels IA par compte, pour se
  prémunir d'un usage abusif.
