Date : 24/01/2026 16:30 Status : IMPLEMENTEE Projet : qwik-interface-generator Phase : 1 - Fondations
Le prérequis connectors-api est maintenant complété (v2.3.1) avec :
/api/connectors - Liste et config des connecteurs/api/connectors/:id/auth - OAuth flow/api/fetch - Proxy générique avec auth autoconnectors.config, connectors.tokensOn peut donc commencer le projet de génération d'interfaces.
Livrable : Upload Swagger -> CRUD basique fonctionnel
Démontrer le concept "Component-as-Data" :
# Créer repo GitLab
# Initialiser projet Qwik
npm create qwik@latest
# Structure de base
Structure cible :
qwik-interface-generator/
├── src/
│ ├── components/
│ │ ├── dynamic/ # Renderer dynamique
│ │ │ ├── DynamicRenderer.tsx
│ │ │ └── components/ # Composants atomiques
│ │ │ ├── Text.tsx
│ │ │ ├── Button.tsx
│ │ │ ├── Card.tsx
│ │ │ ├── Table.tsx
│ │ │ ├── Form.tsx
│ │ │ └── Input.tsx
│ │ └── ui/ # Composants UI statiques
│ ├── lib/
│ │ ├── parser/ # Swagger parser
│ │ │ ├── swagger.ts
│ │ │ └── intent.ts
│ │ ├── builder/ # JSON UI builder
│ │ │ └── builder.ts
│ │ └── connector/ # Client connectors-api
│ │ └── client.ts
│ └── routes/
│ ├── index.tsx # Landing page
│ └── app/ # Application générée
│ └── [page]/
└── conf.gouroubleu.yml # Config déploiement
Input : Fichier OpenAPI 3.0 JSON/YAML
Output : Intent structuré
interface SwaggerIntent {
info: {
title: string;
domain?: string; // Inféré ou explicite
};
entities: Entity[];
endpoints: Endpoint[];
schemas: Schema[];
}
interface Entity {
name: string;
schema: string; // Ref vers schemas
endpoints: {
list?: string; // GET /entities
get?: string; // GET /entities/{id}
create?: string; // POST /entities
update?: string; // PUT /entities/{id}
delete?: string; // DELETE /entities/{id}
};
}
Input : SwaggerIntent
Output : JSON Interface (pages + composants)
interface UIPage {
id: string;
title: string;
path: string;
components: UIComponent[];
}
interface UIComponent {
id: string;
type: 'text' | 'button' | 'card' | 'table' | 'form' | 'input';
props: Record<string, any>;
bindings?: Record<string, string>; // {{data.xxx}}
children?: UIComponent[];
actions?: UIAction[];
}
Concept : Interpréter le JSON pour rendre des composants Qwik.
// DynamicRenderer.tsx
export const DynamicRenderer = component$<{ node: UIComponent }>((props) => {
const { node } = props;
const ComponentMap: Record<string, any> = {
text: TextComponent,
button: ButtonComponent,
card: CardComponent,
table: TableComponent,
form: FormComponent,
input: InputComponent,
};
const Component = ComponentMap[node.type];
if (!Component) return null;
return (
<Component {...node.props} bindings={node.bindings}>
{node.children?.map((child) => (
<DynamicRenderer key={child.id} node={child} />
))}
</Component>
);
});
| Composant | Props | Usage |
|---|---|---|
| Text | content, variant | Titres, labels |
| Button | label, variant, action | Actions |
| Card | title, children | Conteneur |
| Table | columns, data | Listes CRUD |
| Form | fields, onSubmit | Création/édition |
| Input | type, label, value | Champs formulaire |
// Wrapper pour appeler connectors-api /api/fetch
export async function connectorFetch(
connectorId: string,
path: string,
options?: RequestInit
) {
const response = await fetch('https://connectors.33800.nowhere84.com/api/fetch', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
connector_id: connectorId,
path,
method: options?.method || 'GET',
body: options?.body,
}),
});
return response.json();
}
Utilisateur upload : petstore.swagger.json
Parser extrait :
Builder génère :
Renderer affiche : Interface fonctionnelle
Actions utilisent : connectors-api pour appeler l'API source
| Couche | Technologie |
|---|---|
| Framework | Qwik |
| Styling | Tailwind + DaisyUI |
| Parsing YAML | yaml (npm) |
| HTTP Client | fetch natif |
| Déploiement | Docker + GitLab CI |
# .gitlab-ci.yml
stages:
- build
- deploy
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
deploy:
stage: deploy
script:
- smart-deploy trigger qwik-interface-generator
only:
- main
/stock_8to/33800-stack/projects/qwik-interface-generator/ - Repo localgouroubleu/qwik-interface-generatorconf.prod.gouroubleu.yml - Config Dockerqig.33800.nowhere84.com (ou autre subdomain)Total Phase 1 : ~8-10 sessions
qig.33800.nowhere84.com/api/auth/login de connectors-api┌─────────────────────────────────────────────────────────────────────┐
│ QIG (qig.33800.nowhere84.com) │
│ │
│ 1. User arrive → Redirect login si pas de JWT │
│ 2. Login form → POST connectors-api/api/auth/login │
│ 3. JWT reçu → Stocké localStorage │
│ 4. Toutes requêtes vers connectors-api avec Authorization: Bearer │
│ 5. Upload Swagger → Parse → Génère UI │
│ 6. UI générée appelle connectors-api/api/fetch avec JWT │
└─────────────────────────────────────────────────────────────────────┘
Avantages :
URL : https://connectors.33800.nowhere84.com/swagger/json
Endpoints disponibles :
GET /api/connectors - Liste connecteursGET /api/connectors/:id - Détail connecteurPOST /api/fetch - Proxy fetchParfait pour le MVP : on génère une interface pour gérer connectors-api lui-même.