Date ajout : 24/01/2026 Priorité : HAUTE Catégorie : DEV / PROJET MAJEUR Statut : CONCEPTION Effort estimé : XL (plusieurs mois)
Plateforme permettant de générer des interfaces utilisateur complètes à partir de prompts en langage naturel, connectées à des APIs externes via un système de connecteurs modulaires.
Philosophie : "Component-as-Data" - les interfaces sont des données JSON interprétées dynamiquement, pas du code compilé.
┌─────────────────────────────────────────────────────────────────────┐
│ 1. INTERPRÉTEUR DE DEMANDE (Multi-Input) │
│ "Comprendre ce que l'utilisateur veut, peu importe la source" │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ ENTRÉES POSSIBLES : │ │
│ │ │ │
│ │ A) Prompt naturel │ │
│ │ "Je veux un admin pour gérer mes produits et commandes" │ │
│ │ → LLM génère le schéma implicite │ │
│ │ │ │
│ │ B) Swagger/OpenAPI │ │
│ │ { "paths": {...}, "components": {...} } │ │
│ │ → Parse + inference sémantique │ │
│ │ │ │
│ │ C) Schéma SQL/DB │ │
│ │ CREATE TABLE products (...); │ │
│ │ → Extraction structure + relations FK │ │
│ │ │ │
│ │ D) JSON Schema │ │
│ │ { "type": "object", "properties": {...} } │ │
│ │ → Mapping direct vers types UI │ │
│ │ │ │
│ │ E) Exemple de données │ │
│ │ [{ "name": "iPhone", "price": 999, "stock": 50 }] │ │
│ │ → Inference de schéma depuis sample │ │
│ │ │ │
│ │ → OUTPUT UNIFIÉ : Intent structuré (même format) │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────┐
│ 2. CONSTRUCTEUR D'AFFICHAGE │
│ "Transformer l'intent en composants UI" │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Intent → Arbre de composants JSX (JSON serialisé) │ │
│ │ • Mapping sémantique → composants │ │
│ │ • Layout intelligent (grids, tabs, kanban) │ │
│ │ • Bindings données ↔ UI │ │
│ │ → Output: JSON structure UI prête pour Qwik │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────┐
│ 3. RENDERER QWIK (Resumable JSX) │
│ "Afficher le JSON comme du vrai JSX" │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ JSON UI → Composants Qwik natifs │ │
│ │ • Interpréteur récursif de l'arbre JSON │ │
│ │ • Composants atomiques (Button, Input, Card, Table...) │ │
│ │ • Hydratation lazy (resumability Qwik) │ │
│ │ • Signals pour réactivité │ │
│ │ → Output: Interface utilisateur interactive │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
↓↑
┌─────────────────────────────────────────────────────────────────────┐
│ 4. CONNECTEUR (Auth + Fetch) │
│ "Communiquer avec les APIs externes" │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Actions UI → Requêtes API authentifiées │ │
│ │ • Gestion OAuth/JWT/API Keys centralisée │ │
│ │ • Abstraction fetch (REST, GraphQL, RPC) │ │
│ │ • Cache intelligent │ │
│ │ • Retry + error handling │ │
│ │ → Bridge entre UI et monde extérieur │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
↓↑
┌─────────────────────────────────────────────────────────────────────┐
│ 5. INFRASTRUCTURE │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PostgreSQL │ │ Vector DB │ │ Bucket │ │
│ │ (Supabase) │ │ (pgvector) │ │ (S3/Minio) │ │
│ │ │ │ │ │ │ │
│ │ • Configs UI │ │ • Embeddings │ │ • Fichiers │ │
│ │ • Users │ │ • Semantic │ │ • Medias │ │
│ │ • Données │ │ search │ │ • Exports │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ IA OPENSOURCE (Ollama) │ │
│ │ • Inference locale (llama, qwen, mistral) │ │
│ │ • Embeddings (nomic-embed, mxbai) │ │
│ │ • Pas de dépendance cloud │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Resumability = Le JSX peut être "suspendu" côté serveur et "repris" côté client sans re-exécuter le code.
// Approche classique React :
// Le JSON est transformé en JSX → hydraté entièrement au chargement
// Approche Qwik :
// Le JSON génère du HTML avec des marqueurs
// Le JS ne charge QUE quand l'utilisateur interagit
// = Interface générée dynamiquement SANS coût de bundle
Avantages pour notre cas :
| Problème | Solution Qwik |
|---|---|
| UI générée = bundle imprévisible | Pas de bundle, lazy load par interaction |
| Hydratation lente sur grosses UI | Pas d'hydratation, resumability |
| Composants dynamiques = lourd | Serialisation native des closures |
| SSR + interactivité | Les deux gratuitement |
Exemple concret :
// Notre JSON stocké en DB
{
"type": "table",
"props": { "columns": ["name", "price", "status"] },
"bindings": { "data": "connector.api.products" },
"actions": [
{ "on": "row:click", "do": "navigate", "to": "/products/{{row.id}}" }
]
}
// Renderer Qwik (simplifié)
export const DynamicRenderer = component$((props: { node: UINode }) => {
const { node } = props;
// Qwik sérialise cette fonction, pas besoin de la re-créer côté client
const Component = getComponent(node.type); // Table, Form, Card, etc.
return (
<Component
{...node.props}
data={useConnector(node.bindings?.data)}
onAction$={(action) => executeAction(action)}
>
{node.children?.map(child => <DynamicRenderer node={child} />)}
</Component>
);
});
Peu importe la source, tout converge vers le même format interne :
┌────────────────────┐
│ "Un CRM simple" │ ──→ LLM inference
└────────────────────┘ │
│
┌────────────────────┐ │
│ swagger.json │ ──→ Parser │
└────────────────────┘ │
▼
┌────────────────────┐ ┌──────────────────────────┐
│ schema.sql │ ──→│ INTENT UNIFIÉ │
└────────────────────┘ │ │
│ { │
┌────────────────────┐ │ entities: [...], │
│ { "$schema": ...} │ ──→│ relations: [...], │
└────────────────────┘ │ workflows: [...], │
│ fields: [...], │
┌────────────────────┐ │ actions: [...] │
│ [sample data] │ ──→│ } │
└────────────────────┘ └──────────────────────────┘
│
▼
Constructeur d'affichage
Exemples de convergence :
| Input | Traitement | Intent généré |
|---|---|---|
"admin pour e-commerce" |
LLM génère schema | entities: [products, orders, users] |
swagger.json (PetStore) |
Parse endpoints | entities: [pets, orders], actions: [addPet, findByStatus] |
CREATE TABLE users (...) |
Parse DDL | entities: [users], fields: [id, email, created_at] |
[{name: "...", price: 99}] |
Inference types | entities: [items], fields: [name:string, price:number] |
Concept : Interprète du JSON pour générer des composants Qwik à la volée.
// Exemple de composant JSON
{
"type": "card",
"props": { "variant": "elevated" },
"children": [
{ "type": "text", "props": { "content": "{{data.title}}" }},
{ "type": "button", "props": { "action": "connector.stripe.pay" }}
]
}
Avantages :
Pipeline :
Exemple :
Prompt: "Un formulaire de réservation de vol"
↓
Intent: { type: "form", domain: "travel", action: "booking" }
↓
Actions: [
"connector.amadeus.search_flights",
"connector.stripe.create_payment"
]
↓
JSON: { components: [...], bindings: [...], actions: [...] }
Architecture : Chaque connecteur expose une interface standardisée.
interface Connector {
id: string;
name: string;
actions: Action[];
auth: AuthConfig;
execute(action: string, params: object): Promise<Result>;
getSchema(): OpenAPISpec;
}
Connecteurs prévus : | Connecteur | Usage | Priorité | |------------|-------|----------| | Supabase | BDD, Auth | P0 | | Stripe | Paiements | P1 | | Amadeus | Réservations voyage | P1 | | Google APIs | Maps, Calendar | P2 | | OpenAI | LLM externe | P2 | | Custom HTTP | APIs tierces | P1 |
Concept : Générer un admin à partir d'un Swagger/OpenAPI, avec une couche IA qui comprend la sémantique pour déterminer les UI/UX appropriées.
# Input: Swagger
paths:
/products:
get: { summary: "List products" }
post: { summary: "Create product" }
/products/{id}:
get/put/delete: ...
components:
schemas:
Product:
properties:
id: { type: string, format: uuid }
name: { type: string, maxLength: 100 }
price: { type: number }
category_id: { type: string, format: uuid }
status: { enum: [draft, published, archived] }
created_at: { type: string, format: date-time }
→ Output: Admin intelligent (PAS juste un CRUD bête)
Couche d'Intelligence UI/UX :
| Analyse Swagger | Décision IA | UI Générée |
|---|---|---|
maxLength: 100 |
Champ court | Input text (pas textarea) |
format: uuid + _id suffix |
Relation FK | Select avec recherche async |
enum: [draft, published, archived] |
États finis | Badges colorés + dropdown |
format: date-time |
Temporel | DatePicker + affichage relatif |
required: [name, price] |
Validation | Indicateurs visuels + validation |
| Endpoint DELETE existe | Action destructive | Confirmation modal + soft delete UI |
| Beaucoup de propriétés | Complexité | Tabs ou sections collapsibles |
Inférences Sémantiques :
// L'IA analyse les noms et contextes
{
"name": "...", // → Colonne principale, titre dans les cards
"description": "...", // → Textarea, preview markdown
"email": "...", // → Input email + validation format
"password": "...", // → Input password + toggle visibility
"avatar_url": "...", // → Image upload + preview
"price": "...", // → Input number + currency formatting
"is_active": "...", // → Toggle switch (pas checkbox)
"tags": ["..."], // → Multi-select chips
"metadata": {...}, // → JSON editor collapsible
}
Workflows Déduits :
Swagger: POST /products → 201
PUT /products/{id}/publish → 200
DELETE /products/{id} → 204
IA déduit:
1. Création → état "draft" par défaut
2. Action "Publier" visible si draft
3. Suppression = archivage soft (pas hard delete)
4. Liste filtrée par status avec compteurs
Exemple Concret :
Input: Swagger API e-commerce (products, categories, orders, users)
Output Intelligent:
├── Dashboard avec stats clés (orders today, revenue, low stock)
├── Products
│ ├── Liste avec filtres intelligents (status, category, stock < 10)
│ ├── Bulk actions (publish, archive, update price)
│ ├── Inline edit pour champs simples
│ └── Form création avec preview live
├── Categories
│ ├── Tree view (si self-referencing detected)
│ └── Drag & drop réorganisation
├── Orders
│ ├── Kanban par status (pending → processing → shipped → delivered)
│ ├── Timeline des events
│ └── Actions contextuelles (refund, cancel, resend)
└── Users
├── Recherche full-text
├── Rôles avec badges
└── Activity log
Étapes d'analyse :
┌─────────────────────────────────────────────────────────────────────┐
│ 1. PARSING │
│ Swagger JSON/YAML → Structure normalisée │
│ - Endpoints, méthodes, schémas, relations │
└─────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────┐
│ 2. INFERENCE SÉMANTIQUE (LLM) │
│ "Qu'est-ce que cette API gère réellement ?" │
│ - Domaine métier (e-commerce, CRM, booking, etc.) │
│ - Entités principales vs secondaires │
│ - Relations (1-N, N-N, hiérarchie) │
│ - Workflows implicites (états, transitions) │
└─────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────┐
│ 3. MAPPING UI/UX │
│ "Quelle UI correspond à cette sémantique ?" │
│ - Composants par type de donnée │
│ - Layouts par complexité │
│ - Actions par workflow │
│ - Navigation par relations │
└─────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────┐
│ 4. GÉNÉRATION JSON │
│ Structure d'interface complète │
│ - Pages, composants, bindings, actions │
│ - Connecteur auto-configuré vers l'API source │
└─────────────────────────────────────────────────────────────────────┘
Prompt LLM (exemple) :
Analyse ce Swagger et détermine :
1. Le domaine métier de cette API
2. L'entité principale (celle qu'on gère le plus)
3. Les relations entre entités
4. Les workflows métier implicites (ex: draft → published)
5. Les champs qui méritent une UI spéciale (images, richtext, etc.)
Swagger:
{swagger_json}
Réponds en JSON structuré.
Output LLM :
{
"domain": "e-commerce",
"primary_entity": "products",
"entities": {
"products": {
"importance": "primary",
"display_field": "name",
"image_field": "thumbnail_url",
"status_field": "status",
"workflows": [
{ "from": "draft", "to": "published", "action": "publish" },
{ "from": "*", "to": "archived", "action": "archive" }
]
},
"categories": {
"importance": "secondary",
"hierarchy": true,
"parent_field": "parent_id"
},
"orders": {
"importance": "primary",
"display_mode": "kanban",
"status_field": "status",
"timeline_field": "events"
}
},
"special_fields": {
"description": "richtext",
"metadata": "json_editor",
"tags": "multi_select",
"avatar_url": "image_upload"
}
}
Éléments partageables :
Livrables : Upload Swagger → CRUD basique fonctionnel
Livrables : Upload Swagger e-commerce → Admin intelligent avec dashboard, filtres, bulk actions
Livrables : Admin connecté à plusieurs services externes
| Couche | Technologie | Justification |
|---|---|---|
| Frontend | Qwik | Resumability, performance |
| Styling | Tailwind + DaisyUI | Rapid prototyping |
| Backend | FastAPI | Async, Python ML-friendly |
| BDD | Supabase (PostgreSQL) | Realtime, Auth intégrée |
| Cache | Redis | Queue jobs IA |
| IA | Ollama local | Contrôle, pas de coûts API |
interface UIComponent {
id: string; // Unique identifier
type: string; // Component type (card, form, button...)
props: Record<string, any>; // Static properties
bindings: Record<string, string>; // Dynamic bindings {{data.xxx}}
children?: UIComponent[]; // Nested components
actions?: ActionRef[]; // Triggered actions
conditions?: Condition[]; // Visibility conditions
}
interface PageState {
data: Record<string, any>; // Données dynamiques
ui: Record<string, any>; // États UI (loading, errors)
user: UserContext; // Contexte utilisateur
connectors: ConnectorStates; // États des connecteurs
}
| Service | Usage | Status |
|---|---|---|
| AI-Orchestrator | Exécution jobs IA | ✅ PROD |
| Supabase | BDD + Auth | ✅ PROD |
| Ollama (win11) | LLM local | ✅ PROD |
| GitLab CI/CD | Déploiement | ✅ PROD |
| connectors-api | Auth + Fetch centralisé | 🔧 À ÉVOLUER |
AVANT de commencer le générateur, il faut évoluer connectors-api pour en faire un hub centralisé auth + fetch.
connectors-api (port 5400)
├── /api/connectors → Liste/config des connecteurs
├── /api/connectors/:id/auth → Initier OAuth
├── /api/fetch → Proxy générique (injecte auth auto)
└── DB: connectors_config, connectors_tokens (Supabase)
Backlog dédié : À créer pour l'évolution connectors-api
qwik-interface-generatorSwagger cible : Une API REST existante (ex: PetStore, ou une API interne)
Résultat attendu :
1. Upload swagger.json
2. IA analyse → "C'est une API de gestion d'animaux de compagnie"
3. Génère admin avec :
- Liste pets avec filtres (status, category)
- Formulaire création avec upload image
- Vue détail avec infos propriétaire (relation)
- Actions: adopt, vaccinate (si endpoints existent)