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/DockerfiledoesCOPY .env conf.js favicon.ico ./— meaning the.envis 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-apihas 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.jsships 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.