Files
retail/docs/DATABASE_SCHEMA.md
Phuoc Nguyen b94c158004 runable
2025-10-10 16:38:07 +07:00

18 KiB

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

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

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

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 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

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

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final database = HiveDatabase.instance;
  final initializer = DatabaseInitializer(database);

  await initializer.initialize(seedIfEmpty: true);

  runApp(MyApp());
}

Query Products

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

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

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

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:

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:

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:

await HiveDatabase.instance.compactAll();

Reset Database

Clear all data and reseed:

final initializer = DatabaseInitializer(HiveDatabase.instance);
await initializer.resetDatabase();

Clear Specific Data

// 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:

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