Skip to content

ASK Frontend

Repo: ask-frontend-main
Language: TypeScript / Node.js ≥ 22
Framework: Next.js (standalone mode)
Helm Chart: frontend v1.0.0
Port: 3000


Architecture

The Frontend is a Turborepo monorepo containing a Next.js web application (apps/web) and shared workspace packages. It serves the ASK platform UI and communicates with the Core Service and Assistant Service APIs.

ask-frontend-main/           ← Turborepo monorepo root
├── apps/
│   └── web/                 ← Next.js application (the deployed artifact)
│       └── Dockerfile       ← Production container build
└── packages/                ← Shared workspace packages
    ├── @workspace/ui
    ├── @workspace/analytics
    ├── @workspace/errors
    └── @workspace/network

Container Images

Multi-Stage Build Pattern

Stage Base Image Purpose
base node:22-alpine Common Node.js + corepack (pnpm)
pruner base turbo prune --scope=web — extract only web app from monorepo
builder base pnpm install + pnpm turbo run build --filter=web
runner node:22-alpine Minimal standalone Next.js server

The DEPENDENCY_PROXY_PREFIX ARG allows routing through a registry mirror.

Image Produced

Image Name Dockerfile Port Entrypoint
frontend apps/web/Dockerfile 3000 node --max-old-space-size-percentage=75 apps/web/server.js

Production image registry:

ai71uaenprodask71acr01.azurecr.io/frontend:<tag>

Dev image uses a separate tag:

ai71uaenprodask71acr01.azurecr.io/frontend-dev:<tag>

Build Arguments

ARG Default Description
DEPENDENCY_PROXY_PREFIX "" Registry mirror prefix for base images
ENV_FILE .env.production Source .env file copied to apps/web/.env.local at build time
COMMIT_SHA "" Git SHA embedded in the Sentry release identifier

Runtime Environment Variables

Variable Value Description
NODE_ENV production Node.js mode
NEXT_TELEMETRY_DISABLED 1 Disable Next.js telemetry
PORT 3000 HTTP listen port

User

The runner stage creates and uses a non-root user: - Group: nodejs (gid 1001) - User: nextjs (uid 1001)


Helm Chart

Chart: helm/Chart.yaml

name: frontend
version: "1.0.0"
appVersion: "0.1.0"

No subchart dependencies — the frontend is stateless and has no external service dependencies managed by Helm.


Environments

Environment File Environment Cloud/DC Notes
values-dev.yaml Development Azure UAE North Uses frontend-dev image; Azure Spot VM node pool
values-stg.yaml Staging Azure UAE North Pre-prod
values-mec1-stg.yaml MEC1 Staging Azure MEC1 Secondary staging region
values-prod.yaml Production Azure UAE North
values-ai71-pp-auh1-prod-ask.yaml PP Production On-prem Abu Dhabi Gov cloud, air-gapped
values-mod-auh1-dev-ask.yaml core42 Dev On-prem RKE2 (core42) Air-gapped, Harbor images

PP Environment — Frontend

Full PP environment details: PP Environment page

PP Image

registry.pp.gov.ae/ask/frontend-prod:<tag>

imagePullSecrets: harbor-registry-secret

PP Configuration

Setting PP Value Notes
image.repository registry.pp.gov.ae/ask/frontend-prod Note: frontend-prod not frontend
replicaCount 1 Base (autoscaling takes over)
autoscaling.enabled true
autoscaling.minReplicas 3
autoscaling.maxReplicas 100
autoscaling.targetCPUUtilizationPercentage 80
NODE_TLS_REJECT_UNAUTHORIZED 0 Private CA cert — bypass TLS verification
Liveness probe path /api/health
Liveness initial delay 60s Longer than default (Next.js startup time)
Readiness initial delay 60s

PP Ingress — Three Hostnames

Hostname Purpose
ask.pp.gov.ae Main tenant entry point
chat.ask.pp.gov.ae Single-tenant organization UI
admin.ask.pp.gov.ae Super Admin organization UI

TLS: ask-pp-gov-ae-cert (all three hostnames share the same wildcard secret).

PP-Specific Notes

  • NODE_TLS_REJECT_UNAUTHORIZED=0 is set because the frontend calls backend APIs via the public *.ask.pp.gov.ae hostnames which are signed by an internal private CA.
  • Three ingress hostnames serve different organizational contexts (main, single-tenant chat, super-admin).
  • Build-time ENV_FILE for PP must set NEXT_PUBLIC_API_URL to https://api.ask.pp.gov.ae.

core42 Environment — Frontend (mod-auh1-dev-ask)

Values file: helm/environments/values-mod-auh1-dev-ask.yaml

core42 Image

harbor.cl1.sq4.aegis.internal/ask/frontend-stg:<tag>

imagePullSecrets: harbor-pull-secret

Image must be rebuilt with air-gap NEXT_PUBLIC_* vars baked in

The staging image has NEXT_PUBLIC_APP_BASE_URL=https://ask.stg.ai71.ai baked at build time. The AI71 build for this env must set: NEXT_PUBLIC_APP_BASE_URL=https://ask.mod.auh1.dev.dir, NEXT_PUBLIC_APP_ENV=mod-auh1-dev-ask, NEXT_PUBLIC_AMPLITUDE_ENABLED=false, NEXT_PUBLIC_SENTRY_ENABLED=false, NEXT_PUBLIC_FF_DISABLE_VOICE_MODE=true, NEXT_PUBLIC_FF_DISABLE_SPEECH_TO_TEXT=true.

core42 Configuration Changes vs PP

Setting PP Value core42 Value
image.repository registry.pp.gov.ae/ask/frontend-prod harbor.cl1.sq4.aegis.internal/ask/frontend-stg
NODE_TLS_REJECT_UNAUTHORIZED 0 0 (same — internal CA not in Node.js trust store)
autoscaling.minReplicas 3 disabled, 1 replica for bring-up

core42 Ingress

Hostname Purpose
ask.mod.auh1.dev.dir Main tenant entry point
admin.ask.mod.auh1.dev.dir Super Admin organization UI

TLS: frontend-tls (cert-manager internal-ca-issuer).

core42 Secrets

Key Vault path k8s secret
AUTH_SECRET secret/ask/frontend/auh1-dev frontend-secret
BILLING_API_KEY secret/ask/frontend/auh1-dev frontend-secret

Secret is created manually from bastion (no ExternalSecret template in this chart). See 41 — Frontend Deployment Phase 2 for the creation command.

core42 Notes

  • No TOML config file — frontend uses Next.js env vars, not Dynaconf TOML
  • No ESOfrontend-secret created manually from Vault on bastion (one-time)
  • Two ingress hostnamesask.* (main) + admin.* (super admin), matching PP's 3-host pattern

Configuration Variables

The frontend application is largely configured at build time via the ENV_FILE argument (.env.production, .env.staging, etc.). Runtime configuration is minimal.

Typical Build-Time .env Variables

Variable Description
NEXT_PUBLIC_API_URL Core Service API base URL
NEXT_PUBLIC_ASSISTANT_API_URL Assistant Service API base URL
NEXT_PUBLIC_SENTRY_DSN Sentry browser SDK DSN
NEXT_PUBLIC_APP_ENV Environment label (dev, staging, production)
NEXT_PUBLIC_ANALYTICS_WRITE_KEY Analytics/telemetry write key
NEXT_PUBLIC_* Any other public client-side config

Secrets

The frontend has minimal server-side secrets. Build-time secrets (API keys baked into .env.local) are the primary concern:

Secret Description Injection Method
SENTRY_AUTH_TOKEN Sentry release upload token (build-time) CI environment variable
NEXT_PUBLIC_* values Public config (not secret) ENV_FILE build arg

There are no ExternalSecret manifests in the frontend Helm chart — the stateless nature of the app means secrets are limited to build artefacts and any server-side API routes that proxy backend calls.


Key Dependencies

Runtime (apps/web/package.json — selected)

Package Version Purpose
next (workspace) Next.js framework
react / react-dom (workspace) React
@sentry/nextjs ~10.51.0 Sentry error/performance monitoring
@sentry/profiling-node ~10.51.0 Node.js profiling
@tanstack/react-table ~8.20.6 Data tables
@radix-ui/react-* various Accessible UI primitives
framer-motion ~12.4.1 Animation library
date-fns ~4.1.0 Date formatting
dompurify ~3.3.1 XSS sanitization
html2canvas ~1.4.1 Screenshot / canvas
json-bigint ~1.0.0 BigInt-safe JSON parsing
@notionhq/client ~3.1.3 Notion API client
@microlink/mql ~0.13.14 URL metadata
fast-deep-equal ~3.1.3 Deep equality comparison
import-in-the-middle ~3.0.1 Module instrumentation
@workspace/analytics workspace Internal analytics package
@workspace/errors workspace Internal error handling
@workspace/network workspace Internal API client
@workspace/ui workspace Internal component library

Build / Dev (monorepo root devDependencies)

Package Version Purpose
turbo 2.9.3 Monorepo build orchestration
typescript 5.5.4 TypeScript compiler
eslint 9.17 Linting
prettier 3.2.5 Code formatting
prettier-plugin-tailwindcss 0.6.11 Tailwind class sorting
husky 9.1.7 Git hooks
commitlint 20.4.2 Conventional commit enforcement
only-allow Enforce pnpm as package manager

Package Manager

pnpm (enforced via only-allow). Node.js ≥ 22 required.

Security Overrides (pnpm)

The monorepo pins these transitive dependencies for security:

Package Pinned Version
tar-fs ≥ 2.1.3
form-data 4.0.4
esbuild ≥ 0.28
picomatch 4.0.4
flatted 3.4.2
minimatch 5.1.2
lodash 4.18.1
@sentry/cli 3.4.1
import-in-the-middle 3.0.1

CI/CD Pipeline

File: .gitlab-ci.yml
Tool: GitLab CI

Stage Key Jobs Description
validate validate ESLint, TypeScript type-check
build-dev build-dev Docker build to ACR with dev ENV_FILE
auto-version-bump auto-version-bump Semantic version bump on merge to main
helm-release helm-release Publish Helm chart to GitLab OCI registry

The production build uses a separate ENV_FILE override passed as a CI/CD variable per environment.