# Minecraft ComputerCraft ME API — Backend TypeScript backend that collects Minecraft ME system data pushed by a ComputerCraft computer and exposes it over **HTTPS** (REST) and **WSS** (live websocket feed). This is the TypeScript rewrite of the original Rust/Axum + SQLite backend. ## Stack - **[Fastify 5](https://fastify.dev/)** — HTTP + WebSocket server. Chosen over Express/Nest because it has first-class WebSocket, JSON-schema validation and OpenAPI support built in, which keeps the project small for this scope. - **PostgreSQL** — runs in Docker via `docker-compose`. - **`@fastify/swagger` + `@fastify/swagger-ui`** — OpenAPI docs at `/api/docs`. - **TypeBox** — schemas used both for request validation and OpenAPI generation. - **`selfsigned`** — generates a self-signed TLS certificate on first start. ## Data model Two tables, mirroring the original design: | Table | Purpose | | ------------------- | -------------------------------------------------- | | `me_system_live` | current contents — one row per item (`name` unique) | | `me_system_history` | historic snapshots — references `me_system_live.id` | The `mod` of each item (the namespace before the `:` in `minecraft:iron_ingot`) is derived on ingest and stored on the live row so it can be filtered cheaply. ## Quick start (Docker) ```bash cp .env.example .env docker compose up --build ``` This starts PostgreSQL and the backend. A self-signed certificate is generated into `./certs` automatically. ## Quick start (local dev) ```bash cp .env.example .env # adjust DATABASE_URL to your local Postgres npm install npm run dev ``` ## Accept the self-signed certificate Because the certificate is self-signed, browsers reject it until trusted. **Open once and accept the warning** — this also makes `fetch` and `wss://` calls from the frontend work. ## Endpoints | Method | Path | Description | | ------ | -------------------------- | ---------------------------------------------- | | `POST` | `/api/me-system/update` | Ingest a full snapshot (called by ComputerCraft) | | `GET` | `/api/me-system/live` | Current contents — `search`, `mod`, `sort`, `order` | | `GET` | `/api/me-system/mods` | Aggregated per-mod overview | | `GET` | `/api/me-system/history` | History points for one item — `name`, `limit` | | `GET` | `/api/health` | Health and runtime metrics | | `WS` | `/api/ws/live` | Live data feed (see below) | | `GET` | `/api/docs` | OpenAPI / Swagger UI | ### WebSocket protocol — `/api/ws/live` - On connect the server sends a `snapshot` message. - The client may send `{ "type": "setFilters", "filters": { "search": "iron", "mod": "minecraft", "sort": "amount", "order": "desc" } }`. - The server replies with a fresh `snapshot` and keeps the filter for every later `update` message — so filters persist across data updates. - On every ingest the server pushes an `update` message to each client, with that client's filter already applied. Message shape: ```json { "type": "snapshot|update", "items": [...], "mods": [...], "filters": {...} } ``` ## Configuration See `.env.example`. Key variables: `PORT`, `DATABASE_URL`, `HISTORY_INTERVAL_SECONDS`, `TLS_ENABLED`, `CORS_ORIGIN`. ## ComputerCraft uploader An example uploader script is provided in `computercraft/me_uploader.lua`. See the comment at the top of that file regarding the self-signed certificate. ## Scripts | Command | Description | | ------------------ | --------------------------------- | | `npm run dev` | Watch-mode dev server (`tsx`) | | `npm run build` | Compile TypeScript to `dist/` | | `npm start` | Run the compiled server | | `npm run typecheck`| Type-check without emitting |