Superfasttt

Manifest

Décrire publiquement une app tierce : identité, URL, permissions, collections, documents et fichiers.

Le manifest est le contrat public entre votre app, le client et Superfasttt. Il decrit ce que votre app demande et quelles ressources elle utilisera.

Vous le fournissez au format JSON. Une fois importe puis installe, il determine les permissions et ressources disponibles pour votre app dans l'espace client.

Exemple complet

{
  "manifest_version": "2.0",
  "id": "audit-pro",
  "name": "Audit Pro",
  "version": "1.0.0",
  "description": "Audits qualité et conformité multi-site.",
  "author": {
    "name": "Acme Solutions",
    "email": "contact@acme.example.com",
    "url": "https://acme.example.com"
  },
  "runtime": {
    "type": "external",
    "entry_url": "https://audit-pro.example.com",
    "allowed_origins": [
      "https://audit-pro.example.com",
      "https://staging-audit-pro.example.com"
    ]
  },
  "permissions": [
    "app_data:read",
    "app_data:write",
    "rich_documents:read",
    "rich_documents:write",
    "assets:read",
    "assets:write"
  ],
  "collections": {
    "inspections": {
      "schema": {
        "type": "object",
        "properties": {
          "title": { "type": "string", "maxLength": 200 },
          "site_id": { "type": "string" },
          "status": {
            "type": "string",
            "enum": ["draft", "in_review", "validated", "archived"]
          },
          "score": { "type": "number", "minimum": 0, "maximum": 100 },
          "inspector_email": { "type": "string", "format": "email" }
        },
        "required": ["title", "site_id", "status"],
        "additionalProperties": false
      },
      "indexes": ["status", "site_id", "inspector_email"]
    }
  },
  "rich_documents": {
    "audit_report": {
      "editor": "prosemirror",
      "schema_version": "audit-report-v1",
      "is_indexable": false
    }
  },
  "assets": {
    "allowed_mime_types": ["image/png", "image/jpeg", "application/pdf"],
    "max_file_size_mb": 25,
    "max_total_size_mb": 1024
  }
}

Champs racine

ChampRequisDescription
manifest_versionouiVersion du format de manifest. Utilisez "2.0".
idouiIdentifiant stable de l'app. Utilisez un slug court, en minuscules, sans espace.
nameouiNom affiché au client.
versionouiVersion SemVer, par exemple 1.0.0.
descriptionnonDescription courte de l'app.
authornonInformations publiques de l'éditeur : name, email, url.
runtimeouiURL de lancement et origins autorisées.
permissionsouiPermissions demandées par l'app.
collectionsnonDonnées métier JSON gérées par l'app.
rich_documentsnonTypes de documents riches utilisés par l'app.
assetsnonRègles de fichiers et médias.

runtime

"runtime": {
  "type": "external",
  "entry_url": "https://audit-pro.example.com",
  "allowed_origins": ["https://audit-pro.example.com"]
}
ChampRequisDescription
typeouiUtilisez "external" pour une app hébergée par vous.
entry_urlouiURL de lancement de votre app. En production, utilisez HTTPS.
allowed_originsouiOrigins exactes autorisées à appeler l'API depuis le navigateur.

Règles importantes :

  • Une origin a la forme scheme://host[:port], sans chemin ni query string.
  • Les wildcards ne sont pas acceptées.
  • En production, utilisez https://.
  • En développement, http://localhost:<port> est accepté.
  • L'origin de entry_url doit être présente dans allowed_origins.

Exemples valides :

[
  "https://audit-pro.example.com",
  "https://staging-audit-pro.example.com",
  "http://localhost:3000"
]

Exemples invalides :

[
  "*",
  "https://*.example.com",
  "https://audit-pro.example.com/app",
  "http://audit-pro.example.com"
]

permissions

Demandez uniquement les permissions nécessaires.

PermissionUtilisation
app_data:readLire les records de vos collections.
app_data:writeCréer, modifier et supprimer les records de vos collections.
rich_documents:readLire vos documents riches et leurs versions.
rich_documents:writeCréer, modifier, restaurer et supprimer vos documents riches.
assets:readLister, consulter et obtenir une URL de téléchargement de vos fichiers.
assets:writeUploader, compléter, rattacher et supprimer vos fichiers.

Si vous ajoutez une permission après installation, réimportez le manifest puis réinstallez l'app pour que le client accorde la nouvelle permission.

collections

Une collection représente un type d'objet métier de votre app.

"collections": {
  "inspections": {
    "schema": {
      "type": "object",
      "properties": {
        "title": { "type": "string" },
        "status": { "type": "string", "enum": ["draft", "done"] }
      },
      "required": ["title"],
      "additionalProperties": false
    },
    "indexes": ["status"]
  }
}
ChampDescription
Clé de collectionIdentifiant utilisé dans l'URL, par exemple /api/v1/app-data/inspections.
schemaJSON Schema de type object appliqué au champ data de chaque record.
indexesChamps autorisés pour les filtres de /query.

Bonnes pratiques :

  • Gardez des noms de collections simples : inspections, sites, contracts, cases.
  • Utilisez additionalProperties: false pour éviter les données non prévues.
  • Ajoutez dans indexes uniquement les champs que vous devez filtrer souvent.
  • Pour faire evoluer un schema, ajoutez d'abord des champs optionnels. Un nouveau champ requis doit être traité comme une évolution incompatible.

rich_documents

Les documents riches servent aux rapports, comptes-rendus et contenus editables associes a votre app.

"rich_documents": {
  "audit_report": {
    "editor": "prosemirror",
    "schema_version": "audit-report-v1",
    "is_indexable": false
  }
}
ChampDescription
Clé du documentType de document utilisé dans les appels API.
editorFormat éditeur utilisé par votre app.
schema_versionVersion du format de contenu que votre app produit.
is_indexableIndique si ce type de document peut être considéré comme indexable.

Le contenu du document est un objet JSON produit par votre éditeur. Votre app reste responsable de savoir l'afficher et le modifier.

À l'usage, votre app envoie collection, editor, schema_version, title et content à POST /api/v1/rich-documents. Le serveur extrait automatiquement plain_text et incrémente la version à chaque PATCH. Exemple complet dans le Quickstart §7.

assets

"assets": {
  "allowed_mime_types": ["image/png", "image/jpeg", "application/pdf"],
  "max_file_size_mb": 25,
  "max_total_size_mb": 1024
}
ChampDescription
allowed_mime_typesListe des types MIME acceptes. Si absent, aucun filtre MIME specifique n'est demande.
max_file_size_mbTaille maximale d'un fichier individuel.
max_total_size_mbTaille maximale cumulee pour les fichiers de l'installation.

Evitez les types trop larges. Declarez explicitement les formats necessaires a votre cas d'usage.

L'upload se fait en 3 appels : POST /api/v1/app-assets/upload-url (réponse : asset_id, upload_url, required_headers), PUT direct vers le stockage, puis POST /api/v1/app-assets/complete qui revérifie la taille et le content type via HEAD. Le téléchargement passe ensuite par POST /api/v1/app-assets/{asset_id}/download-url. Exemple complet dans le Quickstart §7.

Valider et importer

Les endpoints de manifest attendent toujours une enveloppe :

{
  "manifest": {
    "manifest_version": "2.0",
    "id": "audit-pro",
    "name": "Audit Pro",
    "version": "1.0.0",
    "runtime": {
      "type": "external",
      "entry_url": "https://audit-pro.example.com",
      "allowed_origins": ["https://audit-pro.example.com"]
    },
    "permissions": ["app_data:read"]
  }
}

Valider sans effet de bord :

curl -X POST https://api.superfasttt.ai/api/v1/app-platform/manifests/validate \
  -H "Authorization: Bearer <user_access_token>" \
  -H "X-Tenant-ID: <espace_client>" \
  -H "Content-Type: application/json" \
  -d @manifest-request.json

Importer :

curl -X POST https://api.superfasttt.ai/api/v1/app-platform/manifests/import \
  -H "Authorization: Bearer <user_access_token>" \
  -H "X-Tenant-ID: <espace_client>" \
  -H "Content-Type: application/json" \
  -d @manifest-request.json

Erreurs de validation courantes

CodeCause
requiredUn champ obligatoire est absent.
invalid_typeUn champ n'a pas le type attendu.
invalid_semverversion n'est pas au format SemVer complet.
https_requiredUne URL de production n'utilise pas HTTPS.
wildcard_forbiddenUne origin contient *.
origin_not_allowedL'origin de entry_url n'est pas dans allowed_origins.
unknown_permissionUne permission demandee n'est pas disponible.
must_be_objectLe JSON Schema d'une collection n'est pas un objet.
index_field_unknownUn champ indexe n'existe pas dans schema.properties.
reserved_fieldLe champ schema utilise un nom de champ réservé.

Versioning

  • Incrementez version pour chaque changement publie a un client.
  • Les changements compatibles ajoutent des champs optionnels ou des collections nouvelles.
  • Les changements incompatibles modifient le type d'un champ, rendent un champ obligatoire ou changent la signification d'une valeur existante.
  • Apres un changement de manifest, reimportez puis reinstallez l'app pour que l'espace client utilise la nouvelle version.

On this page