Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
BMSview is an advanced web application for analyzing Battery Management System (BMS) screenshots using Google's Gemini AI. The system is built on a local-first sync architecture, which prioritizes offline functionality, enhances user experience by providing immediate data access, and significantly reduces server load. This design uses intelligent caching in the browser's IndexedDB and periodic synchronization with the backend.
The architecture is divided into a React-based frontend, a serverless backend using Netlify Functions, and a MongoDB database. This document provides a detailed breakdown of these components, their interactions, and the underlying design principles. For more information on state management, see the State Management Guide.
Sources: GEMINI.md:10-13, ARCHITECTURE.md:8-11
Technology Stack
The project utilizes a modern technology stack for its frontend, backend, and AI components.
| Category | Technology | Description |
|---|---|---|
| Frontend | React, Vite, TypeScript | A modern, fast, and type-safe web application framework. |
| Styling | Tailwind CSS | A utility-first CSS framework for rapid UI development. |
| Backend | Netlify Functions | Serverless functions running on a Node.js runtime. |
| Database | MongoDB | A NoSQL database for storing analysis and system data. |
| AI | Google Gemini | Used for screenshot analysis and generating insights. |
| APIs | Solar Charge Estimator, OpenWeather | External services for integrated solar and weather data. |
| Authentication | Netlify Identity | Manages user authentication, primarily for the admin dashboard. |
Sources: GEMINI.md:15-23, README.md:94-100
System Architecture
The application is designed around several key principles that enable its local-first capabilities and efficient data handling.
Key Architectural Principles
- Local-First: Data is primarily stored and retrieved from the browser's IndexedDB. The server acts as the authoritative source for conflict resolution.
- Intelligent Sync: Synchronization is driven by comparing metadata (timestamps, record counts) rather than being triggered on every user operation. This minimizes unnecessary data transfer.
- Periodic Sync: A background timer automatically syncs data every 90 seconds.
- Dual-Write for Critical Actions: Important actions, like a new analysis, are written to both the local cache and the server immediately to ensure data persistence.
- UTC Timestamps: All timestamps use the ISO 8601 UTC format (
YYYY-MM-DDTHH:mm:ss.sssZ) for consistency across the system.
Sources: GEMINI.md:27-35, ARCHITECTURE.md:13-17
High-Level Component Diagram
This diagram illustrates the main components of the BMSview application and their interactions.
Sources: GEMINI.md:22-23, ARCHITECTURE.md:40-66
Core Components
| Component | Location | Responsibility |
|---|---|---|
SyncManager | src/services/syncManager.ts | Orchestrates the entire sync process, including the 90-second periodic timer and sync decision logic. |
LocalCache | src/services/localCache.ts | Manages IndexedDB storage using Dexie.js, handling data persistence and sync status. |
ClientService | services/clientService.ts | An API wrapper that implements the cache-first data fetching strategy and dual-write pattern. |
AppState / AdminState | state/appState.tsx, state/adminState.tsx | Global React state contexts managed with useReducer and useContext. |
| Netlify Sync Functions | netlify/functions/sync-*.cjs | Serverless functions for metadata comparison, incremental data fetching, and data pushes. |
Sources: GEMINI.md:37-45, ARCHITECTURE.md:116-128
Data Flow
The application uses different strategies for reading and writing data to optimize for performance and offline availability.
Sources: GEMINI.md:47-53, ARCHITECTURE.md:83-102
Backend Architecture
The backend is composed of serverless Netlify Functions written in TypeScript and using the CommonJS module system.
Sources: CODEBASE.md:9-11
Sync API Endpoints
A set of dedicated functions handles the local-first synchronization logic.
| Endpoint | Method | Description |
|---|---|---|
sync-metadata.cjs | GET | Returns metadata for a collection, including recordCount, lastModified, and a checksum. |
sync-incremental.cjs | GET | Returns new or updated items since a given ISO timestamp, along with IDs of deleted records. |
sync-push.cjs | POST | Receives a batch of items from the client to be created or updated in the database. |
Sources: ARCHITECTURE.md:70-81
Other Key Endpoints
/api/analyze: The primary endpoint for submitting BMS screenshots for analysis. It supports a synchronous flow for single files.solar-estimate.ts: A proxy function to the Solar Charge Estimator API, handling requests for solar generation estimates.create-github-issue.cjs: An internal tool for creating GitHub issues based on AI feedback, featuring duplicate detection.
Sources: GEMINI.md:55-59, README.md:73-78, GITHUB_INTEGRATION_COMPLETE.md:41-51
Security
- CORS: A centralized CORS utility (
netlify/functions/utils/cors.cjs) manages cross-origin requests, using an environment-based origin allowlist for production. - Input Validation: Zod schemas are used in endpoints like
systems.cjsto validate incoming data against predefined rules.
Sources: MAJOR_FIX_UPDATE_SUMMARY.md:60-72, MAJOR_FIX_UPDATE_SUMMARY.md:104-106
Frontend Architecture
The frontend is a React application built with Vite and TypeScript, using ES Modules. It is structured into two main parts: a public-facing application and a separate admin dashboard.
Sources: CODEBASE.md:9-10, STATE_MANAGEMENT_GUIDE.md:7-9
State Management Architecture
BMSview uses React's Context API with reducers for state management, maintaining two independent state contexts to separate concerns and improve performance.
AppState: Manages state for the public-facing application, including analysis results, system registration, and historical data. It is defined instate/appState.tsx.AdminState: Manages state for the admin dashboard, including paginated data, bulk operations, diagnostics, and detailed action statuses. It is defined instate/adminState.tsx.
This separation ensures that the admin state is only loaded for authenticated admins and that the public app is not burdened with unnecessary data.
The diagram below shows the relationship between the main app component, the state provider, and the sync manager.
Sources: STATE_MANAGEMENT_GUIDE.md, App.tsx:39-45
Database Architecture
The application uses MongoDB as its primary data store.
Collections
| Collection | Description |
|---|---|
analysis-results | Stores the results of each screenshot analysis. Contains a contentHash for deduplication. |
systems | Contains records of user-registered BMS systems. |
history | Stores historical analysis records, used for tracking performance over time. |
insights-jobs | Manages background jobs for AI-driven insights generation. |
ai_feedback | Stores structured feedback from the AI for application improvement. |
Sources: CODEBASE.md:13-19, SPRINT_COMPLETE_SUMMARY.md:200-229
Schema and Indexes
To support the local-first sync architecture and ensure efficient queries, collections include specific fields and indexes.
updatedAt: An ISO 8601 UTC timestamp indicating the last server-side update. This is crucial for incremental sync._syncStatus: A field in the local cache to track whether a record is'pending'or'synced'.contentHash: A SHA-256 hash inanalysis-resultsused for deduplication.
The following indexes are recommended for the analysis-results collection to optimize performance for sync and query operations.
// analysis-results collection indexes
db.analysis_results.createIndex({ updatedAt: 1 }) // For incremental sync
db.analysis_results.createIndex({ systemId: 1, timestamp: -1 }) // For history lookups
db.analysis_results.createIndex({ contentHash: 1 }) // For deduplication
Sources: ARCHITECTURE.md:155-163, ARCHITECTURE.md:214-225
Conclusion
BMSview's architecture is thoughtfully designed around a local-first sync model. This approach provides a robust, responsive, and efficient user experience by leveraging browser caching while ensuring data integrity through periodic, intelligent synchronization with a serverless backend. The clear separation of concerns between the frontend state contexts, the modular backend functions, and the well-defined database schemas creates a scalable and maintainable system.
Sources: ARCHITECTURE.md:8-11, GEMINI.md:25-26