Data Persistence
The Pizza Chef Frontend uses localStorage for client-side data persistence, ensuring user data survives page refreshes and browser sessions. This document details the persistence strategy, localStorage keys, data structures, and synchronization mechanisms.Persistence Strategy
The application follows a synchronous persistence model:- Write-through: Data is persisted to localStorage immediately after Redux state updates
- Read-on-mount: localStorage is read during Redux slice initialization
- Graceful degradation: Falls back to default values if localStorage is unavailable
- Type safety: All persisted data is validated on read
Architecture Diagram
localStorage Keys
The application uses four primary localStorage keys:| Key | Purpose | Redux Slice | Data Type |
|---|---|---|---|
pizza_current_order | Active shopping cart | order.currentOrder | OrderItem[] |
pizza_orders | Completed order history | order.orderHistory | Order[] |
custom_pizzas | User-created pizzas | pizza.pizzas | Pizza[] |
pizza_filters | UI filter preferences | pizza.filters | PizzaFilters |
Data Structures
1. Current Order (pizza_current_order)
Type: OrderItem[]
Purpose: Persists the active shopping cart so users don’t lose their selections.
Structure:
2. Order History (pizza_orders)
Type: Order[]
Purpose: Stores completed orders for analytics and historical tracking.
Structure:
3. Custom Pizzas (custom_pizzas)
Type: Pizza[]
Purpose: Persists user-created pizzas separate from the default catalog.
Structure:
pizzas.json during initialization.
4. Filters (pizza_filters)
Type: PizzaFilters
Purpose: Remembers user’s filter preferences (search, category, price, sort).
Structure:
maxPrice is reset to at least 50 to ensure newly added pizzas aren’t accidentally filtered out.
Synchronization Mechanisms
Immediate Persistence Pattern
Every Redux action that modifies persisted state writes to localStorage synchronously:- No data loss on page refresh
- No need for separate persistence middleware
- Simple and predictable
- Synchronous I/O (minimal performance impact for small data)
- localStorage size limits (5-10MB per domain)
Initialization Pattern
Each slice loads persisted data during initialization:Error Handling
All localStorage operations are wrapped in error handling:Data Migration Strategy
When data structures change, implement migration logic:Storage Size Management
Current Storage Usage
Typical storage usage by key:pizza_current_order: ~2-5 KB (depends on cart size)pizza_orders: ~10-50 KB (grows with order history)custom_pizzas: ~5-20 KB (grows with custom pizzas)pizza_filters: ~100-200 bytes
Monitoring Storage
Quota Management
Handle quota exceeded errors:Privacy & Security
Data Stored Locally
All data is stored in the user’s browser:- No server synchronization: Data never leaves the device
- Domain-specific: Only accessible by the app’s origin
- Unencrypted: localStorage stores plain text
Best Practices
- No sensitive data: Never store passwords, credit cards, or PII
- User control: Provide UI to clear all data
- Privacy mode: Handle private browsing (localStorage may be disabled)
Clear All Data
Testing Persistence
Unit Tests
Integration Tests
Performance Considerations
Optimization Strategies
- Batch updates: For multiple changes, update state first, then persist once
- Debounce writes: For high-frequency updates (e.g., search input)
- Selective persistence: Only persist changed portions of state
Debounced Persistence Example
Browser Compatibility
The application assumes modern browser support:- localStorage: Supported in all modern browsers (IE 8+)
- JSON.parse/stringify: Native support
- crypto.randomUUID(): Modern browsers (polyfill for older browsers)
Polyfill for Private Browsing
Next Steps
- State Management - Redux implementation details
- Architecture Overview - Complete system architecture