Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

canvas-api

CI Latest Release Go Version Go Report Card

Canvas API is the real-time drawing and feedback service of the MathTrail platform. Students solve math problems by writing with a stylus on an interactive canvas — the service streams strokes to the event bus and delivers AI-generated hints back to the canvas in real time via WebSocket.

Business Capabilities

  • Stroke Ingestion — Receives stylus input (pen pressure, coordinates) from the browser and publishes strokes to AutoMQ for downstream AI analysis.
  • Real-time Hints — Consumes AI-generated hint events and pushes them instantly to the student's canvas via Centrifugo WebSocket.
  • Secure Sessions — Issues scoped Centrifugo JWT tokens bound to the student's Ory session, preventing channel spoofing.
  • Interactive Canvas UI — Ships a Vite Module Federation Remote (React + Konva) consumed by the ui-web shell: task text on a protected read-only layer, drawing on a separate erasable layer, hint overlays on a third layer.

System Architecture

AutoMQ Centrifugo Protobuf

Architecture: EDA Kubernetes Vault

graph LR
    Student([Student UI\nReact MFE]) -- "session cookie" --> OK[Oathkeeper]

    subgraph CanvasService [Canvas API]
        direction TB
        App["canvas-api\n(Go / chi)"]
        UI["canvas-api/ui\n(React / Konva\nMFE Remote)"]
    end

    OK -- "forwards session" --> App
    UI -- "POST strokes\noctet-stream" --> App
    UI -- "GET token" --> App

    subgraph Bus [Event Bus]
        direction TB
        AMQ{AutoMQ}
    end

    App -- "canvas.strokes\nCanvasStrokeEvent\nProtobuf" --> AMQ
    AMQ -- "canvas.hints\nHintEvent\nProtobuf" --> App

    subgraph Realtime [Real-time Layer]
        CFG["Centrifugo\n(WebSocket + Protobuf)"]
    end

    App -- "HTTP Publish API\nb64data" --> CFG
    CFG -- "WS push\nHintEvent" --> UI

    subgraph Identity [Identity]
        Kratos["Ory Kratos"]
    end

    App -- "GET /sessions/whoami" --> Kratos

    subgraph Support [Infra Support]
        direction TB
        VSO["VSO"] --> KSec["K8s Secret"]
        Vault["Vault"] --> VSO
    end

    KSec -- "env vars\n(HMAC key, API key,\nSCRAM creds)" --> App

    %% Styling
    classDef svc fill:#5b21b6,stroke:#7c3aed,color:#fff
    classDef ui fill:#1e3a5f,stroke:#3b82f6,color:#fff
    classDef authCls fill:#b45309,stroke:#f59e0b,color:#fff
    classDef eventCls fill:#1c1917,stroke:#78716c,color:#fff
    classDef rtCls fill:#064e3b,stroke:#10b981,color:#fff
    classDef idCls fill:#374151,stroke:#9ca3af,color:#fff
    classDef secretCls fill:#7f1d1d,stroke:#ef4444,color:#fff
    classDef actorCls fill:#1e1b4b,stroke:#818cf8,color:#fff

    class App svc; class UI ui;
    class OK authCls;
    class AMQ eventCls;
    class CFG rtCls;
    class Kratos idCls;
    class Vault,VSO,KSec secretCls;
    class Student actorCls;
Loading

Canvas Layers

The React UI uses a three-layer Konva Stage so that erasing never touches the task text:

┌─────────────────────────────────┐
│  Layer 3 — HintLayer            │  listening=false  server hint overlays
│  Layer 2 — DrawingLayer         │  listening=true   pen strokes + eraser
│  Layer 1 — TaskLayer            │  listening=false  task text (read-only)
└─────────────────────────────────┘

Each Konva layer is a separate DOM <canvas> element. The eraser uses globalCompositeOperation: "destination-out" which acts only within the DrawingLayer canvas, leaving the TaskLayer untouched.

Development

All commands are run via just.

just first-build     # seed k3d registry before first skaffold run
just dev             # skaffold dev — hot-reload + port-forward :8080

cd ui && npm install
cd ui && npm run dev  # MFE dev server on :3001

Debug

Telepresence intercepts live cluster traffic and routes it to your local process. --mapped-namespaces all ensures that kratos.identity.svc and automq.streaming.svc DNS names resolve correctly in the local environment.

just tp-intercept
go run ./cmd/server

just tp-stop

Releases

git tag -a v0.1.0 -m "Release description"
git push origin v0.1.0

GitHub Actions will build binaries, generate a Changelog, and publish a GitHub Release.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages