Modèle de données
Les cinq tables fraza_licenses_* du module de licences, leurs colonnes et leurs contraintes.
Cinq tables, toutes préfixées fraza_licenses_, créées par fraza-db init après celles de Facturation, auxquelles elles se rattachent. Les contraintes CHECK reprennent exactement les valeurs de constants.js.
fraza_licenses_plan
Ce qu'une offre de Facturation donne. Une offre sans ligne ici ne donne pas de licence.
| Colonne | Type | Rôle |
|---|---|---|
plan_id | INTEGER PK | L'offre, fraza_billing_plan(id), supprimée avec elle. |
project_quota | INTEGER | Projets actifs permis. NULL : illimité. |
fair_use_alert | INTEGER | Seuil de l'alerte d'usage raisonnable. NULL : aucune. |
created_at, updated_at | TIMESTAMPTZ |
fraza_licenses_license
Une licence par abonnement. Un client qui revient reprend sa licence suspendue : subscription_id est toujours l'abonnement en cours.
| Colonne | Type | Rôle |
|---|---|---|
id | SERIAL | |
billing_client_id | INTEGER | La fiche client, fraza_billing_client(id). |
subscription_id | INTEGER, unique | L'abonnement, fraza_billing_subscription(id). |
plan_id | INTEGER | L'offre en vigueur, qui donne le quota. Change au changement d'offre effectif. |
status | VARCHAR(20) | pending, active, grace, suspended ou revoked. |
grace_ends_on | DATE | Fin de la grâce, en grace. |
suspended_at | TIMESTAMPTZ | Début de la suspension, d'où part le délai de révocation. Gardé tant que la licence n'est pas de nouveau utilisable. |
revoked_at | TIMESTAMPTZ | |
fair_use_notified_at | TIMESTAMPTZ | L'alerte d'usage raisonnable est partie : elle ne repart pas. |
created_at, updated_at | TIMESTAMPTZ |
Index : billing_client_id, status.
fraza_licenses_project
| Colonne | Type | Rôle |
|---|---|---|
id | SERIAL | |
license_id | INTEGER | La licence, supprimé avec elle. |
name | VARCHAR(100) | Le nom donné par le client. |
status | VARCHAR(20) | active, suspended ou revoked. Seuls les projets active comptent dans le quota. |
suspended_at, revoked_at | TIMESTAMPTZ | |
created_at, updated_at | TIMESTAMPTZ |
Index : (license_id, status).
fraza_licenses_credential
L'identité d'un projet chez un fournisseur. Un projet a au plus un identifiant en service (retired_at nul) ; ceux qu'une régénération a remplacés restent, révoqués, pour l'historique.
| Colonne | Type | Rôle |
|---|---|---|
id | SERIAL | |
project_id | INTEGER | Le projet, supprimé avec lui. |
connector | VARCHAR(63) | La clé du connecteur qui l'a créé. |
external_id | VARCHAR(255) | L'identifiant chez le fournisseur : le nom du projet au registre, fz-…, pour Verdaccio. Unique par connecteur. |
secret_hash | CHAR(64) | Le SHA-256 du secret, la clé fzk_… pour Verdaccio, ou NULL si le connecteur n'en donne pas. Le registre retrouve une clé par ce hachage. |
desired_state | VARCHAR(20) | active, suspended ou revoked : ce que disent la licence et le projet. |
actual_state | VARCHAR(20) | Ce que le connecteur a appliqué. NULL tant que rien ne l'a été. |
retired_at | TIMESTAMPTZ | Remplacé par une régénération : révoqué pour de bon. |
last_used_at | TIMESTAMPTZ | Dernière vérification réussie par le registre, à l'heure près. |
last_sync_at, last_error, sync_attempts | La dernière synchronisation, son erreur, et le nombre d'échecs de suite, qui espace les essais. | |
created_at, updated_at | TIMESTAMPTZ |
Index : unique sur (connector, external_id) ; unique partiel sur project_id quand retired_at est nul ; unique partiel sur secret_hash quand il n'est pas nul (uq_fraza_licenses_credential_secret) ; partiel sur les identifiants à synchroniser.
fraza_licenses_event
L'historique d'une licence, pour le support et pour la page d'admin.
| Colonne | Type | Rôle |
|---|---|---|
id | BIGSERIAL | |
license_id | INTEGER | La licence, supprimé avec elle. |
project_id | INTEGER | Le projet concerné, s'il y en a un. |
type | VARCHAR(63) | license.created, license.activated, license.renewed, license.grace, license.suspended, license.revoked, license.plan_changed, license.cancel_scheduled, license.resumed, project.created, project.suspended, project.restored, project.revoked, project.regenerated. |
data | JSONB | Le détail : motif, offres, dates. |
billing_event_id | BIGINT, unique | L'événement de Facturation qui a produit la ligne. L'unicité rend un rejeu inoffensif. |
actor_user_id | TEXT | Le compte qui a fait l'action, client ou administration. |
created_at | TIMESTAMPTZ |
Migrations
Appliquées par npx fraza-db migrate. Une base neuve reçoit directement le schéma courant, figé par 000-baseline.
| Identifiant | Effet |
|---|---|
001-credential-registry-key | Crée l'index unique uq_fraza_licenses_credential_secret, et retire (retired_at) les identifiants Verdaccio d'avant les clés, qui avaient un mot de passe : le registre ne les accepte plus. Chaque client régénère la clé de ses projets depuis son espace. |