The Q is the Service BC platform for managing in-person office flow, appointments, smartboard and digital signage displays, outbound notifications, and related service delivery workflows. The application is used by Service BC as well as other B.C. government ministries.
Service BC connects people with services offered by the B.C. provincial government. This application supports the day-to-day operations of Service BC locations by helping staff manage queues, appointments, exams, walk-ins, and communications across the province.
The primary backend service for the platform. It serves the main REST API under /api/v1 plus Socket.IO endpoints used by the staff and public frontends.
Key responsibilities include:
- Queue and citizen service flows: create and manage citizens, service requests, queue state transitions, invite and serve flows, hold flows, and completion flows.
- Office and reference data: offices, services, categories, channels, CSR state, user context, and related administrative data.
- Appointments, bookings, and walk-ins: appointment slots, appointment creation and updates, recurring bookings, walk-in queue support, and reminder-related workflows.
- Exams, rooms, and invigilators: exam scheduling, uploads, exports, room management, and invigilator management.
- Smartboard and real-time updates: smartboard data endpoints plus Socket.IO events for queue changes and office-specific live updates.
- Health endpoints: readiness and health checks for operational monitoring.
The internal staff-facing Vue 2 application. Staff use it for queue management, office administration, appointments, exams, uploads, smartboard support, and optional service-flow integrations.
The public-facing Vue 2 application for booking appointments, viewing booked appointments, managing account settings, handling sign-in flows, and viewing walk-in queue status.
The new under development public-facing React 19 + TypeScript application for booking appointments at Service BC locations. It will eventually replace appointment-frontend. See appointment-booking/README.md for setup instructions.
A separate Flask service for outbound notifications. It exposes authenticated POST /api/v1/notifications/sms and POST /api/v1/notifications/email endpoints and supports pluggable delivery providers, including GC Notify, CHES, and logging/custom implementations.
Warning
feedback-api is deprecated, retained only for legacy compatibility, and will be removed in a future version.
This legacy Flask service accepts feedback submissions and forwards them to the older Camunda-based feedback flow.
- Backend: Python, Flask, Flask-RESTX, SQLAlchemy, Flask-Migrate, Flask-SocketIO, Marshmallow, Gunicorn, and Gevent.
- Frontend: Vue 2 , React 19 + TypeScript + Vite , Vue Router, Vuex, Vuetify, BootstrapVue, Buefy, and Axios.
- Data and integrations: PostgreSQL, Redis-backed real-time/message queue usage, MinIO for object storage, Keycloak/OIDC authentication, optional Snowplow analytics, and GC Notify/CHES/custom notification providers.
- Serving/runtime: Nginx serves built frontend assets in containerized deployments.
Older references to RabbitMQ remain in the repository, but they are not part of the current development guidance in this README.
This repository supports two local development workflows:
- Using a development container
- Developing locally on your host machine
- Podman or another compatible Docker engine
- Visual Studio Code (or another editor with Dev Container support)
- The Dev Containers extension for VS Code
- Open the repository in an editor with dev container support
- Use the editor to reopen the project in the devcontainer
- For example, in VS Code, click the popup prompt or use the Command Palette to select "Dev Containers: Reopen in Container"
- Let the container build from the root
compose.yamldefinition and finish running the post-create script - Confirm that the container has provisioned PostgreSQL and Keycloak, and forwarded the main ports
The devcontainer now prepares local config files before API migrations/bootstrap and waits for PostgreSQL and Keycloak readiness before the post-create flow continues.
It also provisions project-local Python environments for both api and notifications-api, so the checked-in VS Code debug configurations work without extra manual setup.
5000: queue management API5002: notifications API5173: appointment booking frontend (React)8080: staff frontend8081: appointment frontend8085: Keycloak auth server5432: PostgreSQL
The devcontainer installs dependencies automatically for api, notifications-api, frontend, and appointment-frontend, applies database migrations, and may initialize seed data depending on the current database state.
- Python 3.14 with
uv - Node.js 20 with
npm - PostgreSQL 16
-
Install backend dependencies:
cd ./api uv sync --group dev cd ./notifications-api uv sync --group dev
-
Install frontend dependencies:
cd ./frontend npm install cd ./appointment-frontend npm install cd ./appointment-booking npm install
-
Create the required local config files:
./scripts/setup-local-config.sh
This script copies the checked-in local config defaults from
.devcontainer/config, creates missing destination directories, validates required API auth keys, and leaves any existing local files untouched. -
Start the local auth server:
docker compose up -d keycloak
Local Keycloak details:
- Realm:
servicebc-local - Base URL:
http://localhost:8085/auth - Admin console:
http://localhost:8085/auth/admin/ - Admin credentials:
admin/password - Demo users:
democsr@idir,demoga@idir,admin@idir,citizen@bceidboth,citizen2@bceidboth - Demo user password:
password - Confidential client id:
theq-queue-management-api - Confidential client secret:
theq-local-dev-secret
- Realm:
-
Make sure the database settings in
api/.envpoint to your local PostgreSQL instance. -
Run database migrations:
cd ./api uv run python manage.py db upgrade
Start the services in separate terminals.
Queue management API using the local Python environment:
cd ./api
uv run gunicorn wsgi --bind=0.0.0.0:5000 --access-logfile=- --config=gunicorn_config.py --reload --timeout=0Queue management API using the production Dockerfile through Compose:
docker compose --profile api up --build apiThe root compose.yaml is the single source of truth for local Docker services and the devcontainer. The optional api Compose service still serves the application on http://localhost:5000. It reads api/.env, then overrides container-only settings so it can reach the host PostgreSQL and host-run notifications API while continuing to use the local Keycloak on http://localhost:8085/auth.
Notifications API:
cd ./notifications-api
uv run gunicorn wsgi:application --bind=0.0.0.0:5002 --access-logfile=- --config=gunicorn_config.py --reload --timeout=0Staff frontend:
cd ./frontend
npm run serveAppointment frontend:
cd ./appointment-frontend
npm run serve -- --port 8081Appointment booking frontend (React):
cd ./appointment-booking
npm run devOpens at http://localhost:5173. See appointment-booking/README.md for Docker and environment variable details.
These are the main local files you should expect to have in place when running the application locally:
api/.envapi/client_secrets/secrets.jsonfrontend/public/static/keycloak/keycloak.jsonfrontend/public/config/configuration.jsonappointment-frontend/.env.localappointment-frontend/public/config/kc/keycloak-public.jsonappointment-frontend/public/config/configuration.json
The checked-in local auth defaults now target the local Keycloak realm on http://localhost:8085/auth. If you need to switch back to the shared dev Keycloak server, update the copied local config files before starting the apps.
This repository includes Python/pytest suites, Artillery-based load tests, and Postman/Newman collections. The commands below assume you already completed the local setup for the relevant service and, for API-backed tests, have the local stack running.
The main application test suite lives in api/app/tests and is split into a DB-free smoke slice and a Postgres-backed integration slice.
From api:
./scripts/run_api_smoke_tests.sh
./scripts/run_api_integration_tests.sh
./scripts/run_api_full_tests.shEquivalent direct pytest commands:
uv run pytest app/tests -m smoke -q --override-ini "addopts=--strict-markers"
uv run pytest app/tests -m integration -q --override-ini "addopts=--strict-markers" --require-integration-db
uv run pytest app/tests -q --require-integration-dbAdditional pytest suites:
cd ./notifications-api
uv sync --group dev
uv run pytestcd ./feedback-api
make setup
make testLoad testing lives in tests/loadtesting and uses Artillery against the local API stack.
Initial setup:
cd ./tests/loadtesting
npm install
cp envs.example.sh envs.sh
chmod +x envs.sh profile-python.shBefore running the load tests locally, start the local Keycloak realm and seed the API data:
docker compose up -d keycloak
cd ./api
uv run python manage.py db upgrade
uv run python manage.py bootstrapRun the load suites from tests/loadtesting:
npm run tests:all
npm run tests:http
npm run tests:socketOptional Python profiling commands are also available there:
npm run python:profile
npm run python:topPostman collections live in api/postman. They target the local API and local Keycloak realm, and the checked-in local setup expects the demo users from keycloak-local/servicebc-local-realm.json.
Before running Newman locally, make sure the API database is migrated and bootstrapped:
cd ./api
uv run python manage.py db upgrade
uv run python manage.py bootstrapThen install Newman and run the main collection from api/postman:
cd ./api/postman
npm install
./node_modules/newman/bin/newman.js run API_Test_TheQ_Booking.json -e postman_env.json --bail failure \
--global-var userid=cfms-postman-operator \
--global-var password=password \
--global-var userid_nonqtxn=cfms-postman-non-operator \
--global-var password_nonqtxn=password \
--global-var client_secret=theq-local-dev-secret \
--global-var url=http://localhost:5000/api/v1/ \
--global-var auth_url=http://localhost:8085 \
--global-var clientid=theq-queue-management-api \
--global-var realm=servicebc-local \
--global-var public_url=http://localhost:5000/api/v1/ \
--global-var public_user_id=cfms-postman-public-user \
--global-var public_user_password=passwordSee api/postman/README-local-auth.md for local auth troubleshooting details.
For deployment within the B.C. government, this project can be hosted on the B.C. government Private Cloud. The platform is the B.C. Government Private Cloud PaaS, powered by Red Hat OpenShift, and is designed for hosting government applications in a managed private-cloud environment.
This repository still includes deployment artifacts under openshift/templates for platform-specific builds and deployments.
To report bugs/issues/feature requests, please file an issue.
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
This project is licensed under the Apache License, Version 2.0. See the root LICENSE file for the full license text.