The Car Pulse Tracker WUI (bnc-cpt-wui) is a Vue 3 single-page application that serves as the customer-facing frontend. It is built as static files and deployed to GCS buckets, served via HTTPS load balancer with CDN across 4 environments.
Internet
│
┌───────────┴───────────┐
│ │
{env}.carpulsetracker.com {env}.api.carpulsetracker.com
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ GCS Bucket │ │ Cloud Run │
│ (WUI) │ ◄── THIS │ (API) │
└─────┬─────┘ └───────────┘
│
┌─────┴─────┐
│ HTTPS LB │
│ + CDN │
│ + SSL │
└───────────┘
| Environment | Bucket Name | Site URL |
|---|---|---|
| inf | bnc-cpt-inf-site-static | https://inf.carpulsetracker.com |
| dev | bnc-cpt-dev-site-static | https://dev.carpulsetracker.com |
| tst | bnc-cpt-tst-site-static | https://tst.carpulsetracker.com |
| prd | bnc-cpt-prd-site-static | https://carpulsetracker.com |
Properties: - Location: europe-north1 - Storage class: Standard - Versioning: enabled - Force destroy: true
Each environment has:
- URL map: bnc-cpt-{env}-wui-https-url-map
- SSL certificate: Google-managed
- HTTPS redirect: enabled
- CDN: enabled with cache invalidation on deploy
| Environment | SSL Covered Domains |
|---|---|
| prd | carpulsetracker.com, www.carpulsetracker.com, prd.carpulsetracker.com |
| dev | dev.carpulsetracker.com |
| tst | tst.carpulsetracker.com |
| inf | inf.carpulsetracker.com |
DNS records managed by Terraform step 007-dns:
- A records pointing to load balancer IP
- Zones: subzone-bnc-cpt-{env}
Landing → Payment → Payment Gateway → Success → OAuth → Report
│ │ │ │ │ │
│ Select │ Choose │ Redirect to │ Confirm │ Tesla │ View/
│ vehicle │ plan + │ Stripe/PayPal │ payment │ login │ download
│ brand/model│ method │ │ │ │ PDF
| Layer | Technology | Version |
|---|---|---|
| Framework | Vue 3 (Composition API) | 3.5 |
| Language | TypeScript | 5.8 |
| Build Tool | Vite | 6.2 |
| State | Pinia | 2.2 |
| Styling | Tailwind CSS | 3.4 |
| Charts | ECharts | 5.5 |
| Payments | Stripe.js | 4.8 |
| i18n | Vue I18n | 10 |
| Component | Purpose |
|---|---|
| App.vue | Root (step navigation, OAuth/payment callbacks) |
| Header.vue | Navigation + language switcher + mobile menu |
| Hero.vue | Landing page |
| StepIndicator.vue | Progress bar (active/completed/clickable states) |
| BrandSelector.vue | Vehicle brand selection |
| BrandCarousel.vue | Brand carousel display |
| PaymentStep.vue | Plan + method selection, voucher, quotes |
| PaymentGateway.vue | Payment processing state |
| OAuthStep.vue | Tesla authentication |
| GeneratingStep.vue | Report generation progress + error fallback |
| ReportDashboard.vue | PDF display + download, multi-vehicle tabs |
| SupportPage.vue | Support/help article search + navigation |
| ServiceAgreement.vue | Terms modal with markdown render |
| SupportedBrands.vue | Brand grid with badges |
| FeeRow.vue | Price line item (label + currency format) |
| Footer.vue | Copyright + agreement link |
All backend calls through services/api.ts:
- Base URL from VITE_API_BASE_URL environment variable
- JWT token from localStorage for authenticated requests
- 15 API methods covering payments, Tesla, VIN, and reports
| Environment | VITE_API_BASE_URL |
|---|---|
| Local dev | /api/v1 (Vite proxy to localhost:8100) |
| dev | https://dev.api.carpulsetracker.com/api/v1 |
| tst | https://tst.api.carpulsetracker.com/api/v1 |
| prd | https://api.carpulsetracker.com/api/v1 |
The Pinia store persists payment state to localStorage to survive Stripe/PayPal redirects:
| localStorage Key | Data |
|---|---|
| cpt-payment-id | Active payment ID |
| cpt-selected-plan | basic / pro / expert |
| cpt-payment-method | stripe / paypal / googlepay / applepay |
| cpt-current-step | Navigation step |
| cpt-selected-brand-id | Vehicle brand |
| cpt-selected-model-id | Vehicle model |
9 languages: English (en), Finnish (fi), Swedish (sv), German (de), French (fr), Spanish (es), Italian (it), Danish (da), Norwegian (no). All UI text in i18n/locales/{lang}.json.
npm run build produces static files in dist/:
- index.html with version meta tag
- assets/*.js (bundled + minified)
- assets/*.css (Tailwind compiled)
- Source maps for debugging
Git tag (v0.2.3)
│
▼
Docker container builds Vue app
│ VITE_APP_VERSION=v0.2.3
▼
dist/ directory
│
▼
gsutil rsync → gs://bnc-cpt-{env}-site-static
│
▼
CDN cache invalidation
│
▼
Health check: https://{fqdn}/index.html → HTTP 200
ci.yaml)Single workflow with 4 jobs:
do_build_wui_vue shell action → npm install + type-check + build. Runs UI tests against local dev server.Auto-deploy on master push: inf + dev. Protected: tst, prd (workflow_dispatch only).
| Secret | Purpose |
|---|---|
| ALL_CSI_GITHUB_TOKEN | Clone team repos |
| GCP_SA_KEY_INF | GCS auth for inf |
| GCP_SA_KEY_DEV | GCS auth for dev |
| GCP_SA_KEY_TST | GCS auth for tst |
| GCP_SA_KEY_PRD | GCS auth for prd |
Provisioned by Terraform step 120-github-general-secrets.
v0.2.3)<meta name="version" content="v0.2.3" /> into HTML at build time./run -a do_version_bump (from bnc-cpt-utl)| Terraform Step | What it provides |
|---|---|
| 007-dns | DNS records for {env}.carpulsetracker.com |
| 015-gcp-buckets-for-sites-static | GCS bucket + HTTPS LB + CDN + SSL |
| 120-github-general-secrets | GitHub Actions secrets for CI/CD |
The API's CORS settings must match the WUI domains:
| Environment | CORS Origins |
|---|---|
| dev | https://dev.carpulsetracker.com, http://localhost:3333 |
| tst | https://tst.carpulsetracker.com |
| prd | https://carpulsetracker.com, https://www.carpulsetracker.com |
| inf | https://inf.carpulsetracker.com, http://localhost:3333 |