# TCN simple ads backend MVP Date: 2026-06-06 Status: implemented MVP backend in Ballbox Next.js ## Goal Serve the simplest possible Ballbox-controlled manifest plus static files to test remote ad changes on one machine. ## Current endpoint - `GET /api/machines/2601070188/ads-manifest` Current live-style URL shape when deployed on Ballbox: - `https://ballbox.app/api/machines/2601070188/ads-manifest` ## Current behavior - no auth - one machine hardcoded for MVP: `2601070188` - manifest is generated from files stored in `public/machine-assets/2601070188/...` - response includes: - target runtime path - absolute file URL - sha256 - byte size - restart requirement ## Current files served - `VideoAndImageAd/See You Again (Cover)--音悦Tai.mp4` - `ImageScreen/流程图.jpg` Public file URLs: - `/machine-assets/2601070188/VideoAndImageAd/See You Again (Cover)--音悦Tai.mp4` - `/machine-assets/2601070188/ImageScreen/流程图.jpg` ## Why this is the right MVP - simplest possible backend - no DB - no admin UI - no webhook - no write path - enough to prove polling/downloading/overwrite on a real machine ## Files added - `app/api/machines/[machineId]/ads-manifest/route.ts` - `lib/machine-ads-manifest.ts` - `public/machine-assets/2601070188/VideoAndImageAd/See You Again (Cover)--音悦Tai.mp4` - `public/machine-assets/2601070188/ImageScreen/流程图.jpg` ## Sample response shape ```json { "ok": true, "manifest": { "machineId": "2601070188", "version": "...", "generatedAt": "2026-06-06T...Z", "restartPolicy": "app", "files": [ { "target": "VideoAndImageAd/See You Again (Cover)--音悦Tai.mp4", "url": "https://ballbox.app/machine-assets/2601070188/VideoAndImageAd/See%20You%20Again%20(Cover)--音悦Tai.mp4", "sha256": "...", "bytes": 19932032, "restartRequired": "app" } ] } } ``` ## Next machine-side test 1. machine polls manifest 2. machine downloads one changed file 3. overwrite exact vendor-path target 4. restart app 5. confirm visible change ## Simple local test client A minimal sync client now exists at: - `scripts/machine-ads-sync.mjs` Usage: - `node scripts/machine-ads-sync.mjs ` What it does: - fetches the manifest - downloads changed files only - validates sha256 - writes them under the provided target root using exact `target` relative paths - prints a JSON result summary ## Intended near-term evolution After first proof: - add more file targets - add bearer auth if needed - add per-machine config source - add simple operator upload/change flow later