# Plan de mise en production — ALDANA / Kinetic Silence

> **Version** : v3 — révisée 2026-05-20 (ajout Jalon 0 : packs annuels multi-droits)
> **État actuel** : ~62 % livré (révision après analyse vitrine actuelle aldanayoga.com/tarifs)
> **Effort restant estimé** : 31-40 jours ouvrés
> **Date cible mise en prod** : 2026-07-22
> **Auteur** : R. Galofaro

---

## Sommaire

1. [Synthèse exécutive](#synthèse-exécutive)
2. [Périmètre déjà livré](#périmètre-déjà-livré)
3. [Périmètre restant — 11 jalons](#périmètre-restant)
4. [Calendrier 8 semaines](#calendrier-8-semaines)
5. [Risques et mitigations](#risques)
6. [Décisions à prendre](#décisions-à-prendre)
7. [Tarification](#tarification)

---

## Synthèse exécutive

Le site ALDANA / Kinetic Silence est à **~65 % de réalisation**. Les fondations PHP/MySQL, la vitrine publique (14 pages), l'espace membre, le backoffice admin (11 modules), l'upload médias et le thème Emerald sont opérationnels.

**Reste à livrer** :
- Reprise des données du système actuel (clients, forfaits, historique)
- Paiement Stripe end-to-end (checkout + webhook idempotent)
- Module facturation en cours (forfaits hérités, suspensions, avoirs)
- Exports comptabilité (FEC + Excel pour le cabinet)
- Emails transactionnels + facture PDF
- Reset password
- Conformité RGPD/CNIL (cookies, export, suppression)
- Audit sécurité final
- Recette fonctionnelle complète
- Déploiement Hostinger + bascule DNS

---

## Périmètre déjà livré

| Bloc | État | Détail |
|---|---|---|
| Fondations | 100 % | PSR-4, PDO singleton, sessions, CSRF, Argon2id, routing, .env |
| Base de données | 95 % | 18 migrations idempotentes, schéma users/classes/bookings/events/payments/forfaits |
| Vitrine publique | 90 % | 14 pages : home, planning, pratiques, tarifs, équipe, contact, mentions, RGPD, CGV |
| Espace membre | 85 % | Login, dashboard, profil, réservations, forfaits, factures |
| Backoffice admin P6 | 95 % | 11 modules CRUD + Clients/Paiements + Planning + Practices |
| Médias P7 | 100 % | Upload WebP, durcissement .htaccess |
| Thème Emerald | 80 % | 12 pages alternatives + bascule `?theme=emerald` |
| Réservation concurrence | 80 % | Transaction `FOR UPDATE`, décrément `spots_left` atomique |

---

## Périmètre restant

### JALON 0 — Packs annuels multi-droits (4-5 j) — NOUVEAU BLOQUANT

**Pourquoi en Jalon 0** : Stripe doit connaître la structure des packs avant le Jalon 1. Le modèle "carnet de séances" actuel ne représente pas les packs réels du studio (Bronze/Silver/Gold/Platinum + Entreprise — abonnements annuels multi-droits avec visio + master class + studio + retraite).

#### 0.1 Migration BDD + seed (0.5 j) — LIVRÉ

Fichiers créés :

- `database/migrations/024_create_plan_inclusions.sql` — extension `t_subscription_plans` (`duration_months`, `target_audience`, `requires_quote`, `tier_label`, `tier_color`, `bonus_count`) + nouvelle table `t_plan_inclusions` + `t_inclusion_usage` + seed 5 packs

#### 0.2 Repository + Service entitlement (1.5 j)

- `src/Repositories/PlanInclusionRepository.php` — `findByPlan`, `findByActivityType`
- `src/Repositories/InclusionUsageRepository.php` — `recordUsage`, `countForPeriod`
- `src/Services/SubscriptionEntitlementService.php` — `canBook(userId, classId)`, `consume(...)`, `getDashboard(userId)`

Logique métier : autoriser la réservation si `count(usage WHERE period_start = current_week_or_month) < quantity`.

#### 0.3 Admin form pack + inclusions (1 j)

- `src/Controllers/Admin/PlansController.php` — gestion création/édition pack avec N inclusions
- `views/pages/admin/plans/form.php` — ajout dynamique d'inclusions (JS vanilla `+/-` bouton)
- Aperçu live de la carte tarif générée

#### 0.4 Vitrine tarifs dynamique (0.5 j)

- `views/pages/emerald/tarifs.php` — refactor pour boucler sur `t_subscription_plans` actifs avec leurs inclusions (cf mockup `docs/mockup-tarifs-packs.html`)

#### 0.5 Dashboard espace membre — suivi consommation (0.5 j)

- `views/pages/account/dashboard.php` — pour chaque inclusion active : barre progression "0/1 cette semaine", "1.5/2.5h ce mois"

#### 0.6 Formulaire devis B2B Pack Entreprise (0.5 j)

- `src/Controllers/QuoteController.php` — `formEntreprise()`, `submit()`
- `views/pages/public/devis-entreprise.php` — formulaire RGPD-compliant
- Email admin + accusé client

#### 0.7 Tests (0.5 j)

- `tests/Feature/SubscriptionEntitlementTest.php` — quotas hebdo/mensuel/annuel, période ISO, edge cases (changement de semaine)

**Critères d'acceptation Jalon 0**

- Migration 024 idempotente exécutée en local et staging
- Les 5 packs apparaissent sur `/emerald/tarifs` avec leurs inclusions
- Admin peut créer/éditer/supprimer un pack et ses inclusions
- Un client qui a réservé sa visio du mardi ne peut plus réserver de visio cette semaine-là
- Le dashboard affiche les compteurs corrects par inclusion
- Pack Entreprise affiche "Sur devis" au lieu d'un bouton "Souscrire" et redirige vers le formulaire

**Impact Stripe (Jalon 1)** : les packs Bronze/Silver/Gold/Platinum seront vendus comme **Stripe Subscription annuelle** (renouvellement auto), pas en `checkout.session` simple. Le webhook écoute `customer.subscription.created`, `invoice.paid`, `customer.subscription.deleted`.

---

### JALON A — Reprise de l'existant (4-6 j) — BLOQUANT

#### A.1 Audit source de données (1 j)

Identifier le système source (Excel, Google Sheets, Yoplanning, Bsport, Mindbody, autre SaaS) et le mapping colonne-à-colonne ancien → nouveau schéma.

**Livrable** : `docs/audit-donnees-existant.md`

#### A.2 Scripts d'import idempotents (2-3 j)

Fichiers à créer :
- `database/imports/01_import_clients.php`
- `database/imports/02_import_subscriptions.php`
- `database/imports/03_import_bookings_history.php`
- `database/imports/04_import_payments_history.php`
- `database/migrations/020_add_legacy_id.sql`

Règles critiques :
- Idempotence absolue (clé sur `legacy_id`)
- Dry-run obligatoire (flag `--dry-run`)
- Rapport détaillé JSON (succès / skip / erreurs)
- Sauvegarde BDD avant import

#### A.3 Email de bascule clients (0.5 j)

- `views/emails/migration-welcome.php` — email personnalisé avec crédits restants
- `src/Console/SendMigrationEmails.php` — batch CLI étalé

#### A.4 Validation client (0.5 j)

- 10 clients témoins validés manuellement
- Go/No-go formel client par email

---

### JALON B — Facturation en cours (2-3 j) — IMPORTANT

#### B.1 Gestion forfaits multi-statuts (1 j)

- `database/migrations/021_alter_subscriptions_status.sql` — ENUM enrichi : `active|expired|suspended|imported|refunded`
- Méthodes repository : `getActiveForUser`, `decrementCredits`, `suspend`, `refund`

#### B.2 Admin gestion forfaits clients (1 j)

Actions dans `src/Controllers/Admin/ClientsController.php` :
- Suspendre forfait (congés, blessure)
- Réactiver forfait suspendu
- Ajuster crédits manuellement avec motif obligatoire + log
- Rembourser forfait avec génération d'avoir comptable
- Prolonger date d'expiration (cas COVID, fermeture studio)

#### B.3 Notifications automatiques (0.5 j)

CRON quotidien `src/Console/Cron/CheckExpiringSubscriptions.php` :
- J-15 : email "forfait expire bientôt"
- J-1 : email rappel
- J+0 : statut `expired` automatique
- Crédits faibles (≤ 2) : email proactif

---

### JALON C — Exports comptabilité (2-3 j) — LÉGAL

#### C.1 Export FEC (1 j)

Format normalisé 18 colonnes, séparateur `|`, encodage `UTF-8`. Obligation article A. 47 A-1 du LPF.

- `src/Services/AccountingExportService.php`
- `src/Controllers/Admin/AccountingController.php`
- `views/pages/admin/accounting/index.php`

Plan comptable à valider avec l'expert-comptable :
- `7061` — Prestations de services (cours)
- `7062` — Vente de marchandises (tapis, accessoires)
- `4111` — Clients
- `512` — Banque
- `707` — Vente forfaits

#### C.2 Exports CSV/Excel (1 j)

Excel `.xlsx` via `phpoffice/phpspreadsheet` avec onglets :
- Ventes (forfaits + événements)
- Clients actifs
- Avoirs / remboursements
- Récap TVA (si assujetti)

#### C.3 Numérotation factures conforme (0.5 j)

- `database/migrations/022_create_invoice_sequence.sql`
- `src/Services/InvoiceService.php::nextInvoiceNumber()` avec `SELECT ... FOR UPDATE`
- Format `2026-0001`, `2026-0002`, …
- Avoirs avec préfixe `A-2026-0001`

---

### JALON 1 — Paiement Stripe end-to-end (5-7 j) — BLOQUANT

#### 1.1 Stripe Checkout (2 j)

Fichiers à créer :
- `src/Controllers/CheckoutController.php`
- `src/Services/StripeService.php`
- `views/pages/account/checkout-success.php`
- `views/pages/account/checkout-cancel.php`

Routes : `POST /checkout/forfait/{plan_ID}`, `GET /checkout/success`, `GET /checkout/cancel`

Activation forfait **uniquement après webhook** (jamais sur retour `success`).

#### 1.2 Webhook + idempotence (2 j)

- `src/Controllers/WebhookController.php` — vérif signature `Stripe-Signature`
- `src/Repositories/ProcessedWebhookRepository.php` — `exists($event_id)`, `markProcessed(...)`
- Transaction SQL : INSERT payment + subscription + processed_webhook

#### 1.3 Stripe événement à l'unité (1-2 j)

Visiteur non-abonné peut payer un événement ponctuel sans forfait.

#### 1.4 Tests Stripe (1 j)

- `tests/Feature/StripeWebhookTest.php`
- `tests/Feature/CheckoutFlowTest.php`

---

### JALON 2 — Emails transactionnels + facture PDF (2-3 j)

#### 2.1 Templates emails (1 j)

- `views/emails/booking-confirmation.php`
- `views/emails/booking-cancellation.php`
- `views/emails/booking-reminder.php` (CRON J-1)
- `views/emails/subscription-activated.php`
- `views/emails/password-reset.php`
- `views/emails/welcome.php`
- `views/emails/layout.php`

#### 2.2 Facture PDF (1-2 j)

- Composer : `dompdf/dompdf`
- `src/Services/InvoiceService.php::generate($payment_ID)`
- `views/invoices/template.php`

---

### JALON 3 — Reset password (1 j)

- `src/Controllers/PasswordResetController.php`
- `views/pages/auth/password-forgot.php`
- `views/pages/auth/password-reset.php`
- `database/migrations/019_create_password_resets.sql` — token hashé, expiration 1h

Critères : usage unique, pas de fuite "email inconnu", Argon2id sur le nouveau mot de passe.

---

### JALON 4 — RGPD / CNIL (2 j) — LÉGAL

#### 4.1 Bandeau cookies (0.5 j)

- `public/assets/js/cookie-consent.js`
- `public/assets/css/cookie-consent.css`
- `src/Controllers/CookieConsentController.php`

#### 4.2 Export + suppression compte (1 j)

- `src/Services/GdprService.php::exportUserData($user_ID)` → JSON complet
- `AccountController::deleteAccount()` — soft-delete + anonymisation
- Conservation `t_payments` 10 ans (obligation comptable)

#### 4.3 Documents légaux (0.5 j)

Mise à jour finale :
- `views/pages/public/mentions-legales.php`
- `views/pages/public/politique-de-confidentialite.php`
- `views/pages/public/rgpd.php`
- `views/pages/public/cgv.php`

Livrable Word `.docx` : registre des traitements via `phpoffice/phpword`.

---

### JALON 5 — Audit sécurité (1 j) — BLOQUANT

**Agent** : `securite-php`

Périmètre :
- `src/Controllers/AuthController.php`
- `src/Controllers/WebhookController.php` (signature Stripe, idempotence)
- `src/Controllers/BookingController.php` (concurrence, IDOR)
- `src/Controllers/CheckoutController.php` (montant côté serveur)
- `src/Services/ImageUploadService.php` (MIME, taille, double extension)
- `src/Middleware/CsrfMiddleware.php`
- `public/.htaccess` + `public/uploads/.htaccess`

**Livrable** : `docs/audit-securite-2026-06.md`

---

### JALON 6 — Recette fonctionnelle (2-3 j)

Environnement staging sur sous-domaine Hostinger.

**Parcours à valider** (`docs/recette-2026-06.md`) :

1. Visiteur → client payant : inscription, achat forfait Stripe test, réservation, annulation > 24h, annulation < 24h bloquée
2. Admin studio : création cours, attribution prof/salle, planning, attribution forfait manuel, listing paiements, upload photos
3. Concurrence : 2 navigateurs sur la dernière place → 1 OK, 1 KO propre
4. Edge cases : webhook rejoué 3× = 1 activation, reset expiré, email inexistant en reset

---

### JALON 7 — Déploiement Hostinger (2-3 j) — BLOQUANT

**Agent** : `deploiement-mutualise`

#### 7.1 Préparation Hostinger (0.5 j)
- Domaine + DNS
- SSL Let's Encrypt
- BDD MySQL prod

#### 7.2 Migration BDD prod (0.5 j)
- Exécuter migrations 001 → 022 dans l'ordre
- Seed initial `013_seed_initial_data.sql`
- Création super-admin manuelle (Argon2id)

#### 7.3 Upload code + config (0.5 j)
- SFTP `public/` → `public_html/`
- SFTP reste hors `public_html/` (`src/`, `vendor/`, `config/`, `storage/`)
- `.env.production` avec clés Stripe **live**
- Permissions : `storage/` 755, `.env` 600

#### 7.4 Stripe live (0.5 j)
- Bascule compte Stripe live
- Webhook prod : `https://kinetic-silence.fr/webhook/stripe`
- Test paiement réel 1 € puis remboursement

#### 7.5 Vérifications post-déploiement (0.5 j)
- Lighthouse : perf > 85, accessibilité > 90, SEO > 90
- Headers sécurité (X-Frame-Options, CSP, HSTS)
- Sitemap.xml + robots.txt
- Sauvegarde BDD quotidienne (CRON Hostinger)

---

### JALON 8 — Lancement (0.5 j)

- Bascule DNS production
- Vérif SSL A+
- Annonce client + mode d'emploi admin (PDF 5-10 pages)
- Warranty 30 j : monitoring quotidien

---

## Calendrier 9 semaines (v3)

| Semaine | Période | Jalons | Charge |
|---|---|---|---|
| **S1** | 20-26 mai | J0 packs multi-droits (migration + repo + service entitlement) + A.1 audit données + démarrer KYC Stripe + brief client | 5 j |
| **S2** | 27 mai - 2 juin | J0 admin pack + vitrine tarifs dynamique + dashboard + devis B2B + A.2 scripts import | 5 j |
| **S3** | 3-9 juin | A.2 fin scripts import + démarrer Stripe checkout (J1) | 5 j |
| **S4** | 10-16 juin | J1 fin Stripe + webhook + idempotence (incluant Stripe Subscription annuelle pour packs) | 5 j |
| **S5** | 17-23 juin | J2 emails + facture PDF + C.3 numérotation factures + J3 reset | 5 j |
| **S6** | 24-30 juin | B forfaits hérités + C exports FEC/Excel | 3 j |
| **S7** | 1-7 juillet | J4 RGPD + J5 audit sécurité | 3 j |
| **S8** | 8-14 juillet | A.3 emails migration + J6 recette complète | 5 j |
| **S9** | 15-22 juillet | J7 déploiement Hostinger + J8 lancement | 3 j |
| | **Total** | | **39 j** |

---

## Risques

| Risque | Probabilité | Mitigation |
|---|---|---|
| Validation Stripe live (KYC) en retard | Moyenne | Démarrer dossier S1 |
| Source données illisible | **Haute** | Audit S1 obligatoire, +2 j nettoyage |
| Doublons clients ancien système | Moyenne | Dédoublonnage email + flag manuel |
| Crédits restants contestés | Moyenne | `legacy_id` + snapshot CSV archivé |
| Bascule DNS pendant cours actif | Faible | Bascule mardi 6h |
| Comptable refuse le FEC | Moyenne | Valider export test mai/juin avant prod |
| Email migration en spam | Haute | SPF/DKIM/DMARC + warm-up SMTP |
| Contenu rédactionnel client manquant | **Haute** | Demander textes définitifs dès S1 |
| Photos vraies salles/profs absentes | Haute | Briefer client S2 max |
| Migrations idempotentes oubliées | Faible | Convention `IF NOT EXISTS` + agent `bdd-mysql` |

---

## Décisions à prendre

Voir `docs/questionnaire-client.md` pour le détail à valider avec le studio.

Décisions stratégiques :
1. Nom de domaine définitif
2. Compte Stripe (KYC à lancer S1)
3. Hébergeur définitif
4. Système source actuel
5. Volume exact (clients, forfaits actifs, historique)
6. Expert-comptable et format d'export préféré
7. Régime TVA
8. Numérotation facture (reprise ou nouveau départ)
9. Email transactionnel (SMTP Hostinger ou Brevo/Mailgun)

---

## Tarification

**Forfait global avec reprise existant** : **22 000 – 33 000 € HT**

Découpage paiement suggéré :
- 30 % à la commande (signature)
- 25 % à la livraison Jalon 1 (Stripe opérationnel)
- 25 % à la recette espace membre + reprise données validée
- 20 % à la mise en prod

Maintenance évolutive : **80-120 €/mois** ou **TJM 500 €** à la demande.

---

## Annexes

- `docs/audit-donnees-existant.md` — audit source de données client
- `docs/questionnaire-client.md` — questionnaire pré-projet
- `docs/audit-securite-2026-06.md` — rapport audit sécurité (à produire J5)
- `docs/recette-2026-06.md` — script de recette (à produire J6)
