Frontend

Frontend Architecture

Last updated: 2026-02-01 | Frontend

Frontend Architecture

Key Takeaways

  1. Both repos are Angular 18frontends has been upgraded from 14 to 18.2.13, matching peeq-mono. This removes the version gap as a unification barrier.
  2. Massive duplication — Both repos call the same 24+ backend services, have overlapping component libraries (@vzlabs/ui vs @vzlabs/peeq-ui), and duplicate services for celebrity, content, events, and payments.
  3. Different UI foundations — peeq-mono uses Tailwind/DaisyUI; frontends uses Bootstrap/Angular Material. This is the primary unification blocker.
  4. Frontend dead code — 5 API gateways (broadcast, conference, stream, dwolla, logging) call backend services not deployed to production. ~17% of API calls target non-existent services.
  5. 11 brand tenants themed in peeq-mono, 6 in frontends — theming is CSS-variable-based in both, but different variable naming conventions.

Migration Decision Question

Can frontends be unified into a single Angular 18 monorepo, and what does the frontend call?

Migration Verdict

Verdict: Consolidate Complexity: XL Key Constraint: Different CSS framework foundations (Tailwind/DaisyUI vs Bootstrap/Angular Material) require component-by-component migration, not a simple merge Dependencies: Backend API stability (all frontend services depend on 24+ GraphQL gateways)

Services Inventory

Service Gen Deployed? Stack Purpose
peeq-mono 2 Yes (mono-web) Angular 18.2 / Nx 19.8 / Ionic 6 Fan-facing web + mobile app
frontends 2 Yes (admin-fe, celeb-fe) Angular 18.2 / Nx 19.6 Admin + Expert dashboards
landing-page 2 Yes (site-maintenance) Vanilla HTML Tenant maintenance pages
celeb-keycloak-theme 2 Yes (identityx-26) Freemarker/CSS Expert login theming
fan-keycloak-theme 2 Yes (identityx-26) Freemarker/CSS Fan login theming

Frontend App Matrix

App Repo User Type Port Routes Components
mono-web peeq-mono Fan/Consumer 40+ 370+
mobile peeq-mono Fan/Consumer 12+ Shared with web
admin-fe frontends Admin 8081 43+ 461 (across all)
celeb-fe frontends Expert 8080 15+ Shared with admin
org-dashboard-fe frontends Organization 8082 4 Standalone components

API Surface

GraphQL Gateways (24+ endpoints)

Both peeq-mono and frontends call essentially identical backend services via Apollo Client:

API Gateway Backend Service peeq-mono frontends In Prod?
/api/celebrity celebrity Yes Yes Yes
/api/fan fan Yes Yes Yes
/api/users users Yes Yes Yes
/api/content content Yes Yes Yes
/api/media media Yes Yes Yes
/api/stripe stripe Yes Yes Yes
/api/subscriptions subscriptions Yes Yes Yes
/api/wallet wallet Yes Yes Yes
/api/transaction transaction Yes Yes Yes
/api/shoutout shoutout Yes Yes Yes
/api/inventory inventory Yes Yes Yes
/api/email email Yes Yes Yes
/api/sms sms Yes Yes Yes
/api/chat chat Yes Yes Yes
/api/notifications notifications Yes Yes Yes
/api/sse sse Yes Yes Yes
/api/messageboard message-board Yes Yes Yes
/api/tags tags Yes Yes Yes
/api/webinar webinar Yes Yes Yes
/api/journey journey Yes Yes Yes
/api/classcatalog class-catalog Yes Yes Yes
/api/orgmanager org-manager Yes Yes Yes
/api/groupprofile group-profile Yes Yes Yes
/api/onsiteevent onsite-event No Yes 1/4 tenants
/api/query query Yes Yes 1/4 tenants
/api/broadcast broadcast Yes Yes No
/api/conference conference Yes Yes No
/api/stream stream Yes No No
/api/dwolla dwolla No Yes No
/api/logging logging No Yes No

Cross-Check Result (Session 0 validation)

Mismatch: 5 of 30 API gateways (~17%) call backend services NOT deployed to production. This exceeds the 10% threshold set in the plan.

Resolution: All 5 mismatches are frontend dead code — API calls to services that were once deployed but have been removed from production (broadcast, conference, stream) or never deployed (dwolla, logging). The Session 0 service list is correct; the frontend simply hasn’t been cleaned up.

Dead code inventory: - BroadcastGateway / BroadcastService — broadcast never reached prod - ConferenceGateway / ConferenceService — conference/Jitsi not deployed - StreamGateway — peeq-stream replaced by other services - DwollaService (frontends only) — Dwolla SDK calls in admin-fe - LoggingService (frontends only) — no dedicated logging service in prod

REST/Non-GraphQL Endpoints

Endpoint Pattern Purpose Repo
/api/media/multipart File upload (images, videos) Both
/api/content/multipart Content upload Both
/api/shoutout/file Shoutout video upload frontends
/api/sse/subscribe Real-time event stream Both
/api/conference/sse/subscribe/* Conference events Both

API Backward Compatibility Constraints

Data Model

No frontend-specific persistent data. All state is: - Apollo InMemoryCache — per-gateway GraphQL response cache - BehaviorSubject stores — in-memory reactive state (peeq-mono) - SessionStorage/LocalStorage — auth tokens, user preferences, tenant config - No IndexedDB or Service Worker caching observed

External Integrations

Integration SDK Used In Purpose
Keycloak keycloak-js 26.2 Both OAuth2/OIDC authentication
Stripe @stripe/stripe-js Both Payment forms
Mux @mux/videojs-kit Both Video playback
Phenix RTS @phenixrts/sdk Both Real-time streaming
100ms @100mslive/hms-video-store Both Interactive video
Stream Chat stream-chat-angular Both In-app messaging
Socket.io socket.io-client Both WebSocket real-time
Zendesk Widget embed Both themes Customer support
Google Analytics Script embed fan-keycloak-theme Consumer analytics
LogRocket logrocket frontends Session recording
Plaid @types/plaid-link frontends Bank linking (Dwolla)
Dwolla dwolla.min.js frontends ACH payments (admin)

Architecture Comparison

Aspect peeq-mono frontends
Angular 18.2.13 18.2.13
Nx 19.8.9 19.6.4
TypeScript 5.5.4 5.5.2
CSS Framework Tailwind + DaisyUI Bootstrap + Angular Material
Component Lib @vzlabs/ui (249 components) @vzlabs/peeq-ui (100+ modules)
State Management Custom Store + BehaviorSubject BehaviorSubject + Apollo cache
GraphQL Client Apollo 3.6.9 / apollo-angular 11 Apollo 3.11.8 / apollo-angular 7
Auth keycloak-angular 16.1 keycloak-angular 16.1
Video Player video.js + Mux video.js + Mux
Chat stream-chat-angular 4.68 stream-chat-angular 4.68
Mobile Ionic 6 / Capacitor 3.6 None
Testing Jest 29.5 / Cypress 13 (6 files) Jest 29.7 (passWithNoTests)
Brand Tenants 11 themes 6 themes
Rich Text suneditor suneditor + quill + monaco
Date Library luxon 3 date-fns + moment + luxon 1

Key Differences

  1. CSS foundation — Tailwind vs Bootstrap is the biggest gap. Components can’t be shared without restyling.
  2. Component library naming@vzlabs/ui vs @vzlabs/peeq-ui are separate packages with overlapping but not identical APIs.
  3. Apollo versions — Different major versions of apollo-angular (11 vs 7).
  4. Date libraries — peeq-mono uses luxon 3; frontends uses date-fns + moment + luxon 1 (three libraries for the same purpose).
  5. Additional tools in frontends — Monaco editor, Quill, Plaid, OpenPGP.

Multi-Brand Theming

peeq-mono: 11 Tenants

libs/ui/tenants/
├── agilenetwork/     ← Primary
├── peeq/
├── braintrust/
├── monster/
├── geoffreyzakarian/
├── peeqkitchen/
├── speedofai/
├── fanfuzenil/
├── vtnil/
├── nilgameplan/
└── sd4l/

frontends: 6 Tenants

libs/peeq-ui/assets/styles/themes/
├── agilenetwork.scss
├── braintrust.scss
├── nilgameplan.scss
├── fanfuzenil.scss
├── speedofai.scss
└── vtnil.scss

Theming Mechanism (Both Repos)

  1. Theme compiled as separate CSS bundle with inject: false
  2. Environment config sets themeStylesheet path
  3. App initialization dynamically loads tenant CSS
  4. CSS custom properties (:root variables) override component styles
  5. Brand-specific assets loaded from GCS tenant buckets

Keycloak Themes

Theme User Type Key Feature
celeb-keycloak-theme Expert Google OAuth, email templates (13+), Zendesk
fan-keycloak-theme Consumer Google Analytics, T&C flows, dynamic tenant resolution

Fan theme uses realm.getName() for dynamic tenant assets (more scalable). Celeb theme uses hardcoded paths.

Testing Status

Metric peeq-mono frontends
Test files 6 ~0 (passWithNoTests)
Test framework Jest + Cypress Jest + Cypress
Coverage Near zero Near zero
E2E Configured, not populated Configured, not populated

Both repos have effectively zero test coverage. This is a significant risk for any migration.

Gen 1 → Gen 2 Comparison

Aspect Gen 1 (Legacy FE) Gen 2 (Current)
Fan frontend peeq-fan-fe (standalone) peeq-mono/web (Nx monorepo)
Expert frontend peeq-celeb-fe (standalone) frontends/celeb-fe (Nx monorepo)
Admin frontend peeq-admin-fe (standalone) frontends/admin-fe (Nx monorepo)
Mobile peeq-fan-ionic (standalone Ionic) peeq-mono/mobile (Nx + Ionic + Capacitor)
Handler frontend peeq-handler-fe (standalone) None — handler role absorbed?

All Gen 1 standalone frontend repos are inactive and archivable. Gen 2 is the active codebase.

Modernization Implications

Can frontends be unified?

Technically feasible, but XL complexity. The barriers are:

  1. CSS Framework Migration (L effort): Tailwind/DaisyUI ↔︎ Bootstrap/Material requires restyling every component. Cannot be automated.
  2. Component Library Merge (L effort): @vzlabs/ui (249 components) and @vzlabs/peeq-ui (100+ modules) overlap significantly but have different APIs and styles.
  3. Apollo Version Alignment (S effort): Upgrade frontends from apollo-angular 7 to 11, or vice versa.
  4. Date Library Consolidation (S effort): Pick one — luxon 3 is the best candidate. Remove moment and date-fns.
  5. Brand Theme Reconciliation (M effort): Merge 11 + 6 tenant themes into one system. CSS variable names may differ.
graph LR
    A[Current: 2 Repos] --> B{Phase 1}
    B --> C[Shared API layer<br/>Extract common services]
    C --> D{Phase 2}
    D --> E[Standardize on Tailwind<br/>Migrate frontends components]
    E --> F{Phase 3}
    F --> G[Merge into single<br/>Nx monorepo]
    G --> H[Unified: 1 Repo<br/>4 apps + 1 lib]

Phase 1: Extract common service layer (GraphQL gateways, auth) into a shared library usable by both repos. This provides immediate value without restyling.

Phase 2: Migrate frontends components from Bootstrap/Material to Tailwind/DaisyUI, or vice versa. This is the bottleneck.

Phase 3: Merge into single Nx monorepo with apps: mono-web, mobile, admin-fe, celeb-fe, org-dashboard-fe and one unified component library.

What to do with org-dashboard-fe?

Only 4 pages using Angular standalone components. This is already the most modern pattern. Consider it a pilot for the unified architecture — migrate it first.

Dead Code Cleanup

Remove these dead API integrations from both repos before any migration: - BroadcastGateway / BroadcastService - ConferenceGateway / ConferenceService - StreamGateway - DwollaService (if Dwolla is confirmed inactive in Session 5) - LoggingService


Last updated: 2026-01-30 — Session 1 Review by: 2026-07-30 Staleness risk: Medium — frontend evolves with feature development