1. Build and delivery boundary
index.tsx mounts App, while Vite turns React 19 and TypeScript into a browser bundle. Store images and static HTML ship in the same deployment and are delivered from Vercel. There is no server rendering or API route, so search, modals and AI actions execute after the browser receives the shell.
2. Presentation and state orchestration
App.tsx owns the source catalog, query, category, nearby mode, active view, modals, AI response, receipt state, favorites and recent stores. Header, MenuBar, StoreCard and Modal receive this state through props and callbacks. The flow is visible in one place, but async behavior and regression scope grow with that central component.
3. Discovery data path
STATIC_STORE_DATA in constants.tsx is the source catalog. An effect applies category and text filters; nearby mode also calculates Haversine distance and sorts the derived filteredStores. Discovery stays deterministic offline, while benefit changes require a new static build.
4. Personalization and AI path
Favorites, recent stores and receipt history use three localStorage keys. Recommendations send preference text and catalog context to Gemini, then map returned IDs back to known stores. Receipt input uses FileReader for preview and sends image bytes with a MIME type to obtain a structured analysis result.
5. Trust, failure and security boundaries
Denied geolocation becomes an error state or a Gangnam/Yongsan demo coordinate. Gemini output is expected as JSON, so malformed shapes and unknown IDs require filtering. Because VITE_API_KEY is injected into the client bundle, a production system needs a server proxy, secret management, request limits, input-size checks and an observable error contract.
6. Data and state ownership
constants.tsx owns the source catalog, App.tsx owns navigation and result state, and browser localStorage owns favorites, receipts and recent items. Cross-device consistency is missing because no server synchronization exists; retention and expiration also need explicit policy.
The broad state surface in one App component and full-catalog filtering increase render cost as data grows. Image lazy loading, memoized derived lists, cancellation and timeouts for Gemini are the next validation points; static catalog discovery remains available when the external API fails.
8. Observability, validation and debt
Toasts expose user-facing errors, but stage-level latency and failure telemetry are missing. Removing client secrets, defining receipt-data retention and splitting App state into domain hooks are the primary debts. Production outcomes have not been measured.