Refactor entity services with hybrid sync pattern

Introduces BaseEntityService and SyncPlugin to eliminate code duplication across entity services

Improves:
- Code reusability through inheritance and composition
- Sync infrastructure for all entity types
- Polymorphic sync status management
- Reduced boilerplate code by ~75%

Supports generic sync for Event, Booking, Customer, and Resource entities
This commit is contained in:
Janus C. H. Knudsen 2025-11-18 16:37:33 +01:00
parent 2aa9d06fab
commit 8e52d670d6
30 changed files with 1960 additions and 526 deletions

View file

@ -26,7 +26,11 @@ import { WorkweekPresets } from './components/WorkweekPresets';
import { IEventRepository } from './repositories/IEventRepository';
import { MockEventRepository } from './repositories/MockEventRepository';
import { IndexedDBEventRepository } from './repositories/IndexedDBEventRepository';
import { IApiRepository } from './repositories/IApiRepository';
import { ApiEventRepository } from './repositories/ApiEventRepository';
import { ApiBookingRepository } from './repositories/ApiBookingRepository';
import { ApiCustomerRepository } from './repositories/ApiCustomerRepository';
import { ApiResourceRepository } from './repositories/ApiResourceRepository';
import { IndexedDBService } from './storage/IndexedDBService';
import { OperationQueue } from './storage/OperationQueue';
import { IStore } from './storage/IStore';
@ -34,6 +38,11 @@ import { BookingStore } from './storage/bookings/BookingStore';
import { CustomerStore } from './storage/customers/CustomerStore';
import { ResourceStore } from './storage/resources/ResourceStore';
import { EventStore } from './storage/events/EventStore';
import { IEntityService } from './storage/IEntityService';
import { EventService } from './storage/events/EventService';
import { BookingService } from './storage/bookings/BookingService';
import { CustomerService } from './storage/customers/CustomerService';
import { ResourceService } from './storage/resources/ResourceService';
// Import workers
import { SyncManager } from './workers/SyncManager';
@ -113,7 +122,30 @@ async function initializeCalendar(): Promise<void> {
// Register storage and repository services
builder.registerType(IndexedDBService).as<IndexedDBService>();
builder.registerType(OperationQueue).as<OperationQueue>();
builder.registerType(ApiEventRepository).as<ApiEventRepository>();
// Register API repositories (backend sync)
// Each entity type has its own API repository implementing IApiRepository<T>
builder.registerType(ApiEventRepository).as<IApiRepository<any>>();
builder.registerType(ApiBookingRepository).as<IApiRepository<any>>();
builder.registerType(ApiCustomerRepository).as<IApiRepository<any>>();
builder.registerType(ApiResourceRepository).as<IApiRepository<any>>();
// Resolve all API repositories and register as array for SyncManager
const apiRepositories = container.resolveTypeAll<IApiRepository<any>>();
builder.registerInstance(apiRepositories).as<IApiRepository<any>[]>();
// Register entity services (sync status management)
// Open/Closed Principle: Adding new entity only requires adding one line here
builder.registerType(EventService).as<IEntityService<any>>();
builder.registerType(BookingService).as<IEntityService<any>>();
builder.registerType(CustomerService).as<IEntityService<any>>();
builder.registerType(ResourceService).as<IEntityService<any>>();
// Resolve all IEntityService implementations and register as array for SyncManager
const entityServices = container.resolveTypeAll<IEntityService<any>>();
builder.registerInstance(entityServices).as<IEntityService<any>[]>();
// Register IndexedDB repositories (offline-first)
builder.registerType(IndexedDBEventRepository).as<IEventRepository>();
// Register workers