05-Specifications / 05.02.Puppeteer-PDF-Generation.plan

05.02.Puppeteer PDF Generation.plan

05.02. Puppeteer PDF Generation.plan

This plan outlines the surgical steps to implement the proactive PDF generation flow described in specs/puppeteer-control-flow.spec.md (v1.5.0).

MANDATORY: All shell actions must be run as ysg user from bnc-cpt-utl/.


Phase 1: Infrastructure & Environment (Terraform)

Goal: Provision the new service identity, internal secret, and networking.

  1. Step 003 (IAM): Provision the new pdf-api Service Account.
  2. Step 016 (Storage): Grant objectCreator and objectViewer roles to the pdf-api SA on the reports bucket.
  3. Step 029 (Secrets): Create the bnc-cpt-internal-secret in Secret Manager.
  4. Step 030 (Cloud Run): Define the pdf-api service (internal-only) and attach it to the existing VPC connector.

Prompt 1: Apply the Terraform changes for the PDF-API identity, storage permissions, and internal secrets across all environments.


Phase 2: WUI Component Refactor & Print Route

Goal: Prepare the Vue 3 frontend for "clean" rendering.

  1. Extract Content Components: Create ReportContentBasic.vue and ReportContentPro.vue from existing Dashboard components.
  2. Implement Print Route: Add logic to App.vue to recognize /report/print/:vin and render the Content components without navigation/menus.
  3. Print-Route Data Fetch: Implement GET /api/v1/tesla/print-report/{vin} support in the frontend to use the print token.

Prompt 2: Refactor the WUI to extract core report content into pure components and implement the headless-ready print route.


Phase 3: Node.js PDF-API Service Scaffolding

Goal: Build the co-located rendering service.

  1. Scaffold Project: Initialize bnc-cpt-api/src/nodejs/pdf-api/ with Express and Puppeteer.
  2. Internal Auth: Implement the X-Internal-Secret middleware.
  3. Rendering Loop: Implement the /generate endpoint with generic-pool and 3-retry logic.
  4. GCS Upload: Implement the PDF upload logic to the reports bucket.
  5. Dockerization: Add pdf-api to docker-compose-app.yaml and create the production Dockerfile.

Prompt 3: Implement the Node.js pdf-api service inside the bnc-cpt-api repository, including the worker pool and retry logic.


Phase 4: Python API Integration & Proactive Trigger

Goal: Connect the Python backend to the new rendering pipeline.

  1. Redis Schema Updates: Add support for pdf:hook:* and pdf:report:* keys.
  2. Print Token Logic: Implement the short-lived JWT generation and verification in app/services/auth.py.
  3. Proactive Trigger: Add the asyncio.create_task call in the Tesla fetch flow to hit pdf-api.
  4. Internal Callbacks: Implement the /api/v1/internal/pdf-render-* endpoints.
  5. Download Hook: Implement the GET /api/v1/tesla/pdf/{random_id} endpoint.

Prompt 4: Integrate the Python backend with the pdf-api, implementing the proactive trigger and the opaque download hook mechanism.


Phase 5: Cleanup & Lifecycle

Goal: Ensure data privacy and resource optimization.

  1. OAuth Success Anchor: Update the OAuth callback to record the success timestamp in Redis.
  2. Cleanup Task: Implement the background task in cpt-api to scan and delete expired GCS objects and Redis keys.

Prompt 5: Implement the 30-minute post-OAuth cleanup task for GCS objects and Redis metadata.


Phase 6: Validation & Verification

Goal: Ensure end-to-end correctness.

  1. Local E2E Test: Verify proactive generation, 3-second grace period, and download via hook.
  2. Fallback Test: Simulate pdf-api failure and verify WeasyPrint fallback.
  3. Cleanup Test: Verify objects are deleted after 30 minutes.

Prompt 6: Perform end-to-end verification of the Puppeteer control flow, including fallback and cleanup scenarios.