Skip to content

02 — designer-api stack

A trimmed-down fork of the someli-api skeleton, focused on internal staff workflows (template management, content library, AI-assisted content factory).


Runtime and language

Runtime Node.js 20.x
Module system CommonJS
Process manager (dev) nodemon (via yarn start)
Process manager (prod) PM2 (manifest not in repo — opaque)
Container Docker (Dockerfile in repo)

Risk: designer-api/Dockerfile does COPY .env conf.js favicon.ico ./ — meaning the .env is baked into the image. Anyone with image access reads all secrets. See ../../audit/designer-api/build-and-deploy.md.


HTTP framework

Framework Express 4.x
Body parsing body-parser JSON, 50 MB limit (smaller than someli-api's 150 MB — sensible for a designer tool)
File uploads express-fileupload
CORS cors() middleware + a manual Access-Control-Allow-Origin: * line that's double-applied; the adjacent "Access-Control-Allow-Credentials" : true is syntactically wrong (the entire string is the header name, no value). Don't replicate the pattern.
WebSockets Socket.IO
Sessions None (no express-session)
Webhooks None — no Paddle / Stripe handlers
Passport / OAuth None — auth is hand-rolled inside routes/routes.js
Health endpoints None (no /health or /db-health)

Auth

Pattern Hand-rolled token verification, no JWT
Token transport Custom (see helper/index.js)
OAuth Not present
Sessions Not present

Junior gotcha: if you're used to someli-api's JWT + AES + Bearer pattern, don't expect it here. designer-api has its own (thinner) auth shape.

See ../../audit/designer-api/authentication.md.


Database

Engine MySQL (the same shared instance as someli-api in production)
Connection patterns mysql (callback, via App.db), sync-mysql (blocking, used in routes/routes.js and most jobs), mysql2/promise (in newer code)

Same three-pattern coexistence as someli-api. Same advice: don't introduce new sync-mysql usage — prefer mysql2/promise.

Cross-repo gotcha: because the DB is shared, a schema change here affects someli-api, Someli-admin-api, all jobs and bots, and the FE's expectations. Always coordinate schema changes, even when they "look local" to designer-api.


AI providers

Provider Used for Where
OpenAI All AI content generation content_generation_bot.js, scattered in routes
Polotno SDK (polotno-node) Server-side image rendering polotno_image_uploader.js, image-generation jobs

That's it. designer-api does not use: - AWS Bedrock - Google Vertex / Gemini - Google Cloud RAG

The smaller AI surface reflects the smaller scope (template factory, not customer-facing AI).

See ../../audit/designer-api/content-pipeline.md.


Background workers and bots

Type Count Pattern Examples
job_*.js ~57 node-cron-scheduled inside the file job_auto_garge_*, job_disability_insurance, job_It_cyber_security, …
*bot.js ~6 Standalone AI workers; some scheduled, some not FAQsbot.js, quizbot.js, quotesbot.js, trendsbot.js, content_generation_bot.js, post_image_generation1_bot.js

There is no ecosystem.config.js — production PM2 orchestration lives outside the repo. See ../../audit/designer-api/jobs-inventory.md.

Industry-clone jobs

A striking pattern: 30+ of the job_*.js files are near-duplicates — each parameterised by an industry (auto-garage, disability insurance, IT cybersecurity, etc.). The code is the same boilerplate copy-pasted with the industry ID hard-coded. A single parameterised job + a config table would remove ~6000 lines of code.

Junior gotcha: if you're changing one industry-clone job, the same logic exists in 30+ other files. Decide whether the change is industry-specific or applies to all clones. If the latter, the right move is usually to refactor toward parameterisation — but flag that as a separate, larger task.

See ../../audit/designer-api/jobs-inventory.md.


External integrations

Service Used for
AWS S3 (two buckets, two regions) Template + media storage
SendGrid Transactional email
OpenAI AI content generation
Polotno (Node + Cloud) Image rendering
Pexels, Pixabay Stock images
News API Trend bot
MS Teams webhook Notifications when content is missing (via teamsnotification.js)

Hardcoded credentials in source. teamsnotification.js ships a hardcoded Slack bot token and channel ID. Known finding. Don't add more.

See ../../audit/designer-api/Integration-inventory.md and ../../audit/designer-api/notifications.md.


Logging and observability

Logger console.log only
Error tracking None
Healthcheck None
Tracing None

Same pattern as someli-api, but even thinner — no /health, no /db-health.

See ../../audit/designer-api/observability.md.


Differences from someli-api

Worth memorising — these are common surprises.

Feature someli-api designer-api
Routes mount routes/auth.js, routes/social.js, routes/paddle.js, routes/partnerAuth.js, routes/routes.js, dashboard/... Only routes/routes.js
Auth JWT + AES Bearer (heavy) Hand-rolled (lighter)
Webhooks Paddle + Stripe with raw-body exemption None
Sessions express-session None
Passport Google, FB, LI, TT, TW strategies None
Dashboard sub-app dashboard/ mounted in-process None
Health endpoint /health, /db-health None
appData re-export module.exports.appData = App No — so dashboard/-style cross-requires don't work
Helper folder 10+ files (aiLogics.js, helper.js, etc.) Only helper/index.js (88 lines)
Body limit 150 MB 50 MB
AI providers Bedrock + Vertex + OpenAI OpenAI only
RAG Google Cloud RAG None
Jobs ~108 ~57
ecosystem.config.js Yes No
Notifications Slack MS Teams + Slack (teamsnotification.js)

Build, lint, test

Build None — Node runs source directly
Lint Not configured
Tests None
CI None in repo — no Jenkinsfile, no GitHub Actions
Deploy Process owned outside the repo
Branches dev, uat, main

Consequence for you: no automated check on your PR. You are the entire CI surface. Manual verification before requesting review is mandatory.


Next

03-architecture.md.