Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# AGENTS.md

## Guide index

| Area | Path | Guide |
|------|------|-------|
| Angular web app (this file) | `src/` | § below |
| Kubernetes Helm chart | `helm/` | [`helm/AGENTS.md`](helm/AGENTS.md) |
| Android (Capacitor) native project | `android/` | [`android/AGENTS.md`](android/AGENTS.md) |

## Repository Overview

This repository contains the **Angular web (and Android) front-end for the MOSIP Compliance Toolkit (CTK)** — the "Compliance Toolkit Portal". CTK lets technology partners test whether their biometric products comply with MOSIP specifications, and lets MOSIP administrators review and approve the resulting compliance reports.

It supports three project types, mirroring the backend [mosip-compliance-toolkit](https://github.com/mosip/mosip-compliance-toolkit) service:

- **SBI** (Secure Biometric Interface) — biometric capture devices, driven locally (web) or via an on-device intent (Android)
- **SDK** (Software Development Kit) — a biometric matching/quality SDK exposed as a `biosdk-service` REST endpoint
- **ABIS** (Automated Biometric Identification System) — communicates asynchronously over ActiveMQ for insert/identify operations

The UI does not implement compliance rules itself — it orchestrates test execution: pulls test cases from the backend, drives the target product, sends responses back to the backend for validation, stores the run, and renders pass/fail reports. For a product overview, see [docs.mosip.io/compliance-tool-kit](https://docs.mosip.io/compliance-tool-kit).

## Technology Stack

- **Angular 13.3** (TypeScript ~4.6), **Angular Material 13**, **Angular CLI ~13.3.2** (per `package.json`/README) for local/web development. Note: `.github/workflows/android.yml` installs Angular CLI `13.0.0` specifically for the Android build — this is a real version split between local tooling and Android CI, not a typo in one place; if you touch either, confirm whether the split is still intentional before aligning them.
- **@ngx-translate** for i18n (English/Arabic/French, RTL-aware)
- **Keycloak**-based authentication (cookie/JWT on web; a dedicated `android-keycloak` handler for the Android app)
- **`@stomp/rx-stomp` + `stompjs`** for ActiveMQ messaging (ABIS flow)
- **Capacitor 4** (`@capacitor/*`, `mosip-sbi-capacitor-plugin`) to package the same codebase as an **Android app** (`android/`) that talks to on-device SBI hardware
- **Karma + Jasmine** for unit tests
- Production build is served by **nginx** (see `Dockerfile`, `nginx.conf`, `default.conf`)
- **Node 14.17.3 / npm 6.14.13** recommended (per README)

## Build & Test Commands

Run from the repository root:

```shell
# Install dependencies
npm install

# Dev server (http://localhost:4200)
npm start

# Dev server via proxy, to avoid CORS against a real backend
ng serve --proxy-config proxy.conf.json

# Production build (output to dist/)
ng build "--prod" "--base-href" "." "--output-path=dist"

# Unit tests (Karma + Jasmine)
npm test

# Static analysis (requires sonar-scanner + SONAR_TOKEN)
npm run sonar
```

Build and run the Docker image:

```shell
docker build -t toolkitui .
docker run -d -p 8080:8080 --name toolkitui toolkitui
# UI now reachable at http://localhost:8080
```

There is no dedicated end-to-end/integration test suite in this repo — `npm test` runs Karma unit tests only.

## Configuration

Configuration is layered across a few files, all of which are **environment-specific and get overridden per deployment**:

- `src/assets/config.json` (tracked) — runtime config loaded via `APP_INITIALIZER`/`AppConfigService` before the app renders: `SERVICES_BASE_URL`, `SBI_BASE_URL`, `SDK_BASE_URL`, `toolkitUiUrl`, `login`/`logout` paths. Locally this points at the `ng serve` proxy (`/proxyapi/`); in production it is replaced to point at the real backend. `AppConfigService` also merges server-side config (session timeouts, admin roles, RTL language list) from the backend `configs` endpoint on top of this file.
- `proxy.conf.json` — Angular CLI dev-server proxy config used to avoid CORS locally; not committed by default (create it per the README, pointing `target` at the backend services URL).
- `.env` — local-only environment variables consumed by the Android build (`NX_APP_SERVICES_BASE_URL`, `NX_APP_IAM_URL`, `NX_APP_IAM_REALM`, `NX_APP_IAM_CLIENT_ID`). **This file is not covered by `.gitignore`** — take care never to `git add` it; the Android CI workflow (`.github/workflows/android.yml`) sets the equivalent values as GitHub Actions env vars via `workflow_dispatch` inputs instead.
- `src/environments/environment*.ts` (`environment.ts`, `.prod.ts`, `.android.ts`) — build-time Angular environment files; `environment.isAndroidAppMode` switches the app between web and Android behavior (e.g. Android reads `SERVICES_BASE_URL` from `environment.android.ts` instead of `config.json`).

Because none of these files should carry real credentials or environment-specific secrets in version control, double-check `git status`/`git diff` before committing changes near `config.json`, `.env`, or `environment.*.ts`.

## Project Structure Notes

```text
src/
├── main.ts, index.html, styles.css # bootstrap + global styles
├── environments/ # environment.ts | .prod.ts | .android.ts
├── assets/
│ ├── config.json # runtime config (overridden per environment)
│ └── i18n/ # eng.json | ara.json | fra.json | default.json
└── app/
├── app.module.ts # root module + APP_INITIALIZER
├── app-routing.module.ts # top-level routes: landing | toolkit (lazy) | wildcard
├── landing-page/ # pre-login page, checks for an existing Keycloak session
├── main-app/ # lazy "toolkit" shell module + routing, guarded by AuthguardService
├── core/ # singletons: layout, services, models (see below)
└── features/ # lazy feature modules: dashboard, project, collections, test-data, test-run
```

Key core services under `src/app/core/services/`:

- `data-service.ts` — the single REST gateway; every backend endpoint call lives here, components don't call `HttpClient` directly for the backend
- `httpinterceptor.ts` (`AuthInterceptor`) — attaches credentials/XSRF token (web) or Capacitor cookie/header (Android) to every backend call
- `authservice.service.ts` / `authguard.service.ts` — route guard for the `toolkit` area
- `sbi-testcase-service.ts` / `sbi-testcase-android-service.ts` — orchestrate SBI test cases (web vs. Android)
- `sdk-testcase-service.ts` — orchestrates SDK test cases against `biosdk-service`
- `abis-testcase-service.ts` + `activemq-service.ts` / `rx-stomp*.ts` — orchestrate ABIS test cases over STOMP/ActiveMQ

`android/` contains the Capacitor-generated native Android project (synced via `npx cap sync`); it is a tracked part of the repo, not a build artifact — don't delete or regenerate it casually. See [`android/AGENTS.md`](android/AGENTS.md) for the Android build/run guide.

`helm/` contains the Kubernetes Helm chart used to deploy the built UI image; see [`helm/AGENTS.md`](helm/AGENTS.md) for install/upgrade commands.

## Development Workflow

- Default integration branch is `develop`; release branches follow `release-<version>` naming (e.g. `release-1.4.x`).
- `.github/workflows/push-trigger.yml` builds and dockerizes the app on pushes to `develop`, `master`, `release-1*`, and `1.*`, and on pull requests, via reusable workflows in `mosip/kattu` (`npm-build.yml`, `docker-build.yml`, `npm-sonar-analysis.yml`).
- `.github/workflows/android.yml` builds the Android APK on pushes to `develop` (or manual `workflow_dispatch`), setting `NX_APP_*` env vars and running `ng build -c=android` followed by a Gradle build via Capacitor.
- `.github/workflows/chart-lint-publish.yml` lints/publishes the Helm charts under `helm/` when that path changes.
- Before opening a PR, run `npm test` and `ng build "--prod" "--base-href" "." "--output-path=dist"` locally to confirm the app still builds and unit tests pass.

## Pull Request Guidelines

- Target the `develop` branch unless the change is specifically a backport/fix for a release branch.
- If a change affects a backend contract (request/response shapes, new endpoints), check whether it needs a corresponding change in [mosip-compliance-toolkit](https://github.com/mosip/mosip-compliance-toolkit) and note that in the PR description.
- If a change affects the Android build (Capacitor plugins, `android/` project, `.env`/`environment.android.ts`), call that out explicitly so the Android CI workflow gets exercised.
- Sign off commits (`git commit -s`) per MOSIP contribution conventions.

## Repository-Specific Considerations

- The UI's "compliance verdict" always comes from the backend (`validateRequest`/`validateResponse`); this app's job is limited to collecting the real product's behavior and feeding it to those backend validators, then presenting the result. Don't add client-side pass/fail logic that duplicates backend validation.
- Web vs. Android behavior is branched via `environment.isAndroidAppMode`; when touching SBI test-case orchestration, check whether the change needs mirroring in both `sbi-testcase-service.ts` (web) and `sbi-testcase-android-service.ts` (Android).
- Routing uses hash-based navigation (`useHash: true` in `app-routing.module.ts`); keep that in mind when adding new top-level routes or deep links.
- `dist/`, `node_modules/`, and `/.angular/cache` are gitignored build artifacts — don't hand-edit or commit them.
95 changes: 95 additions & 0 deletions android/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# AGENTS.md — `android/`

> Capacitor-generated native Android project that packages the same Angular codebase for on-device
> SBI (biometric device) testing.
> Parent guide: [repo root `AGENTS.md`](../AGENTS.md).

---

## 1. Purpose

The web app in `src/` is compiled with an Android-specific configuration
(`ng build -c=android`, using `src/environments/environment.android.ts`) and wrapped by Capacitor
into a native Android app so it can call biometric devices through the on-device
`mosip-sbi-capacitor-plugin` instead of the browser-only SBI flow. This folder is the
Capacitor-generated native project — it is **tracked in git, not a build artifact** — and is kept
in sync with `capacitor.config.ts` (repo root) via `npx cap sync`.

## 2. Layout

```text
android/
├── build.gradle # top-level Gradle build (AGP 7.2.1, google-services 4.3.13)
├── variables.gradle # shared SDK/library versions (compileSdk 32, minSdk 22, targetSdk 32, cordovaAndroidVersion, etc.)
├── settings.gradle, gradle.properties, capacitor.settings.gradle
├── gradlew, gradlew.bat, gradle/ # Gradle wrapper
└── app/
├── build.gradle # applicationId io.mosip.compliance.toolkit, versionCode/versionName
├── capacitor.build.gradle # Capacitor plugin wiring (regenerated by `npx cap sync`)
├── proguard-rules.pro
└── src/ # native Android sources/resources + the synced web build output
```

`applicationId` is `io.mosip.compliance.toolkit` (set in `android/app/build.gradle`); keep it in
sync with any Keycloak client / deep-link configuration on the backend side.

## 3. How to run

Mirrors what `.github/workflows/android.yml` does — run these from the **repo root**, not from
inside `android/`:

```shell
# 1. Install JS deps (repo root)
npm install --ignore-scripts

# 2. Set the Android-specific runtime config as env vars (consumed by environment.android.ts / .env).
# Values below are .github/workflows/android.yml's *default* inputs, pointing at MOSIP's shared
# dev environment — override all four with your own target environment's values unless you
# specifically intend to test against that shared environment.
export NX_APP_SERVICES_BASE_URL="<services-base-url>" # CI default: https://api-internal.dev.mosip.net/v1/toolkit/
export NX_APP_IAM_URL="<iam-url>" # CI default: https://iam.dev.mosip.net/auth
export NX_APP_IAM_REALM="<iam-realm>" # CI default: mosip
export NX_APP_IAM_CLIENT_ID="<android-client-id>" # CI default: mosip-toolkit-android-client

# 3. Build the Angular app in Android mode
ng build -c=android

# 4. Sync the web build + native plugins into android/
npx cap sync

# 5. Build the APK
cd android
chmod +x ./gradlew
./gradlew build
# debug APK output: android/app/build/outputs/apk/debug/app-debug.apk
```

CI (`.github/workflows/android.yml`) runs this same sequence on pushes to `develop` or via manual
`workflow_dispatch` (which prompts for `services_base_url` / `iam_url`), installing Angular CLI
`13.0.0` specifically for this build — note that's a lower pin than the `~13.3.2` used for the web
build (see root `AGENTS.md` Technology Stack section); this split is intentional per current CI,
not a typo to "fix" without checking both pipelines.

## 4. Agent rules — Do / Do not

### Do

- Run `npx cap sync` after any change to `capacitor.config.ts`, installed `@capacitor/*` plugins,
or `mosip-sbi-capacitor-plugin` version, so `android/app/capacitor.build.gradle` and native
plugin references stay current.
- Keep shared version numbers (SDK levels, library versions) in `android/variables.gradle` rather
than hardcoding them in `android/app/build.gradle`.
- Mirror any SBI test-case orchestration change in both `src/app/.../sbi-testcase-service.ts`
(web) and `sbi-testcase-android-service.ts` (Android) — see root `AGENTS.md`
"Repository-Specific Considerations".
- Call out Android-affecting changes explicitly in PRs (see root `AGENTS.md` PR guidelines) so the
Android CI workflow gets exercised, since it only runs on `develop` pushes or manual dispatch.

### Do not

- Do not hand-edit `android/app/capacitor.build.gradle` — it is regenerated by `npx cap sync`;
edit `capacitor.config.ts` or plugin dependencies instead and re-sync.
- Do not commit `google-services.json` with real Firebase credentials; `android/app/build.gradle`
already tolerates its absence (push notifications simply won't work without it).
- Do not assume `android/` is disposable build output — it is tracked in git; regenerate its
generated sub-files (like `capacitor.build.gradle`) via `cap sync`, don't delete the folder.
85 changes: 85 additions & 0 deletions helm/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# AGENTS.md — `helm/`

> Kubernetes Helm chart for deploying the Compliance Toolkit Portal (`compliance-toolkit-ui`).
> Parent guide: [repo root `AGENTS.md`](../AGENTS.md).

---

## 1. Purpose

This folder packages the built Angular app (served by nginx, see the repo-root `Dockerfile`) as a
Helm chart for installation into a MOSIP Kubernetes cluster. It is a thin deployment wrapper — no
application source lives here. Charts are linted and published to the `mosip-helm` repo
(`https://mosip.github.io/mosip-helm`) by `.github/workflows/chart-lint-publish.yml` whenever
`helm/**` changes on a push, PR, or release.

## 2. Layout

```text
helm/
└── compliance-toolkit-ui/
├── Chart.yaml # chart name/version, depends on bitnami "common" library chart
├── values.yaml # image, service, probes, istio gateway, resource limits
├── copy_cm.sh # copies shared configmaps (global, artifactory, config-server) into namespace
├── copy_cm_func.sh # helper invoked by copy_cm.sh
├── install.sh # creates namespace, copies configmaps, helm install
├── restart.sh # rollout restart of the deployment
├── delete.sh # helm uninstall (interactive confirm)
└── templates/
├── deployment.yaml, service.yaml, serviceaccount.yaml
├── configmap.yaml, gateway.yaml, virtualservice.yaml
├── servicemonitor.yaml, _helpers.tpl, NOTES.txt
```

The image referenced by `values.yaml` (`image.repository: mosipdev/compliance-toolkit-ui`) is the
same Docker image built from the repo-root `Dockerfile` — keep `Chart.yaml`'s `version` and
`install.sh`'s `CHART_VERSION` in sync when cutting a release.

## 3. How to run

```shell
# From helm/compliance-toolkit-ui/, against a cluster you have kubectl/helm access to:
./install.sh [kubeconfig-path] # create ns "compliance-toolkit", copy configmaps, helm install
./restart.sh [kubeconfig-path] # rolling restart of the deployment
./delete.sh # helm uninstall (prompts for confirmation)
```

`install.sh` expects the `global`, `artifactory-share`, and `config-server-share` configmaps to
already exist in the source namespaces it copies from (`copy_cm.sh` handles the copy); it reads
`mosip-api-internal-host` and `mosip-compliance-host` off the cluster's `global` configmap to wire
up `compliance.apiHost` and the Istio `hosts` value.

Chart lint/publish itself is CI-driven — see `.github/workflows/chart-lint-publish.yml`
(`mosip/kattu` reusable workflow, `CHARTS_DIR: ./helm`); there is no local `helm lint` wrapper
script in this folder. For a local check, run from `helm/` (not from inside
`helm/compliance-toolkit-ui/`):

```shell
cd helm
helm lint compliance-toolkit-ui
helm template compliance-toolkit-ui compliance-toolkit-ui
```

## 4. Agent rules — Do / Do not

### Do

- Bump `Chart.yaml`'s `version` whenever chart templates or `values.yaml` change in a
release-affecting way, and keep `install.sh`'s `CHART_VERSION` in sync.
- Keep `image.repository`/`tag` in `values.yaml` pointed at the same image the Dockerfile in the
repo root produces.
- Test template changes with `helm template compliance-toolkit-ui compliance-toolkit-ui` (run from `helm/`) before committing.
- Reference the parent guide ([`../AGENTS.md`](../AGENTS.md)) for how the UI itself is built and
configured (`src/assets/config.json`, environment files) — this chart only deploys the built
artifact, it does not configure app behavior beyond env/configmap wiring.

### Do not

- Do not hardcode environment-specific hosts (`api-internal.sandbox.xyz.net`,
`compliance.sandbox.xyz.net`) as anything other than sample defaults in `values.yaml` — real
values come from `--set` overrides in `install.sh`, sourced from cluster configmaps.
Do not copy real deployment secrets or per-environment host names into git.
- Do not remove or rename `copy_cm.sh` / `copy_cm_func.sh` without also updating `install.sh`,
which calls them by relative path.
- Do not run `delete.sh` against a shared/production namespace without confirming with the
cluster owner — it uninstalls the whole release.
Loading