splatGraph
System design

CREATE / AUTHOR → Aurora PostgreSQL · RECORD / PLAY → DynamoDB · PUBLISH / DISTRIBUTE → Aurora DSQL · INFERENCE → FAL TripoSplat

splatGraph treats a place as a navigable graph of Gaussian splats, anchors, photos, and wiki entries. Rather than forcing one database to do everything, each workload runs on the store that fits it best. Any point in any photo can become a graph edge. DynamoDB records the raw path. Aurora turns it into an authored trajectory. DSQL publishes it as a global playback.

Authoring graph

Amazon Aurora PostgreSQL

The relational source of truth for the editable knowledge graph: places, splats, spatial anchors, photo contributions, image-point links, child scenes, wiki entries, and the typed edges that connect them.

  • Strongly consistent writes for every contribution
  • Foreign keys + typed graph edges (source_type / target_type / relation_type)
  • Per-place graphVersion bump on every structural change
Stored in Aurora PostgreSQL

Live runtime

Amazon DynamoDB

High-frequency, time-ordered traversal state. Trajectory recording sessions, per-event camera segments, generation progress streams, and concurrent visitor presence all live here.

  • Append-only event log keyed by session + sequence number
  • current_session_state rows for real-time presence
  • Single-digit-ms writes during camera recording
Recorded in Amazon DynamoDB

Published read model

Amazon Aurora DSQL

A distributed, read-optimized projection. When a curator publishes a place, its approved graph slice is compiled into immutable manifests that visitors read without touching the authoring database.

  • Compiled manifests for places, splats, anchors, photos, scenes, wiki
  • Decouples public reads from authoring writes
  • Versioned snapshots for instant rollbacks
Published to Aurora DSQL

C4 level 1

System context

Who talks to splatGraph and which backing service handles each job. Visitors read the public graph; contributors and curators drive every write through the Next.js app, which fans out to MoGe-2 inference, S3 assets, and the three databases.

Container / layering

Layered architecture

UI and Server Actions call domain services; services depend only on repository interfaces; concrete repositories (mock for local dev, AWS-backed for production) are the only code that knows about a specific store.

Domain model

Seven bounded contexts

Each context follows the same shape — entities, repository interface, service, mock repository. Contexts are grouped by their production store: authoring in Aurora PostgreSQL, runtime in DynamoDB, published read model in Aurora DSQL.

Why three stores

Database boundaries

The jobs are never mixed: Aurora authors the graph, DynamoDB records the raw path, DSQL distributes the public read model. A visitor moves through the graph → DynamoDB records it → Aurora compiles an authored trajectory → DSQL publishes it as global playback.

Contribution-to-publish pipeline

A single detail-capture flow touches all three databases plus the generation service.

  1. 1
    Aurora PostgreSQL

    A contributor pins a photo to a spatial anchor and drops an image point.

  2. 2
    DynamoDB

    fal TripoSG/Splat job streams progress events as the child Gaussian splat is generated.

  3. 3
    Aurora PostgreSQL

    The generated splat, child scene, and a typed graph edge are written back to the graph.

  4. 4
    Aurora DSQL

    A curator approves and publishes — the slice is compiled into public manifests.

Key flow

Pin a photo, generate a child scene, publish

A single detail-capture flow across the contributor, the domain services, MoGe-2 inference, and a curator — showing exactly which store each step writes to and where progress is streamed.

Trajectory lifecycle

Record → compile → publish

Raw camera paths are recorded to DynamoDB, compiled into an authored Trajectory in Aurora PostgreSQL, then published to Aurora DSQL as an immutable manifest for global replay.

Runtime / deployment

Vercel + AWS wiring

The Next.js app runs on Vercel and reaches AWS through Vercel OIDC-issued credentials — no long-lived keys. Aurora PostgreSQL, DynamoDB, Aurora DSQL, and S3 sit behind it, with fal.ai called directly for inference.

Auth boundary

Reading the graph is open to everyone. Contributing — pinning anchors, generating splats, editing wiki entries, and recording trajectories — requires an account. Curator and admin roles gate moderation and publishing. The auth adapter is swappable; this build ships a local mock so the full flow is explorable without a backend.

Generation service (MoGe-2)

Child scenes are produced by a MoGe-2 image-to-3D job behind a typed adapter. Progress is streamed through DynamoDB so any client can watch a generation advance, and the finished scene mesh is registered back into the Aurora PostgreSQL graph as a new node.

Explore the demo place Take the guided tour