Skip to content

quable/customapp-helloworld

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CustomApp HelloWorld - Quable PIM

📚 Introduction

Cette application exemple démontre l'intégration avec Quable PIM via une Quable App "Custom" (non intégrée à l'app Store).

🎯 FonctionnalitĂ©s

  • ✅ Configuration automatique de webhook custom_app.helloworld
  • ✅ Configuration automatique d'une clĂ©/valeur custom_app.helloworld
  • ✅ Gestion de clĂ©/valeur dans le PIM Ă  la rĂ©ception d'un event webhook
  • ✅ Support de tous les slots de documents
  • ✅ Validation HMAC pour sĂ©curitĂ©

📋 PrĂ©requis

  • Node.js >= 16.0.0
  • Instance Quable PIM
  • Token API Quable avec permissions full_access

🚀 Installation

1. Cloner le repository

git clone https://github.com/quable/customapp-helloworld.git
cd customapp-helloworld

2. Installer les dépendances

npm install
# ou
yarn install

3. Configuration

cp .env.dist .env

Éditer .env :

DATABASE_URL=file:./dev.db 
QUABLE_APP_PORT=4000
QUABLE_APP_HOST_URL=https://votre-url.com

Pour l'URL, n'hésitez pas à utilier un tunnel pour que le PIM puisse joidnre votre application lancée localement.

4. Base de données

npx prisma migrate dev --name init
npx prisma generate

🔧 DĂ©claration dans Quable PIM

1. Accéder à l'admin du PIM

  1. Créer une nouvelle CustomApp
  2. Renseigner bien l'URL public de votre application
  3. Cocher TOUS les slots disponibles
  4. Noter le secret pour la validation HMAC

2. Ajouter manuellement l'instance en BDD

npx prisma studio

🏃 Utilisation

Démarrage

// Mode développement
npm run dev
// Mode production
npm run build && npm start

Endpoints

Endpoint Méthode Description
/ GET Page de configuration
/ POST Lancement de slot
/webhook/{instance} POST Réception webhooks
/slot/{slotName} GET Affichage slot iframe

Flow de fonctionnement

  1. AccĂšs Ă  la page de configuration depuis l'administration des Quable App

    • L'app vĂ©rifie/crĂ©e le webhook custom_app.helloworld
    • L'app vĂ©rifie/crĂ©e la key/value custom_app.helloworld
  2. Webhook document.update

    • RĂ©ception du webhook
    • Mise Ă  jour key/value avec datetime
  3. Affichage slots

    • Validation HMAC de la requĂȘte
    • Retour URL iframe
    • Affichage "Hello World"

🔐 SĂ©curitĂ©

  • Validation HMAC sur tous les endpoints
  • Tokens stockĂ©s en base de donnĂ©es
  • Utilisation de timingSafeEqual contre timing attacks

🔧 Erreurs avec la base de DonnĂ©es

❌ Erreur IdentifiĂ©e

{
    "statusCode": 500,
    "message": "Invalid `databaseService.quableInstance.findFirst()` invocation...
    Inconsistent column data: Conversion failed: premature end of input"
}

🔍 Diagnostic

L'erreur provient de la base de données SQLite qui contient des données corrompues ou mal formatées dans la table quable_instance.

✅ Solutions

Solution 1: RĂ©initialiser la Base de DonnĂ©es (RECOMMANDÉ)

# 1. ArrĂȘter l'application
# 2. Sauvegarder l'ancienne base (optionnel)
cp database/dev.db database/dev.db.backup

# 3. Supprimer la base corrompue
rm database/dev.db

# 4. Recréer la base avec Prisma
npx prisma migrate dev --name init
npx prisma generate

# 5. Ajouter une instance de test
npx prisma studio
# OU utiliser un script SQL

Solution 2: Script d'Initialisation

Créer un fichier scripts/init-db.js:

const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();

async function initDatabase() {
  try {
    // Nettoyer la table existante
    await prisma.quableInstance.deleteMany();
    
    // Créer une instance de test
    const instance = await prisma.quableInstance.create({
      data: {
        name: 'test-instance',
        authToken: 'your-api-token-here',
        quableAppSecret: 'your-hmac-secret-here'
      }
    });
    
    console.log('✅ Base de donnĂ©es initialisĂ©e avec succĂšs');
    console.log('Instance créée:', instance);
    
  } catch (error) {
    console.error('❌ Erreur lors de l\'initialisation:', error);
  } finally {
    await prisma.$disconnect();
  }
}

initDatabase();

Puis exécuter:

node scripts/init-db.js

Solution 3: Vérifier le Schéma Prisma

Vérifier que database/schema.prisma est correct:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

model QuableInstance {
  id              Int      @id @default(autoincrement())
  name            String
  authToken       String
  quableAppSecret String
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt

  @@map("quable_instance")
}

Solution 4: Migration ComplĂšte

# 1. Nettoyer tout
rm -rf database/dev.db
rm -rf node_modules/.prisma
rm -rf node_modules/@prisma

# 2. Réinstaller les dépendances
npm install

# 3. Générer Prisma
npx prisma generate

# 4. Créer la base
npx prisma db push

# 5. Vérifier avec Prisma Studio
npx prisma studio

đŸ› ïž Script de Test Complet

Créer scripts/test-db.js:

const { PrismaClient } = require('@prisma/client');

async function testDatabase() {
  const prisma = new PrismaClient({
    log: ['query', 'error', 'warn']
  });

  try {
    // Test de connexion
    await prisma.$connect();
    console.log('✅ Connexion Ă  la base rĂ©ussie');

    // Test de lecture
    const count = await prisma.quableInstance.count();
    console.log(`📊 Nombre d'instances: ${count}`);

    // Test de création
    const testInstance = await prisma.quableInstance.create({
      data: {
        name: `test-${Date.now()}`,
        authToken: 'test-token',
        quableAppSecret: 'test-secret'
      }
    });
    console.log('✅ Instance créée:', testInstance.name);

    // Test de lecture aprÚs création
    const instances = await prisma.quableInstance.findMany();
    console.log(`✅ ${instances.length} instance(s) trouvĂ©e(s)`);

    // Nettoyage
    await prisma.quableInstance.delete({
      where: { id: testInstance.id }
    });
    console.log('✅ Instance de test supprimĂ©e');

  } catch (error) {
    console.error('❌ Erreur:', error);
  } finally {
    await prisma.$disconnect();
  }
}

testDatabase();

📝 VĂ©rifications SupplĂ©mentaires

1. Vérifier les Variables d'Environnement

.env:

DATABASE_URL="file:./dev.db"
# Chemin relatif depuis la racine du projet

2. Vérifier les Permissions

# Vérifier les permissions du dossier database
ls -la database/

# Si nécessaire, corriger les permissions
chmod 755 database/
chmod 644 database/dev.db

3. Vérifier la Version de SQLite

# Installer sqlite3 si nécessaire
npm install sqlite3

# Vérifier l'intégrité de la base
sqlite3 database/dev.db "PRAGMA integrity_check;"

🚹 Points d'Attention

  1. Données de Production: Si c'est en production, sauvegarder TOUJOURS avant modification
  2. Tokens Sensibles: Ne pas commiter les vrais tokens dans le code
  3. Migration: Utiliser les migrations Prisma pour tracer les changements

✅ Validation Finale

AprĂšs correction, tester avec:

# 1. Lancer l'application
npm run dev

# 2. Tester l'endpoint
curl -X POST http://localhost:4000/ \
  -H "Content-Type: application/json" \
  -H "X-Signature: [signature]" \
  -H "X-Timestamp: [timestamp]" \
  -d '{
    "instance": "test-instance",
    "slot": "document.page.tab",
    "data": {
      "dataLocale": "fr_FR",
      "interfaceLocale": "fr_FR",
      "userId": "123"
    }
  }'

📝 License

MIT - Quable 2025

About

An example of a Custom QuableApp with the help of the Quable SDK

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages