Date: 24-01-2026 18:22 Status: ✅ VALIDÉ
Fin des frontends. Juste des APIs.
Un utilisateur dit ce qu'il veut en langage naturel, Ollama comprend, trouve l'API, génère un formulaire beau et user-friendly, l'utilisateur remplit, l'API est appelée. Terminé.
"Je veux créer un projet GitLab"
↓
Interface générée en live
↓
Formulaire rempli
↓
API appelée
↓
Résultat
| Concept | Application QIG |
|---|---|
| Resumability | Serveur génère le form dynamique, client reprend sans re-exécuter JS |
| Micro-bundles | Form de 50 champs = charge JS uniquement du champ cliqué |
| Lazy loading | Composants chargés à la demande, parfait pour UI inconnue à l'avance |
| 0kb JS initial | Page interactive immédiatement, JS streamé au besoin |
Cas d'usage : Ollama génère un form avec 20 champs complexes. Avec React = 500kb JS chargé. Avec Qwik = 0kb initial, ~2kb par interaction.
┌─────────────────────────────────────────────────────────────────┐
│ USER INPUT │
│ - Langage naturel : "créer un projet GitLab" │
│ - URL Swagger : https://api.example.com/swagger.json │
│ - Schema JSON brut │
│ - Description textuelle d'entités │
│ - Anything │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ OLLAMA (cerveau central) │
│ via ai-orchestrator queue │
│ priority: high pour tests │
├─────────────────────────────────────────────────────────────────┤
│ 1. INTENTION : comprendre ce que veut l'utilisateur │
│ 2. DISCOVERY : identifier l'API/connector nécessaire │
│ 3. SCHEMA : analyser le schéma de l'endpoint │
│ 4. RELATIONS : détecter entités liées, workflows │
│ 5. UI SPEC : générer la spec du formulaire │
│ - champs, types, validations │
│ - ordre logique, groupes │
│ - labels user-friendly, hints │
│ - valeurs par défaut intelligentes │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ CONNECTORS-HUB /api/fetch │
│ (pierre angulaire) │
├─────────────────────────────────────────────────────────────────┤
│ - Proxy universel vers N'IMPORTE QUELLE API │
│ - Auth centralisée (bearer, oauth2, basic, custom) │
│ - Découverte schémas (swagger, openapi, graphql) │
│ - Exécution des appels │
│ │
│ Connecteurs existants : github, gitlab, mailjet, o2switch... │
│ Extensible : ajouter n'importe quelle API │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ QIG QWIK RENDERER │
├─────────────────────────────────────────────────────────────────┤
│ SSR (Server Side Render) │
│ ├── Reçoit UI Spec de Ollama │
│ ├── Génère HTML avec Qwik components │
│ ├── Envoie au client (0kb JS) │
│ └── Client "resume" au lieu de "hydrate" │
│ │
│ Composants Qwik (lazy loaded) │
│ ├── FormField (text, number, email, url...) │
│ ├── SelectField (dropdown, multi-select) │
│ ├── CheckboxField, RadioField │
│ ├── TextArea, RichText │
│ ├── FileUpload │
│ ├── DatePicker, ColorPicker │
│ ├── Autocomplete (avec appels API) │
│ ├── ArrayField (items dynamiques) │
│ ├── ObjectField (nested forms) │
│ └── RelationField (référence autre entité) │
│ │
│ DaisyUI + Tailwind pour le style │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ EXECUTION │
├─────────────────────────────────────────────────────────────────┤
│ 1. User remplit le formulaire │
│ 2. Validation côté client (lazy loaded) │
│ 3. Submit → QIG server │
│ 4. QIG → connectors-hub /api/fetch │
│ 5. Résultat affiché proprement │
│ 6. Ollama peut enrichir l'affichage du résultat │
└─────────────────────────────────────────────────────────────────┘
1. USER INPUT
└── "Je veux créer un projet GitLab"
2. OLLAMA (job priority:high)
├── Prompt: "L'utilisateur veut: créer un projet GitLab.
│ Connecteurs disponibles: github, gitlab, mailjet, o2switch.
│ Identifie le connector et l'action."
├── Response: { connector: "gitlab", action: "create_project",
│ endpoint: "POST /projects" }
│
├── Fetch schema via connectors-hub:
│ POST /api/fetch { connector: "gitlab", path: "/projects", method: "OPTIONS" }
│ ou fetch swagger: /api/v4/swagger.json
│
└── Prompt: "Génère un formulaire user-friendly pour créer un projet GitLab.
Schema: { name: string (required), description: string,
visibility: enum[private,internal,public], ... }
Retourne une UI Spec JSON."
3. UI SPEC générée par Ollama
{
"title": "Créer un projet GitLab",
"description": "Nouveau repository sur GitLab",
"groups": [
{
"name": "Informations principales",
"fields": [
{
"id": "name",
"type": "text",
"label": "Nom du projet",
"placeholder": "mon-super-projet",
"required": true,
"hint": "Lettres, chiffres et tirets uniquement"
},
{
"id": "description",
"type": "textarea",
"label": "Description",
"placeholder": "Décrivez votre projet...",
"required": false
}
]
},
{
"name": "Paramètres",
"fields": [
{
"id": "visibility",
"type": "select",
"label": "Visibilité",
"options": [
{ "value": "private", "label": "Privé", "icon": "lock" },
{ "value": "internal", "label": "Interne", "icon": "building" },
{ "value": "public", "label": "Public", "icon": "globe" }
],
"default": "private",
"hint": "Qui peut voir ce projet ?"
}
]
}
],
"submit": {
"connector": "gitlab",
"method": "POST",
"path": "/projects",
"label": "Créer le projet"
}
}
4. QIG RENDER (Qwik SSR)
└── Génère HTML avec composants Qwik
└── Envoie au client (0kb JS initial)
5. USER INTERACTION
├── Clique sur champ "name" → charge micro-bundle validation (~1kb)
├── Clique sur select "visibility" → charge micro-bundle dropdown (~2kb)
└── Clique "Créer" → charge micro-bundle submit (~3kb)
6. SUBMIT
├── QIG POST /api/execute
│ { spec: {...}, values: { name: "test", visibility: "private" } }
├── QIG → connectors-hub POST /api/fetch
│ { connector: "gitlab", method: "POST", path: "/projects",
│ body: { name: "test", visibility: "private" } }
└── Résultat affiché
7. RESULT DISPLAY
└── Ollama enrichit: "Projet 'test' créé avec succès!
URL: https://gitlab.../test
Prochaine étape: ajouter des collaborateurs?"
qwik-interface-generator/
├── src/
│ ├── routes/
│ │ ├── index.tsx # Page principale (input)
│ │ ├── generate/
│ │ │ └── index.tsx # Affiche le form généré
│ │ └── api/
│ │ ├── intent/index.ts # POST: analyse intention (→ Ollama)
│ │ ├── schema/index.ts # POST: fetch schema API
│ │ ├── ui-spec/index.ts # POST: génère UI spec (→ Ollama)
│ │ └── execute/index.ts # POST: exécute l'action (→ fetch)
│ │
│ ├── components/
│ │ ├── input/
│ │ │ ├── NaturalInput.tsx # Input langage naturel
│ │ │ ├── SwaggerInput.tsx # Input URL swagger
│ │ │ └── SchemaInput.tsx # Input JSON brut
│ │ │
│ │ ├── form/ # Composants form (lazy loaded)
│ │ │ ├── FormRenderer.tsx # Render UI Spec → Form
│ │ │ ├── FieldRenderer.tsx # Dispatch vers bon composant
│ │ │ ├── TextField.tsx
│ │ │ ├── TextAreaField.tsx
│ │ │ ├── SelectField.tsx
│ │ │ ├── CheckboxField.tsx
│ │ │ ├── RadioField.tsx
│ │ │ ├── NumberField.tsx
│ │ │ ├── DateField.tsx
│ │ │ ├── FileField.tsx
│ │ │ ├── ArrayField.tsx # Champs répétables
│ │ │ ├── ObjectField.tsx # Nested objects
│ │ │ └── RelationField.tsx # FK vers autre entité
│ │ │
│ │ ├── result/
│ │ │ └── ResultDisplay.tsx # Affiche résultat enrichi
│ │ │
│ │ └── ui/ # Composants génériques
│ │ ├── Button.tsx
│ │ ├── Card.tsx
│ │ ├── Modal.tsx
│ │ └── Loading.tsx
│ │
│ ├── lib/
│ │ ├── ollama/
│ │ │ ├── client.ts # Client ai-orchestrator
│ │ │ ├── prompts.ts # Templates prompts
│ │ │ └── parser.ts # Parse réponses Ollama
│ │ │
│ │ ├── connectors/
│ │ │ ├── client.ts # Client connectors-hub
│ │ │ ├── auth.ts # Gestion auth/session
│ │ │ └── fetch.ts # Wrapper /api/fetch
│ │ │
│ │ └── ui-spec/
│ │ ├── types.ts # Types UISpec
│ │ ├── validator.ts # Valide UISpec
│ │ └── defaults.ts # Valeurs par défaut
│ │
│ └── styles/
│ └── global.css # Tailwind + DaisyUI
│
├── Dockerfile
├── conf.prod.gouroubleu.yml
├── .gitlab-ci.yml
└── package.json
interface UISpec {
title: string;
description?: string;
groups: FieldGroup[];
submit: SubmitAction;
}
interface FieldGroup {
name: string;
description?: string;
collapsible?: boolean;
fields: Field[];
}
interface Field {
id: string;
type: FieldType;
label: string;
placeholder?: string;
hint?: string;
required?: boolean;
default?: any;
validation?: ValidationRule[];
options?: Option[]; // pour select, radio
items?: Field; // pour array
properties?: Field[]; // pour object
relation?: RelationConfig; // pour FK
}
type FieldType =
| 'text' | 'textarea' | 'richtext'
| 'number' | 'currency'
| 'email' | 'url' | 'phone'
| 'select' | 'multiselect' | 'radio' | 'checkbox'
| 'date' | 'datetime' | 'time'
| 'file' | 'image'
| 'color'
| 'array' | 'object'
| 'relation';
interface SubmitAction {
connector: string;
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
path: string;
label: string;
confirmMessage?: string;
}
Tu es un assistant qui comprend les intentions utilisateur.
Connecteurs disponibles: ${connectorsList}
Input utilisateur: "${userInput}"
Analyse et retourne un JSON:
{
"understood": true/false,
"connector": "nom du connector ou null",
"action": "create|read|update|delete|list|custom",
"entity": "nom de l'entité (project, user, issue...)",
"endpoint_hint": "suggestion d'endpoint API",
"needs_clarification": "question si pas clair, sinon null"
}
Tu es un expert UX/UI.
Génère un formulaire user-friendly pour cette action:
- Connector: ${connector}
- Action: ${action}
- Schema API: ${jsonSchema}
Règles:
- Labels en français, clairs
- Groupes logiques
- Champs requis en premier
- Hints utiles
- Valeurs par défaut intelligentes
- Placeholder avec exemples
Retourne un JSON UISpec valide.
Setup projet Qwik propre
Composants Form de base
Intégration Ollama
Page principale
Client connectors-hub
Execution flow
Champs complexes
Validation
UX améliorée
Historique
{
"dependencies": {
"@builder.io/qwik": "latest",
"@builder.io/qwik-city": "latest",
"tailwindcss": "^3.4",
"daisyui": "^4.0"
}
}
name: qwik-interface-generator
type: qwik
port: 5505
env:
CONNECTORS_API_URL: https://connectors.33800.nowhere84.com
AI_ORCHESTRATOR_URL: https://ai-orchestrator.33800.nowhere84.com
OLLAMA_MODEL: llama3.1:8b
OLLAMA_PRIORITY: high
healthcheck:
path: /health
interval: 30s
| Test | Critère de succès |
|---|---|
| Input naturel FR | "créer projet gitlab" → form généré |
| Input naturel EN | "create github repo" → form généré |
| Swagger URL | URL swagger → forms pour tous endpoints |
| Schema JSON | JSON collé → form généré |
| Submit form | Données → API appelée → résultat |
| Micro-bundles | Network tab: JS chargé uniquement au clic |
| Resumability | Pas de hydration, reprise immédiate |
| Risque | Mitigation |
|---|---|
| Ollama lent | Priority high + cache réponses similaires |
| Hallucination Ollama | Validation UISpec + fallback |
| API inconnue | Demander URL swagger/docs |
| Form complexe | Groupes collapsibles, wizard multi-step |
Non applicable (voir règles CLAUDE.md)
✅ VALIDÉ - Phase 1 en cours