This project now uses Dexie.js for IndexedDB management, providing a much cleaner and more powerful API for database operations.
The app automatically migrates data from:
- Old manual IndexedDB implementation
- localStorage storage
Migration happens automatically on app startup and is logged to the console.
interface ScoutingEntryDB {
id: string; // Unique entry ID
teamNumber?: string; // Extracted for indexing
matchNumber?: string; // Extracted for indexing
alliance?: string; // Extracted for indexing
scoutName?: string; // Extracted for indexing
eventName?: string; // Extracted for indexing
data: Record<string, unknown>; // Full scouting data object
timestamp: number; // Entry creation time
}- Version 1: Basic indexes for teamNumber, matchNumber, alliance, scoutName, timestamp
- Version 2: Added eventName index
import {
saveScoutingEntry,
saveScoutingEntries,
loadAllScoutingEntries,
deleteScoutingEntry,
clearAllScoutingData
} from './lib/dexieDB';
// Save single entry
await saveScoutingEntry(entryWithId);
// Save multiple entries
await saveScoutingEntries(entriesArray);
// Load all entries
const entries = await loadAllScoutingEntries();
// Delete entry
await deleteScoutingEntry(entryId);
// Clear all data
await clearAllScoutingData();import {
loadScoutingEntriesByTeam,
loadScoutingEntriesByMatch,
loadScoutingEntriesByEvent,
queryScoutingEntries
} from './lib/dexieDB';
// Load by team
const teamEntries = await loadScoutingEntriesByTeam('1234');
// Load by match
const matchEntries = await loadScoutingEntriesByMatch('42');
// Load by event
const eventEntries = await loadScoutingEntriesByEvent('2025mrcmp');
// Advanced filtering
const filteredEntries = await queryScoutingEntries({
teamNumbers: ['1234', '5678'],
eventNames: ['2025mrcmp'],
alliances: ['red'],
dateRange: { start: startTimestamp, end: endTimestamp }
});import { getDBStats, getFilterOptions } from './lib/dexieDB';
// Get database statistics
const stats = await getDBStats();
// Returns: { totalEntries, teams, matches, scouts, events, oldestEntry, newestEntry }
// Get filter options for UI
const options = await getFilterOptions();
// Returns: { teams, matches, events, alliances, scouts }import { exportScoutingData, importScoutingData } from './lib/dexieDB';
// Export all data
const exportData = await exportScoutingData();
// Import data (append or overwrite)
const result = await importScoutingData(importData, 'append');- Cleaner API: Much simpler than raw IndexedDB
- Better TypeScript Support: Full type safety
- Automatic Schema Management: Version upgrades handled automatically
- Powerful Querying: Complex filters and compound indexes
- Better Error Handling: Promises-based with clear error messages
- Performance: Optimized queries and bulk operations
- Future-Proof: Easy to add new features and indexes
- Runs on app startup
- Checks for existing data in old storage systems
- Migrates to Dexie if needed
- Keeps backups of original data
- Logs migration progress
import migrationUtils from './lib/migrationUtils';
// Check if migration is needed
const status = await migrationUtils.checkMigrationNeeded();
// Perform migration
const result = await migrationUtils.performMigration();
// Clean up old data (optional)
const cleanup = await migrationUtils.cleanupOldData();The new implementation maintains backward compatibility:
- Existing components continue to work unchanged
loadLegacyScoutingData()still returns the expected format- Data transformation functions remain the same
- All existing APIs are preserved
To add new indexes, increment the database version in dexieDB.ts:
this.version(3).stores({
scoutingData: 'id, teamNumber, matchNumber, alliance, scoutName, eventName, newField, timestamp'
});Use Dexie's powerful query API for complex operations:
// Example: Find all entries for a team in the last 30 days
const recentEntries = await db.scoutingData
.where('[teamNumber+timestamp]')
.between(['1234', Date.now() - 30 * 24 * 60 * 60 * 1000], ['1234', Date.now()])
.toArray();src/lib/dexieDB.ts- New Dexie implementationsrc/lib/migrationUtils.ts- Migration utilitiessrc/lib/scoutingDataUtils.ts- Updated to use Dexiesrc/main.tsx- Added auto-migration on startup
- Test the migration with existing data
- Monitor console logs for migration status
- Gradually replace direct
indexedDBUtils.tsimports withdexieDB.ts - Eventually remove
indexedDBUtils.tsafter migration is complete