@fraza/core 0.3.7 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +4 -0
  3. package/THIRD-PARTY-NOTICES.md +2 -2
  4. package/changelog.json +61 -0
  5. package/dist/docs/00-decouverte/01-qu-est-ce-que-fraza.md +1 -1
  6. package/dist/docs/01-demarrage/01-installation.md +9 -15
  7. package/dist/docs/01-demarrage/02-tour-du-proprietaire.md +1 -1
  8. package/dist/docs/01-demarrage/03-configuration.md +1 -1
  9. package/dist/docs/02-guides/accepter-des-paiements.md +1 -1
  10. package/dist/docs/02-guides/basculer-sur-le-registre-de-secours.md +3 -3
  11. package/dist/docs/02-guides/blocs-personnalises.md +1 -1
  12. package/dist/docs/02-guides/gerer-les-medias.md +1 -1
  13. package/dist/docs/02-guides/index.md +1 -1
  14. package/dist/docs/02-guides/seo-et-metadonnees.md +1 -1
  15. package/dist/docs/03-reference/01-cores/templates.md +3 -3
  16. package/dist/docs/03-reference/03-registres/media-registry.md +4 -4
  17. package/dist/docs/03-reference/05-cli/fraza-key.md +1 -1
  18. package/dist/docs/03-reference/06-configuration/paquets-supportes.md +1 -1
  19. package/dist/docs/03-reference/06-configuration/variables-d-environnement.md +2 -2
  20. package/dist/docs/04-architecture/02-frontieres-serveur-client.md +1 -1
  21. package/dist/docs/04-architecture/05-securite.md +1 -1
  22. package/dist/docs/04-architecture/07-licence-et-propriete.md +1 -1
  23. package/dist/docs/05-contribution/03-redaction.md +10 -0
  24. package/dist/docs/05-contribution/05-publication.md +0 -1
  25. package/dist/docs/06-modules/booking/{installation.md → 01-installation.md} +35 -20
  26. package/dist/docs/06-modules/booking/{configuration.md → 02-configuration.md} +5 -5
  27. package/dist/docs/06-modules/booking/{admin.md → 03-admin.md} +3 -3
  28. package/dist/docs/06-modules/booking/{reservation-en-ligne.md → 04-reservation-en-ligne.md} +2 -2
  29. package/dist/docs/06-modules/booking/{courriels.md → 05-courriels.md} +2 -2
  30. package/dist/docs/06-modules/booking/{modele-de-donnees.md → 06-modele-de-donnees.md} +1 -1
  31. package/dist/docs/06-modules/booking/{api.md → 07-api.md} +2 -2
  32. package/dist/docs/06-modules/booking/index.md +22 -12
  33. package/dist/docs/06-modules/drive/01-installation.md +92 -0
  34. package/dist/docs/06-modules/drive/{configuration.md → 02-configuration.md} +5 -5
  35. package/dist/docs/06-modules/drive/{admin.md → 03-admin.md} +8 -8
  36. package/dist/docs/06-modules/drive/{partages.md → 04-partages.md} +5 -5
  37. package/dist/docs/06-modules/drive/{fichiers.md → 05-fichiers.md} +4 -4
  38. package/dist/docs/06-modules/drive/{modele-de-donnees.md → 06-modele-de-donnees.md} +2 -2
  39. package/dist/docs/06-modules/drive/{api.md → 07-api.md} +5 -5
  40. package/dist/docs/06-modules/drive/index.md +22 -12
  41. package/dist/docs/06-modules/facturation/{installation.md → 01-installation.md} +61 -39
  42. package/dist/docs/06-modules/facturation/{configuration.md → 02-configuration.md} +5 -5
  43. package/dist/docs/06-modules/facturation/{facturation.md → 03-facturation.md} +4 -4
  44. package/dist/docs/06-modules/facturation/{taxes.md → 04-taxes.md} +2 -2
  45. package/dist/docs/06-modules/facturation/{paiements.md → 05-paiements.md} +3 -3
  46. package/dist/docs/06-modules/facturation/{recurrences-et-rappels.md → 06-recurrences-et-rappels.md} +4 -4
  47. package/dist/docs/06-modules/facturation/{courriels.md → 07-courriels.md} +5 -5
  48. package/dist/docs/06-modules/facturation/{modele-de-donnees.md → 08-modele-de-donnees.md} +2 -2
  49. package/dist/docs/06-modules/facturation/{api.md → 09-api.md} +3 -3
  50. package/dist/docs/06-modules/facturation/index.md +26 -16
  51. package/dist/docs/06-modules/forms/{installation.md → 01-installation.md} +25 -30
  52. package/dist/docs/06-modules/forms/{configuration.md → 02-configuration.md} +4 -4
  53. package/dist/docs/06-modules/forms/{champs.md → 03-champs.md} +4 -4
  54. package/dist/docs/06-modules/forms/{admin.md → 04-admin.md} +9 -9
  55. package/dist/docs/06-modules/forms/{soumissions.md → 05-soumissions.md} +7 -7
  56. package/dist/docs/06-modules/forms/{affichage.md → 06-affichage.md} +3 -3
  57. package/dist/docs/06-modules/forms/{modele-de-donnees.md → 07-modele-de-donnees.md} +3 -3
  58. package/dist/docs/06-modules/forms/{api.md → 08-api.md} +4 -4
  59. package/dist/docs/06-modules/forms/index.md +26 -14
  60. package/dist/docs/06-modules/index.md +2 -2
  61. package/dist/docs/06-modules/medias/{installation.md → 01-installation.md} +33 -36
  62. package/dist/docs/06-modules/medias/{configuration.md → 02-configuration.md} +5 -5
  63. package/dist/docs/06-modules/medias/{televersement.md → 03-televersement.md} +4 -4
  64. package/dist/docs/06-modules/medias/{admin.md → 04-admin.md} +7 -7
  65. package/dist/docs/06-modules/medias/{modele-de-donnees.md → 06-modele-de-donnees.md} +4 -4
  66. package/dist/docs/06-modules/medias/{api.md → 07-api.md} +6 -6
  67. package/dist/docs/06-modules/medias/index.md +25 -13
  68. package/dist/docs/06-modules/pages/{installation.md → 01-installation.md} +15 -17
  69. package/dist/docs/06-modules/pages/{configuration.md → 02-configuration.md} +1 -1
  70. package/dist/docs/06-modules/pages/{admin.md → 03-admin.md} +6 -6
  71. package/dist/docs/06-modules/pages/{modele-de-donnees.md → 04-modele-de-donnees.md} +2 -2
  72. package/dist/docs/06-modules/pages/{templates.md → 05-templates.md} +1 -1
  73. package/dist/docs/06-modules/pages/{api.md → 06-api.md} +2 -2
  74. package/dist/docs/06-modules/pages/index.md +21 -9
  75. package/dist/docs/06-modules/posts/{installation.md → 01-installation.md} +28 -34
  76. package/dist/docs/06-modules/posts/{configuration.md → 02-configuration.md} +6 -6
  77. package/dist/docs/06-modules/posts/{types-et-champs.md → 03-types-et-champs.md} +11 -11
  78. package/dist/docs/06-modules/posts/{taxonomies-et-relations.md → 04-taxonomies-et-relations.md} +5 -5
  79. package/dist/docs/06-modules/posts/{admin.md → 05-admin.md} +13 -13
  80. package/dist/docs/06-modules/posts/{modele-de-donnees.md → 06-modele-de-donnees.md} +3 -3
  81. package/dist/docs/06-modules/posts/{templates.md → 07-templates.md} +2 -2
  82. package/dist/docs/06-modules/posts/{api.md → 08-api.md} +3 -3
  83. package/dist/docs/06-modules/posts/index.md +25 -13
  84. package/dist/shared/lib/version.js +1 -1
  85. package/package.json +1 -1
  86. package/supported.json +1 -1
  87. package/dist/docs/06-modules/drive/installation.md +0 -69
  88. /package/dist/docs/06-modules/medias/{integration.md → 05-integration.md} +0 -0
@@ -1,53 +1,52 @@
1
1
  ---
2
2
  title: Installation
3
- description: Installer le module de facturation, créer les tables et déclarer le webhook Stripe.
3
+ description: Installer le module de facturation, créer les tables, renseigner l'émetteur et déclarer le webhook Stripe.
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/configuration
8
- - 06-modules/facturation/paiements
7
+ - 06-modules/facturation/02-configuration
8
+ - 06-modules/facturation/05-paiements
9
9
  ---
10
10
 
11
- Ce module est distribué sous la licence Fraza Pro : son utilisation en production demande une licence par projet, renouvelée chaque année, qui comprend les mises à jour, la conformité et le support. Voir [Licence et propriété](../../04-architecture/07-licence-et-propriete.md).
11
+ Cette page installe `@fraza-pro/module-billing` dans un projet créé par `npx @fraza/start`. Le module n'est jamais déclaré à la main : il est découvert au boot par scan des dépendances, comme décrit dans [Cycle de vie d'un module](../../02-guides/cycle-de-vie-d-un-module.md). Son utilisation en production demande une licence Fraza Pro : voir [Licence et propriété](../../04-architecture/07-licence-et-propriete.md).
12
12
 
13
- ## Installer
13
+ ## Prérequis
14
+
15
+ - Un projet créé par `npx @fraza/start`, avec `@fraza/core` à jour.
16
+ - Le token du registre Fraza dans le `.npmrc` du projet, sans lequel `npm i` échoue : `npm login --registry=https://registry.fraza.ca/`, puis `npx fraza-key`. Voir [Modules Pro](../../01-demarrage/01-installation.md#modules-pro).
17
+ - `NEXT_PUBLIC_URL` renseignée : les liens de paiement envoyés aux clients en sont dérivés.
14
18
 
15
- Le paquet demande la ligne `@fraza-pro:registry=https://registry.fraza.ca/` et le token du registre dans le `.npmrc` du projet, sans lesquels `npm i` échoue. `npx @fraza/start` écrit déjà la ligne de portée. Le token s'obtient avec `npm login --registry=https://registry.fraza.ca/`, puis `npx fraza-key` le reprend dans le projet. Voir [`fraza-key`](../../03-reference/05-cli/fraza-key.md).
19
+ ## Installer
16
20
 
17
21
  ```bash
18
22
  npm i @fraza-pro/module-billing
19
23
  ```
20
24
 
21
- Activer dans `.env.local`, et dans les variables de la plateforme en production :
25
+ Ajouter la variable d'activation à `.env.local`, et aux variables de la plateforme en production :
22
26
 
23
- ```bash
27
+ ```dotenv
28
+ #------ MODULE - BILLING ------#
24
29
  FRAZA_MODULE_BILLING=true
25
30
  ```
26
31
 
27
- Sans cette variable, le module est chargé mais n'enregistre rien : ni tables, ni routes, ni entrée d'admin, ni tâches planifiées.
32
+ Sans ce drapeau, le module est chargé mais n'enregistre rien : ni tables, ni routes, ni entrée d'admin, ni tâches planifiées.
28
33
 
29
- Puis régénérer les manifestes et créer les tables :
34
+ Régénérer les manifestes, puis créer les tables :
30
35
 
31
36
  ```bash
32
- npx fraza-modules sync # auto-déclenché par postinstall
33
- npx fraza-db init # crée les treize tables fraza_billing_*
37
+ npx fraza-modules sync # déclenché automatiquement au postinstall
38
+ npx fraza-db init # crée les treize tables fraza_billing_*
34
39
  ```
35
40
 
36
- `fraza-db init` accorde aussi les permissions `billing.view` et `billing.manage` au rôle `admin`, et applique les migrations en attente.
37
-
38
- Sur un site déjà en service, une mise à jour du module se termine par `npx fraza-db migrate`, qui applique les évolutions de schéma que la création de tables ne peut pas atteindre. `002-drop-job-lock` y supprime `fraza_billing_job_lock` : les tâches se verrouillent maintenant dans `fraza_cron_runs` du core. Voir [Modèle de données](./modele-de-donnees.md#migrations).
41
+ `fraza-db init` est idempotent : sur une base qui a déjà les tables, il applique les migrations en attente sans toucher aux données. Il enregistre aussi les permissions `billing.view` et `billing.manage`, et les attribue au rôle `admin`. Voir [Modèle de données](./08-modele-de-donnees.md).
39
42
 
40
43
  ## Version du core
41
44
 
42
- Le module fonctionne avec la dernière version de `@fraza/core` : tous les paquets Fraza à leur dernière version fonctionnent ensemble. Installer la dernière version de tous les paquets Fraza du site, toutes à la fois :
43
-
44
- ```bash
45
- npx fraza-update
46
- ```
45
+ Le module suit la dernière version de `@fraza/core` : tous les paquets Fraza à leur dernière version fonctionnent ensemble, et `npx fraza-update` les met à jour ensemble.
47
46
 
48
47
  Un core en retard ne dériverait pas `FRAZA_MODULE_BILLING` du nom du paquet : le module y resterait désactivé, sans erreur.
49
48
 
50
- Trois choses viennent du core et n'ont aucun substitut dans le module : la génération de `app/.fraza/public-pages.server.js`, le manifeste par lequel la page de paiement s'enregistre ; la transmission des paramètres d'URL aux pages publiques, sans laquelle le retour de Stripe n'affiche aucun bandeau, et l'affichage en ligne d'un document, sans lequel les visionneuses de PDF restent vides. Les deux dernières échouent en silence sur un core en retard.
49
+ Trois choses viennent du core et n'ont aucun substitut dans le module : la génération de `app/.fraza/public-pages.server.js`, le manifeste par lequel la page de paiement s'enregistre ; la transmission des paramètres d'URL aux pages publiques, sans laquelle le retour de Stripe n'affiche aucun bandeau ; et l'affichage en ligne d'un document, sans lequel les visionneuses de PDF restent vides. Les deux dernières échouent en silence sur un core en retard.
51
50
 
52
51
  Sur un projet dont `app/za/[...path]/page.js` n'importe pas encore ce manifeste, il faut ajouter l'import. La correction est automatique :
53
52
 
@@ -60,9 +59,9 @@ Sans elle, `/za/billing/<token>` échoue au rendu sur « Could not find the modu
60
59
 
61
60
  ## Renseigner l'émetteur
62
61
 
63
- Une facture doit nommer qui l'émet. Sans ces variables, le bloc émetteur du PDF est vide.
62
+ Une facture doit nommer qui l'émet. Sans ces variables, le bloc émetteur du PDF est vide. Dans `.env.local` :
64
63
 
65
- ```bash
64
+ ```dotenv
66
65
  FRAZA_MODULE_BILLING_COMPANY_NAME=Mon entreprise inc.
67
66
  FRAZA_MODULE_BILLING_COMPANY_ADDRESS=123 rue Principale
68
67
  FRAZA_MODULE_BILLING_COMPANY_CITY=Montréal
@@ -74,28 +73,28 @@ FRAZA_MODULE_BILLING_COMPANY_PHONE=514 555 0100
74
73
 
75
74
  Une entreprise inscrite aux fichiers de la TPS et de la TVQ doit faire figurer ses numéros sur toute facture de plus de 30 $ :
76
75
 
77
- ```bash
76
+ ```dotenv
78
77
  FRAZA_MODULE_BILLING_GST_NUMBER=123456789 RT0001
79
78
  FRAZA_MODULE_BILLING_QST_NUMBER=1234567890 TQ0001
80
79
  ```
81
80
 
82
81
  Ces numéros sont recopiés sur chaque facture au moment de l'émission, pas à l'affichage. Une facture déjà émise garde donc les numéros en vigueur ce jour-là.
83
82
 
84
- La liste complète est dans [Configuration](./configuration.md).
83
+ La liste complète est dans [Configuration](./02-configuration.md).
85
84
 
86
85
  ## Courriels
87
86
 
88
- Le module envoie sept courriels par la [file d'envoi](../../03-reference/01-cores/email.md#file-denvoi) du core, qui demande la table `fraza_email_outbox` (`npx fraza-db migrate`) et la configuration courriel du projet, Resend ou SMTP. `NEXT_PUBLIC_URL` doit être renseignée : les liens de paiement envoyés aux clients en sont dérivés.
87
+ Le module envoie sept courriels par la [file d'envoi](../../03-reference/01-cores/email.md#file-denvoi) du core, qui demande la table `fraza_email_outbox` (`npx fraza-db migrate`) et la configuration courriel du projet, Resend ou SMTP.
89
88
 
90
89
  Sans configuration de courriel, tout le reste du module fonctionne : l'émission réussit, le courriel est mis en file, et la tâche `fraza:email-outbox` du core le reprend jusqu'à son dernier essai.
91
90
 
92
- Le contenu de chaque message est décrit dans [Courriels](./courriels.md).
91
+ Le contenu de chaque message est décrit dans [Courriels](./07-courriels.md).
93
92
 
94
93
  ## Paiement par carte
95
94
 
96
- Le paiement par carte demande `STRIPE_SECRET_KEY` et `STRIPE_WEBHOOK_SECRET` :
95
+ Le paiement par carte demande `STRIPE_SECRET_KEY` et `STRIPE_WEBHOOK_SECRET`. Dans `.env.local` :
97
96
 
98
- ```bash
97
+ ```dotenv
99
98
  STRIPE_SECRET_KEY=sk_…
100
99
  STRIPE_WEBHOOK_SECRET=whsec_…
101
100
  ```
@@ -117,7 +116,7 @@ Déclarer l'endpoint dans le tableau de bord Stripe, sur `https://exemple.ca/za/
117
116
  | `refund.updated` | Suit son statut : en attente, réussi, échoué. |
118
117
  | `charge.refunded` | Relit chez Stripe les remboursements du paiement, pour un endpoint qui n'aurait coché que lui. |
119
118
 
120
- Sans le webhook, un client peut payer sans que la facture soit créditée. Un retour de navigateur n'est pas une preuve de paiement, et le module ne l'utilise que pour afficher un bandeau. Une tâche relit aussi Stripe chaque nuit et rattrape ce que le webhook a manqué. Voir [Paiements](./paiements.md#réconciliation).
119
+ Sans le webhook, un client peut payer sans que la facture soit créditée. Un retour de navigateur n'est pas une preuve de paiement, et le module ne l'utilise que pour afficher un bandeau. Une tâche relit aussi Stripe chaque nuit et rattrape ce que le webhook a manqué. Voir [Paiements](./05-paiements.md#réconciliation).
121
120
 
122
121
  ### Vérifier en local
123
122
 
@@ -135,7 +134,9 @@ Le solde ne doit pas bouger : l'événement est reconnu comme un doublon et igno
135
134
 
136
135
  ## Virement Interac
137
136
 
138
- ```bash
137
+ Dans `.env.local` :
138
+
139
+ ```dotenv
139
140
  FRAZA_MODULE_BILLING_INTERAC_ENABLED=true
140
141
  FRAZA_MODULE_BILLING_INTERAC_EMAIL=paiements@exemple.ca
141
142
  ```
@@ -146,17 +147,38 @@ Si `FRAZA_ENCRYPTION_KEY` est configurée, la réponse est chiffrée en base. El
146
147
 
147
148
  ## Tâches planifiées
148
149
 
149
- Quatre tâches quotidiennes sont enregistrées automatiquement. Les désactiver sur une instance qui ne doit pas les exécuter :
150
+ Quatre tâches quotidiennes sont enregistrées automatiquement. Pour les désactiver sur une instance qui ne doit pas les exécuter :
150
151
 
151
- ```bash
152
+ ```dotenv
152
153
  FRAZA_MODULE_BILLING_CRON=false
153
154
  ```
154
155
 
155
- Aucun réglage n'est nécessaire pour un déploiement à plusieurs instances : chaque tâche est planifiée avec le verrou de `@fraza/core/cron`, dans `fraza_cron_runs` : une seule instance exécute un déclenchement donné. Elles demandent cette table du core (`npx fraza-db migrate`).
156
+ Aucun réglage n'est nécessaire pour un déploiement à plusieurs instances : chaque tâche est planifiée avec le verrou de `@fraza/core/cron`, dans `fraza_cron_runs`, et une seule instance exécute un déclenchement donné. Elles demandent cette table du core (`npx fraza-db migrate`).
157
+
158
+ ## Vérifier
159
+
160
+ 1. La connexion à la base répond :
161
+ ```bash
162
+ npx fraza-db test
163
+ ```
164
+ 2. `Facturation` apparaît dans la barre latérale de l'admin.
165
+ 3. Créer un client, puis une facture avec une ligne à 100,00 $ en TPS et TVQ. Le total affiché doit être 114,98 $.
166
+ 4. Émettre la facture. Elle reçoit un numéro de la forme `FAC-2026-0001` et le client reçoit le courriel avec le PDF joint.
167
+ 5. Ouvrir le lien public dans une fenêtre de navigation privée. La ventilation des taxes et les numéros d'inscription doivent y figurer.
168
+
169
+ ## Mettre à jour
170
+
171
+ ```bash
172
+ npx fraza-update
173
+ ```
174
+
175
+ La commande installe la dernière version de tous les paquets Fraza du site, toutes à la fois, puis enchaîne `fraza-modules sync`, `fraza-db migrate` et `fraza-doctor`. Tous les paquets Fraza à leur dernière version fonctionnent ensemble : mettre à jour `@fraza-pro/module-billing` seul, par `npm i`, laisserait le core et les autres modules en arrière.
176
+
177
+ `fraza-db migrate` applique les évolutions de schéma que la création de tables ne peut pas atteindre. `002-drop-job-lock` y supprime `fraza_billing_job_lock` : les tâches se verrouillent maintenant dans `fraza_cron_runs` du core. Voir [Modèle de données](./08-modele-de-donnees.md#migrations).
178
+
179
+ Les notes de version sont livrées avec le paquet, dans `node_modules/@fraza-pro/module-billing/CHANGELOG.md`.
156
180
 
157
- ## Vérifier l'installation
181
+ ## Notes
158
182
 
159
- 1. La section « Facturation » apparaît dans l'admin.
160
- 2. Créer un client, puis une facture avec une ligne à 100,00 $ en TPS et TVQ. Le total affiché doit être 114,98 $.
161
- 3. Émettre la facture. Elle reçoit un numéro de la forme `FAC-2026-0001` et le client reçoit le courriel avec le PDF joint.
162
- 4. Ouvrir le lien public dans une fenêtre de navigation privée. La ventilation des taxes et les numéros d'inscription doivent y figurer.
183
+ - Le module dépend de `@fraza/core` en `peerDependency`. Il n'embarque pas sa propre copie du core.
184
+ - Désinstaller le module ne supprime pas les tables. `dropTables` est exporté depuis `@fraza-pro/module-billing` pour le faire explicitement.
@@ -4,8 +4,8 @@ description: Variables d'environnement du module de facturation, permissions et
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/taxes
8
- - 06-modules/facturation/recurrences-et-rappels
7
+ - 06-modules/facturation/04-taxes
8
+ - 06-modules/facturation/06-recurrences-et-rappels
9
9
  ---
10
10
 
11
11
  Toute la configuration passe par des variables d'environnement, lues une fois au démarrage et mises en cache. Changer une valeur demande un redéploiement.
@@ -21,7 +21,7 @@ Les tâches ne sont jamais enregistrées pendant `next build`, quelle que soit l
21
21
 
22
22
  ## Émetteur
23
23
 
24
- Ces valeurs remplissent le bloc émetteur de la facture et du reçu. Elles n'habillent **pas** les courriels : leur expéditeur, leur logo et leur pied viennent de la configuration du site, `FRAZA_EMAIL_*` et `FRAZA_NAME`. Voir [Courriels](./courriels.md#lhabillage-appartient-au-site).
24
+ Ces valeurs remplissent le bloc émetteur de la facture et du reçu. Elles n'habillent **pas** les courriels : leur expéditeur, leur logo et leur pied viennent de la configuration du site, `FRAZA_EMAIL_*` et `FRAZA_NAME`. Voir [Courriels](./07-courriels.md#lhabillage-appartient-au-site).
25
25
 
26
26
  | Variable | Défaut |
27
27
  |---|---|
@@ -58,7 +58,7 @@ Le nom, le logo et la cible du lien retombent sur la marque du site quand la var
58
58
  | `FRAZA_MODULE_BILLING_QST_NUMBER` | vide | Numéro d'inscription à la TVQ. |
59
59
  | `FRAZA_MODULE_BILLING_DEFAULT_TAX_PROFILE` | `gst_qst` | Profil des nouveaux clients, articles et lignes. |
60
60
 
61
- Les taux acceptent la virgule comme la période décimale. Ils sont convertis en parties par million et figés sur chaque facture au moment de l'émission. Voir [Taxes](./taxes.md).
61
+ Les taux acceptent la virgule comme la période décimale. Ils sont convertis en parties par million et figés sur chaque facture au moment de l'émission. Voir [Taxes](./04-taxes.md).
62
62
 
63
63
  `..._TAXES_ENABLED=false` s'adresse à un émetteur qui n'est pas inscrit aux taxes : un travailleur autonome sous le seuil d'inscription, par exemple. Les sélecteurs de taxes disparaissent de l'admin, toute écriture est ramenée au profil `none`, et aucune facture ne porte de ligne de TPS ni de TVQ. `..._DEFAULT_TAX_PROFILE` n'a alors plus d'effet.
64
64
 
@@ -96,7 +96,7 @@ La séquence des factures et des transactions se remet à zéro chaque année. C
96
96
  | `FRAZA_MODULE_BILLING_OVERDUE_MAX_NOTICES` | `4` | Nombre maximal d'avis de retard. |
97
97
  | `FRAZA_MODULE_BILLING_ADMIN_EMAIL` | vide | Reçoit une copie au premier retard de chaque facture. |
98
98
 
99
- `FRAZA_MODULE_BILLING_REMINDER_DAYS` est trié par ordre décroissant et dédoublonné à la lecture, donc l'ordre de saisie n'a pas d'importance. Voir [Récurrences et rappels](./recurrences-et-rappels.md).
99
+ `FRAZA_MODULE_BILLING_REMINDER_DAYS` est trié par ordre décroissant et dédoublonné à la lecture, donc l'ordre de saisie n'a pas d'importance. Voir [Récurrences et rappels](./06-recurrences-et-rappels.md).
100
100
 
101
101
  ## Virement Interac
102
102
 
@@ -4,8 +4,8 @@ description: Du brouillon à l'encaissement, ce que chaque étape fige et ce qui
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/paiements
8
- - 06-modules/facturation/taxes
7
+ - 06-modules/facturation/05-paiements
8
+ - 06-modules/facturation/04-taxes
9
9
  ---
10
10
 
11
11
  ## Les cinq statuts
@@ -85,7 +85,7 @@ Un paiement se produit de trois façons : le client règle par carte sur la page
85
85
 
86
86
  Dans tous les cas, la même écriture, sous le verrou de la facture : une transaction rattachée à la facture, puis un recalcul immédiat de `paid_cents`, du statut et de la date de paiement à partir de la somme des transactions.
87
87
 
88
- Ce recalcul est ce qui manquait à l'ancien module, où seule la création d'un paiement mettait la facture à jour : modifier ou supprimer un paiement laissait la facture prétendre avoir reçu de l'argent qu'elle n'avait plus. Voir [Paiements](./paiements.md).
88
+ Ce recalcul est ce qui manquait à l'ancien module, où seule la création d'un paiement mettait la facture à jour : modifier ou supprimer un paiement laissait la facture prétendre avoir reçu de l'argent qu'elle n'avait plus. Voir [Paiements](./05-paiements.md).
89
89
 
90
90
  ## Le solde
91
91
 
@@ -93,7 +93,7 @@ Ce recalcul est ce qui manquait à l'ancien module, où seule la création d'un
93
93
  solde = max(0, total + intérêts − payé)
94
94
  ```
95
95
 
96
- C'est le seul montant dû du module. Il sert à la session Stripe, au PDF, à la page publique, aux courriels et à la colonne « Solde ». Les intérêts, eux, courent sur `max(0, total − payé)` : voir [Récurrences et rappels](./recurrences-et-rappels.md). Une facture annulée a un solde nul : tout ce qu'elle a reçu est un excédent à rembourser.
96
+ C'est le seul montant dû du module. Il sert à la session Stripe, au PDF, à la page publique, aux courriels et à la colonne « Solde ». Les intérêts, eux, courent sur `max(0, total − payé)` : voir [Récurrences et rappels](./06-recurrences-et-rappels.md). Une facture annulée a un solde nul : tout ce qu'elle a reçu est un excédent à rembourser.
97
97
 
98
98
  L'ancien module en avait deux : Stripe facturait `total − payé` pendant que l'interface affichait `total + intérêts − payé`. Un client qui payait une facture en retard par carte restait donc débiteur des intérêts sans en être informé.
99
99
 
@@ -4,8 +4,8 @@ description: Profils de taxes, base de calcul de la TPS et de la TVQ, règle d'a
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/facturation
8
- - 06-modules/facturation/configuration
7
+ - 06-modules/facturation/03-facturation
8
+ - 06-modules/facturation/02-configuration
9
9
  ---
10
10
 
11
11
  ## Facturer sans taxes
@@ -4,8 +4,8 @@ description: Registre sérialisé, paiement par carte, virement Interac, saisie
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/installation
8
- - 06-modules/facturation/modele-de-donnees
7
+ - 06-modules/facturation/01-installation
8
+ - 06-modules/facturation/08-modele-de-donnees
9
9
  ---
10
10
 
11
11
  ## Un seul registre
@@ -120,7 +120,7 @@ Le webhook peut manquer un paiement : endpoint non déclaré, secret changé, si
120
120
 
121
121
  Un reçu PDF est disponible pour chaque paiement, dans l'admin comme sur la page publique une fois la facture soldée. Il reprend la ventilation des taxes, que le client utilise pour ses propres crédits de taxe sur les intrants.
122
122
 
123
- Le courriel de reçu part automatiquement après un paiement par carte. Il porte le PDF en pièce jointe seulement quand le paiement solde la facture. Voir [Courriels](./courriels.md).
123
+ Le courriel de reçu part automatiquement après un paiement par carte. Il porte le PDF en pièce jointe seulement quand le paiement solde la facture. Voir [Courriels](./07-courriels.md).
124
124
 
125
125
  ## Notes
126
126
 
@@ -4,8 +4,8 @@ description: Les quatre tâches planifiées, génération des factures réguliè
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/facturation
8
- - 06-modules/facturation/configuration
7
+ - 06-modules/facturation/03-facturation
8
+ - 06-modules/facturation/02-configuration
9
9
  ---
10
10
 
11
11
  Quatre tâches quotidiennes, enregistrées dans [`core/cron`](../../03-reference/01-cores/cron.md).
@@ -71,13 +71,13 @@ Une copie interne part à `FRAZA_MODULE_BILLING_ADMIN_EMAIL` au premier retard d
71
71
 
72
72
  Chaque message occupe un créneau `(facture, type, numéro)` dans `fraza_billing_reminder`. Le créneau est **réservé avant la mise en file** par une insertion qu'un index unique partiel refuse de dupliquer. Pas de ligne insérée, pas de message.
73
73
 
74
- Si le courriel ne peut pas être mis dans la file d'envoi du core, la ligne est marquée en échec, ce qui libère le créneau et laisse le passage suivant réessayer. Une fois en file, l'envoi et ses reprises reviennent à la file. Voir [Courriels](./courriels.md).
74
+ Si le courriel ne peut pas être mis dans la file d'envoi du core, la ligne est marquée en échec, ce qui libère le créneau et laisse le passage suivant réessayer. Une fois en file, l'envoi et ses reprises reviennent à la file. Voir [Courriels](./07-courriels.md).
75
75
 
76
76
  L'idempotence tient donc aux données, pas à l'horaire. Exécuter une tâche deux fois dans la journée n'envoie rien de plus, et une journée sautée est rattrapée.
77
77
 
78
78
  Une pause de 900 ms sépare deux envois, pour rester sous la limite de débit du fournisseur de courriel.
79
79
 
80
- Le contenu de ces messages est décrit dans [Courriels](./courriels.md).
80
+ Le contenu de ces messages est décrit dans [Courriels](./07-courriels.md).
81
81
 
82
82
  ## Intérêts de retard
83
83
 
@@ -4,8 +4,8 @@ description: Les sept messages envoyés par le module, leur déclencheur, leur c
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/recurrences-et-rappels
8
- - 06-modules/facturation/configuration
7
+ - 06-modules/facturation/06-recurrences-et-rappels
8
+ - 06-modules/facturation/02-configuration
9
9
  ---
10
10
 
11
11
  Le module envoie sept messages. Tous passent par la file d'envoi de [`core/email`](../../03-reference/01-cores/email.md), donc par le fournisseur configuré pour le projet, et tous sont bâtis sur le `BaseLayout` du core : ce sont les mêmes expéditeur, en-tête, largeur et pied que les courriels de compte que le client a déjà reçus.
@@ -22,7 +22,7 @@ Le module envoie sept messages. Tous passent par la file d'envoi de [`core/email
22
22
  | Remboursement | Remboursement Stripe réussi, lancé depuis l'admin ou le tableau de bord. | `Remboursement : facture FAC-2026-0001` | — |
23
23
  | Note de crédit | Annulation d'une facture émise, et bouton « Renvoyer » de la note. | `Note de crédit NC-2026-0001 : facture FAC-2026-0001 annulée` | La note de crédit en PDF. |
24
24
 
25
- La cadence des rappels et des avis de retard est décrite dans [Récurrences et rappels](./recurrences-et-rappels.md).
25
+ La cadence des rappels et des avis de retard est décrite dans [Récurrences et rappels](./06-recurrences-et-rappels.md).
26
26
 
27
27
  ## Ce que porte un message
28
28
 
@@ -30,7 +30,7 @@ Toujours la même ossature, celle du `BaseLayout` : logo de l'émetteur, titre,
30
30
 
31
31
  L'encadré est ce qui porte l'état, par sa couleur : neutre pour une facture ou un rappel, vert pour un paiement reçu, rouge pour un retard. Ces couleurs, comme celle du bouton, viennent du [thème du projet](../../02-guides/personnaliser-l-apparence.md), dans ses valeurs claires : le vert est son `success`, le rouge son `danger`, le bouton sa couleur `primary`. Il ne contient que ce dont le lecteur a besoin pour décider : le numéro, le montant à payer, l'échéance, et l'acompte déjà versé s'il y en a un. Les montants, les dates et les identifiants y sont en chasse fixe.
32
32
 
33
- **La ventilation des taxes n'est pas dans les courriels.** Sous-total, TPS, TVQ et détail des lignes vivent sur le PDF joint et sur la [page publique](./paiements.md#la-page-publique). Un courriel qui recopie une facture complète est un courriel que personne ne lit, et la seule version qui fait foi reste le document.
33
+ **La ventilation des taxes n'est pas dans les courriels.** Sous-total, TPS, TVQ et détail des lignes vivent sur le PDF joint et sur la [page publique](./05-paiements.md#la-page-publique). Un courriel qui recopie une facture complète est un courriel que personne ne lit, et la seule version qui fait foi reste le document.
34
34
 
35
35
  Deux exceptions à cette ossature :
36
36
 
@@ -56,7 +56,7 @@ Une seule exception, et elle est fonctionnelle plutôt que visuelle : l'**adress
56
56
 
57
57
  Cette même adresse est **écrite en toutes lettres** dans le message, sur la facture, l'avis de retard et l'avis de remboursement : « Si vous avez des questions sur cette facture, écrivez-nous à facturation@exemple.ca. » Le bouton de réponse y mène déjà, mais un courriel transféré, imprimé, ou lu dans un client qui masque les en-têtes perd cette information. Une adresse écrite dans le corps ne dépend pas de la façon dont le message est ouvert. Sans `..._COMPANY_EMAIL` configurée, la phrase invite simplement à répondre au courriel.
58
58
 
59
- L'émetteur, lui, signe le document : c'est sur la facture et sur le reçu que figurent sa raison sociale, son adresse, son logo et ses numéros d'inscription. Voir [Configuration](./configuration.md#émetteur).
59
+ L'émetteur, lui, signe le document : c'est sur la facture et sur le reçu que figurent sa raison sociale, son adresse, son logo et ses numéros d'inscription. Voir [Configuration](./02-configuration.md#émetteur).
60
60
 
61
61
  L'alerte interne de retard est le seul message sans lien de support dans son pied : son destinataire travaille chez vous.
62
62
 
@@ -4,8 +4,8 @@ description: Les treize tables fraza_billing_, leurs colonnes, leurs contraintes
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/api
8
- - 06-modules/facturation/facturation
7
+ - 06-modules/facturation/09-api
8
+ - 06-modules/facturation/03-facturation
9
9
  ---
10
10
 
11
11
  Treize tables, créées dans l'ordre ci-dessous par `fraza-db init` et supprimées dans l'ordre inverse. La création est idempotente : une table existante est ignorée, jamais modifiée.
@@ -4,8 +4,8 @@ description: Routes HTTP du module de facturation et fonctions serveur importabl
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/modele-de-donnees
8
- - 06-modules/facturation/paiements
7
+ - 06-modules/facturation/08-modele-de-donnees
8
+ - 06-modules/facturation/05-paiements
9
9
  ---
10
10
 
11
11
  ## Fonctions serveur
@@ -184,5 +184,5 @@ Les routes de document répondent en `Content-Disposition: inline` : le navigate
184
184
  ## Notes
185
185
 
186
186
  - Les PDF sont rendus par le module et servis en ligne (`disposition: 'inline'`), ce que le core n'accorde qu'à un document produit par le serveur. L'en-tête de cadrage passe alors à `SAMEORIGIN` : les visionneuses du même site peuvent les afficher dans un cadre.
187
- - Le webhook Stripe n'est pas dans ce tableau : il appartient au core, sur `/za/api/payments/stripe/webhook`, et le module s'y abonne. Voir [Installation](./installation.md).
187
+ - Le webhook Stripe n'est pas dans ce tableau : il appartient au core, sur `/za/api/payments/stripe/webhook`, et le module s'y abonne. Voir [Installation](./01-installation.md).
188
188
  - Les pages d'admin appellent ces routes par `apiFetch` du core, qui envoie le cookie de session. Sans lui, toute route d'admin répond 401.
@@ -4,33 +4,43 @@ description: Clients, factures avec ventilation TPS et TVQ, paiement Stripe et I
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/facturation/installation
8
- - 06-modules/facturation/configuration
7
+ - 06-modules/facturation/01-installation
8
+ - 06-modules/facturation/02-configuration
9
9
  ---
10
10
 
11
11
  `@fraza-pro/module-billing` ajoute une section « Facturation » à l'admin : un fichier clients, un catalogue d'articles, des factures avec ventilation TPS et TVQ, et une page publique où le client règle sa facture par carte ou par virement Interac.
12
12
 
13
- Ce module est distribué sous la licence Fraza Pro : son utilisation en production demande une licence par projet, renouvelée chaque année, qui comprend les mises à jour, la conformité et le support. Voir [Licence et propriété](../../04-architecture/07-licence-et-propriete.md).
13
+ ```bash
14
+ npm i @fraza-pro/module-billing
15
+ ```
16
+
17
+ | Paquet | `@fraza-pro/module-billing` |
18
+ |---|---|
19
+ | Licence | Fraza Pro : une licence par projet en production, renouvelée chaque année, qui comprend les mises à jour, la conformité et le support. Voir [Licence et propriété](../../04-architecture/07-licence-et-propriete.md). |
20
+ | Registre | `https://registry.fraza.ca/`, avec le token du projet. Voir [Modules Pro](../../01-demarrage/01-installation.md#modules-pro). |
21
+ | Activation | `FRAZA_MODULE_BILLING=true` |
22
+
23
+ L'activation, la création des tables et le webhook Stripe sont dans [Installation](./01-installation.md).
14
24
 
15
25
  Le module est autonome. Il porte ses propres clients plutôt que de dépendre d'un module externe, et se relie facultativement aux comptes du site par la colonne `user_id`.
16
26
 
17
27
  ![La liste des factures, ses totaux en tête et ses onglets de statut](../../assets/modules/facturation/factures.light.webp)
18
28
 
19
- Une facture ouverte dont l'échéance est passée affiche « En retard » dans la colonne « Statut », et le nombre de jours de retard sous l'échéance, alors que son statut stocké reste `sent` ou `partial` : c'est une déduction, pas un état stocké, et [Facturation](./facturation.md) explique pourquoi. Le décompte sous l'échéance ne paraît que tant qu'un solde reste dû. Une facture payée, annulée ou en brouillon n'en porte aucun. Le brouillon en tête de liste n'a ni numéro ni lien public, il ne les reçoit qu'à l'émission.
29
+ Une facture ouverte dont l'échéance est passée affiche « En retard » dans la colonne « Statut », et le nombre de jours de retard sous l'échéance, alors que son statut stocké reste `sent` ou `partial` : c'est une déduction, pas un état stocké, et [Facturation](./03-facturation.md) explique pourquoi. Le décompte sous l'échéance ne paraît que tant qu'un solde reste dû. Une facture payée, annulée ou en brouillon n'en porte aucun. Le brouillon en tête de liste n'a ni numéro ni lien public, il ne les reçoit qu'à l'émission.
20
30
 
21
31
  ## Pages de cette section
22
32
 
23
33
  | Page | Contenu |
24
34
  |---|---|
25
- | [Installation](./installation.md) | Installer le module, créer les tables, déclarer le webhook Stripe. |
26
- | [Configuration](./configuration.md) | Variables d'environnement, permissions, entrée d'admin. |
27
- | [Cycle de vie d'une facture](./facturation.md) | Brouillon, émission, encaissement, annulation. |
28
- | [Taxes](./taxes.md) | Profils, base de calcul, arrondi, numéros d'inscription. |
29
- | [Paiements](./paiements.md) | Stripe, Interac, saisie manuelle et remboursements. |
30
- | [Récurrences et rappels](./recurrences-et-rappels.md) | Génération automatique, échelle de rappels, intérêts. |
31
- | [Courriels](./courriels.md) | Les sept messages, leur contenu et leur non-répétition. |
32
- | [Modèle de données](./modele-de-donnees.md) | Les treize tables `fraza_billing_*`. |
33
- | [API](./api.md) | Routes HTTP et fonctions serveur importables. |
35
+ | [Installation](./01-installation.md) | Installer le module, créer les tables, déclarer le webhook Stripe. |
36
+ | [Configuration](./02-configuration.md) | Variables d'environnement, permissions, entrée d'admin. |
37
+ | [Cycle de vie d'une facture](./03-facturation.md) | Brouillon, émission, encaissement, annulation. |
38
+ | [Taxes](./04-taxes.md) | Profils, base de calcul, arrondi, numéros d'inscription. |
39
+ | [Paiements](./05-paiements.md) | Stripe, Interac, saisie manuelle et remboursements. |
40
+ | [Récurrences et rappels](./06-recurrences-et-rappels.md) | Génération automatique, échelle de rappels, intérêts. |
41
+ | [Courriels](./07-courriels.md) | Les sept messages, leur contenu et leur non-répétition. |
42
+ | [Modèle de données](./08-modele-de-donnees.md) | Les treize tables `fraza_billing_*`. |
43
+ | [API](./09-api.md) | Routes HTTP et fonctions serveur importables. |
34
44
 
35
45
  ## Ce que le module apporte
36
46
 
@@ -45,11 +55,11 @@ Une facture ouverte dont l'échéance est passée affiche « En retard » dans l
45
55
  | Tâches planifiées | Quatre : réconciliation Stripe, intérêts, récurrences, rappels. |
46
56
  | Documents | Facture, reçu et note de crédit en PDF, générés à la demande. |
47
57
  | Dépendances | `stripe` (SDK 23, appelé au premier paiement) et `@react-pdf/renderer` (chargé au premier PDF), installés avec le module. |
48
- | Courriels | Sept, du courriel d'émission à la note de crédit. Voir [Courriels](./courriels.md). |
58
+ | Courriels | Sept, du courriel d'émission à la note de crédit. Voir [Courriels](./07-courriels.md). |
49
59
 
50
60
  ## Deux principes qui expliquent le reste
51
61
 
52
- **Le solde est calculé à un seul endroit.** `computeBalance` dans `money.js` produit le montant dû, et c'est ce nombre qui sert à la session Stripe, au PDF, à la page publique, aux courriels et à la colonne Solde. Aucune seconde formule ne peut diverger. Les intérêts, eux, courent sur la part impayée du total, voir [Récurrences et rappels](./recurrences-et-rappels.md).
62
+ **Le solde est calculé à un seul endroit.** `computeBalance` dans `money.js` produit le montant dû, et c'est ce nombre qui sert à la session Stripe, au PDF, à la page publique, aux courriels et à la colonne Solde. Aucune seconde formule ne peut diverger. Les intérêts, eux, courent sur la part impayée du total, voir [Récurrences et rappels](./06-recurrences-et-rappels.md).
53
63
 
54
64
  **Le retard n'est pas un statut.** Une facture est `draft`, `sent`, `partial`, `paid` ou `cancelled`. Le retard se déduit de la date d'échéance et du solde, à la lecture. Une facture en retard reste donc `sent` ou `partial`, et ne peut pas disparaître de la requête qui alimente les avis de retard.
55
65
 
@@ -69,5 +79,5 @@ Une colonne `DECIMAL` revient de `pg` sous forme de chaîne, ce qui oblige à un
69
79
 
70
80
  - La page publique est protégée par un jeton de 64 caractères hexadécimaux, et rien d'autre. Toute personne qui détient le lien voit la facture et peut la payer. Le jeton n'expire pas et ne se révoque pas.
71
81
  - Les PDF publics s'affichent dans une visionneuse plutôt que de se télécharger. Le routeur du core sert par défaut en pièce jointe tout ce qui n'est pas une image ; les deux routes de document demandent explicitement l'affichage en ligne, ce qu'elles peuvent faire parce qu'elles rendent le document elles-mêmes au lieu de le relire depuis le stockage.
72
- - Le webhook Stripe est servi par le core, sur `/za/api/payments/stripe/webhook`. Le module s'y abonne : le projet hôte n'a aucune route à créer, seulement l'endpoint à déclarer chez Stripe. Voir [Installation](./installation.md).
82
+ - Le webhook Stripe est servi par le core, sur `/za/api/payments/stripe/webhook`. Le module s'y abonne : le projet hôte n'a aucune route à créer, seulement l'endpoint à déclarer chez Stripe. Voir [Installation](./01-installation.md).
73
83
  - Le champ `version` du manifeste suit la version du paquet : [`fraza-module sync-version`](../../03-reference/05-cli/fraza-module.md#sync-version), lancé par chaque build, la recopie dans `src/version.js`, et `prepublishOnly` refuse de publier si les deux divergent.
@@ -4,16 +4,17 @@ description: Installer @fraza/module-forms, créer les tables, vérifier les dé
4
4
  related:
5
5
  title: Étapes suivantes
6
6
  links:
7
- - 06-modules/forms/configuration
8
- - 06-modules/forms/affichage
7
+ - 06-modules/forms/02-configuration
8
+ - 06-modules/forms/06-affichage
9
9
  ---
10
10
 
11
- Cette page couvre l'installation de `@fraza/module-forms` dans un projet déjà structuré par `@fraza/start`. Le module n'est jamais déclaré à la main : il est découvert au boot par scan des dépendances, comme décrit dans [Cycle de vie d'un module](../../02-guides/cycle-de-vie-d-un-module.md).
11
+ Cette page installe `@fraza/module-forms` dans un projet créé par `npx @fraza/start`. Le module n'est jamais déclaré à la main : il est découvert au boot par scan des dépendances, comme décrit dans [Cycle de vie d'un module](../../02-guides/cycle-de-vie-d-un-module.md).
12
12
 
13
13
  ## Prérequis
14
14
 
15
- - Un projet généré par `npx @fraza/start`, avec `@fraza/core` installé.
16
- - **`NEXT_PUBLIC_URL` renseignée.** Ce n'est pas une recommandation : sans elle, toute soumission est rejetée. Voir plus bas.
15
+ - Un projet créé par `npx @fraza/start`, avec `@fraza/core` à jour.
16
+ - **`NEXT_PUBLIC_URL` renseignée.** Sans elle, toute soumission est rejetée. Voir [Vérifier l'origine publique](#vérifier-lorigine-publique).
17
+ - Aucun compte : le paquet est publié sur npmjs.
17
18
 
18
19
  ## Installer
19
20
 
@@ -23,54 +24,52 @@ npm i @fraza/module-forms
23
24
 
24
25
  Ajouter la variable d'activation à `.env.local`, et aux variables de la plateforme en production :
25
26
 
26
- ```bash
27
+ ```dotenv
27
28
  #------ MODULE - FORMS ------#
28
29
  FRAZA_MODULE_FORMS=true
29
30
  ```
30
31
 
31
32
  Sans ce drapeau, le module est ignoré : aucune table, aucune route, aucune entrée d'admin.
32
33
 
33
- Régénérer les manifestes puis créer les tables :
34
+ Régénérer les manifestes, puis créer les tables :
34
35
 
35
36
  ```bash
36
37
  npx fraza-modules sync # déclenché automatiquement au postinstall
37
- npx fraza-db init # crée fraza_forms_form et fraza_forms_submission
38
+ npx fraza-db init # crée les tables fraza_forms_*
38
39
  ```
39
40
 
40
- ## Version de core exigée
41
+ `fraza-db init` est idempotent : sur une base qui a déjà les tables, il applique les migrations en attente sans toucher aux données. Il crée `fraza_forms_form`, `fraza_forms_submission` et `fraza_forms_storage_deletion`, la file des fichiers à retirer du stockage. Il enregistre aussi les permissions `forms.view` et `forms.manage`, et les attribue au rôle `admin`. Voir [Modèle de données](./07-modele-de-donnees.md).
42
+
43
+ La tâche planifiée `forms-retention` demande la table `fraza_cron_runs` du core, créée par `npx fraza-db migrate`.
41
44
 
42
- Le module réclame `@fraza/core` 0.1.0 ou plus, et le boot refuse une combinaison plus ancienne en nommant le module. C'est ce core qui sait générer `app/.fraza/public-pages.server.js`, le manifeste par lequel la page publique `/za/forms/<slug>` s'enregistre.
45
+ ## Projet monté à la main
43
46
 
44
- Si `app/za/[...path]/page.js` ne porte pas encore l'import du manifeste, par exemple sur un projet monté à la main, le doctor l'ajoute :
47
+ La page publique `/za/forms/<slug>` s'enregistre par le manifeste `app/.fraza/public-pages.server.js`, que génère `fraza-modules sync`. Le start template importe déjà ce manifeste dans `app/za/[...path]/page.js`. Sur un projet monté à la main, le doctor ajoute l'import :
45
48
 
46
49
  ```bash
47
50
  npx fraza-doctor --fix
48
51
  npx fraza-modules sync
49
52
  ```
50
53
 
51
- `fraza-db init` saute les tables déjà présentes, et crée aussi `fraza_forms_storage_deletion`. Les migrations `001-truncate-stored-ips` et `002-queue-storage-deletions` passent par `npx fraza-db migrate`. La tâche `forms-retention` demande la table `fraza_cron_runs` du core. Voir [Modèle de données](./modele-de-donnees.md).
52
-
53
54
  ## Vérifier l'origine publique
54
55
 
55
- C'est l'étape que l'on oublie, et elle rend le module inutilisable si elle manque.
56
+ C'est l'étape que l'on oublie, et elle rend le module inutilisable si elle manque. Dans `.env.local`, et dans les variables de la plateforme en production avec l'adresse du site :
56
57
 
57
- ```bash
58
+ ```dotenv
58
59
  NEXT_PUBLIC_URL=https://exemple.com
59
60
  ```
60
61
 
61
62
  Le routeur du core protège toute requête modifiante par une **comparaison d'origine**. L'en-tête `Origin` de la requête doit correspondre à l'origine déclarée dans cette variable. Si elle n'est pas renseignée, la comparaison échoue systématiquement et la soumission remonte en `403`.
62
63
 
63
- En local, placer `NEXT_PUBLIC_URL=http://localhost:3000` dans `.env.local`. Voir [Fichiers d'environnement](../../01-demarrage/03-configuration.md#fichiers-denvironnement).
64
+ En local, `@fraza/start` a déjà écrit `NEXT_PUBLIC_URL=http://localhost:3000` dans `.env.local`. Voir [Fichiers d'environnement](../../01-demarrage/03-configuration.md#fichiers-denvironnement).
64
65
 
65
- Le symptôme est trompeur : le formulaire s'affiche, se remplit, et l'envoi échoue sans message explicite côté visiteur.
66
-
67
- Voir [Soumissions](./soumissions.md) pour le détail de cette protection.
66
+ Le symptôme est trompeur : le formulaire s'affiche, se remplit, et l'envoi échoue sans message explicite côté visiteur. Voir [Soumissions](./05-soumissions.md) pour le détail de cette protection.
68
67
 
69
68
  ## Activer les courriels
70
69
 
71
- Les notifications à l'équipe et les accusés de réception passent par le service de courriel du core, donc par le fournisseur configuré pour le projet.
70
+ Les notifications à l'équipe et les accusés de réception passent par le service de courriel du core, donc par le fournisseur configuré pour le projet. Dans `.env.local` :
72
71
 
73
- ```bash
72
+ ```dotenv
74
73
  FRAZA_EMAIL_RESEND_APIKEY=re_...
75
74
  FRAZA_EMAIL_FROM_ADDRESS=noreply@exemple.com
76
75
  FRAZA_EMAIL_FROM_NAME=Exemple
@@ -78,9 +77,7 @@ FRAZA_EMAIL_FROM_NAME=Exemple
78
77
 
79
78
  Sans ces variables, le module fonctionne : les soumissions sont enregistrées et consultables dans l'admin, seuls les courriels ne partent pas. Leur échec n'a jamais d'effet sur la soumission.
80
79
 
81
- Les courriels passent par la table `fraza_email_outbox` du core, créée par `npx fraza-db migrate`. Sans elle, ils ne sont pas mis en file (erreur journalisée), et la soumission reste enregistrée.
82
-
83
- Voir [core/email](../../03-reference/01-cores/email.md).
80
+ Les courriels passent par la table `fraza_email_outbox` du core, créée par `npx fraza-db migrate`. Sans elle, ils ne sont pas mis en file (erreur journalisée), et la soumission reste enregistrée. Voir [core/email](../../03-reference/01-cores/email.md).
84
81
 
85
82
  ## Activer les champs fichier
86
83
 
@@ -96,7 +93,7 @@ Créer un formulaire depuis `/admin/forms`, lui donner un slug, puis l'ouvrir di
96
93
  /za/forms/<slug>
97
94
  ```
98
95
 
99
- Cette page est enregistrée par le module au boot, il n'y a rien à câbler. Elle sert avant tout à vérifier l'installation : pour un vrai site, préférer un bloc du BlockEditor écrit dans le projet ou le composant `FormEmbed`. Voir [Affichage](./affichage.md).
96
+ Cette page est enregistrée par le module au boot, il n'y a rien à câbler. Elle sert avant tout à vérifier l'installation : pour un vrai site, préférer un bloc du BlockEditor écrit dans le projet ou le composant `FormEmbed`. Voir [Affichage](./06-affichage.md).
100
97
 
101
98
  ## Vérifier
102
99
 
@@ -107,9 +104,7 @@ Cette page est enregistrée par le module au boot, il n'y a rien à câbler. Ell
107
104
  2. `Formulaires` apparaît dans la barre latérale de l'admin, avec les items `Formulaires` et `Soumissions`.
108
105
  3. Créer un formulaire, l'ouvrir à `/za/forms/<slug>`, l'envoyer, puis retrouver la soumission dans `/admin/forms/submissions`.
109
106
 
110
- Si l'envoi échoue, vérifier d'abord `NEXT_PUBLIC_URL`, puis attendre trois secondes avant de valider : un envoi trop rapide est refusé par la protection anti-robot. Voir [Soumissions](./soumissions.md).
111
-
112
- Les permissions du module sont enregistrées et attribuées au rôle `admin` pendant `fraza-db init`. Un module ajouté après coup n'a donc besoin que d'un `npx fraza-db init` pour que `forms.view` et `forms.manage` apparaissent dans `/admin/roles`.
107
+ Si l'envoi échoue, vérifier d'abord `NEXT_PUBLIC_URL`, puis attendre trois secondes avant de valider : un envoi trop rapide est refusé par la protection anti-robot. Voir [Soumissions](./05-soumissions.md).
113
108
 
114
109
  ## Mettre à jour
115
110
 
@@ -117,9 +112,9 @@ Les permissions du module sont enregistrées et attribuées au rôle `admin` pen
117
112
  npx fraza-update
118
113
  ```
119
114
 
120
- La commande installe la dernière version de tous les paquets Fraza du site, toutes à la fois : tous les paquets Fraza à leur dernière version fonctionnent ensemble. Mettre à jour `@fraza/module-forms` seul, par `npm i`, laisserait le core et les autres modules en arrière.
115
+ La commande installe la dernière version de tous les paquets Fraza du site, toutes à la fois, puis enchaîne `fraza-modules sync`, `fraza-db migrate` et `fraza-doctor`. Tous les paquets Fraza à leur dernière version fonctionnent ensemble : mettre à jour `@fraza/module-forms` seul, par `npm i`, laisserait le core et les autres modules en arrière.
121
116
 
122
- Les notes de version sont livrées avec le package, dans `node_modules/@fraza/module-forms/CHANGELOG.md`.
117
+ Les notes de version sont livrées avec le paquet, dans `node_modules/@fraza/module-forms/CHANGELOG.md`.
123
118
 
124
119
  ## Notes
125
120