Full-stack LEXIS application for log export workflows.
| Component | Technology |
|---|---|
| Frontend | React 19, TypeScript, Carbon Design System |
| Backend | Spring Boot 3.5, Java 21 |
| Database | Oracle (shared, BC Gov-managed) |
| Concurrency | Optimistic stale-save checks and Oracle transaction locks |
| Auth | BC Gov SSO (Keycloak) with FAM roles, including region-scoped staff roles, for interactive users; Keycloak scopes for NEXCOL service-client submission |
| Reports | JasperReports library |
LEXIS runs as separate frontend and backend workloads on OpenShift while retaining Oracle as its system of record. Uploaded content is scanned through a shared ClamAV service in a dedicated namespace. Interactive access uses nr-fam / BC Gov SSO; NEXCOL federal submissions use a dedicated Keycloak service client through the API gateway.
See docs/architecture.md for the runtime architecture, component boundaries, deployment constraints, and the major legacy-to-modern shifts.
Two supported ways to run LEXIS locally. Pick whichever fits your workflow.
| Option A - direct on host | Option B - Docker Compose | |
|---|---|---|
| Backend hot reload | Manual restart | Manual restart |
| Frontend hot reload (Vite HMR) | Yes | Yes |
| First-time setup cost | Install Java 21 + Node 24 on host | Just Docker Desktop |
| Best for | Day-to-day backend/frontend work | Quick smoke tests, frontend-only work, and container parity |
Both options share the same prerequisites and property files below. Reports use the checked-in JRXML templates in the Spring Boot backend.
Virus scanning is disabled by default for local development, and neither option starts a ClamAV container. Deployed environments use a shared ClamAV service; see Shared ClamAV service for configuration and network-policy ownership.
Users sign in through BC Gov SSO (Keycloak) with roles managed in FAM; see Identity and authorization.
- Network access to the BC Gov Oracle environment. Compose cannot route that for you.
- Maven 3.9+ and Java 21.0.12 or newer (Option A only). Older Java 21 builds have outdated B.C. time rules, so backend tests fail; see B.C. Pacific Time to check your JDK. The repo has no Maven wrapper.
- Node 24+ (Option A only).
- Docker Desktop (Option B only).
These files are gitignored and stay local.
Activated by the Spring local profile. Holds Oracle credentials, interactive SSO issuer/client ID, optional separate Keycloak issuer URI for service-client tokens, and TRUSTSTORE_PATH. It must also provide the four approved LEXIS_MAIL_* positional-mailbox settings when running with the oracle profile, because startup validates outbound-mail configuration. Obtain all values through approved team channels and keep them out of git. See outbound email configuration for the setting names and safe local/TEST delivery behavior.
For Option B, Compose overrides TRUSTSTORE_PATH inside Docker to /app/src/main/resources/cert/jssecacerts; no local edit is needed for the container path.
Java keystore containing the trusted CA chain for the Oracle TLS connection. Obtain it through approved team channels and keep it out of git.
Copy frontend/.env.example and fill in the SSO issuer and public client ID. Vite inlines these values into the app bundle, so restart npm run dev after changing .env.
Run the backend and frontend in separate terminal tabs.
Backend:
cd backend
mvn -DskipTests spring-boot:run -Dspring-boot.run.profiles=local,oraclePort check:
nc -z localhost 8080Frontend:
cd frontend
npm ci
npm run devFrontend: http://localhost:3000
docker compose up # foreground; Ctrl-C to stop
docker compose up -d # detached
docker compose down # stop containers, keep cache
docker compose down -v # stop + drop the Maven cache volume
docker compose logs -f backendServices:
backend->localhost:8080(Spring Boot viamvn spring-boot:runinsidemaven:3.9.9-amazoncorretto-21-alpine).frontend->localhost:3000(Vite vianpm run devinsidenode:24-alpine).
First up downloads Maven dependencies into the maven-cache named volume. Subsequent starts are faster.
An optional production-like frontend variant is on the caddy profile:
docker compose --profile caddy up caddy backendThat builds the real frontend/Dockerfile and serves it at localhost:3005.
- If you Ctrl-C mid dependency download, Maven can leave partial files in
maven-cache. Fix withdocker compose down -v && docker compose up. - The backend is not hot-reloading. Java changes need
docker compose restart backend. - HMR uses WebSocket from your browser to
localhost:3000. If you remap the published port, also overrideVITE_HMR_PORTindocker-compose.yml.
Regardless of option:
nc -z localhost 8080succeeds once the backend port is listening.- Open
http://localhost:3000and complete the BC Gov SSO login round trip.
If the backend starts but authenticated API calls fail, check network access, application-local.yml credentials, SSO issuer/client configuration, and the truststore path.
NEXCOL uses a dedicated Keycloak client and the lexis:federal-submission:submit OAuth scope to
validate or submit federal XML through the API gateway. CI manages the client, scope and default
scope assignment in TEST and PROD. Those deployments require the Keycloak provisioner settings and
fail if the scope/client contract or exclusive assignment is not valid.
See docs/nexcol-keycloak-service-client.md for the API contract and gateway/README.md for gateway responsibilities.
The weekly Regression GitHub Actions trigger is paused while the FAM team fixes the TEST IDIR
regression account for Keycloak. Manual dispatch remains available to verify recovery. It reads
TEST IDIR credentials from GitHub test environment secrets, creates its own lifecycle records and
resolves external reference keys at runtime. Playwright uses a reporter that suppresses sensitive
output. Business BCeID browser regression is intentionally not scheduled because repeated automated
login attempts can lock the TEST account. See
frontend/e2e/README.md for the required GitHub environment secrets.
Production releases are manual: create a tag on a commit that passed TEST, then run Release PROD
from main and supply that tag. The workflow deploys the exact frontend/backend image digests
recorded by the successful TEST run. Merges and tag creation do not deploy PROD. See
the release procedure for prerequisites and rollback.
The GitHub environment variable LEXIS_EXPIRY_ENABLED turns nightly exemption expiry and its startup
catch-up on (true) or off (false), independently of application access. A change takes effect on
the next deployment. If the variable is unset, PROD and DEV default to off and TEST to on.
- docs/architecture.md - Runtime architecture and legacy-to-modern shifts.
- docs/intentional-legacy-divergences.md - Business-approved differences from legacy behaviour and their searchable code markers.
- docs/legacy-bug-register.md - Legacy defects, modern corrections and proposed procedure changes deferred pending a business request.
- docs/shared-clamav-service.md - Shared scanner deployment, policy, verification, and ownership.
- backend/README.md - Spring profile reference, env-var table, API areas, test commands.
- frontend/README.md - Vite scripts, env-var table, project structure, testing libraries.
- docs/permit-invoicing.md - Canadian and GBMS permit invoicing modes, consistency limits, and recovery.
- docs/rtm-amv-ui-and-procedure-contract.md - RTM AMV unified-table rules and atomic Oracle persistence contract.