Engineering Logs

A chronological record of technical hurdles, debugging sessions, and infrastructure updates.

Dec 15, 2025
React URL API Deep Linking UX Engineering

Cross-Application Data Persistence Strategy

Eliminated user friction by architecting a 'Deep Link' system between isolated React apps. Reduced a 5-step manual copy-paste workflow into a single click using URL parameter hydration and history state management.

View Engineering Report

The Challenge

Users starting in App 1 (Sermon Generator) had to manually copy-paste text into App 6 (Presentation Engine). This friction disrupted the 'magical' AI experience and made the suite feel disjointed.

The Solution: Deep Linking Architecture

  • Parameter Construction: App 1 constructs a target URL with encoded query parameters (?action=create&title=...).
  • State Hydration: App 6 intercepts these parameters on mount, formats the raw strings, and instantly hydrates the local React state.
  • URL Sanitization: Implemented window.history.replaceState to immediately clear the URL parameters after import. This prevents data duplication if the user refreshes the page.

Key Implementation: URL Parsing & Sanitization

useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    
    if (params.get('action') === 'create') {
        const importedText = formatIncomingData(params);
        setSermonText(importedText);
        
        // UX Critical: Clean URL so refresh doesn't duplicate data
        window.history.replaceState({}, document.title, window.location.pathname);
    }
}, []);
Dec 14, 2025
Next.js 15 TypeScript Vercel PDF Renderer

Resolving SSR Conflicts & Real-Time PDF Generation

Stabilized a crashing production build caused by PDF generation library dependencies. Implemented dynamic client-side loading to bypass SSR limitations and synchronized Firestore types for real-time reporting.

View Engineering Report

The Challenge

During deployment of the Income Packet reporting engine, the Vercel build failed repeatedly. The PDF generation library relied on browser-specific APIs (canvas, window) that do not exist in the Next.js server runtime, causing a panic during pre-rendering.

1. Dynamic Client-Side Loading

I refactored the component to use next/dynamic with ssr: false. This forces Next.js to bypass the server-render step for the heavy PDF component, loading it only once the browser environment is active.

2. Webpack & Turbopack Config

Updated next.config.ts to explicitly externalize heavy dependencies (pdfjs-dist) and ignore canvas modules during the build process, preventing server-side bundling errors.

The Fix: Bypassing SSR

const DownloadReportButton = dynamic(
  () => import('../components/DownloadReportButton'),
  { 
    ssr: false, 
    loading: () => <LoadingSpinner /> 
  }
);
Dec 10, 2025
Cloud Run Eventarc Stripe Vertex AI

Scalable, Multi-Tiered AI Media Processing

Engineered a serverless, asynchronous pipeline for SermonTranscribe. Solved HTTP timeout limits for large audio files and implemented a 'Tier-Aware' architecture that dynamically adjusts processing costs based on subscription status.

View Engineering Report

The Challenge

The objective was to build a multi-tenant SaaS that allows users to upload 1-hour+ audio files for AI transcription. Standard HTTP timeouts (60s) made synchronous processing impossible, and the system needed to rigorously gatekeep features between Free and Paid tiers.

1. Asynchronous "Factory" Pipeline

  • Decoupled Uploads: Frontend uploads directly to Cloud Storage via signed URLs, bypassing the backend to avoid bandwidth bottlenecks.
  • Eventarc Triggers: File upload events automatically trigger a lightweight Cloud Run submitter service, which queues a BatchRecognize job and returns immediately.

2. Robust "Tier-Aware" Logic

I implemented a custom "Gatekeeper" pattern to handle Stripe subscriptions dynamically:

  • Free Users: Jobs submitted with processing_strategy=DYNAMIC_BATCH (24hr turnaround, ~80% cheaper).
  • Paid Users: Jobs submitted with DEFAULT strategy (instant) and trigger extra "Premium" LLM prompts for SEO and Social Media.
Dec 03, 2025
GCP IAM Node.js DNS/SSL OAuth2

Orchestration & Infrastructure: Google Slides API

Resolved critical deadlocks in the MinisterSuite Presentation Engine. Re-architected Service Account permissions, fixed API schema mismatches, and resolved DNS CAA conflicts to achieve sub-20s generation times.

View Engineering Report

The Challenge

The goal was to build an automated system that takes unstructured sermon notes and generates a professionally designed Google Slides presentation. The system faced failures at multiple integration points: Permission Deadlocks, API Schema Mismatches, and SSL/DNS conflicts.

Phase 1: Auth & Permissions Architecture

Problem: Service Account hit storage quotas and permission errors when trying to transfer file ownership.

Fix: Re-architected to a "Share & Clone" model. The Service Account now temporarily shares the Master Template with the User, and uses the User's token to create the copy, bypassing Service Account storage limits.

Phase 2: API Schema Debugging

Problem: "Layout Not Found" errors despite matching names.

Fix: Implemented a verbose "Layout Dumper" logging utility. Discovered the Google Slides API nests names under layoutProperties.displayName rather than the root. Updated traversal logic.

Phase 4: DNS & SSL Resolution

Problem: Persistent "Not Secure" warning on deployment.

Fix: identified conflicting CAA records blocking Google's pki.goog. Purged conflicts and explicitly authorized the wildcard certificate.

Dec 01-03, 2025
React UX/UI State Management Browser APIs

Optimizing Game Loop Logic & Presentation State

Refactored game loop logic for MinisterSuite's Game Engine to solve user flow entrapment. Implemented native Fullscreen API integration and modularized timer logic across 5 distinct game modes.

View Engineering Report

The Challenge

While building the "Story Sequence" mode for the Game Suite (App 7), I encountered a critical UX flaw. Unlike auto-advancing Trivia modes, Sequence games require audience discussion. The initial logic trapped users in a "Revealed" state with no path to trigger the "Round Complete" logic.

State Logic Refinement

I separated the revealed state from isGameOver. I implemented a conditional "Finish Round" button that only renders after the solution is revealed. This allows the presenter to facilitate discussion before manually triggering the next round generation.

Native Fullscreen Integration

To support live projection without relying on browser shortcuts, I implemented the document.documentElement.requestFullscreen() API wrapped in a useEffect hook to sync React state with native browser events (like pressing ESC).

Nov 22, 2025
React 19 Firebase Auth CORS Vertex AI

Debugging Cross-App Auth & Phantom 404s

Resolved silent production failures in the MinisterSuite monorepo. Implemented an SSO Bridge for cross-origin auth, fixed CORS middleware issues, and bypassed regional AI model unavailability.

View Engineering Report

The Challenge

The core "Sermon Generator" application was failing silently in production. Users were authenticated on the homepage but locked out of the subdomain app, and API calls to Vertex AI were returning generic 500 errors.

1. Auth State Disconnect

Problem: AuthContext initialized with a null user on subdomains because localStorage does not share state across origins/ports.

Fix: Implemented a "SSO Bridge" architecture using a custom Cloud Function to mint tokens and securely pass authentication state between the apps.

2. The "Phantom" 404 Error

Problem: Backend logs showed a persistent 404 Not Found for the Vertex AI model despite correct IAM permissions.

Fix: Discovered the issue was actually "Region Availability." The model was temporarily restricted in us-central1. Configured the Vertex client to target us-east1 while keeping the Compute infrastructure in central, bypassing the restriction.