My Cambridge Application¶
[Team : Hopper Team] [Tech Lead : amh254] [Service Owner : hr244] [Service Manager : soj23] [Product Manager : bmd42]
This page gives an overview of the My Cambridge Application[1] - the undergraduate applicant portal - describing its current status, where and how it's developed and deployed, and who is responsible for maintaining it.
[1] My Cambridge Application is often internally abbreviated to MyCApp, and has been
historically been referred to as "Admissions Portal (AP)" or "Cambridge Admissions Portal (CAP)".
You will find references to these names throughout historic documentation and the
codebase.
Note
This service only applies to undergraduate applicants. The Applicant Portal for postgraduates is an unrelated web application.
Service Description¶
My Cambridge Application (MyCApp) is the undergraduate applicant portal for the University of Cambridge, accessible at apply.undergraduate.study.cam.ac.uk. It provides a web application where undergraduate applicants can supply supplementary information as part of their university application (such as additional questionnaires and supporting materials). The service also exposes a Data Service API via the API Gateway for programmatic access to admissions data. A payment callback API handles WPM payment processing for application-related fees.
Key Features¶
- Applicant-facing portal for submitting supplementary application information including course-specific questionnaires, document uploads, and formal qualification details
- Programmatic API access to undergraduate admissions data via the API Gateway Data Service
- Application fee payment processing via WPM integration
- Applicant account management and authentication with automatic account creation from CamSIS applicant feed integration synchronisation
- CAO admin panel for applicant impersonation, audit reporting, admissions cycle data management, and fee waiver administration
- Applicant photo upload and submission to the Photo API
- Service alert messaging system for communicating live service issues to targeted pages and user groups
- Automated audit export for the Cambridge Admissions Office to review detailed application statuses
- Malware scanning of applicant file uploads
User Base & Audience¶
- Undergraduate applicants — prospective students applying to the University of Cambridge
- Cambridge Admissions Office (CAO) — oversee the admissions process and data flows
- API consumers — access undergraduate admissions data via the API Gateway Data Service
Integrations¶
| System | Direction | Description |
|---|---|---|
| CamSIS | Upstream | Applicant data feed providing student records and application details; consumed by the backend via paginated HTTP API with Cloud Tasks fan-out |
| Photo API (via API Gateway) | Upstream | Applicant photos submitted from the frontend via Cloud Functions |
| Data Service | Downstream | Backend applicant data; frontend Cloud Functions submit answers and transcripts; exposes the Data Service API on the API Gateway for external consumers |
| Firebase | Platform | Authentication (applicant and admin accounts with custom claims), Firestore (real-time applicant data store), Cloud Storage (file uploads), Cloud Functions (submission pipeline, activity tracking, admin writes) |
| WPM | Bidirectional | Payment processing for application fees via XML callback API |
| GCP Cloud Run | Platform | Internal data service backend API and WPM callback API |
| GCP CDN | Platform | Static asset delivery for the Gatsby-built frontend |
| GCP Cloud Tasks | Platform | Distributes per-applicant import work from the bulk CamSIS import endpoint |
| GCP Cloud Scheduler | Platform | Triggers periodic CamSIS feed imports and audit exports |
| Cloud SQL (PostgreSQL) | Platform | Data service database |
Data Managed¶
- Applicant submissions — supplementary questionnaire responses across course-specific sections (about you, educational experience, funding, high school studies, higher education, interview, other qualifications, photo, your course), stored in Firestore and submitted to the Data Service
- Applicant profiles — imported CamSIS data (personal details, college, course, UCAS scheme, nationality, formal qualifications) stored in Firestore read-only profiles
- Application activity state — progress tracking through onboarding, UCAS details confirmation, confidentiality declaration, accuracy confirmation, fee payment, and submission
- Applicant accounts — Firebase Auth accounts with custom claims (application number, admin roles) synced from CamSIS feed
- Payment tokens and records — pre-generated WPM payment tokens per applicant and transaction status updates from WPM callbacks
- Admissions data — undergraduate admissions dataset served via the Data Service API on the API Gateway
- Applicant photos — uploaded by applicants and submitted to the Photo API; scanned for malware before acceptance
- Document uploads — high school transcripts, university transcripts, and other supporting documents stored in Cloud Storage
- Service alerts — configurable alert messages stored in Firestore targeting specific pages and user groups
- Admin and audit data — admin user accounts with role-based claims, audit CSV exports of application statuses
Service Status¶
My Cambridge Application is currently live.
Note
The production environment's Data Service API URL contains "alpha" because the project started out following the GDS agile phases, but the current phase hasn't been advanced from alpha.
Contact¶
Technical queries and support should be directed to the DevOps Hopper team and will be picked up by a member of the team working on the service.
Issues discovered in the service or new feature requests should be opened as GitLab issues within the operational support project.
Environments¶
My Cambridge Application is currently deployed to the following environments:
Environment details¶
| Environment | Deployment Frequency | User Access | Purpose |
|---|---|---|---|
| Production | End of each sprint | An environment where code changes are tested on live user traffic. | |
| Integration | End of each sprint | An environment to test various interfaces and the interactions between integrated components or systems. | |
| Regression | On merge to default branch | An environment to test that defects have not been introduced or uncovered in unchanged areas of the software, as a result of the changes made. | |
| UAT | An environment to determine if intended users, customers or other authorised entities accept the system. | ||
| Test | On merge to default branch | An environment to evaluate if a component or system satisfies functional requirements. | |
| Development | On demand via pipeline job | An environment to check any development code changes without affecting end-users. |
Environment integration mapping¶
| MyCApp env | CamSIS env (applicant feed) | Photo API env |
|---|---|---|
| Production | https://camsis.cam.ac.uk/intb_prod/ | https://api.apps.cam.ac.uk/photo/ |
| Integration | https://camsis.cam.ac.uk/intb_reg/ | https://api.apps.cam.ac.uk/photo-test/ |
| UAT | gs://ap-testdata-uat-76f5195d | none |
| Regression | gs://ap-testdata-regression-052d7463 | https://api.apps.cam.ac.uk/photo-test/ |
| Test | gs://ap-testdata-staging-26edd96d | https://api.apps.cam.ac.uk/photo-test/ |
| Development | gs://ap-testdata-development-f1130a5d | none |
The mapping between MyCApp environments the Photo API is defined in ap-deployment/workspace-specific-settings.yml.
ap-backend receives the applicant feed URL as follows:
-
An EXTRA_SETTINGS_URL points to two environment-specific artefacts:
-
an
apiapp-secret-settingssecret in GCP Secret Manager -
an
apiapp-settingsYAML config file in GCP Cloud Storage -
Both are fetched by
ap-backendon startup and their contents read to populate the load_settings FastAPI dependable. -
The location of the applicant feed is now available as either
-
load_settings.applicants_source.camsis.urlfor a CamSIS feed. load_settings.applicants_source.test_source.urlfor a feed mocked by a JSON file.
Google Cloud Platform¶
The GCP console pages for managing the infrastructure of each component of the deployment are:
| Name | Public Application Static Assets | Public Application Backend | Internal Portal Backend and Payment Callback API | Frontend Cloud Functions | Data service backend |
|---|---|---|---|---|---|
| Production | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | n/a |
| Integration | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | GCP Cloud Run |
| Regression | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | GCP Cloud Run |
| UAT | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | n/a |
| Test | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | GCP Cloud Run |
| Development | GCP CDN | Firebase | GCP Cloud Run | Cloud Functions | GCP Cloud Run |
All environments share access to a set of secrets stored in the meta-project Secret Manager.
Source code¶
The source code for My Cambridge Application is spread over the following repositories:
| Repository | Description |
|---|---|
| Portal Frontend | The source code for the application frontend and supporting cloud functions. |
| Internal Portal Backend | The source code for the internal backend service and WPM callback API |
| Portal Infrastructure Deployment | The Terraform infrastructure code for deploying the portal to GCP |
| Data service | The source code for the data service which provides an API on the API Gateway |
| Data service Deployment | The Terraform infrastructure code for deploying the data service to GCP |
Technologies used¶
The following gives an overview of the technologies My Cambridge Application is built on.
| Category | Language | Framework(s) |
|---|---|---|
| Frontend | TypeScript | React, Gatsby, Firestore, MUI |
| Cloud Functions | TypeScript | Firebase Functions (Node.js), nodemailer |
| Internal Backend API | Python | FastAPI, Pydantic, firebase-admin |
| WPM Callback API | Python | FastAPI, xmltodict |
| Data Service API | Python | FastAPI, PostgreSQL |
| Platform | Unified DevOps Platform |
Technical Architecture¶
My Cambridge Application is split across a React/Gatsby frontend, a Python FastAPI internal backend, a separate WPM payment callback service, a set of Firebase Cloud Functions, and an independent Data Service API. The frontend communicates with Firestore directly (via client-side Firebase SDK); the backend is an internal service-to-service API that is not called by the frontend at all.
Frontend (ap-frontend): A pnpm monorepo containing 14 workspace packages. The main
applicant-facing webapp is a Gatsby static site using React, MUI for UI components, and Emotion for
CSS-in-JS styling. It connects to Firebase Auth for authentication and Firestore for real-time
data. Key workspace packages include:
webapp— Gatsby application with pages for sign-in, account management, application sections (answers, details, payment, submission, welcome), an admin panel (applicant lookup, impersonation, cycle data management, fee waivers), and accessibility/terms pagesquestions— Data-driven question definitions organised by section (about you, educational experience, funding, high school studies, higher education, interview, other qualifications, photo, your course) with college-specific email configurationvalidation— Shared validation logic (condition evaluation, status calculation, visibility rules) used by both the webapp and cloud functionstypes— Shared TypeScript types for user profiles, activity state, answers, alerts, submission status, admin roles, and cycle/fee configurationemails— Email template definitionsutility— Shared utility functionsfirebase/functions/*— Eight Cloud Functions triggered by Firestore document events:activityUpdate,adminUsersWrite,submissionsCreate,fileUpload,deletionsCreate,deletionsUpdate,photoSubmissionsCreate,photoSubmissionsUpdatefirebase/rules— Firestore security rules with role-based access control (admin claims: impersonation, audit, retrySubmission, manageCycleData, manageFeeWaivers)fixture— Test data loader for local development (pre-populates Firestore and Firebase Auth)wpm-emulator— Local WPM payment mockexternal-api-emulators— Express server mocking Albatross and Photo API
The submission workflow is orchestrated by the submissionsCreate Cloud Function, which executes a
pipeline of steps: initialise, fetch data, validate answers, merge transcripts, submit transcripts,
translate answers, submit answers to Albatross via the API Gateway, and send
confirmation/missing-files emails.
Backend (ap-backend): A Python FastAPI application deployed as two separate Cloud Run services
from the same codebase, controlled by the WPM_APP environment variable:
- Internal API (default mode) — exposes CamSIS import, audit export, and regression/test endpoints. Not publicly accessible; called by Cloud Scheduler and Cloud Tasks.
- WPM callback API (
WPM_APPset) — exposes only the/wpm/callbackendpoint as a public service for WPM payment notifications.
The backend uses FastAPI dependency injection extensively for Firestore clients, Firebase Auth
clients, Cloud Tasks clients, email clients, and API Gateway OAuth tokens. Settings are loaded at
startup from YAML configuration files fetched via the geddit library from URLs specified in the
EXTRA_SETTINGS_URLS environment variable (pointing to GCP Secret Manager secrets and Cloud
Storage config files).
The CamSIS import flow works in two stages: a bulk import endpoint (POST /camsis/import) pages
through the CamSIS feed and enqueues a GCP Cloud Task per applicant; each task calls an individual
import endpoint (POST /camsis/import/{appNum}) which upserts the applicant across Firestore,
Firebase Auth, and the Albatross Data Service, sending a welcome email for new applicants.
Firestore data model: Each applicant is stored as a document in the applicants collection
with sub-collections: internal/imported (raw CamSIS data), internal/portal (Firebase Auth
UID), user/answers (questionnaire responses), user/activity (progress state such as onboarding
completion and submission timestamp), userReadonly/profile (derived read-only profile), and
userReadonly/paymentTokens (pre-generated WPM payment tokens). Additional top-level collections
include alerts (service alerts), admin-users (CAO admin accounts), submissions, deletions,
and photo-submissions.
Deployment model: Infrastructure is managed by Terraform in the ap-deployment repository. The
frontend is built as a static site and served via GCP CDN. Cloud Functions are deployed individually
from built archives. Backend services run on GCP Cloud Run with single-worker Uvicorn. Both
ap-frontend and ap-backend auto-deploy to staging and regression environments on merge to their
default branch by triggering downstream pipelines in ap-deployment.
Testing strategy:
- Backend: pytest with pytest-asyncio, factory-boy, hypothesis, freezegun, and pytest-mock. Coverage enforced via tox. Linting with mypy, black, and isort.
- Frontend: Jest unit tests, Cypress component tests, and Cypress e2e tests (running against Firebase emulators and external API mocks). Firebase rules have dedicated tests. eslint and prettier for code quality. syncpack for dependency consistency across workspace packages.
Operational documentation¶
The following gives an overview of how My Cambridge Application is deployed and maintained.
How and where My Cambridge Application is deployed¶
My Cambridge Application infrastucture is deployed using Terraform, with releases of the frontend and service-to-service backend API deployed by the GitLab CD pipelines associated with the infrastructure deployment repository.
Deploying a new release¶
The README.md files in each of the source code repositories explain how to deploy the Admissions
Portal.
Deployment schedule¶
All environments are deployed to at sprint end. However, there are some exceptions:
- Development is only deployed to at sprint end, to keep it up to date, if there is no one currently using it for feature testing. This manual feature testing deployments are only done when a larger piece of functionality needs further testing, after manual development before or during a review.
- Staging is deployed to on merge to master.
User access management¶
| Environment | User access management |
|---|---|
| Production | Firebase Auth - Accounts created Live CamSIS feed sync |
| Integration | Firebase Auth - Fake CamSIS feed sync into Albatross and MyCApp |
| Regression | Firebase Auth - API calls to create and tear down |
| User testing | Firebase Auth - Excel spreadsheet sync to Albatross and MyCApp |
| Staging | Firebase Auth - JSON file import to Albatross and MyCApp |
| Development | Firebase Auth - JSON file import to Albatross and MyCApp |
Monitoring¶
GCP Cloud Monitoring is used for tracking the health of applications in the environments and sending alert emails when problems are detected.
Debugging¶
TBD
Displaying service alert messages¶
My Cambridge Application supports the display of service alert messages, to target one or more pages and/or user groups with information relevant to any ongoing live service issues.
For more information on how to configure these alerts, see
alerts
in the ap-frontend repository.
Specifications¶
- Admissions Portal: High-Level Specification
- Admissions Portal: Backend Specification
- Admissions Portal: Frontend Specification
- Digital Admissions Project Index
Service Management¶
The Team responsible for this service is Hopper Team.
The Tech Lead for this service is amh254.
The Service Owner for this service is hr244.
The Service Manager for this service is soj23.
The Product Manager for this service is bmd42.
The following engineers have operational experience with this service and are able to respond to support requests or incidents: