33800 Docs

← Retour

Proposition : Qwik Interface Generator - Phase 1 (MVP)

Date : 24/01/2026 16:30 Status : IMPLEMENTEE Projet : qwik-interface-generator Phase : 1 - Fondations


Contexte

Le prérequis connectors-api est maintenant complété (v2.3.1) avec :

On peut donc commencer le projet de génération d'interfaces.


Objectif Phase 1

Livrable : Upload Swagger -> CRUD basique fonctionnel

Démontrer le concept "Component-as-Data" :

  1. Parser un Swagger pour extraire les endpoints et schémas
  2. Générer un JSON d'interface (pages, composants, bindings)
  3. Rendre dynamiquement l'interface avec Qwik

Étapes Proposées

1. Setup Projet (GitLab + Qwik)

# 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

2. Parser Swagger (lib/parser/)

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}
  };
}

3. Builder JSON UI (lib/builder/)

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[];
}

4. Renderer Dynamique (components/dynamic/)

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>
  );
});

5. Composants Atomiques MVP

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

6. Client Connectors-API (lib/connector/)

// 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();
}

Scénario de Démonstration

  1. Utilisateur upload : petstore.swagger.json

  2. Parser extrait :

    • Entities: pets, orders, users
    • Endpoints: CRUD pour chaque entité
  3. Builder génère :

    • Page "Pets" avec Table (list) + bouton "Add"
    • Page "Pet Details" avec Card + boutons Edit/Delete
    • Modal "Add Pet" avec Form
  4. Renderer affiche : Interface fonctionnelle

  5. Actions utilisent : connectors-api pour appeler l'API source


Stack Technique Phase 1

Couche Technologie
Framework Qwik
Styling Tailwind + DaisyUI
Parsing YAML yaml (npm)
HTTP Client fetch natif
Déploiement Docker + GitLab CI

CI/CD

# .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

Fichiers à Créer

  1. /stock_8to/33800-stack/projects/qwik-interface-generator/ - Repo local
  2. GitLab : gouroubleu/qwik-interface-generator
  3. conf.prod.gouroubleu.yml - Config Docker
  4. Nginx config pour qig.33800.nowhere84.com (ou autre subdomain)

Estimation

Total Phase 1 : ~8-10 sessions


Décisions Validées

  1. Subdomain : qig.33800.nowhere84.com
  2. Swagger de test : Utiliser le Swagger de connectors-api (v2.3.1)
  3. Authentification : Utilisateur DOIT être connecté via connectors-api
    • Login via /api/auth/login de connectors-api
    • JWT stocké côté client
    • Accès aux connecteurs (github, mailjet, o2switch, linkedin) via le compte gouroubleu
  4. Priorité composants : Table + Form (CRUD first)

Flow Authentification

┌─────────────────────────────────────────────────────────────────────┐
│  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 :


Swagger de Test : connectors-api

URL : https://connectors.33800.nowhere84.com/swagger/json

Endpoints disponibles :

Parfait pour le MVP : on génère une interface pour gérer connectors-api lui-même.


Validation