Skip to content
Platform

The whole surface,part by part

DjiniousMap is one Bun API over two databases, with a React client on top. This page walks the whole surface: what harvests data, what measures it, what draws it, what computes on it, and what keeps every tenant's rows out of every other tenant's queries.

sources · connections · catalog

Ingest

  • Public harvest

    A harvester registers datasets from data.gouv.fr, keeping the publisher's own external identifier, source URL, licence and update frequency. Re-harvesting updates the registration in place rather than creating a duplicate.

  • Connections

    Register your own sources and create datasets from them. A connection carries its credentials and its reachability separately from the datasets that use it, so rotating a secret does not orphan a catalogue entry.

  • Materialization

    Copying a dataset's features into the platform is an explicit act with its own job. It downloads the source, detects the format, and inserts in batches into a table created for that dataset alone — `managed.ds_<id>`, one table per dataset, never a shared feature store.

  • Formats

    GeoJSON, GeoPackage and the compressed variants the French open-data catalogue actually publishes, including gzipped GeoJSON measured in hundreds of megabytes. Ingest streams rather than buffering, so source size is bounded by disk, not by memory.

The DjiniousMap dataset catalogue listing fourteen registered datasets with their source, classification and state, and per-row actions for geocoding, reverse geocoding, isochrones and routing.The DjiniousMap dataset catalogue listing fourteen registered datasets with their source, classification and state, and per-row actions for geocoding, reverse geocoding, isochrones and routing.
What ingest produces: a catalogue row per dataset carrying its source, its classification, and — decisively — whether anything has actually been copied into the platform yet.Seeded development stack
profiles · CRS · quality

Measurement

  • CRS inference

    The coordinates are measured and matched against candidate projections, producing an inferred EPSG code and a confidence. The publisher's declared code is recorded beside it and never overwritten. When the two disagree, the platform says so and draws from the measured one.

  • The profile

    Feature count, geometry types, spatial index presence, null and invalid geometry rates, temporal columns, declared and inferred SRID, and the WGS 84 bounding box. The bbox is computed in PostGIS because `ST_Transform` lives there and nowhere else.

  • Quality findings

    Each finding states what was measured, why it matters, and the remediation. Excess coordinate precision quantifies the implied accuracy against survey-grade GNSS; stale data names the column and the threshold; invalid geometry reports a rate rather than a verdict.

  • Undetermined is a result

    When the inputs a finding needs are missing — no declared update frequency, no owner, no date-shaped column — the verdict is Undetermined and the page says which inputs were absent. A guess presented as a measurement would be worse than no answer.

  • Suitability

    A dataset that cannot be placed on a map is flagged as unsuitable for visualization, with the finding that caused it. The table preview keeps working: the data is not unusable, it is unmappable, and the platform distinguishes the two.

A dataset detail page reporting that no CRS could be inferred, with a full profile, a Full profile badge, and quality findings for excessive coordinate precision and stale data.A dataset detail page reporting that no CRS could be inferred, with a full profile, a Full profile badge, and quality findings for excessive coordinate precision and stale data.
This dataset declares EPSG:32631 and nothing in its coordinates supports naming a CRS, so it has no bounding box and cannot be drawn. The table preview is unaffected, and the page says exactly that.Seeded development stack
map studio · assets

Composition

  • Layers

    Materialized datasets become layers with their own style, opacity, order and visibility. Fill, stroke, stroke width and point radius are set per layer, and the paint resolves through the product's design tokens, so switching brand palette repaints the map along with the chrome.

  • Filters

    Categorical, range and temporal filters per layer, composable and shareable. A filter authored by a widget is tracked back to it, so removing the widget removes the filters it authored — atomically, rather than leaving orphans behind.

  • Widgets and cross-filtering

    Category, histogram, formula and time-series widgets. Selecting in one widget filters the map and every other widget, which is what makes a multi-layer map explorable rather than merely legible.

  • Time replay

    Any column the profiler identified as temporal can drive a timeline: scrub it, or play it, and the map redraws over the period. The rail appears only when such a column exists, so it never implies a time dimension the data does not have.

  • Versioned assets

    A map is an asset with immutable published versions, a slug and a current version pointer — the same model as a workflow. Publishing freezes a document and hashes its body, so a shared view is exactly the one that was shared.

The DjiniousMap studio with two materialized layers over Plan IGN, a category widget and a time replay rail.The DjiniousMap studio with two materialized layers over Plan IGN, a category widget and a time replay rail.
Two layers, one cross-filtering widget, and a timeline bound to the layer's own date column.Seeded development stack
analysis · routing · geocoding

Computation

  • Spatial analysis

    Run analyses over materialized layers and land the result back in the catalogue as a dataset of its own, profiled like any other. An output is therefore a first-class input, and the lineage is a catalogue relationship rather than a filename convention.

  • Isochrones

    Travel-time polygons from a point or from every feature in a layer, through a pluggable routing provider. The result is a dataset, so it can be styled, filtered and joined like anything else.

  • Routing

    Point-to-point routes with the same provider abstraction, returning a geometry the studio can draw.

  • Geocoding, both directions

    Forward geocoding turns an address column into points; reverse geocoding turns points into addresses. Both run as jobs over a whole dataset rather than one row at a time.

  • The job queue

    Anything that takes time runs on a leased queue with heartbeats. A worker that dies mid-run stops heartbeating and its lease expires, so the job is picked up again instead of being stranded in a running state forever.

The DjiniousMap jobs page showing four succeeded materialization jobs with progress bars and one failed job whose error explains that the source bytes are an XML document rather than a supported vector format.The DjiniousMap jobs page showing four succeeded materialization jobs with progress bars and one failed job whose error explains that the source bytes are an XML document rather than a supported vector format.
Analyses, materializations, geocoding runs and workflow steps share one leased queue. The failure at the bottom is the point: it names the format it detected, lists the formats that would have worked, and states that the dataset stays registered and discoverable.Seeded development stack
workflows · automations

Orchestration

  • Workflow canvas

    Author a pipeline as a graph, configure each node, and publish it as a versioned asset. A run streams its progress live, and the stream is durable: reconnecting replays the run from its event log rather than losing what happened while you were away.

  • Triggers

    Automations bind a trigger to a published workflow version. Schedule triggers fire on a cadence; event triggers fire on platform events such as `dataset.refreshed`, so a rebuild follows a harvest without anybody watching for it.

  • Last-run status

    Each automation carries the outcome of its most recent run, so a pipeline that has been failing quietly for a week is visible on the list page rather than only in a log.

The DjiniousMap workflow canvas editor showing a published pipeline graph with its node configuration panel.The DjiniousMap workflow canvas editor showing a published pipeline graph with its node configuration panel.
A workflow is authored as a graph and published as a versioned asset; automations bind triggers to a published version.Seeded development stack
sharing · embeds · provider API

Distribution

  • Public share links

    Publish a map behind a share token for readers with no account. The token scopes what is readable; it is not a bypass of the tenancy model but a principal within it.

  • Embeds

    The same viewer runs in embed mode for putting a live map inside another page — including a conversational embed, where the reader asks questions of the map rather than operating its controls.

  • Provider Interface v1

    `map-provider@1` exposes the platform as a service to sibling Djinious applications: scoped service tokens, a versioned operation surface under `/api/provider/v1`, and `/ready`, `/version` and `/metrics` for the operator.

A DjiniousMap project detail page listing its versioned map and workflow assets with their publication status.A DjiniousMap project detail page listing its versioned map and workflow assets with their publication status.
Projects group assets; each asset carries immutable published versions, which is what makes a shared link reproducible.Seeded development stack
Under it

Two databases, and the reason there are two

Everything above rests on a split that is unusual enough to be worth stating plainly: the platform's records live in SurrealDB, and only geometry lives in PostgreSQL.

SurrealDB owns
Organizations, users, credentials, sessions, memberships; projects, assets and their immutable versions; datasets, profiles, suitability and quality findings; the audit log; the job queue.
PostGIS owns
The materialized feature tables — one per dataset — plus the handful of projected rows the geometry's own policies and functions have to read.
Why split at all
Every SurrealDB table is SCHEMAFULL with a PERMISSIONS clause per verb, evaluated against the record the connection signed in as. Geometry stays in PostGIS because ST_Transform, spatial indexes and row-level security on feature tables live there.
The cost, named
Three PostgreSQL rows are projected from SurrealDB records, and a projection can drift. A reconcile command enumerates both sides and exits non-zero when they disagree; it is scheduled, not hoped for.
Identity
An HttpOnly session cookie holding a 256-bit random token, of which only the SHA-256 hash is stored. Request headers are never consulted for identity.
Checked against apps/map, not asserted

Walk the surface with us

A demo goes through this page in the running product — harvest something, watch it profile, compose it, and run an analysis on it inside the hour.

DjiniousMapCatalogue · Map studio · Spatial analysis

Harvest the data, profile it honestly, compose it into a map, and act on it — with tenancy enforced by the database rather than by application code.

  1. Harvest
  2. Profile
  3. Compose
  4. Act

Every screenshot on this site is a capture of the running platform.