638 lines
18 KiB
Markdown
638 lines
18 KiB
Markdown
# Hive CE Database Schema Documentation
|
|
|
|
## Overview
|
|
This document describes the complete Hive CE database schema for the Retail POS application. The database uses Hive CE (Community Edition) for offline-first local storage with type-safe adapters.
|
|
|
|
---
|
|
|
|
## Database Structure
|
|
|
|
### Hive Boxes
|
|
The application uses 5 main Hive boxes:
|
|
|
|
| Box Name | Type | Purpose |
|
|
|----------|------|---------|
|
|
| `products` | `Box<ProductModel>` | Store all product data |
|
|
| `categories` | `Box<CategoryModel>` | Store all category data |
|
|
| `cart` | `Box<CartItemModel>` | Store current cart items |
|
|
| `transactions` | `Box<TransactionModel>` | Store completed transactions |
|
|
| `settings` | `Box<AppSettingsModel>` | Store app settings |
|
|
|
|
### Type ID Assignments (0-223)
|
|
|
|
| Model | Type ID | Description |
|
|
|-------|---------|-------------|
|
|
| `ProductModel` | 0 | Product entity |
|
|
| `CategoryModel` | 1 | Category entity |
|
|
| `CartItemModel` | 2 | Shopping cart item |
|
|
| `TransactionModel` | 3 | Completed transaction |
|
|
| `AppSettingsModel` | 4 | Application settings |
|
|
|
|
---
|
|
|
|
## Model Schemas
|
|
|
|
### 1. ProductModel (typeId: 0)
|
|
|
|
**File**: `lib/features/products/data/models/product_model.dart`
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | HiveField | Description | Required |
|
|
|-------|------|-----------|-------------|----------|
|
|
| `id` | String | 0 | Unique product identifier (UUID) | Yes |
|
|
| `name` | String | 1 | Product name | Yes |
|
|
| `description` | String | 2 | Product description | Yes |
|
|
| `price` | double | 3 | Product price (USD) | Yes |
|
|
| `imageUrl` | String? | 4 | Product image URL | No |
|
|
| `categoryId` | String | 5 | Associated category ID | Yes |
|
|
| `stockQuantity` | int | 6 | Current stock quantity | Yes |
|
|
| `isAvailable` | bool | 7 | Availability status | Yes |
|
|
| `createdAt` | DateTime | 8 | Creation timestamp | Yes |
|
|
| `updatedAt` | DateTime | 9 | Last update timestamp | Yes |
|
|
|
|
#### Methods
|
|
- `copyWith()` - Create a copy with updated fields
|
|
- `toJson()` - Convert to JSON map
|
|
- `fromJson()` - Create from JSON map
|
|
- `toString()` - String representation
|
|
- Equality operators (==, hashCode)
|
|
|
|
#### Example
|
|
```dart
|
|
ProductModel(
|
|
id: 'prod_123',
|
|
name: 'Wireless Headphones',
|
|
description: 'Premium noise-cancelling wireless headphones',
|
|
price: 299.99,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
categoryId: 'cat_electronics',
|
|
stockQuantity: 25,
|
|
isAvailable: true,
|
|
createdAt: DateTime.now(),
|
|
updatedAt: DateTime.now(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 2. CategoryModel (typeId: 1)
|
|
|
|
**File**: `lib/features/categories/data/models/category_model.dart`
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | HiveField | Description | Required |
|
|
|-------|------|-----------|-------------|----------|
|
|
| `id` | String | 0 | Unique category identifier | Yes |
|
|
| `name` | String | 1 | Category name | Yes |
|
|
| `description` | String? | 2 | Category description | No |
|
|
| `iconPath` | String? | 3 | Icon path or Material icon name | No |
|
|
| `color` | String? | 4 | Hex color string (e.g., '#2196F3') | No |
|
|
| `productCount` | int | 5 | Number of products in category | Yes |
|
|
| `createdAt` | DateTime | 6 | Creation timestamp | Yes |
|
|
|
|
#### Methods
|
|
- `copyWith()` - Create a copy with updated fields
|
|
- `toJson()` - Convert to JSON map
|
|
- `fromJson()` - Create from JSON map
|
|
- `toString()` - String representation
|
|
- Equality operators (==, hashCode)
|
|
|
|
#### Example
|
|
```dart
|
|
CategoryModel(
|
|
id: 'cat_electronics',
|
|
name: 'Electronics',
|
|
description: 'Electronic devices and accessories',
|
|
iconPath: 'devices',
|
|
color: '#2196F3',
|
|
productCount: 15,
|
|
createdAt: DateTime.now(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 3. CartItemModel (typeId: 2)
|
|
|
|
**File**: `lib/features/home/data/models/cart_item_model.dart`
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | HiveField | Description | Required |
|
|
|-------|------|-----------|-------------|----------|
|
|
| `productId` | String | 0 | Product identifier | Yes |
|
|
| `productName` | String | 1 | Product name (cached) | Yes |
|
|
| `price` | double | 2 | Price at time of adding | Yes |
|
|
| `quantity` | int | 3 | Quantity of items | Yes |
|
|
| `imageUrl` | String? | 4 | Product image URL (cached) | No |
|
|
| `addedAt` | DateTime | 5 | Timestamp when added | Yes |
|
|
|
|
#### Computed Properties
|
|
- `lineTotal` - Calculated as `price * quantity`
|
|
|
|
#### Methods
|
|
- `copyWith()` - Create a copy with updated fields
|
|
- `toJson()` - Convert to JSON map
|
|
- `fromJson()` - Create from JSON map
|
|
- `toString()` - String representation
|
|
- Equality operators (==, hashCode)
|
|
|
|
#### Example
|
|
```dart
|
|
CartItemModel(
|
|
productId: 'prod_123',
|
|
productName: 'Wireless Headphones',
|
|
price: 299.99,
|
|
quantity: 2,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
addedAt: DateTime.now(),
|
|
)
|
|
// lineTotal = 599.98
|
|
```
|
|
|
|
---
|
|
|
|
### 4. TransactionModel (typeId: 3)
|
|
|
|
**File**: `lib/features/home/data/models/transaction_model.dart`
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | HiveField | Description | Required |
|
|
|-------|------|-----------|-------------|----------|
|
|
| `id` | String | 0 | Unique transaction identifier | Yes |
|
|
| `items` | List<CartItemModel> | 1 | List of cart items | Yes |
|
|
| `subtotal` | double | 2 | Subtotal (before tax/discount) | Yes |
|
|
| `tax` | double | 3 | Tax amount | Yes |
|
|
| `discount` | double | 4 | Discount amount | Yes |
|
|
| `total` | double | 5 | Total amount | Yes |
|
|
| `completedAt` | DateTime | 6 | Transaction completion time | Yes |
|
|
| `paymentMethod` | String | 7 | Payment method used | Yes |
|
|
|
|
#### Computed Properties
|
|
- `totalItems` - Total number of items in transaction
|
|
|
|
#### Methods
|
|
- `copyWith()` - Create a copy with updated fields
|
|
- `toJson()` - Convert to JSON map
|
|
- `fromJson()` - Create from JSON map
|
|
- `toString()` - String representation
|
|
- Equality operators (==, hashCode)
|
|
|
|
#### Example
|
|
```dart
|
|
TransactionModel(
|
|
id: 'txn_123',
|
|
items: [cartItem1, cartItem2],
|
|
subtotal: 599.98,
|
|
tax: 60.00,
|
|
discount: 0.00,
|
|
total: 659.98,
|
|
completedAt: DateTime.now(),
|
|
paymentMethod: 'cash',
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 5. AppSettingsModel (typeId: 4)
|
|
|
|
**File**: `lib/features/settings/data/models/app_settings_model.dart`
|
|
|
|
#### Fields
|
|
|
|
| Field | Type | HiveField | Description | Required |
|
|
|-------|------|-----------|-------------|----------|
|
|
| `themeModeString` | String | 0 | Theme mode ('light', 'dark', 'system') | Yes |
|
|
| `language` | String | 1 | Language code (e.g., 'en', 'es') | Yes |
|
|
| `currency` | String | 2 | Currency code (e.g., 'USD', 'EUR') | Yes |
|
|
| `taxRate` | double | 3 | Tax rate as decimal (e.g., 0.10 = 10%) | Yes |
|
|
| `storeName` | String | 4 | Store name | Yes |
|
|
| `enableSync` | bool | 5 | Enable automatic sync | Yes |
|
|
| `lastSyncAt` | DateTime? | 6 | Last sync timestamp | No |
|
|
|
|
#### Computed Properties
|
|
- `themeMode` - Returns `ThemeMode` enum from string
|
|
|
|
#### Factory Constructors
|
|
- `fromThemeMode()` - Create from ThemeMode enum
|
|
- `defaultSettings()` - Create with default values
|
|
|
|
#### Methods
|
|
- `copyWith()` - Create a copy with updated fields
|
|
- `toJson()` - Convert to JSON map
|
|
- `fromJson()` - Create from JSON map
|
|
- `toString()` - String representation
|
|
|
|
#### Example
|
|
```dart
|
|
AppSettingsModel(
|
|
themeModeString: 'system',
|
|
language: 'en',
|
|
currency: 'USD',
|
|
taxRate: 0.08,
|
|
storeName: 'My Retail Store',
|
|
enableSync: true,
|
|
lastSyncAt: DateTime.now(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Data Sources
|
|
|
|
### ProductLocalDataSource
|
|
**File**: `lib/features/products/data/datasources/product_local_datasource_hive.dart`
|
|
|
|
#### Methods
|
|
- `getAllProducts()` - Get all products
|
|
- `getProductById(id)` - Get product by ID
|
|
- `getProductsByCategory(categoryId)` - Get products by category
|
|
- `saveProducts(products)` - Bulk save products
|
|
- `saveProduct(product)` - Save single product
|
|
- `updateProduct(product)` - Update product
|
|
- `deleteProduct(id)` - Delete product
|
|
- `deleteAllProducts()` - Clear all products
|
|
- `productExists(id)` - Check if product exists
|
|
- `getAvailableProducts()` - Get available products only
|
|
- `getLowStockProducts(threshold)` - Get low stock products
|
|
- `searchProducts(query)` - Search products by name/description
|
|
|
|
### CategoryLocalDataSource
|
|
**File**: `lib/features/categories/data/datasources/category_local_datasource_hive.dart`
|
|
|
|
#### Methods
|
|
- `getAllCategories()` - Get all categories
|
|
- `getCategoryById(id)` - Get category by ID
|
|
- `saveCategories(categories)` - Bulk save categories
|
|
- `saveCategory(category)` - Save single category
|
|
- `updateCategory(category)` - Update category
|
|
- `deleteCategory(id)` - Delete category
|
|
- `deleteAllCategories()` - Clear all categories
|
|
- `categoryExists(id)` - Check if category exists
|
|
- `updateProductCount(categoryId, count)` - Update product count
|
|
|
|
### CartLocalDataSource
|
|
**File**: `lib/features/home/data/datasources/cart_local_datasource.dart`
|
|
|
|
#### Cart Methods
|
|
- `getCartItems()` - Get all cart items
|
|
- `getCartItem(productId)` - Get specific cart item
|
|
- `addToCart(item)` - Add item to cart
|
|
- `updateCartItem(item)` - Update cart item
|
|
- `removeFromCart(productId)` - Remove from cart
|
|
- `clearCart()` - Clear entire cart
|
|
- `isInCart(productId)` - Check if item is in cart
|
|
- `getCartTotal()` - Calculate cart total
|
|
- `getCartItemCount()` - Get total item count
|
|
|
|
#### Transaction Methods
|
|
- `saveTransaction(transaction)` - Save completed transaction
|
|
- `getAllTransactions()` - Get all transactions
|
|
- `getTransaction(id)` - Get transaction by ID
|
|
- `getTransactionsByDateRange(start, end)` - Get transactions by date
|
|
- `getTodayTransactions()` - Get today's transactions
|
|
- `getTotalSales(start, end)` - Calculate total sales
|
|
- `getTodaySales()` - Calculate today's sales
|
|
- `deleteTransaction(id)` - Delete transaction
|
|
- `clearAllTransactions()` - Clear all transactions
|
|
- `getTransactionCount()` - Get transaction count
|
|
|
|
### SettingsLocalDataSource
|
|
**File**: `lib/features/settings/data/datasources/settings_local_datasource_hive.dart`
|
|
|
|
#### Methods
|
|
- `getSettings()` - Get current settings
|
|
- `saveSettings(settings)` - Save settings
|
|
- `updateThemeMode(mode)` - Update theme mode
|
|
- `updateLanguage(language)` - Update language
|
|
- `updateLastSyncTime(time)` - Update last sync time
|
|
- `updateCurrency(currency)` - Update currency
|
|
- `updateTaxRate(taxRate)` - Update tax rate
|
|
- `updateStoreName(storeName)` - Update store name
|
|
- `toggleSync(enable)` - Toggle sync on/off
|
|
- `resetSettings()` - Reset to defaults
|
|
|
|
---
|
|
|
|
## Database Initialization
|
|
|
|
### HiveDatabase
|
|
**File**: `lib/core/database/hive_database.dart`
|
|
|
|
Singleton class managing all Hive boxes and operations.
|
|
|
|
#### Methods
|
|
- `init()` - Initialize Hive and open all boxes
|
|
- `getBox<T>(boxName)` - Get a specific box
|
|
- `clearAllData()` - Clear all data (except settings)
|
|
- `clearCart()` - Clear cart only
|
|
- `compactAll()` - Compact all boxes (optimize storage)
|
|
- `closeAll()` - Close all boxes
|
|
- `deleteAll()` - Delete all boxes (complete reset)
|
|
- `getStatistics()` - Get database statistics
|
|
- `isInitialized` - Check initialization status
|
|
|
|
#### Properties
|
|
- `productsBox` - Direct access to products box
|
|
- `categoriesBox` - Direct access to categories box
|
|
- `cartBox` - Direct access to cart box
|
|
- `transactionsBox` - Direct access to transactions box
|
|
- `settingsBox` - Direct access to settings box
|
|
|
|
### DatabaseInitializer
|
|
**File**: `lib/core/database/database_initializer.dart`
|
|
|
|
Handles database initialization and seeding.
|
|
|
|
#### Methods
|
|
- `initialize(seedIfEmpty)` - Initialize database and seed if empty
|
|
- `seedDatabase(forceReseed)` - Seed database with sample data
|
|
- `resetDatabase()` - Clear and reseed database
|
|
- `getDatabaseStats()` - Get database statistics
|
|
- `compactDatabase()` - Compact database
|
|
|
|
---
|
|
|
|
## Sample Data
|
|
|
|
### Generated Categories (5)
|
|
1. **Electronics** - Blue (#2196F3)
|
|
- Icon: `devices`
|
|
2. **Home Appliances** - Green (#4CAF50)
|
|
- Icon: `kitchen`
|
|
3. **Sports & Fitness** - Orange (#FF9800)
|
|
- Icon: `fitness_center`
|
|
4. **Fashion** - Pink (#E91E63)
|
|
- Icon: `checkroom`
|
|
5. **Books & Media** - Purple (#9C27B0)
|
|
- Icon: `book`
|
|
|
|
### Generated Products (10)
|
|
1. Wireless Headphones - $299.99 (Electronics)
|
|
2. Smart Watch - $199.99 (Electronics)
|
|
3. Laptop Stand - $39.99 (Electronics)
|
|
4. Coffee Maker - $79.99 (Appliances)
|
|
5. Blender - $59.99 (Appliances)
|
|
6. Yoga Mat - $29.99 (Sports)
|
|
7. Running Shoes - $89.99 (Sports)
|
|
8. Water Bottle - $24.99 (Sports)
|
|
9. Leather Backpack - $129.99 (Fashion)
|
|
10. Sunglasses - $49.99 (Fashion)
|
|
|
|
---
|
|
|
|
## Usage Examples
|
|
|
|
### Initialize Database
|
|
```dart
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
final database = HiveDatabase.instance;
|
|
final initializer = DatabaseInitializer(database);
|
|
|
|
await initializer.initialize(seedIfEmpty: true);
|
|
|
|
runApp(MyApp());
|
|
}
|
|
```
|
|
|
|
### Query Products
|
|
```dart
|
|
final dataSource = ProductLocalDataSourceHive(HiveDatabase.instance);
|
|
|
|
// Get all products
|
|
final products = await dataSource.getAllProducts();
|
|
|
|
// Get by category
|
|
final electronics = await dataSource.getProductsByCategory('cat_electronics');
|
|
|
|
// Search products
|
|
final results = await dataSource.searchProducts('headphones');
|
|
|
|
// Get low stock
|
|
final lowStock = await dataSource.getLowStockProducts(10);
|
|
```
|
|
|
|
### Manage Cart
|
|
```dart
|
|
final dataSource = CartLocalDataSource(HiveDatabase.instance);
|
|
|
|
// Add to cart
|
|
await dataSource.addToCart(CartItemModel(
|
|
productId: 'prod_123',
|
|
productName: 'Wireless Headphones',
|
|
price: 299.99,
|
|
quantity: 1,
|
|
addedAt: DateTime.now(),
|
|
));
|
|
|
|
// Get cart total
|
|
final total = await dataSource.getCartTotal();
|
|
|
|
// Clear cart
|
|
await dataSource.clearCart();
|
|
```
|
|
|
|
### Save Transaction
|
|
```dart
|
|
final dataSource = CartLocalDataSource(HiveDatabase.instance);
|
|
|
|
await dataSource.saveTransaction(TransactionModel(
|
|
id: Uuid().v4(),
|
|
items: cartItems,
|
|
subtotal: 599.98,
|
|
tax: 48.00,
|
|
discount: 0.0,
|
|
total: 647.98,
|
|
completedAt: DateTime.now(),
|
|
paymentMethod: 'cash',
|
|
));
|
|
```
|
|
|
|
### Update Settings
|
|
```dart
|
|
final dataSource = SettingsLocalDataSourceHive(HiveDatabase.instance);
|
|
|
|
// Update theme
|
|
await dataSource.updateThemeMode(ThemeMode.dark);
|
|
|
|
// Update tax rate
|
|
await dataSource.updateTaxRate(0.10); // 10%
|
|
|
|
// Get settings
|
|
final settings = await dataSource.getSettings();
|
|
```
|
|
|
|
---
|
|
|
|
## Code Generation
|
|
|
|
To generate Hive type adapters after modifying models:
|
|
|
|
```bash
|
|
flutter pub run build_runner build --delete-conflicting-outputs
|
|
```
|
|
|
|
---
|
|
|
|
## File Locations
|
|
|
|
```
|
|
lib/
|
|
core/
|
|
constants/
|
|
storage_constants.dart # Box names and type IDs
|
|
database/
|
|
hive_database.dart # Main database class
|
|
database_initializer.dart # Initialization logic
|
|
seed_data.dart # Sample data generator
|
|
|
|
features/
|
|
products/data/
|
|
models/product_model.dart # Product model + adapter
|
|
datasources/
|
|
product_local_datasource.dart # Interface
|
|
product_local_datasource_hive.dart # Hive implementation
|
|
|
|
categories/data/
|
|
models/category_model.dart # Category model + adapter
|
|
datasources/
|
|
category_local_datasource.dart # Interface
|
|
category_local_datasource_hive.dart # Hive implementation
|
|
|
|
home/data/
|
|
models/
|
|
cart_item_model.dart # Cart item model + adapter
|
|
transaction_model.dart # Transaction model + adapter
|
|
datasources/
|
|
cart_local_datasource.dart # Cart & transaction operations
|
|
|
|
settings/data/
|
|
models/app_settings_model.dart # Settings model + adapter
|
|
datasources/
|
|
settings_local_datasource.dart # Interface
|
|
settings_local_datasource_hive.dart # Hive implementation
|
|
```
|
|
|
|
---
|
|
|
|
## Database Statistics
|
|
|
|
Use `getDatabaseStats()` to monitor database usage:
|
|
|
|
```dart
|
|
final stats = HiveDatabase.instance.getStatistics();
|
|
print(stats);
|
|
|
|
// Output:
|
|
// {
|
|
// 'products': 10,
|
|
// 'categories': 5,
|
|
// 'cartItems': 0,
|
|
// 'transactions': 0,
|
|
// 'isInitialized': true
|
|
// }
|
|
```
|
|
|
|
---
|
|
|
|
## Maintenance
|
|
|
|
### Compact Database
|
|
Optimize storage and improve performance:
|
|
```dart
|
|
await HiveDatabase.instance.compactAll();
|
|
```
|
|
|
|
### Reset Database
|
|
Clear all data and reseed:
|
|
```dart
|
|
final initializer = DatabaseInitializer(HiveDatabase.instance);
|
|
await initializer.resetDatabase();
|
|
```
|
|
|
|
### Clear Specific Data
|
|
```dart
|
|
// Clear cart only
|
|
await HiveDatabase.instance.clearCart();
|
|
|
|
// Clear all data except settings
|
|
await HiveDatabase.instance.clearAllData();
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
1. **Type Safety**: Always use type-safe boxes (`Box<T>`)
|
|
2. **Key Strategy**: Use string IDs as keys for easy lookup
|
|
3. **Bulk Operations**: Use `putAll()` for multiple items
|
|
4. **Error Handling**: Wrap all operations in try-catch blocks
|
|
5. **Compaction**: Regularly compact boxes in production
|
|
6. **Backups**: Implement backup strategy for transactions
|
|
7. **Migration**: Plan for schema migrations as app evolves
|
|
8. **Testing**: Test all database operations thoroughly
|
|
|
|
---
|
|
|
|
## Performance Considerations
|
|
|
|
- **Products Box**: ~10-1000 items expected
|
|
- **Categories Box**: ~5-50 items expected
|
|
- **Cart Box**: ~0-20 items expected
|
|
- **Transactions Box**: Growing over time (consider archiving)
|
|
- **Settings Box**: Single item only
|
|
|
|
### Optimization Tips
|
|
- Use lazy boxes for large datasets
|
|
- Implement pagination for transaction history
|
|
- Clear old transactions periodically
|
|
- Cache frequently accessed queries
|
|
- Use RepaintBoundary for grid items
|
|
|
|
---
|
|
|
|
## Security Notes
|
|
|
|
- Sensitive data (prices, transactions) stored unencrypted
|
|
- Consider using `HiveAesCipher` for encryption if needed
|
|
- Validate all data before storage
|
|
- Implement proper access controls in production
|
|
- Never expose raw Hive boxes to UI layer
|
|
|
|
---
|
|
|
|
## Migration Strategy
|
|
|
|
When schema changes are needed:
|
|
|
|
1. Increment type IDs or use versioning
|
|
2. Create migration scripts
|
|
3. Test migration thoroughly
|
|
4. Backup data before migration
|
|
5. Provide rollback mechanism
|
|
|
|
Example migration:
|
|
```dart
|
|
Future<void> migrateToV2() async {
|
|
final versionBox = await Hive.openBox('version');
|
|
final currentVersion = versionBox.get('schema_version', defaultValue: 1);
|
|
|
|
if (currentVersion < 2) {
|
|
// Perform migration
|
|
// Update schema version
|
|
await versionBox.put('schema_version', 2);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
**Last Updated**: 2025-10-10
|
|
**Schema Version**: 1.0.0
|
|
**Hive CE Version**: 2.6.0
|