Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AllianceBioversityCIAT/alliance-research-indicators-client/llms.txt
Use this file to discover all available pages before exploring further.
The Alliance Research Indicators client is a single Angular 19 SPA that acts as the browser tier of a multi-platform results federation. It communicates with three independent backend services, authenticates through AWS Cognito, and maintains a real-time presence channel via WebSocket. This page describes the system topology, the domain module split, and the conventions that govern every new piece of code.
System topology
┌────────────────────────────────────────────┐
│ Browser (Angular 19 SPA, this repo) │
│ │
│ - PrimeNG 19 UI, Signals + RxJS, SCSS │
│ - Lazy standalone routes │
│ - JWT + Cognito auth │
│ - WebSocket presence/notifications │
│ - Analytics: Hotjar, Clarity, GA, BugHerd │
└──────────┬───────────────┬──────────────┬──┘
│ HTTPS / REST │ HTTPS / REST │ WSS
│ │ │
┌──────────▼──┐ ┌────────▼──────┐ ┌────▼──────────┐
│ Main API │ │ Text-Mining │ │ File Manager │
│ (NestJS) │ │ microservice │ │ microservice │
└─────────────┘ └───────────────┘ └───────────────┘
│
▼
┌─────────────┐ ┌───────────────────┐
│ CLARISA │ │ STAR / TIP / PRMS │
│ (lists) │ │ AICCRA (federation)│
└─────────────┘ └───────────────────┘
│
▼
┌───────────────┐
│ AWS Cognito │
└───────────────┘
Backend services
| Service | Environment variable | Purpose |
|---|
| Main API (NestJS) | mainApiUrl | All core business logic — results CRUD, indicator catalog, user management, CLARISA controlled-list proxying, dashboards, and the authorization endpoints |
| Text-Mining microservice | textMiningUrl | AI/NLP extraction and auto-fill for result form fields |
| File Manager microservice | fileManagerUrl | Multipart evidence file upload; returns a persistent URL that is stored on the result record (raw file bytes are never embedded in a result POST) |
CLARISA provides the authoritative controlled vocabularies (institutions, countries, regions, SDGs, levers, impact areas, and more) via Main API proxy endpoints at /tools/clarisa/*. The federation platforms STAR, TIP, PRMS, and AICCRA are linked read-only from the client via deep-link URLs supplied by the Main API.
Folder layout
src/
├── environments/ # environment.ts / environment.dev.ts
├── styles/ # Global SCSS: colors, fonts, tokens, PrimeNG overrides
└── app/
├── app.config.ts # Providers: router, HTTP client, interceptors, service worker
├── app.routes.ts # Lazy standalone routes and route guards
├── pages/ # Feature pages — one folder per route group
│ ├── landing/ # Public landing surface
│ ├── login/ # Cognito login entry
│ ├── auth/ # OAuth callback handler
│ ├── room/ # WebSocket real-time collaboration
│ ├── oicr-download/ # Public OICR template download
│ ├── dynamic-fields/ # Form-field configuration utility
│ └── platform/ # Authenticated shell + child pages
│ └── pages/
│ ├── home/
│ ├── about/
│ ├── indicator/
│ ├── result/ # Result detail — 11 metadata tabs
│ ├── results-center/
│ ├── search-a-result/
│ ├── my-projects/
│ ├── project-detail/
│ ├── dashboard/
│ ├── notifications/
│ ├── profile/
│ └── administration/center-admin/
├── shared/ # Cross-cutting code
│ ├── components/ # Shared UI components
│ ├── services/ # ApiService, CacheService, RolesService, etc.
│ ├── interceptors/ # JWT, http-error, result
│ ├── guards/ # rolesGuard, centerAdminGuard
│ ├── interfaces/ # TypeScript shapes
│ ├── pipes/ # format-date, s3-image-url, filter-by-text-with-attr
│ ├── utils/ # Date/geo/map helpers
│ ├── sockets/ # WebsocketService
│ ├── types/ # Shared TS type helpers
│ └── enums/ # Enum constants
├── theme/ # PrimeNG Aura preset (roartheme.ts)
└── testing/ # Shared test mocks and harness
Domain modules
The app is organized by page domain under src/app/pages/, mirroring the spec taxonomy in docs/specs/.
| Module | Path | Responsibility |
|---|
| Platform shell | pages/platform/ | Authenticated shell — navbar, sidebar, router outlet for children |
| Home | pages/platform/pages/home/ | Logged-in dashboard / entry actions |
| Indicator | pages/platform/pages/indicator/, about-indicators/ | Indicator catalog and detail view |
| Results | pages/platform/pages/result/, results-center/, search-a-result/, load-result/ | Result lifecycle: create, edit (11 metadata tabs), search, hub |
| Projects | pages/platform/pages/my-projects/, project-detail/ | Project portfolio and detail |
| Dashboard | pages/platform/pages/dashboard/ | Aggregate analytics with Chart.js visualizations |
| Notifications | pages/platform/pages/notifications/ | Real-time notification feed |
| Profile | pages/platform/pages/profile/ | User settings and theme preferences |
| About | pages/platform/pages/about/ | Application information |
| Administration / Center Admin | pages/platform/pages/administration/center-admin/ | Bulk upload and SDG management (requires role_id === 1 or center-admin composite check) |
| Auth | pages/login/, pages/auth/ | Cognito login entry and OAuth callback |
| Landing | pages/landing/ | Public-facing surface |
| Real-time | pages/room/ | WebSocket collaboration room |
| OICR Download | pages/oicr-download/ | Public OICR template download |
| Dynamic Fields | pages/dynamic-fields/ | Form-field configuration utility |
| Shared | src/app/shared/ | Components, services, pipes, utilities, interfaces — referenced by all domain modules |
| Theme | src/app/theme/ | PrimeNG Aura preset (roartheme.ts); dark mode uses .dark-mode CSS class selector |
| Testing | src/app/testing/ | Shared test mocks and harness; co-located .spec.ts files live next to their subjects |
Angular 19 conventions
Standalone components only. No NgModules are used in this codebase (PRD constraint C-6). Every component, directive, and pipe is declared with standalone: true and imports what it needs directly.
Lazy loading via loadComponent. Every authenticated route in app.routes.ts uses the loadComponent: () => import(...) pattern. This keeps the initial bundle small and respects the Angular budget constraints (initial bundle ≤ 2 MB warning / 3 MB error).
View transitions. The router is configured with withViewTransitions() in app.config.ts, enabling CSS @view-transition animations between route changes where the browser supports them.
Component selector prefix. All generated selectors use the app prefix (for example app-results-table), as configured in angular.json.
Strict TypeScript. The tsconfig.json enables strict, noImplicitOverride, noPropertyAccessFromIndexSignature, noImplicitReturns, noFallthroughCasesInSwitch, and strictTemplates. Do not weaken these settings.
Path aliases
All imports inside src/ must use these aliases rather than deep relative paths. They are declared in tsconfig.json and must be kept in sync with jest.config.ts.
| Alias | Resolves to |
|---|
@public/* | public/* |
@envs/* | src/environments/* |
@pages/* | src/app/pages/* |
@platform/* | src/app/pages/platform/* |
@auth/* | src/app/pages/auth/* |
@landing/* | src/app/pages/landing/* |
@shared/* | src/app/shared/* |
@components/* | src/app/shared/components/* |
@services/* | src/app/shared/services/* |
@interfaces/* | src/app/shared/interfaces/* |
@interceptors/* | src/app/shared/interceptors/* |
@guards/* | src/app/shared/guards/* |
@sockets/* | src/app/shared/sockets/* |
@utils/* | src/app/shared/utils/* |
@ts-types/* | src/app/shared/types/* |
Application bootstrap
app.config.ts is the root provider configuration. The interceptor chain, router options, PrimeNG theme, and the app initializer are all registered here:
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes, withViewTransitions()),
provideHttpClient(withInterceptors([jWtInterceptor, httpErrorInterceptor, resultInterceptor])),
importProvidersFrom(BrowserModule, BrowserAnimationsModule),
provideAnimationsAsync(),
providePrimeNG({
theme: {
preset: MyPreset,
options: { darkModeSelector: '.dark-mode' }
}
}),
provideAppInitializer(() => {
// initializes tracking tools, validates cached tokens, and loads date-format config
}),
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000'
})
]
};
The service worker is registered only in production builds (!isDevMode()). It waits 30 seconds after the app stabilizes before registering, avoiding interference with the initial load.