02 — Someli-Designer stack¶
Looks like someli-platform. Is much thinner. Knowing the differences saves you from copy-pasting bad assumptions.
At a glance¶
| Concern | Choice | Version |
|---|---|---|
| Framework | Nuxt 2 | 2.18.1 (CLI), 2.15.8 (core) |
| View library | Vue 2 | 2.7.16 |
| Mode | SPA — ssr: false |
— |
| State | Vuex 3 (single store/index.js, no sub-modules) |
— |
| HTTP | @nuxtjs/axios |
^5.13.6 |
| Auth | @nuxtjs/auth + local strategy |
^4.9.1 |
| Cookies | cookie-universal-nuxt |
^2.2.2 |
| UI | Bootstrap-Vue 2 + Bootstrap 5.3 (from CDN) | ^2.23.1, ^5.3.3 |
| Polotno editor | React 18 + MobX-State-Tree + Polotno 2.13.10 (subproject) | — |
| Form upload | filepond |
— |
| Notifications | vue-notification, vue-toastification |
— |
| Tests | None | — |
| Lint / format | Not configured | — |
Differences from someli-platform¶
| Concern | someli-platform |
Someli-Designer |
|---|---|---|
| Vuex modules | 10+ sub-modules (post/, dashboard/, chat/, common/, plan/, reach/, …) |
Single store/index.js |
store/api.js cache layer |
5-minute TTL across ~12 endpoints | None — components call $axios directly |
components/ |
Many, grouped (Calender/, Charts/, Dashboard/, …) |
Only 4 (Navbar, Notification, skeletonCard, ToasterProgress) |
pages/ |
Nested under _accid/... |
Flat — 73 files, no subdirectories |
| Router middleware chain | 5 middlewares (redirect, axios, validUrl, appendUTM, appendUrl) | Only axios (declared globally in nuxt.config.js → router.middleware) |
Server middleware (api/) |
Yes (small Nuxt serverMiddleware) | None |
| Bootstrap version | Bootstrap 4 (via Bootstrap-Vue) | Bootstrap-Vue (4) AND Bootstrap 5.3 from CDN — double-loaded |
| Polotno editor fork | polotno-editor/ (221 KB, AI-rich) |
polotno-editor/ (50 KB, lean) |
| Auth header name (FE) | Apptype (base64) |
Apptype (base64) |
Junior gotcha: if you've worked on
someli-platform, your muscle memory will be wrong here. There is nostore/api.jscache. There are not 10 Vuex sub-modules. Components hit$axiosdirectly.
Folder layout¶
Someli-Designer/
├── package.json ← 38 deps, 1 devDep (npm-force-resolutions)
├── package-lock.json
├── nuxt.config.js ← 71 lines — SPA mode, auth, modules
├── README.md ← Polotno editor workflow
├── Dockerfile ← multi-stage; EFS-mounted node_modules at runtime
├── polotno-bundle.js (+ .map) ← built artefact of polotno-editor/
│
├── assets/css/ ← blueprint.css, bootstrap.css, common.css
├── components/ ← ONLY 4 files
│ ├── Navbar.vue ← role_type-based nav gating (commit 074b9ec)
│ ├── Notification.vue
│ ├── skeletonCard.vue
│ └── ToasterProgress.vue
├── helpers/ ← small
├── layouts/
│ ├── default.vue ← Navbar + <nuxt/> + notification slots
│ └── blank.vue ← bare layout for login
├── middleware/
│ ├── axios.js ← axios interceptor — adds Apptype header
│ └── guest.js ← redirects authenticated users away from guest-only pages
├── pages/ ← 73 flat files (no subdirectories)
│ ├── login.vue
│ ├── dashboard.vue
│ ├── topics.vue, topicsNew.vue
│ ├── content_library.vue, master_library.vue, master_libraryNew.vue
│ ├── conditionedContent.vue, conditionedContentNew.vue
│ ├── image_Library.vue
│ ├── automationTemplate.vue, nonAutomationTemplate.vue, tempsets.vue, carousaltemplates.vue
│ ├── templateEditor.vue, templateEditor1.vue, carousaltemplateEditor.vue ← Polotno mounts here
│ ├── postEditor.vue, postcreator.vue, postdesigner.vue
│ ├── mediaEditor.vue, MastermediaEditor.vue, PreproductionPostEditor.vue
│ ├── dynamicPost.vue, dynamicPost - Copy.vue, specialdynamicposts.vue, preProductionPost.vue
│ ├── Posts.vue, postsMismatching.vue, contentMismatching.vue
│ ├── PostColorCorrection.vue, TemplateColorCorrection.vue
│ ├── TemplateConditioning.vue, topicvalidation.vue
│ ├── News.vue, LatestNews.vue
│ ├── popularSubjects.vue, subjects.vue, subjectsDemands.vue, subjectsBasedJobs.vue
│ ├── generateSubject.vue, generatedSubjectContent.vue
│ └── ... (and many more)
├── plugins/
│ ├── customCommon.js
│ ├── common.js ← registers BootstrapVue + Notifications (client-only)
│ └── hotjar.js ← client-only Hotjar tracking
├── polotno-editor/ ← React 18 + MobX-State-Tree subproject
│ ├── index.html / index.js / App.js / app.css
│ ├── package.json ← 15 runtime deps
│ ├── alltemplatesPanel.js, templatesPanel.js, carousaltemplatesPanel.js
│ ├── brandkitPanel.js ← note: capital P (customer app has brandkitpanel.js — lowercase)
│ ├── customUploads.js, mediaGrid.js, Pexels.js, PexelVideos.js
│ ├── CustomPageControls.js, CustomWorkspace.js, icons.js, helper.js
│ ├── QrSection.js, ModalPortal.js
│ └── ...
├── static/ ← logos
└── store/
└── index.js ← THE single Vuex module — no sub-modules
nuxt.config.js highlights¶
export default {
ssr: false,
head: { /* title, meta, bootstrap.bundle.min.js from jsdelivr CDN — Bootstrap 5 */ },
css: ['@/assets/css/blueprint.css', '@/assets/css/bootstrap.css', '@/assets/css/common.css'],
plugins: [
'@/plugins/customCommon',
{ src: './plugins/common', ssr: false },
{ src: './plugins/hotjar', ssr: false },
],
components: true, // auto-registration
router: { middleware: 'axios' }, // ONE global middleware
buildModules: ['@nuxtjs/dotenv'],
modules: ['bootstrap-vue/nuxt', '@nuxtjs/axios', '@nuxtjs/auth', 'cookie-universal-nuxt'],
axios: { baseURL: process.env.baseURL },
auth: {
strategies: {
local: {
endpoints: {
login: { url: 'webauthenticate', method: 'post', propertyName: 'data' },
user: { url: 'me', method: 'get', propertyName: 'data' },
logout: false // logout is client-side only
}
}
}
},
build: { transpile: ['swr'] },
};
Read this file end-to-end. It is short.
CDN-loaded scripts¶
The only CDN script of note is Bootstrap 5 JS (cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js), loaded from nuxt.config.js → head.script.
Combined with Bootstrap-Vue's Bootstrap 4 CSS, this double-loads Bootstrap. The Bootstrap 5 JS controls the navbar; the Bootstrap 4 CSS styles other Bootstrap-Vue components. If the navbar misbehaves, the 4-vs-5 conflict is the most likely cause.
SRI: the CDN scripts have no
integrityattributes. Known platform-wide finding.
State — single-module Vuex¶
store/index.js is the entire store. There are no sub-modules. Everything (auth state, page data, UI state) lives in one module.
If you've worked on someli-platform and reach for store.dispatch('post/...') or store.dispatch('api/...') — those don't exist here.
Axios interceptor¶
middleware/axios.js is the only global middleware. It adds the Apptype header (base64-encoded) on outbound requests so designer-api can identify this FE.
Differences from someli-platform/middleware/axios.js:
- Simpler — no
token/accountIdconditional header injection on/auth/paths (designer-api's auth is hand-rolled, not Bearer JWT). - Likely just sets
Apptypeand trusts cookies for the rest.
Read the file directly — it's small.
Role-based nav gating¶
components/Navbar.vue restricts nav items by role_type (introduced in commit 074b9ec). The backend has corresponding access checks.
Role IDs taxonomy (SUPER_ADMIN, ADMIN, ACCOUNT_MANAGER, DEVELOPER, DESIGNER, …) lives in admin_console_R/src/config/env.ts and is replicated on backends. This is a source of drift risk: the FE's role IDs come from env vars; the backend's are in code. Verify alignment with the team before assuming a role number.
Build, lint, test¶
| Build | yarn build → static SPA |
| Lint | Not configured |
| Format | Not configured |
| Tests | None |
| CI | None in repo |
| Deploy | Process owned outside the repo |
| Branches | dev_des_app, uat_des_app, main |