FR
Copied
Concepts

Module registry

A single source of truth describes every module — its inputs, outputs, category, and where it appears in the UI.

Every module outsend exposes is declared in a single registry. It powers the dashboard module grid, the new-job picker, the pipeline editor, and the landing page listing.

Guarantees: a module visible in the dashboard has an endpoint (and vice versa); a machine-readable snapshot is published; categories are hints, while slug, needs and produces are stable.

The endpoint

GET /api/modules-registry

Returns the full registry as JSON. Each entry:

{
  "slug": "scrap",
  "category": "extraction",
  "label": { "fr": "Scrap Google Maps", "en": "Scrape Google Maps" },
  "needs": null,
  "produces": "poi_list",
  "pipelinable": true,
  "is_on_demand": false,
  "coming_soon": false,
  "api_endpoint": "/api/jobs/scrap"
}
Field Meaning
slug Stable identifier, used in URLs and API paths
category extraction | enrichment | intelligence | verification | pipeline | meta
label User-facing display names per language
needs Input shape (poi_list, csv_rows, …) — null if produced from scratch
produces Output shape
pipelinable Usable as a node in a pipeline
is_on_demand If true, no backend yet — triggers a conversation with the team
coming_soon If true, listed for visibility only; interest can be voted
alpha_unavailable If true, the module is built and listed as active everywhere, but frozen during alpha — its create endpoint returns 503
api_endpoint Shortcut to start a job of this type

Flexible input matching

needs and produces describe canonical column names (nom, telephone, site_web, email, lien_google_maps, …). You never have to format your data to match them exactly: inputs are resolved against a shared table of accepted aliases, so columns named Website, url, e-mail, name or raison sociale map to the right canonical field. Header-less files are auto-detected and columns are inferred from their content.

Every job is transparent about it. Each run reports a non-blocking notice (shown as an info banner on the job page and as a discreet ⓘ on the dashboard) describing what was auto-mapped, guessed, or ignored — for example rows skipped because they had no website. A job only fails when a required column is genuinely absent (e.g. an enrichment that needs site_web finds it on zero rows), and that error explicitly names the accepted aliases so you know what header to provide.

Categories

Category What it does Examples
extraction Produces data from public sources scrap
enrichment Augments existing rows with new fields emails, socials, legal_ids
intelligence Computes signals on existing rows pricing, techstack, ads_intelligence
verification Validates or scores existing rows verify_emails, delivery_check
pipeline Orchestration utilities import, filter, sort
meta Not a job — describes pipelines or veilles (no API endpoint)

Lifecycle of a module

  1. Coming soon — landing page only, no backend, interest votable
  2. On-demand — listed in the dashboard, CTA opens a conversation, executed manually
  3. Active — fully backed by an endpoint
  4. Available (alpha-frozen) — built and presented as an active module across every surface, but not launchable during alpha: the UI shows a maintenance banner with a disabled launch button, and the create endpoint returns 503. Unlike coming soon, it is not a placeholder and carries no interest vote — it is a finished module held back only by alpha capacity.
  5. Deprecated — still callable but flagged

Phase changes appear in the registry via coming_soon, is_on_demand, alpha_unavailable, and deprecated_at.

Adding a module (contributors)

Adding a module = 2 files in the codebase: a JS registry entry (UI surfaces) and a Python registry entry (API + worker dispatcher). The runtime then plugs the module everywhere automatically.

What's next