4.9 KiB
4.9 KiB
FRONTEND
Angular 18+, standalone components throughout (no NgModules). See docs/PROJECT-STRUCTURE.md for the full src/app/** folder tour and docs/ARCHITECTURE.md for the layered container/facade/service pattern.
App structure at a glance
src/app/
core/ domain services, DTOs, mappers, repositories (per domain: categories, products, search, admin-auth)
facades/ cross-feature facades (platform/category.facade.ts, platform/search.facade.ts, ...)
features/ feature modules (project-editor, admin/*, backoffice/*, website/catalog, website/product, diagnostics, content-management, search)
shared/ models/config (BootstrapConfig + ~20 sub-configs), shared UI, utils — feature-agnostic
widgets/ widget contracts, registry/manifest, resolvers, ui components
dynamic-renderer/ section-engine, page-renderer, section-renderer, widget-host
layouts/ page-chrome containers (dynamic-page-layout, header/footer shells)
i18n/ translations.ts (interface), en.ts, ru.ts, hy.ts, translate.pipe.ts, TranslateService
pages/ top-level routed pages (home, cart, category, ...)
components/ reusable standalone components used across features (product-card, telegram-login, ...)
guards/ route guards (admin-auth guard, etc.)
Routing (app.routes.ts)
- Locale-prefixed routes:
/:lang/...(lang fromLanguageService.currentLanguage()), plus root redirects. - Storefront:
/,/catalog,/catalog/:id,/product/:id(legacy/item/:idand/category/:id[/items]redirect for compatibility). - Static/CMS pages resolve dynamically:
/:lang/:staticPath(legacy/:lang/page/:keykept for compatibility) — no hardcoded page list, resolved frombootstrap.staticPages. - Project Editor:
/edit/:sectionor/{lang}/edit/:section. - Admin/backoffice:
/:lang/backoffice/**, guarded byadminAuthGuard(core/admin-auth/admin-auth.guard.ts) — dashboard, products (fully wired), categories/static-pages/transactions/orders/media (routed toBackofficeComingSoonPageComponentplaceholders pending features). Seedocs/ADMIN.md. - Dev-only diagnostics:
/__diagnostics(excluded from production).
i18n system
src/app/i18n/translations.tsdefines theTranslationsinterface — the single schema every locale file must satisfy (TypeScript enforces this at compile time: a missing key in any locale is a build error).en.ts,ru.ts,hy.tsimplement that interface, keyed identically and nested by feature area (header,footer,home,builder,dashboard, ...).TranslateServiceresolves the active locale and exposes translated strings;TranslatePipe(| translate) is the template-facing API — never hardcode user-facing strings in templates, always add a key to all three locale files.- 3 locales:
en,ru,hy(Armenian).LanguageServicetracks the active locale and drives the/:lang/route prefix. - Adding a new UI string: add the key to the
Translationsinterface first, then toen.ts/ru.ts/hy.tsin the same position (seedocs/EDITOR.mdfor the pattern used by the field-description work).
Theming
- 3 tenant theme stylesheets:
src/styles/themes/*.theme.scss. - Convention: each theme file defines CSS custom properties (
--color-primary,--text-primary,--border-color, etc.) that mirrorThemeConfig.palette/typography/shadows/borderRadiusScale; components and widgets consume only these custom properties, never hardcoded hex values (ADR-008). theme.mode(light | dark | system) and the palette are runtime-configurable per tenant via bootstrap and editable via the Project Editor's Theme section (docs/EDITOR.md).
State management
- Signals-based facades, no NgRx. Every feature/domain exposes a facade (
ProjectEditorFacade,CategoryFacade,ProductFacade,SearchFacade,AdminDashboardFacade, ...) built on Angular signals (signal,computed,effect), following ADR-007. - Components inject exactly one facade and read/write through it; no direct service or HTTP access from components (ADR-006).
- Local component state (e.g. draft form values) stays in the component; cross-cutting/shared state lives in the facade.
- Persistence for local-only features (Project Editor drafts, admin dashboard activity history) uses scoped
localStoragekeys behind a dedicated service (ProjectEditorDraftStorageService,AdminDashboardHistoryService) — never rawlocalStoragecalls from components/facades.
Dynamic widget/section rendering from bootstrap JSON
Full detail in docs/ARCHITECTURE.md and docs/backend/BACKEND-INTEGRATION.md#4-bootstrap. Summary: page config (bootstrap.pages) -> Section Engine (order/layout/visibility) -> Page Renderer -> Widget Host (resolves component via Widget Manifest + data via Data Source Resolver) -> widget component (props + resolved data only). Nothing in this pipeline calls an API directly except the Data Source Resolver, which delegates to CategoryFacade/ProductFacade.