Skip to content

Architecture

The DataSketchers platform manages every service in a single pnpm monorepo. The frontend (marketing) is a static Astro site, the backend is a Go API, and the MkDocs wiki and Astro blog live in the same repository.


Monorepo Layout

Directory Role Tech Stack
apps/site Marketing site (data-sketchers.com) Astro 5, static, KO/EN
apps/api Backend API Go + Chi + SQLite + S3
apps/wiki This dev wiki Material for MkDocs
apps/blog Tech blog Astro, GitLab Pages
infra/ Deploy configs (nginx, compose) docker-compose
scripts/ Build/deploy helpers bash

Core design principle

The marketing site is 100% static. Whenever dynamic logic is needed, don't put it in Astro — implement it in the Go backend under apps/api.


Frontend: Astro 5 + i18n

  • SSG: every page is rendered to HTML at build time.
  • i18n: with prefixDefaultLocale: false, Korean sits at the default path (/) and English is served under /en.
/data-sketchers.com
├── /              ← Korean home
├── /en/           ← English home
└── /_astro/...    ← static assets (long-cache)

Backend: Go API Scaffold

apps/api is built on the Chi router, uses SQLite as the main store, and stores files/assets in S3.

Method Path Description
GET /health health check
GET /api/events list events/solutions
POST /api/events create event
GET /api/canvas/:id fetch canvas
POST /api/canvas save canvas
apps/api/
├── cmd/api/          # entrypoint
├── internal/
│   ├── handler/      # HTTP handlers
│   ├── service/      # business logic
│   ├── repo/         # SQLite/S3 access
│   └── ai/           # LLM adapters (D-SKET Canvas)
└── storage/          # SQLite file, uploads

About S3

S3 stores user-uploaded assets (canvas images, attachments). SQLite holds structured metadata while S3 holds binary objects — a clean split of duties.


Deploy Flow

flowchart LR
    PUSH["git push"] --> CI["GitLab CI"]
    CI --> LINT["lint"]
    LINT --> BUILD["build-image (kaniko)"]
    BUILD --> PUSHIMG["docker push (nginx image)"]
    PUSHIMG --> DEPLOY["SSH deploy (ds-20000 host)"]
    DEPLOY --> UP["docker compose up"]
    UP --> TUNNEL["cloudflared tunnel"]
    TUNNEL --> PUBLIC["data-sketchers.com"]

See CI/CD Pipeline and Ops & Deploy for details.


Request Flow

sequenceDiagram
    participant U as Browser
    participant CF as Cloudflare
    participant NG as nginx (container)
    participant ASTRO as Static files /_astro
    participant API as Go API (apps/api)

    U->>CF: GET https://data-sketchers.com/
    CF->>NG: request via tunnel
    NG->>ASTRO: serve .html / static assets
    NG-->>CF: 200 HTML
    U->>CF: POST /api/events (dynamic)
    CF->>NG: request via tunnel
    NG->>API: /api proxy
    API-->>CF: JSON response

Current state: /api proxy

The nginx /api proxy setting is a TODO (not yet implemented). Right now the static marketing site is served together on demand. Before using /api, always check Ops & Deploy.