The official client registry and identity management platform for the Province of British Columbia's Ministry of Forests.
Wiki Documentation • Database Schema (SchemaSpy) • Entity-Relationship Diagram • Report Bug
- Overview
- Architecture
- Technology Stack
- Repository Structure
- Getting Started
- Database Management
- Testing Strategy
- CI/CD & Deployment
- Documentation & Wiki
- Contributing & Conventions
- License
Forest Client is the authoritative repository of client information for the British Columbia Ministry of Forests. The ministry relies on Forest Client to establish, verify, and administer business relationships with corporations, First Nations, and individuals conducting business with the province or operating under the Forest Act.
The application caters to two primary user audiences:
- External Clients:
- BCeID Business Users: Authorized representatives of incorporated businesses, partnerships, and sole proprietorships applying for new client registrations or associating corporate locations.
- BC Services Card (BCSC) Users: Individuals applying for client registration for individual permits or timber mark operations.
- Ministry Staff (IDIR):
- Client Viewer: Read-only search, viewing client details, locations, contacts, and historical audit logs.
- Client Editor: Authoring and updating client details, adding new locations and contacts, creating new client records.
- Client Reviewer / Admin: Reviewing pending external submissions, matching against legacy records, adjudicating approvals or rejections, and managing client status (suspension, deactivation, amalgamations).
- Single Source of Truth: Serve as the central, modernized web-based client registry across natural resource ministries.
- Self-Service Onboarding: Enable external applicants to submit complete client registration requests online.
- Automated Validation & Duplicate Detection: Cross-reference submissions against BC Registry corporate data and legacy databases to prevent duplicates and expedite approvals.
- Bi-Directional Legacy Sync: Synchronize modern PostgreSQL transactions with legacy Oracle databases (Forest Tenures / FTA and RESULTS integration).
Forest Client is architected as a cloud-native, multi-tier system deployed on BC Government OpenShift (Kubernetes) Silver clusters.
flowchart TD
subgraph Users["User Layer"]
ExtUser["External User\n(BCeID / BC Services Card)"]
StaffUser["Ministry Staff\n(IDIR)"]
end
subgraph Ingress["Ingress & Security"]
Router["OpenShift Route / Ingress"]
FAM["FAM / AWS Cognito\n(Authentication & JWT)"]
end
subgraph FrontendApp["Frontend Application (SPA)"]
VueApp["Vue 3 + TypeScript\n(Vite + Carbon Design)"]
end
subgraph BackendServices["Backend Services Layer"]
BE["Backend API (WebFlux)\nSpring Boot 4 / Java 17\nGraalVM Native Image"]
PROC["Processor Service\nSpring Integration\nChannel #1-#10 Engine"]
LEGACY["Legacy Connector API\nSpring Boot 4 / Java 21\nOracle DB Adapter"]
end
subgraph DataStorage["Data Storage Layer"]
PG[("PostgreSQL 13 / 17\n(Primary Store)\nFlyway Migrated")]
ORACLE[("Legacy Oracle DB\n(THE Schema)\nFlyway Migrated")]
end
subgraph ExternalAPIs["External Services"]
BCREG["BC Registry API\n(Corporate Lookup)"]
CPOST["Canada Post\n(AddressComplete)"]
CHES["CHES\n(Common Hosted Email)"]
end
ExtUser -->|Access Application| Router
StaffUser -->|Access Application| Router
Router --> VueApp
VueApp -->|Federated SSO| FAM
VueApp -->|Bearer JWT Requests| BE
BE -->|Read / Write Submissions| PG
BE -->|Verify Business| BCREG
BE -->|Resolve Addresses| CPOST
BE -->|Trigger Notifications| CHES
BE -->|Proxy Legacy Queries| LEGACY
LEGACY -->|Query / Sync Records| ORACLE
PROC -->|Poll Submissions (#1)| PG
PROC -->|Verify Duplicates (#2)| LEGACY
PROC -->|Auto-Approve (#4)| PG
PROC -->|Persist Approved (#10)| LEGACY
PROC -->|Trigger Emails (#5, #8, #9)| BE
| Layer / Component | Technology | Version | Purpose |
|---|---|---|---|
| Frontend | Vue 3 (Composition API) | 3.5.x | Reactive single-page web application |
| Frontend Tooling | Vite, TypeScript, Sass | 8.3.x / ~6.0.0 / ~1.104.1 | Lightning-fast build, typed modules, styling |
| UI Components | Carbon Design System | @carbon/web-components 2.x |
Accessible BC Gov-aligned UI system |
| Backend API | Spring Boot (WebFlux), Java | 4.1.x / Java 17 (JDK 25) | Reactive non-blocking REST API, GraalVM native |
| Background Processor | Spring Integration, Java | 4.1.x / Java 17 | Async submission pipeline with queue channels |
| Legacy Connector | Spring Boot (WebFlux), Java | 4.1.x / Java 21 | High-throughput reactive Oracle database interface |
| Primary Database | PostgreSQL | 13.x (moving to 17) | Modern relational store with R2DBC |
| Legacy Database | Oracle Database Free | 23.x (compatible with 19c) | Ministry enterprise data store (THE schema) |
| Database Migrations | Flyway | 10.x / 11.x | Versioned, reproducible SQL schema migrations |
| Testing: Frontend | Vitest, Vue Test Utils | 5.x / 2.x | Fast, modern unit and component testing |
| Testing: Backend | JUnit 5/6, Mockito, Testcontainers | 6.x / 5.x / 2.x | Unit and containerized integration testing |
| Testing: E2E | Cypress, Cucumber Gherkin | 16.x / 28.x | BDD user journey automation and regression |
nr-forest-client/
├── frontend/ # Vue 3 SPA frontend source, components, and tests
├── backend/ # Main Spring Boot reactive backend API
├── legacy/ # Spring Boot legacy service connecting to Oracle
├── processor/ # Spring Integration background processing engine
├── cypress/ # Cypress End-to-End user journey test suite (Gherkin/BDD)
├── database/ # PostgreSQL Dockerfile and configuration
├── .github/ # GitHub Actions CI/CD workflows and issue templates
├── docker-compose.yml # Local development container orchestration
└── README.md # Project overview and guide (this document)
Ensure you have the following tools installed:
- Docker Desktop or Podman
- Java Development Kit (JDK) 17, 21, or 25
- Apache Maven 3.9+
- Node.js (v22 or v24 LTS) and npm
Start the local PostgreSQL, Oracle Free, and Flyway migration services:
docker compose up -d database legacydb legacyflyway- PostgreSQL: Accessible at
localhost:5432(user: postgres,password: default,database: postgres) - Oracle Database: Accessible at
localhost:1521(user: THE,password: default,service: FREEPDB1) - Flyway: Automatically executes migration scripts from
legacy/src/test/resources/db/migrationinto the Oracle database and exits when finished.
Navigate to the frontend/ directory:
cd frontendCreate a .env file in frontend/:
VITE_BACKEND_URL=http://localhost:8080
VITE_FRONTEND_URL=http://localhost:3000
VITE_NODE_ENV=openshift-dev
VITE_COVERAGE=trueInstall dependencies and start the development server:
npm install
npm startThe application will be available at http://localhost:3000.
If you want to work on frontend UI/UX without running Java backend services, use the embedded WireMock stub server:
# Starts both the WireMock stubs and the Vite development server
npm run preview
# Or run the stub server independently in a dedicated terminal
npm run stubEach backend service (backend/, legacy/, and processor/) supports personal developer profiles to override settings without committing secrets. Create an application-dev-<yourname>.yml file in the config/ folder of the service you are running.
Note
The examples below use the safe local container defaults defined in docker-compose.yml (postgres/default and THE/default). Never commit production credentials, secret tokens, or private network hosts to Git configuration files.
ca:
bc:
gov:
nrs:
# Local PostgreSQL container (docker-compose: database)
postgres:
host: localhost:5432
database: postgres
username: postgres
password: default
# Frontend URL for CORS
frontend:
url: http://localhost:3000
# Legacy Oracle service endpoint
legacy:
url: http://localhost:9000# Override TCPS/SSL with standard TCP R2DBC URL to connect to the local container
spring:
r2dbc:
url: r2dbc:oracle://${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.service}
ca:
bc:
gov:
nrs:
# Local Oracle container (docker-compose: legacydb)
oracle:
host: localhost
port: 1521
service: FREEPDB1
database: FREEPDB1
schema: THE
username: THE
password: defaultca:
bc:
gov:
nrs:
# Local PostgreSQL container (docker-compose: database)
postgres:
host: localhost:5432
database: postgres
username: postgres
password: default
# Main Backend API endpoint
backend:
uri: http://localhost:8080/api
# Legacy Oracle service endpoint
legacy:
uri: http://localhost:9000/apiRun each service from its respective directory specifying your active profile:
# Main Backend API (runs on port 8080)
cd backend
mvn spring-boot:run -Dspring-boot.run.profiles=dev-<yourname>
# Legacy Oracle Service (runs on port 9000)
cd legacy
mvn spring-boot:run -Dspring-boot.run.profiles=dev-<yourname>
# Processor Service (runs on port 3100)
cd processor
mvn spring-boot:run -Dspring-boot.run.profiles=dev-<yourname>Database structures are version-controlled using Flyway:
- PostgreSQL Migrations: Managed in
backend/src/main/resources/db/migration/. The Spring Boot backend automatically applies pending SQL scripts on startup. - Oracle Migrations: Maintained in
legacy/src/test/resources/db/migration/and applied automatically via thelegacyflywaycontainer.
We publish automated Entity-Relationship diagrams and database schema references generated with SchemaSpy:
- Interactive Relationships Diagram: https://bcgov.github.io/nr-forest-client/nrfc/relationships.html
- Full Database Documentation: https://bcgov.github.io/nr-forest-client/
All contributions require thorough automated test verification. We enforce a minimum threshold of 80% test coverage for new and modified logic.
cd frontend
npm run test:unit # Run unit tests (with Vitest coverage)
npm run coverage # Run full suite (unit, component, and e2e coverage)# Main Backend API (unit tests and Testcontainers integration tests)
cd backend
mvn clean verify -P all-tests
# Legacy Oracle Service (unit tests and Testcontainers integration tests)
cd legacy
mvn clean verify -P all-tests
# Processor Service (unit tests and Testcontainers integration tests)
cd processor
mvn clean verify -P all-testsNote
Running mvn clean verify -P all-tests executes both fast unit tests and Testcontainers integration tests. To execute only unit tests without spinning up Docker containers, run mvn clean test.
End-to-End tests reside in cypress/ and are authored in plain English using Cucumber Gherkin BDD (.feature files):
cd cypress
npm install
# Run against local dev server (http://127.0.0.1:3000)
npm run cy:open:local # Interactive Cypress GUI (headed)
npm run cy:run:local # Headless test run
# Or execute with custom configuration
npm run cy:open -- --config baseUrl=http://localhost:3000
npm run cy:run -- --config baseUrl=http://localhost:3000Tip
Community-Driven Test Cases: Anyone can propose a new user test journey by opening a GitHub Issue with the "User provided automated test-case" template. Our issue-gherkin.yml GitHub Action automatically compiles the issue into an executable .feature scenario!
- Pull Request Validation: Every PR triggers
.github/workflows/analysis.yml, running linter checks, frontend Vitest tests, backend Maven builds, and SonarCloud quality gate analysis. - Ephemeral PR Environments: Pull requests deploy automated preview environments via GitHub Actions to test changes in isolation.
- Continuous Deployment: Merges to
mainthat include non-documentation changes trigger.github/workflows/merge.yml, building container images and deploying to OpenShift Silver dev/test clusters (changes strictly limited to markdown**.mdfiles and issue templates are excluded).
For deep-dive architecture notes, API specifications, and team frameworks, explore our GitHub Wiki:
- Architecture & System Design
- Developer Guides & Setup
- Team Delivery Framework
- Scrum ceremonies, Story points (Fibonacci scale), Definition of Done, and the Developer Contract.
- Knowledge Base & Integrations
- FAM (AWS Cognito SSO), BC Registry, Canada Post, and CHES Email Service.
We welcome contributions! Please review our conventions before submitting a pull request:
- Conventional Commits: Format commit messages as
feat(...),fix(...),docs(...),chore(...), ortest(...). - Branch Naming: Use
feature/fe/<issue-name>,fix/be/<issue-name>,chore/deps/.... - Code Reviews: All PRs require passing automated CI checks, test coverage compliance, and at least one approving review from the core team.
This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.