Skip to main content

Manager API Overview

The manager-api-node is the backend REST API for the Cheeko platform, built with Node.js/Express. All endpoints share the base path /toy.

Tech Stack

ComponentTechnology
RuntimeNode.js 20+
FrameworkExpress.js
DatabaseDigitalOcean Managed PostgreSQL via Prisma ORM
Auth (admin)Custom token lookup (sys_user_token table, Prisma)
Auth (mobile)Firebase ID tokens (firebase-admin SDK)
Base path/toy
Port8002
API docs/toy/doc.html (Swagger UI)

Middleware Stack

Middleware is applied in the following order in src/app.js:

MiddlewareFilePurpose
helmetexpressSets secure HTTP headers (CORS resource policy: cross-origin)
corsexpressAllows configurable origins; defaults to localhost:8080 and localhost:3000. Reads CORS_ORIGINS env var.
trust proxyexpressEnables correct IP identification behind nginx/load balancer
Rate limiterexpress-rate-limit5000 req / 15 min window per IP; returns 429 with { code: 429, msg: "..." }
express.jsonexpressParses JSON bodies up to 10 MB
express.urlencodedexpressParses URL-encoded bodies up to 10 MB
XSS filtersrc/middleware/xssFilter.jsSanitizes request body/query to strip XSS payloads
Request IDsrc/middleware/requestId.jsAttaches a unique X-Request-ID to every request
Morgan loggermorganHTTP access logging; dev format in development, compact format in production
Routessrc/routes/index.jsAll API routes under /toy
404 handlersrc/middleware/errorHandler.jsReturns { code: 404, msg: "..." } for unknown routes
Global error handlersrc/middleware/errorHandler.jsReturns { code: 500, msg: "..." } for unhandled errors

Authentication

Two dedicated middleware files handle authentication:

src/middleware/auth.js — Custom token + service key auth

Tokens are stored in the sys_user_token database table (Prisma). Exported middleware:

ExportBehavior
requireAuthVerifies Bearer <token> against sys_user_token. Attaches req.user.
requireAdminLike requireAuth but also checks user.role === 'admin' or super_admin === 1. Accepts service key as bypass.
requireServiceKeyVerifies X-Service-Key header equals SERVICE_SECRET_KEY env var. Sets req.isServiceAuth = true.
requireDualAuthAccepts either a valid Bearer token or a valid service key.
optionalAuthTries both methods; attaches req.user or req.isServiceAuth if valid, but never rejects.
requireSuperAdminMust be chained after requireAuth; checks super_admin === 1.

src/middleware/flexAuth.js — Firebase + custom token (dual mobile/admin)

Used on routes that serve both the Flutter mobile app and the web admin dashboard.

ClientToken typeFlow
Flutter appFirebase ID tokenadmin.auth().verifyIdToken(token) → finds or creates sys_user row → sets req.firebaseUser, req.mobileUser, req.user
Admin web dashboardCustom JWTFalls back to verifyCustomToken → sets req.user

If neither check succeeds, returns 401 Unauthorized.

Route Overview

All routes are mounted under the /toy context path.

Mount pathModule fileDescription
/toy/userauth.routes.jsLogin, registration, user management
/toy/devicedevice.routes.jsESP32 device registration, binding, mode control, OTA
/toy/agentagent.routes.jsAI agent config, prompts, character switching, chat history
/toy/contentcontent.routes.jsMusic, stories, content library, file upload
/toy/admin/rfidrfid.routes.jsRFID card mappings, packs, RAG lookup
/toy/api/mobilemobile.routes.js, profile.routes.jsFirebase-backed mobile endpoints (kid profiles, etc.)
/toy/modelsmodel.routes.jsAI model management
/toy/analyticsanalytics.routes.jsGame sessions, media playback, usage stats
/toy/systemsystem.routes.jsSystem settings
/toy/adminadmin.routes.jsAdmin utilities
/toy/configconfig.routes.jsRuntime configuration
/toy/usageusage.routes.jsUsage tracking
/toy/otaota.routes.jsOTA firmware check (device-facing)
/toy/otaMagotaMag.routes.jsOTA firmware management (admin)
/toy/admin/serverserver.routes.jsServer management
/toy/admin/paramsparams.routes.jsSystem parameters
/toy/admin/dictdict.routes.jsData dictionary
/toy/ttsVoicettsVoice.routes.jsTTS voice configuration
/toy/admin/email-reportsemailReport.routes.jsEmail report scheduling

Health Endpoints

MethodPathAuthDescription
GET/healthNoneApp health (uptime, timestamp)
GET/toy/healthNoneAPI health with environment info
GET/toy/health/dbNoneTests Prisma → DigitalOcean PostgreSQL connection
GET/toy/pub-configNonePublic feature flags (rfid, analytics, rag, memory)

Standard Response Envelope

All API responses use the same envelope:

{
"code": 0,
"msg": "success",
"data": { ... }
}

Error responses set code to a non-zero value (e.g. 400, 401, 403, 404, 500) and data to null.

Running the API

cd main/manager-api-node
npm install

# Development (auto-reload)
npm run dev

# Production
npm start

# Tests
npm test
npm run test:coverage

Required Environment Variables

PORT=8002
NODE_ENV=development

# Primary database
DATABASE_URL=postgresql://user:pass@host:5432/dbname?sslmode=require

# Supabase (legacy admin auth only)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# Service-to-service auth (LiveKit agents, MQTT gateway)
SERVICE_SECRET_KEY=your-service-secret

# Firebase (mobile app auth)
FIREBASE_SERVICE_ACCOUNT_KEY=<base64 or path>

# Vector search
QDRANT_URL=https://your-cluster.qdrant.io
QDRANT_API_KEY=your-qdrant-api-key

# Memory/personalization
MEM0_API_KEY=your-mem0-api-key