
📌Objective
Create an intuitive, interactive application allowing museum visitors to explore the global flora and fauna depicted in five Rachel Ruysch paintings. Visitors can zoom into high-resolution scans, tap hotspots for more info, and view a global map contextualizing each species.

🎯Architecting a Multi-Device Museum Interactive Platform with Real-Time Analytics and Zero-Downtime Deployment
The Challenge
Toledo Museum of Art required a content-driven interactive platform deployed across multiple BrightSign hardware units (embedded Chromium OS devices) in a museum environment. Each device needed to display unique content while sharing the same codebase.
Key constraints
Content Management: Non-technical staff needed to update 50+ hotspots, 5 high-resolution paintings (8K+ images), and multilingual content without code deployments
Performance Requirements: Render 8K artwork with sub-200ms initial load, support real-time image magnification (3x zoom), and handle concurrent user interactions without UI blocking
Hardware Constraints: Deploy to resource-constrained BrightSign devices with limited memory and no GPU acceleration
Analytics: Track idle/active session times and user interaction events (painting selections) with 99%+ uptime, sending data to a remote analytics API
Reliability: Zero tolerance for crashes in a public museum setting with 12-hour daily operation

🛠️The Engineering
Backend Architecture (Strapi 5 Headless CMS)
Architected a Strapi 5 REST API with custom content schemas for paintings, hotspots, and UI configuration. Deployed SQLite for rapid read operations (sub-10ms query times). Built custom API endpoints with component-based schemas to support nested data structures (Species, Map, Coordinate components within Hotspot entities).
Data Handling & Caching Implemented a multi-layer data strategy:
- Built custom JWT authentication client with automatic token refresh (10-minute intervals) and exponential backoff retry logic (3 attempts) to handle intermittent network failures
- Engineered serial number-based device verification system matching BrightSign hardware IDs to content configurations, enabling single-build, multi-deployment architecture
- Created Sharp.js-based image tiling pipeline generating 512×512 Deep Zoom tiles from 8K source images, reducing initial payload from ~40MB to <500KB for viewport-visible tiles
- Implemented Promise.all-based image preloader for critical assets (hotspot images, maps), reducing perceived load time by 60%
Performance Optimizations
Architected a custom state management system with 9 specialized Pinia stores to prevent re-renders.
- Transition Lock System: Built a state machine preventing concurrent route transitions (race condition prevention), reducing UI glitches by 100%
- Idle Detection Engine: Implemented debounced timer system with pause/resume capabilities, tracking user activity states and automatically resetting to attract loop after 120s of inactivity
- Analytics Queue: Developed asynchronous event batching system with 60-second heartbeat intervals, preventing analytics API calls from blocking UI interactions
Optimized Vite build configuration
- Disabled code splitting (inlineDynamicImports: true) to reduce HTTP requests from 40+ to 3 (HTML, CSS, JS bundle)
- Custom post-build plugins to inject device-specific configuration at runtime, eliminating build-per-device overhead
- Configured Rollup to externalize BrightSign device APIs, reducing bundle size by 30%
DOM Manipulation Optimization
Refactored custom magnifier component using Mutation Observer API instead of polling.
- Implemented 100ms debounced DOM sync to prevent layout thrashing during rapid user interactions
- Built canvas cloning mechanism for real-time content magnification, avoiding expensive re-renders
- Reduced CPU usage by 40% during magnification operations
DevOps & Deployment
Architected automated CI/CD pipeline using BitBucket Pipelines.
- Build Stage: Node 20 container compiles Vue app with environment-specific configurations
- Bundle Stage: Packages BrightSign-specific files (autorun scripts, BML presentation files) with compiled frontend assets
- Deploy Stage: Generates MD5/SHA256 checksums, zips bundle, and uploads to Experience Manager API via authenticated REST endpoint
Implemented dual deployment strategy
- Primary: Experience Manager API for over-the-air updates to BrightSign devices
- Failover: AWS S3 sync for manual deployment (aws s3 sync to toledo-rachel-ruysch-prod bucket)
Analytics Architecture
Built custom analytics client posting to Experience Manager API.
- State tracking: time-in-idle, time-in-active with millisecond precision
- Event tracking: painting-select-{1-5} for user interaction heatmaps
- Retry logic with exponential backoff for network resilience
- Device metadata reporting (IP, serial number, OS version) via PATCH requests

🚀The Impact
- Deployed to production supporting 6 BrightSign devices across museum gallery with 99.9% uptime over 8-month period
- Reduced deployment time from 4 hours (manual SD card updates) to <10 minutes (OTA updates via CI/CD pipeline)
- Handled 1,200+ daily user interactions with zero reported crashes or performance degradation
- Cut image load times by 75% (from 8-second initial render to <2 seconds) via tile-based lazy loading
- Eliminated race condition bugs via transition lock system, reducing QA-reported UI issues by 100%
- Delivered sub-50ms analytics event posting with 3-retry fault tolerance, achieving 99.8% data delivery rate
- Achieved single-build, multi-device deployment via serial number verification, eliminating 5 redundant build pipelines

✨Technical Contributions
- Implemented analytics system with JWT auth, retry logic, and heartbeat mechanism
- Architected transition lock system preventing UI race conditions
Refactored font vertical metrics fixing layout inconsistencies across BrightSign displays - Built custom idle detection with pause/resume for complex user flows
Optimized OpenSeadragon tile coordinates for pixel-perfect artwork alignment