Technologies
The concrete stack, the tooling around it, and the conventions that are actually enforced.
Frontend (portal/)
- Vue 3.5 + TypeScript, built with Vite 8 (Rolldown bundler). Managed with npm, not pnpm - the one subproject rule people trip on.
- State: Pinia for new code; Vuex only as a shrinking legacy layer.
- Testing: Vitest 4 +
@vue/test-utils+ Testing Library, jsdom, co-located.spec.ts, snapshot tests updated vianpm run test:snapshot. - Linting: hybrid oxlint first, then ESLint - oxlint owns the eslint-core/typescript-eslint surface, ESLint keeps Vue template rules, Prettier, custom rules.
vue-tscfor type-checking. Notable rules: noany, barrel-only imports from@/commonComponents, multi-word component names, max 500 lines per component. - Design system: internal
commonComponentslibrary with its own Storybook. - i18n: JSON locale files; permission display names live in
en.jsonunderpermissionsList. - Path aliases:
@→src,@unified→src/unified,@lotusflare/*→ monorepolibs/*packages (auth, billing, catalog, dto, entities...).
Backend (portalBackend/)
- Express 4 + TypeScript, HTTPS on port 443 in dev.
- Sequelize 6 + MySQL (
mysql2); migrations run throughscripts/(npm run db:smart-migrate:enhanced), never raw sequelize-cli. - Auth: Passport (local,
passport-azure-ad,passport-okta-oauth); sessions viaexpress-session+connect-session-sequelize. - Redis for caching, Kafka event schemas under
eventSchemas/, StatsD metrics. - Testing: Jest with
ENV_FILE=./config/.env.test.
Configuration
- The primary runtime config is
lf_webapp_config.json, pointed at byAPP_CONFIG_PATH. It carriesservice_hosts_map(URLs of every downstream service),portal_mysql_map(DB endpoints and credentials), Redis, AWS/S3, and StatsD settings. - Feature flags: registry in
portalBackend/config/featureFlags.json; enablement per operator in the DB (Tenant Editor), or per user via a cookie endpoint. - Helm-managed env vars are shared by portal and portalBackend; per-DC values live in the env trees.
Local development
- Run
npm run devin bothportal/andportalBackend/; the SPA dev server ishttps://portal-dev.lotusflare.com:5173and needs SSL certs generated by thelf-setuprepo. - The recommended path is the Rhino tool, which provisions the full backend environment (MySQL, Redis, Cassandra) locally in one command - connecting a local BFF to remote AWS databases is painfully slow.
routes.jsonis read once at startup: after editing it, restart portalBackend.
Gotchas worth memorizing
- Lint path-scoping: from inside
portal/, passsrc/...- a repo-rootportal/src/...path silently lints zero files. portalBackend'snpm run lintcannot be path-scoped at all - run it unscoped.- New nav pages need the full checklist on both sides: route, router registration, sidebar, locale strings, backend view key, and permission keys - miss one and the page half-exists.