Chaque outil, en un seul endroit
Cette page est la référence pratique pour chaque outil dans la barre latérale de votre environnement Archestack. Chaque section couvre ce que fait l'outil, quand y recourir, les étapes pour les workflows les plus courants et les pièges qui attrapent les nouveaux utilisateurs. La dernière section (APIs appelables depuis un script) documente la surface exacte que les scripts peuvent appeler.
Schema Designer
Un éditeur visuel pour le schéma de base de données, tables, colonnes, types, relations, indexes, qui s'enregistre automatiquement dans un document JSON. Le schéma est la source de vérité pour votre application ; aucun autre outil ne voit une colonne tant que vous ne l'ajoutez pas ici et ne déployez pas.
Workflow courant : dans la barre d'outils, cliquez sur Add Table
(bouton-icône). Une boîte de dialogue intitulée "Create New Table" s'ouvre ; tapez un nom (le
texte d'aide rappelle "Lowercase with underscores recommended"), cliquez sur Create.
La table apparaît sur le canevas avec une clé primaire id SERIAL auto-générée.
Sélectionnez la table, le panneau de droite s'ouvre sur l'onglet Columns. Ajoutez
des colonnes depuis la boîte "Add column" à bordure pointillée en bas (champ nom, liste
déroulante Type, cliquez sur Add Column). Cliquez sur chaque colonne pour la
développer et ajuster les commutateurs (PK, NULL, UQ),
Length et Default value.
Types de colonne disponibles dans la liste déroulante Type : SERIAL, BIGSERIAL, INTEGER, BIGINT, SMALLINT, DECIMAL, NUMERIC, REAL, DOUBLE PRECISION, VARCHAR, CHAR, TEXT, BOOLEAN, DATE, TIME, TIMESTAMP, TIMESTAMPTZ, UUID, JSON, JSONB, BYTEA, INET, CIDR, MACADDR, MONEY, INTERVAL, plus les types géométriques et tableau. Length n'est pertinent que pour VARCHAR et CHAR.
Les clés étrangères résident dans l'onglet Relations du panneau de droite (pas "Relationships"). Faites défiler jusqu'à "Add relationship" : choisissez la colonne FK sur la table courante, le type de relation (One-to-One / One-to-Many / Many-to-Many), la table référencée, la colonne référencée, et cliquez sur Add Relationship. Chaque relation possède des listes déroulantes On Delete et On Update (CASCADE / SET NULL / SET DEFAULT / RESTRICT / NO ACTION).
Auto-save : l'indicateur en bas à gauche bascule entre "Auto saving..." et "Saved". Il y a aussi un bouton Save dans la barre d'outils (activé uniquement quand il y a des modifications en attente) pour les sauvegardes explicites.
Autres boutons de la barre d'outils : Add Group (conteneurs visuels pour les tables liées, panneau de propriétés intitulé "Group"), Add Text (annotations libres, panneau de propriétés intitulé "Text Annotation"), contrôles de zoom, filtre par package, recherche de table.
Pièges : renommer une colonne produit un plan destructif (drop + add),
modifiez le SQL dans l'onglet Generated SQL du déploiement pour utiliser
RENAME COLUMN si vous voulez préserver les données. Ajouter une colonne NOT
NULL à une table non vide sans valeur par défaut échoue, rendez-la nullable, remplissez,
puis altérez. Le bouton Deploy de la barre d'outils vous amène à une page de
configuration de déploiement, pas directement dans un déploiement.
Database Deployments
Liste chaque déploiement avec son statut (Draft / Executing / Succeeded / Failed) et en
exécute de nouveaux. Route : /database-deployments/overview.
Boutons en haut à droite : Refresh (recharger la liste), New Deployment (créer un nouveau brouillon).
Depuis Schema Designer : le bouton vert Deploy avec une icône de
fusée dans la barre d'outils du Schema Designer vous amène à
/database-deployments/configure/new, une page de configuration de déploiement
fraîche.
Page de configuration de déploiement : deux onglets.
- Configuration - éditeurs de scripts pré/post-déploiement (PostgreSQL) avec un bouton Test Run chacun. Le pré-script s'exécute avant les modifications de schéma ; le post-script après. Utiles pour les remplissages, les reconstructions d'index ou le nettoyage de zone de transit. Plus un basculeur Force Deploy (Allow Data Loss) pour les opérations destructives.
- Generated SQL - affiche la migration produite par la plateforme. Le SQL est éditable. Un bouton Regenerate (icône rafraîchir) relance le diff si vous avez fait des modifications de schéma depuis l'ouverture de cette page.
Boutons du haut : Back, Save (enregistre la configuration en Draft), Deploy (exécute le déploiement immédiatement). Deploy est ce sur quoi vous cliquez en dernier.
Pièges : les déploiements ne sont pas automatiquement enveloppés dans une
transaction, un échec à mi-chemin laisse la base dans un état partiel. Pour les migrations
risquées, enveloppez vos instructions dans BEGIN; ... COMMIT; dans le
pré-script. Le basculeur Force Deploy contourne les vérifications de sécurité,
utilisez-le délibérément.
Business Entities
Vues organisées construites sur une table maître plus des jointures depuis des tables liées. Les pages se lient aux Business Entities, jamais aux tables brutes. Voir Concepts -> Business Entities pour le pourquoi.
Workflow courant : cliquez sur Create. L'éditeur pleine page s'ouvre avec les onglets Visual, JSON, Events. Définissez Entity Name, Master Table (Autocomplete), et Label Column (la colonne dont la valeur représente un enregistrement dans les sélecteurs). Enregistrez, le BE auto-génère une liste de colonnes natives à partir de la table maître.
Ajout de jointures : faites défiler jusqu'à la carte Join Configurator et cliquez sur Add Join. Chaque jointure s'ouvre comme un Accordion avec : Join Type (INNER / LEFT / RIGHT), From Table, To Table (Autocomplete groupé par Database Tables / Third Party), From Column, To Column, listes déroulantes optionnelles Type Cast, et un sélecteur de colonnes pour les colonnes cibles à exposer.
Agrégations : sur une jointure, basculez Aggregate Mode. Pour chaque colonne choisie vous choisissez ensuite une Aggregate Function : COUNT / SUM / AVG / MIN / MAX / COUNT DISTINCT. "Nombre de contacts ouverts sur cette Company" est l'exemple canonique.
Run Preview : l'éditeur a un bouton Run Preview (avec une icône play) qui exécute la configuration de jointure complète et affiche de vraies lignes dans une grille de données. Si une colonne de jointure revient vide, la colonne n'a pas été cochée dans le sélecteur de colonnes de la jointure (ou la relation est mal configurée).
Plusieurs BE par table maître : rien ne vous empêche d'avoir
customer (sales view) et customer (support view) sur la même table
maître. Pages différentes, colonnes adaptées à des publics différents, même ligne
sous-jacente.
Pièges : les colonnes jointes et agrégées sont en lecture seule. Pour éditer le libellé joint, naviguez vers l'enregistrement source. Les colonnes agrégées sont recalculées à chaque requête, acceptable pour des centaines de lignes, lent sur des millions.
Page Editor
Configure l'UI d'exécution en liant une Page à un Business Entity. La plateforme auto-génère des sections en fonction des colonnes du BE ; vous affinez la disposition à partir de là. Il n'y a pas de "sélecteur de template" séparé, chaque page commence à partir de la même baseline générée et vous la personnalisez.
Workflow courant : cliquez sur Create. Remplissez Page
Name, Page Route (par exemple /companies), choisissez le
Business Entity (Autocomplete). La page s'ouvre dans l'éditeur avec les onglets
Visual, Overview, Create, Entities, Events,
JSON. Affinez la disposition auto-générée, puis basculez le switch
Published dans l'en-tête supérieur sur ON.
Types de widget de champ (le Select Type sur chaque champ) : Text,
Textarea, Number, Date, Select, Checkbox, Email. Utilisez Select pour les
champs de clé étrangère et réglez l'autocomplete Entity du champ sur le BE
référencé pour que les utilisateurs choisissent par libellé.
Onglets dans le formulaire de détail : cliquez sur Add Tab dans
l'onglet Visual. À l'intérieur d'un onglet vous pouvez ajouter une section
RelatedGrid liée à un autre BE filtré par la PK de l'enregistrement courant.
Exemple classique : une page Company avec les onglets "Contacts" et "Deals", chacun filtré
par company_id = id de la company courante.
Boutons d'action dans l'inspecteur Header du formulaire de détail. Cliquez sur Add dans la section Actions. Chaque action a Label, Icon (Save / Delete / Add / Refresh / Download / Bolt / None), Variant (Contained / Outlined / Text), Color (Primary / Secondary / Error / Success / Warning / Info) et Steps (une liste ordonnée de : Save Record, Delete Record, Navigate, Business Events, Custom). Pour exécuter un Business Event depuis un bouton, réglez le type de step sur Business Events et choisissez l'event par nom.
Publication : le switch Published dans l'en-tête supérieur est le seul contrôle de publication. ON = la page apparaît sous Published Pages dans la barre latérale et les utilisateurs finaux qui naviguent vers sa route la voient. OFF = brouillon (seuls vous dans l'éditeur voyez vos modifications).
Pièges : les colonnes auto-générées sur une Page fraîche reflètent le BE, si le BE change (vous ajoutez une jointure), la Page ne récupérera pas automatiquement les nouvelles colonnes. Rechargez la page dans l'éditeur ou ajoutez la colonne manuellement à la section. Il n'y a actuellement pas de type de step d'action "Generate PDF", pour câbler un PDF à un bouton de page, exposez le PDF via un Script Module qui appelle l'endpoint REST et utilisez un step Custom (ou appelez l'endpoint directement depuis un Frontend Template).
Business Events
Règles qui se déclenchent sur les changements de données (ou selon un calendrier, ou manuellement) et exécutent des actions quand les conditions sont satisfaites. Le mécanisme "quand X arrive, fais Y" de la plateforme. Voir Concepts -> Business Events pour le modèle.
Workflow courant : cliquez sur Create. Définissez Rule Name, basculez Enabled. Choisissez Business Entity. Cochez un ou plusieurs Triggers : BeforeCreate / BeforeUpdate / AfterCreate / AfterUpdate / BeforeDelete / OnSchedule / Manual / InitialValue. Construisez l'arbre de conditions (groupes AND/OR). Ajoutez une ou plusieurs actions dans le FlowCanvas. Enregistrez.
Types d'action (RuleActionKind) :
- Execute Script - exécute un script C#. L'action la plus flexible ; vous y avez recours dès que vous voulez définir un champ, faire un calcul, appeler une API, n'importe quoi de sur-mesure. Le script reçoit
Entity(mutez-le sur les triggers Before* pour modifier l'écriture en cours),OldEntity,Log,Db,Modules. - Validate - un script qui retourne
bool.truesignifie que la validation échoue et la sauvegarde est bloquée avec le message d'erreur configuré. Met optionnellement en évidence certaines colonnes via errorColumns. - Block Operation - arrête net l'opération avec un message configuré. Pas de script.
- Create Entity - insère un enregistrement dans un autre BE. Les valeurs de champ prennent en charge les expressions de template comme
{{ Entity.column_name }}et{{ now() }}. - Update Entity - met à jour les enregistrements dans un autre BE correspondant à un filtre de condition. Mêmes expressions de template.
- Delete Entity - supprime les enregistrements correspondant à une condition. Refuse de se déclencher sans condition (sécurité).
- Send Email / Send Webhook / Publish Event - définis dans le schéma comme améliorations futures ; actuellement journalisés et ignorés.
Schéma "Set a field" : il n'y a pas d'action discrète Set Field.
La façon de définir un champ est un Execute Script sur un trigger Before* qui mute
Entity. Exemple : Entity.title = ((string)Entity.title)?.Trim();. La
plateforme persiste l'Entity modifiée dans le cadre de l'écriture en cours, pas de requête
supplémentaire, pas de risque de récursion.
Run Simulation : l'onglet Simulate de l'éditeur de trigger a un sélecteur d'enregistrement et un bouton Run Simulation. La plateforme exécute vos conditions et actions à l'encontre de l'enregistrement choisi sans persister les modifications, les opérations d'écriture s'exécutent dans une transaction qui est rollback. Le panneau de sortie montre quelles conditions ont matché et ce que chaque action aurait fait. Utilisez ceci pour attraper les mauvaises configurations avant qu'elles ne frappent les données réelles.
Expressions de template dans la configuration d'action utilisent les
accolades {{ ... }}. Les jetons réels :
{{ Entity.column }}, {{ OldEntity.column }},
{{ now() }} / {{ getdate() }}, {{ today() }},
{{ guid() }} / {{ newid() }}, {{ year() }},
{{ month() }}, {{ day() }}, {{ timestamp() }},
des agrégats comme {{ SUM(column) }} dans les contextes de jointure,
et de l'arithmétique post-substitution comme {{ Entity.quantity * Entity.price }}.
Il n'y a pas de jeton {{ user.email }}.
Opérateurs de condition : Equals, NotEquals, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Like (= ILIKE), Contains (= ILIKE %value%), IsNull, IsNotNull, In (= ANY(...)).
Pièges : un trigger qui mute le même enregistrement qu'il surveille se
redéclenchera si vous utilisez Update Entity ; utilisez plutôt Before Update
+ Execute Script + Entity.field = .... Deux triggers sur le même event
se déclenchent par ordre de priorité. Les events désactivés apparaissent toujours dans la
liste, le basculeur Enabled est séparé de la configuration du trigger.
Script Modules
Scripts C# réutilisables compilés à l'exécution par Roslyn. Prennent des paramètres,
interrogent la base de données via le helper Db, retournent une valeur.
Appelables depuis les Business Events, les Scheduled Events et directement depuis le
front-end.
Workflow courant : cliquez sur Create. L'éditeur s'ouvre avec les
onglets Edit, Parameters, Test, JSON. Nommez le module
(PascalCase, par exemple RecalcOpenRevenue). Dans l'onglet Parameters,
cliquez sur Add par paramètre (Name, Type, Required, Default Value). Options de
Type : string, int, decimal, double, bool, DateTime. Retour à l'onglet Edit,
écrivez du C#. IntelliSense est activé.
Panneau Test : l'onglet Test affiche vos saisies de paramètres à gauche et un bouton Run (icône PlayArrow). Cliquez sur Run ; le côté droit affiche un indicateur de succès ou d'erreur, le log de sortie et la valeur de retour (formatée en JSON).
Le helper Db, voir la référence complète dans APIs appelables depuis un script plus bas.
Appel depuis un Business Event : ajoutez une action Execute Script dont le corps appelle le module :
await Modules.CallAsync("RecalcCompanyOpenDealValue", new Dictionary<string, object?> {
["company_id"] = Entity.company_id
}); Appel depuis un Scheduled Event : créez un event avec le trigger On
Schedule, définissez le cron, ajoutez une action Execute Script avec le même
corps Modules.CallAsync.
Journalisation : chaque invocation écrit une entrée dans Event Logs avec le temps d'exécution, les paramètres et le résultat (ou l'erreur).
Pièges : toujours await les appels Db, l'oublier compile mais
retourne une Task. Les retours sont passés par objet (pas sérialisés JSON par le framework) ;
pour la consommation côté front-end, retournez des objets anonymes avec des champs
primitifs. L'acceptation sur caractère de validation est intentionnellement désactivée dans
l'éditeur ; utilisez Tab pour accepter.
Frontend Templates
Fragments d'UI réutilisables écrits en TSX que le page editor peut déposer dans une page. Utile quand les templates configurés ne suffisent pas, graphiques sur-mesure, dispositions inhabituelles, intégrations de widgets tiers.
Workflow courant : cliquez sur Create, nommez le template, écrivez
un composant TSX dans l'éditeur. Le composant reçoit des props : record
(l'enregistrement courant lorsqu'embarqué dans un formulaire de détail), refresh
(re-récupérer les données) et quelques helpers. Enregistrez. Référencez le template depuis un
champ du Page Editor.
Packageable : les templates passent par le système de Packages comme tout autre objet de configuration, ils sont cascadés lorsqu'une page qui les utilise est ajoutée à un package.
Pièges : le TSX est en sandbox, vous ne pouvez pas importer de paquets npm arbitraires. Restez sur React + les helpers fournis.
PDF Templates
HTML + template Scriban + un petit script de données C# qui rend en PDF (Chromium headless). Chaque template est invocable par nom depuis un script via REST ou directement depuis un bouton sur une Page (avec un petit adaptateur, voir ci-dessous).
Workflow courant : cliquez sur + Create. L'éditeur s'ouvre avec des champs texte Name et Description en haut, cinq onglets sur le côté gauche (HTML Template, Data Script, Settings, Params, JSON) et un panneau PDF Preview toujours visible à droite. Les onglets Data Script et HTML Template ouvrent chacun un éditeur Monaco sur la moitié gauche ; l'aperçu se recompose à l'enregistrement (bouton vert Update en haut à droite).
Déclarez les paramètres dans l'onglet Params via le bouton + Add (Name, Type, Required, Default Value). Le libellé de l'onglet se met à jour en Params (n) avec le nombre. Format de page / orientation / marges / échelle / en-tête / pied de page résident dans l'onglet Settings.
Forme du data script (voir le tutoriel PDF Invoices pour un cas réel) :
var deal = await Db.GetAsync("deal", deal_id);
var lines = await Db.From("deal_line")
.Where("deal_id", "=", deal_id).ToListAsync();
return new {
InvoiceNumber = $"INV-{deal.id:D6}",
Lines = lines.Select(l => new { l.description, l.quantity })
}; Forme du template HTML (Scriban, similaire à Liquid/Handlebars) :
<h1>{{ InvoiceNumber }}</h1>
<table>
{{ for line in Lines }}
<tr><td>{{ line.description }}</td><td>{{ line.quantity }}</td></tr>
{{ end }}
</table> Panneau d'aperçu : toujours visible sur le côté droit de l'éditeur. Se recompose à l'enregistrement (bouton vert Update). Inclut une colonne de miniatures pour les PDF multi-pages et une barre d'outils de visualisation intégrée (zoom, rotation, download, print). Les boutons-icônes en haut à droite de l'éditeur basculent la visibilité du panneau d'aperçu et l'édition plein écran.
L'appeler depuis l'extérieur de l'éditeur :
POST /api/v1/pdf-templates/{id}/preview- rend par ID, retourneapplication/pdf. Utilisé par le panneau d'aperçu de l'éditeur.POST /api/v1/pdf-templates/generate/{name}- rend par nom, retourneapplication/pdf.POST /api/v1/pdf-templates/generate/{name}/base64- identique mais retourne{ "data": "<base64>" }.
Passez les valeurs de paramètre dans le corps JSON. L'auth est le Bearer token standard.
Limitation d'essai : à la fois l'endpoint generate et
l'endpoint {id}/preview (utilisé par le panneau d'aperçu de
l'éditeur) retournent 403 en mode essai, le rendu PDF est entièrement bloqué. Vous pouvez
toujours créer le template (data script, HTML, paramètres, settings) et l'enregistrer ;
vous ne verrez simplement pas de PDF rendu tant que vous n'êtes pas sur un environnement
payant.
Note sur le rendu appelable depuis un script : le contexte de scripting C#
n'expose pas de variable globale Pdf. Pour rendre un PDF depuis un
Script Module aujourd'hui, appelez l'endpoint REST generate via
HttpClient. (L'autocomplete de l'éditeur de script annonce Pdf.RenderAsync
pour compatibilité ascendante ; le binding d'exécution n'est pas encore câblé.)
Pièges : Scriban échappe le HTML par défaut. Les sauts de page sont pilotés
par CSS, page-break-before: always sur une section. Les polices disponibles sur
le serveur de rendu se limitent aux polices système plus les familles Noto et Liberation,
embarquez la vôtre via base64 @font-face si vous avez besoin d'une police de
marque.
Scheduled Events
Le même système d'Event Trigger que les Business Events, avec le trigger On Schedule coché. Utilisez-le pour les recalculs nocturnes, les digests hebdomadaires, les nettoyages périodiques, les rapports mensuels.
Workflow courant : créez un Business Event avec le trigger On
Schedule (au lieu de, ou en plus des triggers de changement de données). Configurez
l'expression cron. Ajoutez une action Execute Script dont le corps invoque un
Script Module via Modules.CallAsync(...).
Expressions cron : Quartz à 6 ou 7 champs, voir Concepts -> Scheduled Events pour les motifs courants. Les heures sont l'heure serveur (UTC sur la stack de production).
Pièges : un job long qui déborde son intervalle cron ne se double pas, Quartz ne déclenchera pas une seconde instance du même job en simultané, le second tick est sauté. Les exécutions échouées ne réessaient pas automatiquement ; intégrez le réessai dans le script.
Packages
Bundles exportables d'objets de configuration (BE, pages, events, scripts, templates, schéma) avec dépendances en cascade. Ajouter une Page à un package tire automatiquement tout ce que cette page référence.
Workflow courant (export) : cliquez sur Create, nommez et versionnez le package. Ajoutez les objets de haut niveau qui vous intéressent, généralement une poignée de pages. Ouvrez le panneau des éléments liés pour voir la liste cascadée (ce que le package contiendra réellement). Décochez ce que vous voulez omettre. Décidez d'inclure ou non les données (basculeur à l'export). Cliquez sur Export, vous obtenez un ZIP.
Workflow courant (import) : sur l'environnement de destination, ouvrez Packages, cliquez sur Import, uploadez le ZIP. La plateforme affiche ce qui sera ajouté ou mis à jour. Les deltas de schéma ne sont pas appliqués automatiquement, si le package référence une colonne qui n'existe pas sur la destination, l'import échoue.
Pièges : les identifiants sont par nom, pas par ID numérique. Un BE appelé "customer" sur la source se lie à un BE appelé "customer" sur la destination, renommez d'un côté ou de l'autre et le lien se casse.
Third-Party Data Connections
Connexions à des bases de données externes (Postgres, SQL Server, MySQL, autres) qui importent les tables selon un calendrier. Les tables importées se comportent comme des tables natives, elles apparaissent dans Schema Designer et peuvent être référencées par des Business Entities, Pages et Scripts.
Workflow courant : créez une connexion (chaîne de connexion, test, enregistrer). Listez les tables distantes disponibles ; choisissez celles à importer. Pour chaque table importée, définissez le mode de sync (Full / Delta) et le déclencheur de sync (cron / manuel / intervalle fixe).
Miroir, pas fédéré : les données importées résident dans votre propre
omnicore-db. Les lectures sont rapides (Postgres local). Compromis : fraîcheur
entre les syncs.
Colonnes gérées par l'application : marquez certaines colonnes comme "gérées par Archestack", elles ne seront pas écrasées par les syncs futurs. Utile lorsque vous voulez annoter des données fournisseur avec vos propres drapeaux de statut.
Pièges : la première sync d'une grande table peut prendre un certain
temps. Les syncs Delta nécessitent une colonne que le connecteur peut utiliser comme
watermark, généralement un timestamp modified_at.
AI Builder
Un assistant guidé dans lequel vous décrivez une fonctionnalité en langage naturel et l'assistant génère un plan de construction, ajouts de schéma, modifications de BE, pages, events, que vous passez en revue ligne par ligne et appliquez. La génération de plan est effectuée par un LLM externe de votre choix (Claude, ChatGPT, Gemini), l'assistant compose une invite autonome que vous collez et accepte la réponse JSON en retour. Il n'y a plus d'assistant de chat in-app.
Workflow courant : décrivez la fonctionnalité en 1 à 3 phrases ("ajouter le support des rendez-vous de service, chacun a une date, un customer, un vehicle et un statut"). Cliquez sur Generate prompt, collez-la dans votre LLM externe, collez la réponse JSON de retour dans l'étape Import, cliquez sur Review. Décochez ce que vous ne voulez pas. Cliquez sur Apply.
Fonctionne bien pour : les fonctionnalités de forme CRUD, les automatismes simples, les extensions directes d'entités existantes.
Moins bien pour : les règles métier non évidentes, les workflows complexes en plusieurs étapes. Le plan est un point de départ, passez-le en revue comme la PR d'un développeur junior.
Pièges : apply est irréversible. Pour les fonctionnalités risquées, prenez une sauvegarde d'abord (ou appliquez sur un environnement d'essai, évaluez, puis reconstruisez en production à partir du Package résultant).
Object Browser
Vue brute de toute table native et importée, ajout, édition, suppression de lignes directement. Inclut un import CSV pour les chargements en masse.
Quand y recourir :
- Chargement en masse de données de référence avant que les pages n'existent (pays, devises, enums de statut).
- Débogage, examen visuel de ce qui se trouve réellement dans une table quand une page se comporte mal.
- Édits admin rapides sur des données non encore exposées via une Page.
- Import CSV : choisissez une table, uploadez un fichier, mappez les colonnes aux champs, aperçu, commit.
Pièges : Object Browser déclenche bien les Business Events (il passe par le même chemin d'écriture EntityService que le front-end). L'exception est le SQL direct via Database Deployments, qui contourne tout.
Dependency Graph
Une carte en lecture seule de la façon dont les objets de configuration de votre environnement se référencent les uns les autres. Huit types de ressources apparaissent sous forme de nœuds, colorés par type : Business Entities, Pages, Event Triggers, Script Modules, PDF Templates, Frontend Templates, Scheduled Events et Packages. Une arête entre deux nœuds signifie qu'une ressource dépend de l'autre. Recourez-y pour répondre aux questions "qu'est-ce qui casserait si je supprimais ceci ?" et "y a-t-il quelque chose d'inutilisé ici ?".
Ce que signifie une arête : une Page liée à une Business Entity, un Event
Trigger enregistré sur une Business Entity, une étape d'action de Page qui déclenche un Event
Trigger, un script qui appelle un autre Script Module via
Modules.CallAsync("Name"), un script qui rend un PDF Template, un Scheduled Event
qui déclenche un Event Trigger, ou un Package qui contient une ressource. C'est une vue de
design-time, elle reflète ce que votre configuration câble ensemble, pas le trafic
d'exécution en direct.
Deux types de problèmes sont mis en évidence visuellement :
- Loose ends (orphelins) - des nœuds que rien ne référence et qui ne référencent rien. Ils sont rassemblés dans une bande "Loose ends" bordée de rouge au bas du canevas. Un Script Module que personne n'appelle ; une Page liée à rien.
- Dangling references - dessinées comme des arêtes pointillées rouges. La référence existe dans la configuration mais sa cible est introuvable, par exemple une étape d'action de Page qui pointe encore vers un Event Trigger supprimé, ou un script qui appelle un Script Module par un nom qui n'existe plus.
Workflow courant : ouvrez Dependency Graph depuis la section Tools de la sidebar. Le panneau de gauche comporte une recherche par nom, un sélecteur Layout (Left to right, Top to bottom, By type, Force-directed), les bascules Group by package, Show loose ends et Show edges, et une liste à cocher par type. Cliquez sur un nœud pour entrer en mode focus : ce nœud et ses voisins directs restent vifs tandis que le reste du graphe s'estompe, ce qui vous permet de tracer exactement ce qu'une ressource touche. Cliquez sur le fond du canevas pour effacer le focus. Chaque nœud porte un petit bouton d'ouverture dans un nouvel onglet qui saute directement vers l'éditeur de cette ressource. La ligne de stats en haut indique le nombre de nœuds, d'arêtes, d'orphelins et de dangling references.
Group by package : enveloppe les membres de chaque package dans une boîte pointillée étiquetée, pour que vous puissiez voir un package comme une unité et repérer les ressources qu'il a tirées par cascade.
Pièges : le graphe est construit à la demande à partir de l'état courant,
utilisez le bouton de rafraîchissement après avoir modifié des ressources ailleurs. Les
arêtes dérivées des scripts sont trouvées en scannant les corps de script à la recherche de la
forme d'appel littérale Modules.CallAsync("Name"), un module invoqué via un nom
calculé n'affichera pas d'arête. Une dangling reference vaut toujours la peine d'être
corrigée ; un orphelin souvent non, un Script Module flambant neuf compte comme orphelin
jusqu'à ce que quelque chose l'appelle.
Event Logs
La piste d'audit pour tout ce que la plateforme a exécuté, Business Events, Script Modules, Scheduled Events, syncs tierces.
Workflow courant : ouvrez Event Logs, réglez Status sur Failed, cliquez dans une entrée. Le panneau de détail affiche le payload (l'état de l'enregistrement au moment, les paramètres passés), l'exception avec la stack trace et le timing.
Notifications en temps réel : l'icône cloche dans la barre supérieure de l'application admin fait remonter les échecs non lus via SignalR.
Pièges : le log peut grossir. Les anciennes entrées sont conservées indéfiniment par défaut ; si le disque est une préoccupation, mettez en place un Scheduled Event qui purge les entrées de plus de N jours.
User Management
Créer, inviter et gérer les utilisateurs ; assigner les rôles realm. Enveloppe l'API REST admin Keycloak.
Rôles :
- admin - tout ; peut gérer toutes les Business Units, utilisateurs, rôles, paramètres système.
- owner - gère ses propres Business Units, peut éditer les pages d'administration et d'exécution.
- editor - peut voir et éditer les pages d'exécution, mais pas modifier la configuration de schéma/BE/event.
- user - lecture seule sur les pages d'exécution.
Pièges : rétrograder un utilisateur d'admin en cours de session ne le déconnecte pas, le changement s'applique au prochain rafraîchissement de token (généralement en moins d'une minute).
Business Units
Groupes adossés à Keycloak qui filtrent la visibilité sur des ressources individuelles. Voir Concepts -> Business Units pour le modèle.
Workflow courant : créez une BU. Invitez des membres par email et choisissez le rôle. Assignez les ressources en allant sur chaque BE / Page / Trigger ou via le panneau des éléments liés de la BU.
Assignments en cascade : lorsque vous assignez une Page à une BU, l'assignment se propage au BE auquel la page se lie.
Pièges : la BU active d'un utilisateur est définie dans le
sélecteur de BU de la barre supérieure et persiste dans localStorage. Les
nouveaux utilisateurs ont par défaut leur première BU ; si une page de liste est
suspicieusement vide, vérifiez quelle BU est active.
Database Backups
pg_dump nocturne des trois bases de données. Déclenchement / upload / restore
manuels depuis l'UI.
Workflow courant : Trigger now -> Download -> Upload -> Restore. Le calendrier est par défaut nocturne à 03:00 UTC.
Limitation d'essai : Les Backups sont désactivés dans l'environnement d'essai.
Branding
Modifier le nom d'affichage de l'application, le logo (clair + sombre) et la palette de couleurs primaire, appliqué à l'exécution, sans rebuild.
Workflow courant : définissez le nom de l'application, uploadez un logo clair et un logo sombre (PNG/JPG/SVG, ≤ 10 Mo), choisissez une couleur de marque primaire. Enregistrez. Rafraîchissez le navigateur.
Pièges : le favicon n'est pas remplacé par Branding, il est embarqué dans la SPA.
Translations
Éditeur clé/valeur pour les chaînes UI de l'application. Ajouter de nouvelles locales, surcharger les libellés par défaut par client.
Workflow courant : choisissez une locale, cherchez une clé, tapez une nouvelle valeur, enregistrez. Rafraîchissez l'application admin.
Pièges : les traductions sont chargées une fois par session ; les utilisateurs sur un onglet rance ne voient pas les changements tant qu'ils ne rafraîchissent pas. Certains libellés (en-têtes de colonnes des BE) viennent de la config du BE, pas des Translations.
APIs appelables depuis un script
La surface exacte que les scripts peuvent appeler. Vérifiée par rapport au code source, chaque méthode ci-dessous existe réellement.
Variables globales
Chaque script reçoit ces variables de premier niveau (aucun autre nom n'existe dans le scope du script) :
Entity-dynamicExpandoObject. Enregistrement courant. Accédez aux champs avecEntity.column_name. MuterEntitydans un trigger Before* persiste les modifications dans le cadre de l'écriture en cours.OldEntity-dynamicExpandoObject. Enregistrement précédent (triggers update + delete). Lecture seule.Log-ILogger.Log.LogInformation("..."),Log.LogWarning(...),Log.LogError(...). Écrit dans les logs serveur et l'entrée Event Log.Db-DbHelper. Accès base de données (voir ci-dessous).Modules-ModulesHelper. Appeler d'autres Script Modules :await Modules.CallAsync("ModuleName", new Dictionary<string, object?> { ["param"] = value }). RetourneTask<object?>.Pdf-ScriptPdfHelper. Rendre un PDF Template stocké par nom :await Pdf.GenerateAsync("invoice", new Dictionary<string, string> { ["id"] = Entity.id.ToString() })retournebyte[];await Pdf.GenerateBase64Async(...)retourne le même payload encodé en base64. Les paramètres sont transmis au data script du template comme variables locales typées string.
Il n'y a pas de User, Http, Email,
Templates ni aucune autre variable globale.
Db - méthodes de ligne unique + écriture
Toutes async, toutes sur l'objet Db de premier niveau :
await Db.GetAsync(string table, object id)- récupérer une ligne par clé primaire. Retournedynamic?(ounullsi non trouvée).await Db.CreateAsync(string table, object values)- insertion.valuespeut être un objet anonyme ou unDictionary<string, object?>. Déclenche les triggers Before/After Create. Retourneint(le nouvel ID).await Db.UpdateAsync(string table, object id, object values)- update par PK. Déclenche les triggers Before/After Update.await Db.DeleteAsync(string table, object id)- delete par PK. Déclenche le trigger Before Delete.
Db - constructeur de requête fluide
Commencez par Db.From(table). Chaînez les filtres, puis un terminal :
.Where(string column, string op, object? value = null)- ajouter une clause WHERE. Opérateurs :=,!=/<>,>,>=,<,<=,LIKE,ILIKE,IN,IS NULL,IS NOT NULL. Chaînez plusieurs appels.Where(...)pour AND..OrderBy(string column, bool desc = false)- définir ORDER BY. Un seul autorisé par requête..Limit(int limit)- lignes max. Par défaut 1000.
Terminaux (chacun exécute la requête) :
await ...ToListAsync()- retourneList<dynamic>.await ...FirstAsync()- retournedynamic?(première correspondance ou null). Définit temporairement la limit à 1.await ...CountAsync()- retourneint.
Il n'y a pas de SumAsync, MaxAsync,
FirstOrDefaultAsync ni SingleAsync. Pour les agrégations,
récupérez avec ToListAsync() et réduisez en C#.
Exemple concret
// Get a row by ID, query a list, calculate a sum, update.
var order = await Db.GetAsync("orders", 42);
if (order == null) return false;
var items = await Db.From("order_items")
.Where("order_id", "=", order.id)
.OrderBy("id")
.ToListAsync();
decimal totalAmount = 0;
foreach (var item in items) {
totalAmount += (decimal)(item.amount ?? 0);
}
await Db.UpdateAsync("orders", 42, new {
total = totalAmount,
updated_at = DateTime.UtcNow
});
return true; Mode simulation
Pendant la simulation d'un trigger (le bouton Run Simulation sur un Business Event),
la plateforme définit Db.SimulationMode = true. Toutes les opérations
d'écriture (CreateAsync, UpdateAsync, DeleteAsync)
s'exécutent à l'intérieur d'une transaction PostgreSQL qui est toujours rollback à la fin.
Les opérations de lecture fonctionnent normalement. C'est ce qui rend Run Simulation
sûr à utiliser contre des données réelles.
Modules
await Modules.CallAsync(string moduleName, Dictionary<string, object?>? parameters = null)- appeler un autre Script Module par son nom. Les paramètres deviennent des variables typées dans le script du module appelé. RetourneTask<object?>(ce que le module a retourné).
Expressions de template (actions de Business Event)
La configuration d'action utilise les accolades {{ ... }}. La liste
complète des jetons valides :
{{ Entity.column_name }}/{{ Entity.id }}{{ OldEntity.column_name }}{{ now() }}/{{ getdate() }}- date-heure UTC ISO 8601{{ today() }}- chaîne date{{ guid() }}/{{ newid() }}- GUID frais{{ year() }},{{ month() }},{{ day() }},{{ timestamp() }}- secondes Unix{{ empty() }},{{ null() }}- Agrégats dans un contexte de jointure :
{{ SUM(column) }},{{ AVG() }},{{ COUNT() }},{{ MIN() }},{{ MAX() }} - Arithmétique :
{{ Entity.quantity * Entity.price }}- évaluée après substitution viaDataTable.Compute()
Il n'y a pas de {{ user.email }} ni d'autre jeton à portée utilisateur.