Refactors calendar project structure and build configuration
Consolidates V2 codebase into main project directory Updates build script to support simplified entry points Removes redundant files and cleans up project organization Simplifies module imports and entry points for calendar application
This commit is contained in:
parent
9f360237cf
commit
863b433eba
200 changed files with 2331 additions and 16193 deletions
|
|
@ -1,103 +1,73 @@
|
|||
import { IApiRepository } from '../repositories/IApiRepository';
|
||||
import { IEntityService } from '../storage/IEntityService';
|
||||
|
||||
/**
|
||||
* DataSeeder - Orchestrates initial data loading from repositories into IndexedDB
|
||||
*
|
||||
* ARCHITECTURE:
|
||||
* - Repository (Mock/Api): Fetches data from source (JSON file or backend API)
|
||||
* - DataSeeder (this class): Orchestrates fetch + save operations
|
||||
* - Service (EventService, etc.): Saves data to IndexedDB
|
||||
*
|
||||
* SEPARATION OF CONCERNS:
|
||||
* - Repository does NOT know about IndexedDB or storage
|
||||
* - Service does NOT know about where data comes from
|
||||
* - DataSeeder connects them together
|
||||
*
|
||||
* POLYMORPHIC DESIGN:
|
||||
* - Uses arrays of IEntityService<any>[] and IApiRepository<any>[]
|
||||
* - Matches services with repositories using entityType property
|
||||
* - Open/Closed Principle: Adding new entity requires no code changes here
|
||||
*
|
||||
* USAGE:
|
||||
* Called once during app initialization in index.ts:
|
||||
* 1. IndexedDBService.initialize() - open database
|
||||
* 2. dataSeeder.seedIfEmpty() - load initial data if needed
|
||||
* 3. CalendarManager.initialize() - start calendar
|
||||
*
|
||||
* NOTE: This is for INITIAL SEEDING only. Ongoing sync is handled by SyncManager.
|
||||
*/
|
||||
export class DataSeeder {
|
||||
constructor(
|
||||
// Arrays injected via DI - automatically includes all registered services/repositories
|
||||
private services: IEntityService<any>[],
|
||||
private repositories: IApiRepository<any>[]
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Seed all entity stores if they are empty
|
||||
* Runs on app initialization to load initial data from repositories
|
||||
*
|
||||
* Uses polymorphism: loops through all services and matches with repositories by entityType
|
||||
*/
|
||||
async seedIfEmpty(): Promise<void> {
|
||||
console.log('[DataSeeder] Checking if database needs seeding...');
|
||||
|
||||
try {
|
||||
// Loop through all entity services (Event, Booking, Customer, Resource, etc.)
|
||||
for (const service of this.services) {
|
||||
// Find matching repository for this service based on entityType
|
||||
const repository = this.repositories.find(repo => repo.entityType === service.entityType);
|
||||
|
||||
if (!repository) {
|
||||
console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Seed this entity type
|
||||
await this.seedEntity(service.entityType, service, repository);
|
||||
}
|
||||
|
||||
console.log('[DataSeeder] Seeding complete');
|
||||
} catch (error) {
|
||||
console.error('[DataSeeder] Seeding failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to seed a single entity type
|
||||
*
|
||||
* @param entityType - Entity type ('Event', 'Booking', 'Customer', 'Resource')
|
||||
* @param service - Entity service for IndexedDB operations
|
||||
* @param repository - Repository for fetching data
|
||||
*/
|
||||
private async seedEntity<T>(
|
||||
entityType: string,
|
||||
service: IEntityService<any>,
|
||||
repository: IApiRepository<T>
|
||||
): Promise<void> {
|
||||
// Check if store is empty
|
||||
const existing = await service.getAll();
|
||||
|
||||
if (existing.length > 0) {
|
||||
console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`);
|
||||
|
||||
// Fetch from repository (Mock JSON or backend API)
|
||||
const data = await repository.fetchAll();
|
||||
|
||||
console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`);
|
||||
|
||||
// Save each entity to IndexedDB
|
||||
// Note: Entities from repository should already have syncStatus='synced'
|
||||
for (const entity of data) {
|
||||
await service.save(entity);
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`);
|
||||
}
|
||||
}
|
||||
import { IApiRepository } from '../repositories/IApiRepository';
|
||||
import { IEntityService } from '../storage/IEntityService';
|
||||
import { ISync } from '../types/CalendarTypes';
|
||||
|
||||
/**
|
||||
* DataSeeder - Orchestrates initial data loading from repositories into IndexedDB
|
||||
*
|
||||
* ARCHITECTURE:
|
||||
* - Repository (Mock/Api): Fetches data from source (JSON file or backend API)
|
||||
* - DataSeeder (this class): Orchestrates fetch + save operations
|
||||
* - Service (EventService, etc.): Saves data to IndexedDB
|
||||
*
|
||||
* POLYMORPHIC DESIGN:
|
||||
* - Uses arrays of IEntityService[] and IApiRepository[]
|
||||
* - Matches services with repositories using entityType property
|
||||
* - Open/Closed Principle: Adding new entity requires no code changes here
|
||||
*/
|
||||
export class DataSeeder {
|
||||
constructor(
|
||||
private services: IEntityService<ISync>[],
|
||||
private repositories: IApiRepository<ISync>[]
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Seed all entity stores if they are empty
|
||||
*/
|
||||
async seedIfEmpty(): Promise<void> {
|
||||
console.log('[DataSeeder] Checking if database needs seeding...');
|
||||
|
||||
try {
|
||||
for (const service of this.services) {
|
||||
const repository = this.repositories.find(repo => repo.entityType === service.entityType);
|
||||
|
||||
if (!repository) {
|
||||
console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.seedEntity(service.entityType, service, repository);
|
||||
}
|
||||
|
||||
console.log('[DataSeeder] Seeding complete');
|
||||
} catch (error) {
|
||||
console.error('[DataSeeder] Seeding failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async seedEntity<T extends ISync>(
|
||||
entityType: string,
|
||||
service: IEntityService<T>,
|
||||
repository: IApiRepository<T>
|
||||
): Promise<void> {
|
||||
const existing = await service.getAll();
|
||||
|
||||
if (existing.length > 0) {
|
||||
console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`);
|
||||
|
||||
const data = await repository.fetchAll();
|
||||
|
||||
console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`);
|
||||
|
||||
for (const entity of data) {
|
||||
await service.save(entity, true); // silent = true to skip audit logging
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue