33800 Docs

← Retour

RapidAPI Builder + Qwik Generator - Architecture Technique

Date : 20/12/2025 Priorite : MOYENNE - FIL ROUGE Status : Draft Projet : Générateur de code API et composants Qwik assisté par IA


1. Vue d'ensemble

┌─────────────────────────────────────────────────────────────────────┐
│                         INTERFACE WEB                                │
│                        Qwik + Monaco Editor                         │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│  │  Schema  │ │   API    │ │  Qwik    │ │ Preview  │ │  Export  │  │
│  │  Editor  │ │Generator │ │Generator │ │   Live   │ │  GitLab  │  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘  │
└─────────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼
┌─────────────────────────────────────────────────────────────────────┐
│                           API                                        │
│                      Elysia (Bun)                                   │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐               │
│  │/generate │ │/templates│ │ /preview │ │ /export  │               │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘               │
└─────────────────────────────────────────────────────────────────────┘
         │              │              │              │
         ▼              ▼              ▼              ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│   Ollama    │  │  Supabase   │  │  Sandpack   │  │   GitLab    │
│   Code Gen  │  │  Templates  │  │  Preview    │  │    API      │
└─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘

2. Concept

Qu'est-ce que ça génère ?

Type Input Output
API Controller Schéma JSON/description Controller Elysia complet
CRUD Supabase Nom de table + colonnes Routes + types + service
Page Qwik Description + wireframe Composant Qwik complet
Module Qwik Description fonctionnelle Composants + routes + state

Exemple d'utilisation

Input:
"Créer une API pour gérer des produits avec nom, prix, description,
catégorie. Inclure pagination, filtres et recherche."

Output:
├── src/
│   ├── routes/products/
│   │   ├── index.ts          # GET /products (liste + filtres)
│   │   ├── [id].ts           # GET /products/:id
│   │   ├── create.ts         # POST /products
│   │   ├── update.ts         # PUT /products/:id
│   │   └── delete.ts         # DELETE /products/:id
│   ├── services/
│   │   └── product.service.ts
│   ├── types/
│   │   └── product.types.ts
│   └── validators/
│       └── product.validator.ts

3. Stack Technique

Frontend

Techno Usage
Qwik Interface principale
Monaco Editor Édition code
Sandpack Preview live
TailwindCSS Styling

Backend

Techno Usage
Elysia (Bun) API génération
Supabase Stockage templates, projets

IA

Techno Usage
Ollama (deepseek-coder / codellama) Génération code

Intégrations

Service Usage
GitLab API Export vers repos
GitHub API Export (optionnel)

4. Schéma Base de Données

-- ============================================
-- TEMPLATES
-- ============================================

CREATE TABLE templates (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    name VARCHAR(200) NOT NULL,
    description TEXT,
    category VARCHAR(50), -- api, component, page, module, full-stack

    -- Type de framework
    framework VARCHAR(50), -- elysia, express, qwik, react
    language VARCHAR(20), -- typescript, javascript

    -- Template content
    template_code TEXT NOT NULL,
    variables JSONB, -- [{ name: "entityName", type: "string", description: "..." }]

    -- Metadata
    is_system BOOLEAN DEFAULT false, -- Templates fournis par défaut
    usage_count INTEGER DEFAULT 0,
    avg_rating DECIMAL(2,1),

    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================
-- PROJETS UTILISATEUR
-- ============================================

CREATE TABLE projects (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,

    name VARCHAR(200) NOT NULL,
    description TEXT,

    -- Configuration
    config JSONB, -- { framework, database, auth, etc }

    -- GitLab/GitHub
    git_provider VARCHAR(20), -- gitlab, github
    git_repo_url TEXT,
    git_repo_id VARCHAR(100),

    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================
-- FICHIERS GÉNÉRÉS
-- ============================================

CREATE TABLE generated_files (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES projects(id) ON DELETE CASCADE,

    file_path VARCHAR(500) NOT NULL, -- src/routes/products/index.ts
    file_type VARCHAR(50), -- controller, service, component, type, validator
    content TEXT NOT NULL,

    -- Génération
    prompt_used TEXT,
    template_id UUID REFERENCES templates(id),
    generation_model VARCHAR(50),

    -- Versioning
    version INTEGER DEFAULT 1,
    is_modified BOOLEAN DEFAULT false, -- Modifié manuellement après génération

    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================
-- SCHÉMAS (pour génération CRUD)
-- ============================================

CREATE TABLE schemas (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES projects(id) ON DELETE CASCADE,

    name VARCHAR(100) NOT NULL, -- Product, User, Order
    table_name VARCHAR(100), -- products, users, orders

    -- Colonnes
    columns JSONB NOT NULL,
    /* [
        { "name": "id", "type": "uuid", "primary": true },
        { "name": "name", "type": "string", "required": true, "maxLength": 200 },
        { "name": "price", "type": "decimal", "required": true },
        { "name": "category_id", "type": "uuid", "foreign": "categories.id" }
    ] */

    -- Relations
    relations JSONB,
    /* [
        { "type": "belongsTo", "model": "Category", "foreignKey": "category_id" },
        { "type": "hasMany", "model": "Review", "foreignKey": "product_id" }
    ] */

    -- Génération
    generate_crud BOOLEAN DEFAULT true,
    generate_types BOOLEAN DEFAULT true,
    generate_validators BOOLEAN DEFAULT true,

    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================
-- HISTORIQUE GÉNÉRATIONS
-- ============================================

CREATE TABLE generation_history (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES projects(id) ON DELETE CASCADE,
    user_id UUID REFERENCES auth.users(id),

    -- Input
    generation_type VARCHAR(50), -- crud, controller, component, page
    input_prompt TEXT,
    input_schema JSONB,

    -- Output
    files_generated TEXT[], -- Liste des chemins
    output_preview TEXT, -- Aperçu du code principal

    -- Metadata
    model_used VARCHAR(50),
    tokens_used INTEGER,
    duration_ms INTEGER,

    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ============================================
-- SNIPPETS FAVORIS
-- ============================================

CREATE TABLE snippets (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,

    name VARCHAR(200) NOT NULL,
    description TEXT,
    language VARCHAR(20),
    code TEXT NOT NULL,
    tags TEXT[],

    usage_count INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

5. API Endpoints

Templates

GET    /api/templates                     # Liste templates
GET    /api/templates/:id                 # Détail template
POST   /api/templates                     # Créer template custom

Projets

GET    /api/projects                      # Mes projets
POST   /api/projects                      # Créer projet
GET    /api/projects/:id                  # Détail projet
GET    /api/projects/:id/files            # Fichiers du projet
DELETE /api/projects/:id                  # Supprimer

Génération

POST   /api/generate/crud
       Body: {
           projectId: "...",
           schema: { name: "Product", columns: [...] }
       }

POST   /api/generate/controller
       Body: {
           projectId: "...",
           description: "API pour gérer les commandes..."
       }

POST   /api/generate/component
       Body: {
           projectId: "...",
           description: "Card produit avec image, prix, bouton achat",
           framework: "qwik"
       }

POST   /api/generate/page
       Body: {
           projectId: "...",
           description: "Page liste produits avec filtres et pagination"
       }

POST   /api/generate/from-prompt
       Body: {
           projectId: "...",
           prompt: "Description libre..."
       }

Preview

POST   /api/preview                       # Preview live (Sandpack)
       Body: { files: { "index.tsx": "..." } }

Export

POST   /api/export/gitlab
       Body: {
           projectId: "...",
           repoUrl: "...",
           branch: "main",
           commitMessage: "..."
       }

POST   /api/export/zip                    # Télécharger ZIP

6. Génération IA

Modèles recommandés

Modèle Usage Qualité code
deepseek-coder:6.7b Génération rapide Très bon
codellama:13b Génération complexe Excellent
mistral:7b Fallback Bon

Prompts système

// /lib/prompts.ts

export const SYSTEM_PROMPTS = {
    elysia_controller: `Tu es un expert en développement TypeScript avec Elysia (Bun).
Tu génères des controllers API REST suivant ces conventions:
- Utiliser Elysia avec le plugin swagger
- Typage strict TypeScript
- Validation avec Zod ou t (Elysia typebox)
- Gestion d'erreurs appropriée
- JSDoc pour documentation
- Pattern async/await

Structure type:
\`\`\`typescript
import { Elysia, t } from 'elysia';
import { swagger } from '@elysiajs/swagger';

const app = new Elysia()
    .use(swagger())
    .get('/items', async () => {...})
    .post('/items', async ({ body }) => {...}, {
        body: t.Object({...})
    })
\`\`\`
`,

    qwik_component: `Tu es un expert Qwik.js.
Tu génères des composants Qwik suivant ces conventions:
- Utiliser component$ pour les composants
- Utiliser useSignal$ pour le state local
- Utiliser useStore pour le state complexe
- Utiliser $() pour les handlers
- Utiliser useTask$ pour les side effects
- Styling avec TailwindCSS
- Accessibilité (aria-*, roles)

Structure type:
\`\`\`tsx
import { component$, useSignal } from '@builder.io/qwik';

export const MyComponent = component$(() => {
    const count = useSignal(0);

    return (
        <div class="...">
            ...
        </div>
    );
});
\`\`\`
`,

    crud_supabase: `Tu génères du code CRUD pour Supabase avec TypeScript.
Conventions:
- Client Supabase typé
- Types générés depuis le schéma
- Gestion erreurs
- Pagination avec range()
- Filtres avec .eq(), .ilike(), etc.
`
};

Générateur CRUD

// /services/crud-generator.ts

interface Column {
    name: string;
    type: 'string' | 'number' | 'boolean' | 'date' | 'uuid' | 'json';
    required?: boolean;
    primary?: boolean;
    maxLength?: number;
    foreign?: string;
}

interface Schema {
    name: string;       // Product
    tableName: string;  // products
    columns: Column[];
}

async function generateCRUD(schema: Schema): Promise<GeneratedFiles> {
    const files: GeneratedFiles = {};

    // 1. Types
    files[`src/types/${schema.name.toLowerCase()}.types.ts`] = generateTypes(schema);

    // 2. Validator
    files[`src/validators/${schema.name.toLowerCase()}.validator.ts`] = generateValidator(schema);

    // 3. Service
    files[`src/services/${schema.name.toLowerCase()}.service.ts`] = generateService(schema);

    // 4. Controller (routes Elysia)
    files[`src/routes/${schema.tableName}/index.ts`] = await generateController(schema);

    return files;
}

function generateTypes(schema: Schema): string {
    const typeMap: Record<string, string> = {
        'string': 'string',
        'number': 'number',
        'boolean': 'boolean',
        'date': 'Date',
        'uuid': 'string',
        'json': 'Record<string, unknown>'
    };

    const props = schema.columns
        .map(col => `    ${col.name}${col.required ? '' : '?'}: ${typeMap[col.type]};`)
        .join('\n');

    return `// Auto-generated types for ${schema.name}

export interface ${schema.name} {
${props}
}

export interface ${schema.name}Create {
${schema.columns.filter(c => !c.primary).map(col =>
    `    ${col.name}${col.required ? '' : '?'}: ${typeMap[col.type]};`
).join('\n')}
}

export interface ${schema.name}Update {
${schema.columns.filter(c => !c.primary).map(col =>
    `    ${col.name}?: ${typeMap[col.type]};`
).join('\n')}
}

export interface ${schema.name}Filters {
    search?: string;
    page?: number;
    limit?: number;
    sortBy?: keyof ${schema.name};
    sortOrder?: 'asc' | 'desc';
}
`;
}

async function generateController(schema: Schema): Promise<string> {
    const prompt = `
Génère un controller Elysia complet pour l'entité ${schema.name}.

Schéma:
${JSON.stringify(schema, null, 2)}

Le controller doit inclure:
- GET / (liste avec pagination, filtres, recherche)
- GET /:id (détail)
- POST / (création avec validation)
- PUT /:id (mise à jour)
- DELETE /:id (suppression)
- Documentation Swagger

Utilise le service ${schema.name}Service déjà créé.
Réponds uniquement avec le code TypeScript, sans explication.
`;

    const response = await fetch('http://192.168.1.30:11434/api/generate', {
        method: 'POST',
        body: JSON.stringify({
            model: 'deepseek-coder:6.7b',
            prompt,
            system: SYSTEM_PROMPTS.elysia_controller
        })
    });

    const result = await response.text();
    return extractCode(result);
}

Générateur Composant Qwik

// /services/component-generator.ts

async function generateQwikComponent(description: string): Promise<string> {
    const prompt = `
Génère un composant Qwik.js basé sur cette description:

"${description}"

Le composant doit:
- Être exporté comme component$
- Utiliser TailwindCSS pour le styling
- Être accessible (aria-labels si nécessaire)
- Gérer le state avec useSignal si nécessaire
- Inclure les types TypeScript

Réponds uniquement avec le code TSX, sans explication.
`;

    const response = await fetch('http://192.168.1.30:11434/api/generate', {
        method: 'POST',
        body: JSON.stringify({
            model: 'deepseek-coder:6.7b',
            prompt,
            system: SYSTEM_PROMPTS.qwik_component
        })
    });

    return extractCode(await response.text());
}

7. Interface Utilisateur

Écran principal

┌─────────────────────────────────────────────────────────────────────┐
│  RapidBuilder                           [Projets ▼]  [Templates] [⚙️]│
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────┐  ┌───────────────────────────────────┐│
│  │  📁 Projet: HelloCar    │  │  GÉNÉRATEUR                       ││
│  │  ─────────────────────  │  │                                   ││
│  │  📂 src/                │  │  [CRUD] [Controller] [Component]  ││
│  │    📂 routes/           │  │                                   ││
│  │      📂 products/       │  │  Décris ce que tu veux générer:   ││
│  │        📄 index.ts ●    │  │  ┌─────────────────────────────┐  ││
│  │        📄 [id].ts       │  │  │ Une API pour gérer les     │  ││
│  │    📂 services/         │  │  │ commandes avec status,     │  ││
│  │      📄 product.ts      │  │  │ client, produits, total... │  ││
│  │    📂 types/            │  │  └─────────────────────────────┘  ││
│  │                         │  │                                   ││
│  │  [+ Nouveau fichier]    │  │  [✨ Générer]                     ││
│  └─────────────────────────┘  └───────────────────────────────────┘│
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────────┐│
│  │  // src/routes/products/index.ts                          [📋] ││
│  │  ─────────────────────────────────────────────────────────────  ││
│  │  import { Elysia, t } from 'elysia';                            ││
│  │  import { ProductService } from '../../services/product';       ││
│  │                                                                 ││
│  │  export const productRoutes = new Elysia({ prefix: '/products' })││
│  │      .get('/', async ({ query }) => {                           ││
│  │          const { page = 1, limit = 10, search } = query;        ││
│  │          return ProductService.list({ page, limit, search });   ││
│  │      })                                                         ││
│  │      .get('/:id', async ({ params }) => {                       ││
│  │          return ProductService.getById(params.id);              ││
│  │      })                                                         ││
│  │  ...                                                            ││
│  └─────────────────────────────────────────────────────────────────┘│
│                                                                     │
│  [Preview Live]  [Export GitLab]  [Download ZIP]                    │
└─────────────────────────────────────────────────────────────────────┘

Schema Builder (pour CRUD)

┌─────────────────────────────────────────────────────────────────────┐
│  Générateur CRUD                                              [✕]  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Nom de l'entité: [Order_____________]                              │
│  Nom de la table: [orders____________]                              │
│                                                                     │
│  Colonnes:                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐│
│  │  Nom          Type        Required   Primary   Foreign          ││
│  │  ───────────────────────────────────────────────────────────    ││
│  │  id           uuid        ✓          ✓                          ││
│  │  user_id      uuid        ✓                    users.id         ││
│  │  status       string      ✓                                     ││
│  │  total        decimal     ✓                                     ││
│  │  items        json                                               ││
│  │  created_at   date        ✓                                     ││
│  │                                                                 ││
│  │  [+ Ajouter colonne]                                            ││
│  └─────────────────────────────────────────────────────────────────┘│
│                                                                     │
│  Options:                                                           │
│  ☑️ Générer types TypeScript                                        │
│  ☑️ Générer validateurs Zod                                         │
│  ☑️ Générer service Supabase                                        │
│  ☑️ Générer routes API (Elysia)                                     │
│  ☐ Générer composants Qwik (liste, formulaire)                     │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────────┐│
│  │              ✨ Générer le CRUD complet                         ││
│  └─────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘

8. Templates pré-définis

API Templates

Template Description Fichiers générés
CRUD Basique Create, Read, Update, Delete 4 fichiers
CRUD + Auth CRUD avec middleware auth 5 fichiers
CRUD + Upload CRUD avec upload fichiers 6 fichiers
API Publique Endpoints read-only 2 fichiers

Qwik Templates

Template Description Fichiers générés
Page Liste DataTable avec filtres 3 fichiers
Page Détail Affichage entité 2 fichiers
Formulaire Create/Edit form 3 fichiers
Dashboard Stats + graphiques 4 fichiers
Auth Pages Login, Register, Forgot 5 fichiers

9. MVP - Phases

Phase 1 : Core (2 semaines)

Phase 2 : IA (2 semaines)

Phase 3 : Templates (1-2 semaines)

Phase 4 : Preview Live (1 semaine)

Phase 5 : Export (1 semaine)


10. Déploiement

services:
  rapidbuilder-app:
    build: ./app
    ports:
      - "5000:3000"

  rapidbuilder-api:
    build: ./api
    ports:
      - "5001:3001"
    environment:
      - OLLAMA_URL=http://192.168.1.30:11434
      - GITLAB_URL=https://gitlab.33800.nowhere84.com
      - GITLAB_TOKEN=${GITLAB_TOKEN}

URLs

Service URL
App https://rapidbuilder.33800.nowhere84.com
API https://rapidbuilder-api.33800.nowhere84.com