@xbg.solutions/backend-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core/src/app.d.ts +28 -0
- package/lib/core/src/app.d.ts.map +1 -0
- package/lib/core/src/app.js +188 -0
- package/lib/core/src/app.js.map +1 -0
- package/lib/core/src/base/BaseController.d.ts +108 -0
- package/lib/core/src/base/BaseController.d.ts.map +1 -0
- package/lib/core/src/base/BaseController.js +307 -0
- package/lib/core/src/base/BaseController.js.map +1 -0
- package/lib/core/src/base/BaseEntity.d.ts +92 -0
- package/lib/core/src/base/BaseEntity.d.ts.map +1 -0
- package/lib/core/src/base/BaseEntity.js +143 -0
- package/lib/core/src/base/BaseEntity.js.map +1 -0
- package/lib/core/src/base/BaseRepository.d.ts +124 -0
- package/lib/core/src/base/BaseRepository.d.ts.map +1 -0
- package/lib/core/src/base/BaseRepository.js +414 -0
- package/lib/core/src/base/BaseRepository.js.map +1 -0
- package/lib/core/src/base/BaseService.d.ts +89 -0
- package/lib/core/src/base/BaseService.d.ts.map +1 -0
- package/lib/core/src/base/BaseService.js +342 -0
- package/lib/core/src/base/BaseService.js.map +1 -0
- package/lib/core/src/base/index.d.ts +8 -0
- package/lib/core/src/base/index.d.ts.map +1 -0
- package/lib/core/src/base/index.js +24 -0
- package/lib/core/src/base/index.js.map +1 -0
- package/lib/core/src/config/app.config.d.ts +70 -0
- package/lib/core/src/config/app.config.d.ts.map +1 -0
- package/lib/core/src/config/app.config.js +106 -0
- package/lib/core/src/config/app.config.js.map +1 -0
- package/lib/core/src/config/auth.config.d.ts +54 -0
- package/lib/core/src/config/auth.config.d.ts.map +1 -0
- package/lib/core/src/config/auth.config.js +88 -0
- package/lib/core/src/config/auth.config.js.map +1 -0
- package/lib/core/src/config/cache.config.d.ts +47 -0
- package/lib/core/src/config/cache.config.d.ts.map +1 -0
- package/lib/core/src/config/cache.config.js +225 -0
- package/lib/core/src/config/cache.config.js.map +1 -0
- package/lib/core/src/config/communications.config.d.ts +175 -0
- package/lib/core/src/config/communications.config.d.ts.map +1 -0
- package/lib/core/src/config/communications.config.js +219 -0
- package/lib/core/src/config/communications.config.js.map +1 -0
- package/lib/core/src/config/database.config.d.ts +68 -0
- package/lib/core/src/config/database.config.d.ts.map +1 -0
- package/lib/core/src/config/database.config.js +95 -0
- package/lib/core/src/config/database.config.js.map +1 -0
- package/lib/core/src/config/firebase-event-mapping.config.d.ts +41 -0
- package/lib/core/src/config/firebase-event-mapping.config.d.ts.map +1 -0
- package/lib/core/src/config/firebase-event-mapping.config.js +180 -0
- package/lib/core/src/config/firebase-event-mapping.config.js.map +1 -0
- package/lib/core/src/config/firestore.config.d.ts +61 -0
- package/lib/core/src/config/firestore.config.d.ts.map +1 -0
- package/lib/core/src/config/firestore.config.js +74 -0
- package/lib/core/src/config/firestore.config.js.map +1 -0
- package/lib/core/src/config/index.d.ts +15 -0
- package/lib/core/src/config/index.d.ts.map +1 -0
- package/lib/core/src/config/index.js +41 -0
- package/lib/core/src/config/index.js.map +1 -0
- package/lib/core/src/config/maps.config.d.ts +31 -0
- package/lib/core/src/config/maps.config.d.ts.map +1 -0
- package/lib/core/src/config/maps.config.js +50 -0
- package/lib/core/src/config/maps.config.js.map +1 -0
- package/lib/core/src/config/middleware.config.d.ts +57 -0
- package/lib/core/src/config/middleware.config.d.ts.map +1 -0
- package/lib/core/src/config/middleware.config.js +68 -0
- package/lib/core/src/config/middleware.config.js.map +1 -0
- package/lib/core/src/config/tokens.config.d.ts +53 -0
- package/lib/core/src/config/tokens.config.d.ts.map +1 -0
- package/lib/core/src/config/tokens.config.js +129 -0
- package/lib/core/src/config/tokens.config.js.map +1 -0
- package/lib/core/src/generator/generator.d.ts +38 -0
- package/lib/core/src/generator/generator.d.ts.map +1 -0
- package/lib/core/src/generator/generator.js +159 -0
- package/lib/core/src/generator/generator.js.map +1 -0
- package/lib/core/src/generator/index.d.ts +7 -0
- package/lib/core/src/generator/index.d.ts.map +1 -0
- package/lib/core/src/generator/index.js +23 -0
- package/lib/core/src/generator/index.js.map +1 -0
- package/lib/core/src/generator/parser.d.ts +10 -0
- package/lib/core/src/generator/parser.d.ts.map +1 -0
- package/lib/core/src/generator/parser.js +197 -0
- package/lib/core/src/generator/parser.js.map +1 -0
- package/lib/core/src/generator/types.d.ts +112 -0
- package/lib/core/src/generator/types.d.ts.map +1 -0
- package/lib/core/src/generator/types.js +7 -0
- package/lib/core/src/generator/types.js.map +1 -0
- package/lib/core/src/index.d.ts +19 -0
- package/lib/core/src/index.d.ts.map +1 -0
- package/lib/core/src/index.js +46 -0
- package/lib/core/src/index.js.map +1 -0
- package/lib/core/src/middleware/auth.middleware.d.ts +57 -0
- package/lib/core/src/middleware/auth.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/auth.middleware.js +256 -0
- package/lib/core/src/middleware/auth.middleware.js.map +1 -0
- package/lib/core/src/middleware/cors.middleware.d.ts +13 -0
- package/lib/core/src/middleware/cors.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/cors.middleware.js +50 -0
- package/lib/core/src/middleware/cors.middleware.js.map +1 -0
- package/lib/core/src/middleware/error.middleware.d.ts +46 -0
- package/lib/core/src/middleware/error.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/error.middleware.js +174 -0
- package/lib/core/src/middleware/error.middleware.js.map +1 -0
- package/lib/core/src/middleware/index.d.ts +11 -0
- package/lib/core/src/middleware/index.d.ts.map +1 -0
- package/lib/core/src/middleware/index.js +27 -0
- package/lib/core/src/middleware/index.js.map +1 -0
- package/lib/core/src/middleware/logging.middleware.d.ts +10 -0
- package/lib/core/src/middleware/logging.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/logging.middleware.js +87 -0
- package/lib/core/src/middleware/logging.middleware.js.map +1 -0
- package/lib/core/src/middleware/rateLimit.middleware.d.ts +26 -0
- package/lib/core/src/middleware/rateLimit.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/rateLimit.middleware.js +105 -0
- package/lib/core/src/middleware/rateLimit.middleware.js.map +1 -0
- package/lib/core/src/middleware/requestId.middleware.d.ts +11 -0
- package/lib/core/src/middleware/requestId.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/requestId.middleware.js +26 -0
- package/lib/core/src/middleware/requestId.middleware.js.map +1 -0
- package/lib/core/src/middleware/validation.middleware.d.ts +25 -0
- package/lib/core/src/middleware/validation.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/validation.middleware.js +133 -0
- package/lib/core/src/middleware/validation.middleware.js.map +1 -0
- package/lib/core/src/types/errors.d.ts +119 -0
- package/lib/core/src/types/errors.d.ts.map +1 -0
- package/lib/core/src/types/errors.js +210 -0
- package/lib/core/src/types/errors.js.map +1 -0
- package/lib/utils-cache-connector/src/cache-connector.d.ts +139 -0
- package/lib/utils-cache-connector/src/cache-connector.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/cache-connector.js +277 -0
- package/lib/utils-cache-connector/src/cache-connector.js.map +1 -0
- package/lib/utils-cache-connector/src/index.d.ts +52 -0
- package/lib/utils-cache-connector/src/index.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/index.js +103 -0
- package/lib/utils-cache-connector/src/index.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.d.ts +95 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.js +120 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.d.ts +58 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.js +418 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.d.ts +57 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.js +217 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.d.ts +21 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.js +42 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.d.ts +64 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.js +414 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/types.d.ts +342 -0
- package/lib/utils-cache-connector/src/types.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/types.js +8 -0
- package/lib/utils-cache-connector/src/types.js.map +1 -0
- package/lib/utils-events/src/event-bus.d.ts +42 -0
- package/lib/utils-events/src/event-bus.d.ts.map +1 -0
- package/lib/utils-events/src/event-bus.js +93 -0
- package/lib/utils-events/src/event-bus.js.map +1 -0
- package/lib/utils-events/src/event-types.d.ts +146 -0
- package/lib/utils-events/src/event-types.d.ts.map +1 -0
- package/lib/utils-events/src/event-types.js +49 -0
- package/lib/utils-events/src/event-types.js.map +1 -0
- package/lib/utils-events/src/index.d.ts +7 -0
- package/lib/utils-events/src/index.d.ts.map +1 -0
- package/lib/utils-events/src/index.js +11 -0
- package/lib/utils-events/src/index.js.map +1 -0
- package/lib/utils-logger/src/index.d.ts +12 -0
- package/lib/utils-logger/src/index.d.ts.map +1 -0
- package/lib/utils-logger/src/index.js +29 -0
- package/lib/utils-logger/src/index.js.map +1 -0
- package/lib/utils-logger/src/logger-types.d.ts +32 -0
- package/lib/utils-logger/src/logger-types.d.ts.map +1 -0
- package/lib/utils-logger/src/logger-types.js +17 -0
- package/lib/utils-logger/src/logger-types.js.map +1 -0
- package/lib/utils-logger/src/logger.d.ts +42 -0
- package/lib/utils-logger/src/logger.d.ts.map +1 -0
- package/lib/utils-logger/src/logger.js +123 -0
- package/lib/utils-logger/src/logger.js.map +1 -0
- package/package.json +49 -0
- package/src/templates/controller.hbs +48 -0
- package/src/templates/entity.hbs +80 -0
- package/src/templates/repository.hbs +56 -0
- package/src/templates/service.hbs +108 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Base Repository Class
|
|
4
|
+
* Provides common CRUD operations with Firestore
|
|
5
|
+
* All repositories should extend this class
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.BaseRepository = void 0;
|
|
9
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
10
|
+
const utils_logger_1 = require("@xbg/utils-logger");
|
|
11
|
+
const errors_1 = require("../types/errors");
|
|
12
|
+
const utils_cache_connector_1 = require("@xbg/utils-cache-connector");
|
|
13
|
+
const cache_config_1 = require("../config/cache.config");
|
|
14
|
+
class BaseRepository {
|
|
15
|
+
constructor(db) {
|
|
16
|
+
/**
|
|
17
|
+
* Cache configuration for this repository
|
|
18
|
+
* Override in subclasses to enable caching
|
|
19
|
+
*/
|
|
20
|
+
this.cacheConfig = {
|
|
21
|
+
enabled: false, // Opt-in per repository
|
|
22
|
+
};
|
|
23
|
+
this.db = db;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get collection reference
|
|
27
|
+
*/
|
|
28
|
+
getCollection() {
|
|
29
|
+
return this.db.collection(this.collectionName);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if caching is enabled for this repository
|
|
33
|
+
* Respects both global and repository-level settings
|
|
34
|
+
*/
|
|
35
|
+
isCacheEnabled() {
|
|
36
|
+
// Global cache must be enabled
|
|
37
|
+
if (!cache_config_1.CACHE_CONFIG.enabled) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
// Repository must opt-in
|
|
41
|
+
return this.cacheConfig.enabled === true;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get effective cache provider for this repository
|
|
45
|
+
*/
|
|
46
|
+
getCacheProvider() {
|
|
47
|
+
return this.cacheConfig.provider || cache_config_1.CACHE_CONFIG.defaultProvider;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get effective TTL for this repository
|
|
51
|
+
*/
|
|
52
|
+
getCacheTTL(override) {
|
|
53
|
+
return override || this.cacheConfig.ttl || cache_config_1.CACHE_CONFIG.defaultTTL;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build cache key with repository prefix
|
|
57
|
+
*/
|
|
58
|
+
buildCacheKey(type, identifier) {
|
|
59
|
+
const prefix = this.cacheConfig.keyPrefix || this.collectionName;
|
|
60
|
+
return `${cache_config_1.CACHE_CONFIG.namespace}:${prefix}:${type}:${identifier}`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build cache tags for invalidation
|
|
64
|
+
*/
|
|
65
|
+
buildCacheTags(entity, additionalTags) {
|
|
66
|
+
const tags = [
|
|
67
|
+
this.collectionName,
|
|
68
|
+
`${this.collectionName}:${entity.id}`,
|
|
69
|
+
...(this.cacheConfig.tags || []),
|
|
70
|
+
...(additionalTags || []),
|
|
71
|
+
];
|
|
72
|
+
return tags;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Invalidate cache for a specific entity
|
|
76
|
+
* Called automatically on update/delete
|
|
77
|
+
*/
|
|
78
|
+
async invalidateEntityCache(id) {
|
|
79
|
+
if (!this.isCacheEnabled()) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const cache = (0, utils_cache_connector_1.getCacheConnector)();
|
|
83
|
+
const provider = this.getCacheProvider();
|
|
84
|
+
try {
|
|
85
|
+
// Invalidate by tags
|
|
86
|
+
await cache.invalidateByTags([this.collectionName, `${this.collectionName}:${id}`], { provider });
|
|
87
|
+
utils_logger_1.logger.debug('Cache invalidated for entity', {
|
|
88
|
+
operation: 'cache.invalidate',
|
|
89
|
+
collection: this.collectionName,
|
|
90
|
+
id,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Log error but don't fail the operation
|
|
95
|
+
utils_logger_1.logger.warn('Failed to invalidate cache', {
|
|
96
|
+
operation: 'cache.invalidate',
|
|
97
|
+
collection: this.collectionName,
|
|
98
|
+
id,
|
|
99
|
+
error: error,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Log cache hit
|
|
105
|
+
*/
|
|
106
|
+
logCacheHit(key) {
|
|
107
|
+
utils_logger_1.logger.debug('Cache hit', {
|
|
108
|
+
operation: 'cache.hit',
|
|
109
|
+
collection: this.collectionName,
|
|
110
|
+
key,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Log cache miss
|
|
115
|
+
*/
|
|
116
|
+
logCacheMiss(key) {
|
|
117
|
+
utils_logger_1.logger.debug('Cache miss', {
|
|
118
|
+
operation: 'cache.miss',
|
|
119
|
+
collection: this.collectionName,
|
|
120
|
+
key,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create a new entity
|
|
125
|
+
*/
|
|
126
|
+
async create(entity) {
|
|
127
|
+
try {
|
|
128
|
+
const validation = entity.validate();
|
|
129
|
+
if (!validation.valid) {
|
|
130
|
+
throw new Error(`Validation failed: ${JSON.stringify(validation.errors)}`);
|
|
131
|
+
}
|
|
132
|
+
const entityId = entity.getId();
|
|
133
|
+
const docRef = entityId ?
|
|
134
|
+
this.getCollection().doc(entityId) :
|
|
135
|
+
this.getCollection().doc();
|
|
136
|
+
entity.id = docRef.id;
|
|
137
|
+
await docRef.set(entity.toFirestore());
|
|
138
|
+
utils_logger_1.logger.info('Entity created', {
|
|
139
|
+
collection: this.collectionName,
|
|
140
|
+
id: entity.getId(),
|
|
141
|
+
});
|
|
142
|
+
return entity;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
146
|
+
utils_logger_1.logger.error('Failed to create entity', err, {
|
|
147
|
+
collection: this.collectionName,
|
|
148
|
+
});
|
|
149
|
+
const repoError = new errors_1.RepositoryError(`Failed to create entity: ${err.message}`, this.collectionName);
|
|
150
|
+
throw repoError;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Find entity by ID
|
|
155
|
+
*/
|
|
156
|
+
async findById(id, includeSoftDeleted = false) {
|
|
157
|
+
try {
|
|
158
|
+
const doc = await this.getCollection().doc(id).get();
|
|
159
|
+
if (!doc.exists) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const data = doc.data();
|
|
163
|
+
if (!data) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
// Check if soft deleted
|
|
167
|
+
if (!includeSoftDeleted && data.deletedAt) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return this.fromFirestore(doc.id, data);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
174
|
+
utils_logger_1.logger.error('Failed to find entity by ID', err, {
|
|
175
|
+
collection: this.collectionName,
|
|
176
|
+
id,
|
|
177
|
+
});
|
|
178
|
+
const repoError = new errors_1.RepositoryError(`Failed to find entity by ID: ${err.message}`, this.collectionName);
|
|
179
|
+
throw repoError;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Find entity by ID with caching
|
|
184
|
+
* Only uses cache if enabled at both global and repository levels
|
|
185
|
+
*/
|
|
186
|
+
async findByIdCached(id, options = {}) {
|
|
187
|
+
// If caching disabled, fallback to regular method
|
|
188
|
+
if (!this.isCacheEnabled()) {
|
|
189
|
+
return this.findById(id);
|
|
190
|
+
}
|
|
191
|
+
const cache = (0, utils_cache_connector_1.getCacheConnector)();
|
|
192
|
+
const cacheKey = this.buildCacheKey('id', id);
|
|
193
|
+
const provider = this.getCacheProvider();
|
|
194
|
+
try {
|
|
195
|
+
// Try cache first (unless force refresh)
|
|
196
|
+
if (!options.forceRefresh) {
|
|
197
|
+
const cached = await cache.get(cacheKey, { provider });
|
|
198
|
+
if (cached) {
|
|
199
|
+
this.logCacheHit(cacheKey);
|
|
200
|
+
return cached;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Cache miss - fetch from database
|
|
204
|
+
this.logCacheMiss(cacheKey);
|
|
205
|
+
const entity = await this.findById(id);
|
|
206
|
+
// Store in cache
|
|
207
|
+
if (entity) {
|
|
208
|
+
await cache.set(cacheKey, entity, {
|
|
209
|
+
ttl: this.getCacheTTL(options.ttl),
|
|
210
|
+
tags: this.buildCacheTags(entity, options.tags),
|
|
211
|
+
provider,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return entity;
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
218
|
+
utils_logger_1.logger.error('Failed to find entity by ID (cached)', err, {
|
|
219
|
+
collection: this.collectionName,
|
|
220
|
+
id,
|
|
221
|
+
});
|
|
222
|
+
const repoError = new errors_1.RepositoryError(`Failed to find entity by ID: ${err.message}`, this.collectionName);
|
|
223
|
+
throw repoError;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Find all entities with optional filtering
|
|
228
|
+
*/
|
|
229
|
+
async findAll(options = {}) {
|
|
230
|
+
try {
|
|
231
|
+
let query = this.getCollection();
|
|
232
|
+
// Apply soft delete filter
|
|
233
|
+
if (!options.includeSoftDeleted) {
|
|
234
|
+
query = query.where('deletedAt', '==', null);
|
|
235
|
+
}
|
|
236
|
+
// Apply where clauses
|
|
237
|
+
if (options.where) {
|
|
238
|
+
for (const clause of options.where) {
|
|
239
|
+
query = query.where(clause.field, clause.operator, clause.value);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Apply ordering
|
|
243
|
+
if (options.orderBy) {
|
|
244
|
+
for (const order of options.orderBy) {
|
|
245
|
+
query = query.orderBy(order.field, order.direction);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Apply pagination
|
|
249
|
+
if (options.offset) {
|
|
250
|
+
query = query.offset(options.offset);
|
|
251
|
+
}
|
|
252
|
+
if (options.limit) {
|
|
253
|
+
query = query.limit(options.limit);
|
|
254
|
+
}
|
|
255
|
+
const snapshot = await query.get();
|
|
256
|
+
return snapshot.docs.map((doc) => this.fromFirestore(doc.id, doc.data()));
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
260
|
+
utils_logger_1.logger.error('Failed to find entities', err, {
|
|
261
|
+
collection: this.collectionName,
|
|
262
|
+
});
|
|
263
|
+
const repoError = new errors_1.RepositoryError(`Failed to find entities: ${err.message}`, this.collectionName);
|
|
264
|
+
throw repoError;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Find with pagination
|
|
269
|
+
*/
|
|
270
|
+
async findPaginated(page, pageSize, options = {}) {
|
|
271
|
+
const offset = (page - 1) * pageSize;
|
|
272
|
+
const [data, total] = await Promise.all([
|
|
273
|
+
this.findAll(Object.assign(Object.assign({}, options), { limit: pageSize + 1, offset })),
|
|
274
|
+
this.count(options),
|
|
275
|
+
]);
|
|
276
|
+
const hasMore = data.length > pageSize;
|
|
277
|
+
if (hasMore) {
|
|
278
|
+
data.pop(); // Remove extra item used for hasMore check
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
data,
|
|
282
|
+
total,
|
|
283
|
+
page,
|
|
284
|
+
pageSize,
|
|
285
|
+
hasMore,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Update an entity
|
|
290
|
+
*/
|
|
291
|
+
async update(entity) {
|
|
292
|
+
try {
|
|
293
|
+
const validation = entity.validate();
|
|
294
|
+
if (!validation.valid) {
|
|
295
|
+
throw new Error(`Validation failed: ${JSON.stringify(validation.errors)}`);
|
|
296
|
+
}
|
|
297
|
+
if (!entity.getId()) {
|
|
298
|
+
throw new Error('Cannot update entity without ID');
|
|
299
|
+
}
|
|
300
|
+
entity.incrementVersion();
|
|
301
|
+
await this.getCollection().doc(entity.getId()).update(entity.toFirestore());
|
|
302
|
+
// Invalidate cache after update
|
|
303
|
+
await this.invalidateEntityCache(entity.getId());
|
|
304
|
+
utils_logger_1.logger.info('Entity updated', {
|
|
305
|
+
collection: this.collectionName,
|
|
306
|
+
id: entity.getId(),
|
|
307
|
+
});
|
|
308
|
+
return entity;
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
312
|
+
utils_logger_1.logger.error('Failed to update entity', err, {
|
|
313
|
+
collection: this.collectionName,
|
|
314
|
+
id: entity.getId(),
|
|
315
|
+
});
|
|
316
|
+
const repoError = new errors_1.RepositoryError(`Failed to update entity: ${err.message}`, this.collectionName);
|
|
317
|
+
throw repoError;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Delete an entity (soft delete by default)
|
|
322
|
+
*/
|
|
323
|
+
async delete(id, hardDelete = false) {
|
|
324
|
+
try {
|
|
325
|
+
if (hardDelete) {
|
|
326
|
+
await this.getCollection().doc(id).delete();
|
|
327
|
+
utils_logger_1.logger.info('Entity hard deleted', {
|
|
328
|
+
collection: this.collectionName,
|
|
329
|
+
id,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
await this.getCollection().doc(id).update({
|
|
334
|
+
deletedAt: firestore_1.Timestamp.now(),
|
|
335
|
+
updatedAt: firestore_1.Timestamp.now(),
|
|
336
|
+
});
|
|
337
|
+
utils_logger_1.logger.info('Entity soft deleted', {
|
|
338
|
+
collection: this.collectionName,
|
|
339
|
+
id,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
// Invalidate cache after delete
|
|
343
|
+
await this.invalidateEntityCache(id);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
347
|
+
utils_logger_1.logger.error('Failed to delete entity', err, {
|
|
348
|
+
collection: this.collectionName,
|
|
349
|
+
id,
|
|
350
|
+
});
|
|
351
|
+
const repoError = new errors_1.RepositoryError(`Failed to delete entity: ${err.message}`, this.collectionName);
|
|
352
|
+
throw repoError;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Count entities
|
|
357
|
+
*/
|
|
358
|
+
async count(options = {}) {
|
|
359
|
+
try {
|
|
360
|
+
let query = this.getCollection();
|
|
361
|
+
if (!options.includeSoftDeleted) {
|
|
362
|
+
query = query.where('deletedAt', '==', null);
|
|
363
|
+
}
|
|
364
|
+
if (options.where) {
|
|
365
|
+
for (const clause of options.where) {
|
|
366
|
+
query = query.where(clause.field, clause.operator, clause.value);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const snapshot = await query.count().get();
|
|
370
|
+
return snapshot.data().count;
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
374
|
+
utils_logger_1.logger.error('Failed to count entities', err, {
|
|
375
|
+
collection: this.collectionName,
|
|
376
|
+
});
|
|
377
|
+
const repoError = new errors_1.RepositoryError(`Failed to count entities: ${err.message}`, this.collectionName);
|
|
378
|
+
throw repoError;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Check if entity exists
|
|
383
|
+
*/
|
|
384
|
+
async exists(id) {
|
|
385
|
+
const doc = await this.getCollection().doc(id).get();
|
|
386
|
+
return doc.exists;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Batch create entities
|
|
390
|
+
*/
|
|
391
|
+
async batchCreate(entities) {
|
|
392
|
+
const batch = this.db.batch();
|
|
393
|
+
for (const entity of entities) {
|
|
394
|
+
const validation = entity.validate();
|
|
395
|
+
if (!validation.valid) {
|
|
396
|
+
throw new Error(`Validation failed for entity: ${JSON.stringify(validation.errors)}`);
|
|
397
|
+
}
|
|
398
|
+
const entityId = entity.getId();
|
|
399
|
+
const docRef = entityId ?
|
|
400
|
+
this.getCollection().doc(entityId) :
|
|
401
|
+
this.getCollection().doc();
|
|
402
|
+
entity.id = docRef.id;
|
|
403
|
+
batch.set(docRef, entity.toFirestore());
|
|
404
|
+
}
|
|
405
|
+
await batch.commit();
|
|
406
|
+
utils_logger_1.logger.info('Batch entities created', {
|
|
407
|
+
collection: this.collectionName,
|
|
408
|
+
count: entities.length,
|
|
409
|
+
});
|
|
410
|
+
return entities;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
exports.BaseRepository = BaseRepository;
|
|
414
|
+
//# sourceMappingURL=BaseRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseRepository.js","sourceRoot":"","sources":["../../../../src/base/BaseRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Service Class
|
|
3
|
+
* Handles business logic orchestration and event publishing
|
|
4
|
+
* All services should extend this class
|
|
5
|
+
*/
|
|
6
|
+
import { BaseEntity } from './BaseEntity';
|
|
7
|
+
import { BaseRepository, QueryOptions, PaginationResult } from './BaseRepository';
|
|
8
|
+
export interface RequestContext {
|
|
9
|
+
requestId: string;
|
|
10
|
+
userId?: string;
|
|
11
|
+
userRole?: string;
|
|
12
|
+
timestamp: Date;
|
|
13
|
+
metadata?: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
export interface ServiceResult<T> {
|
|
16
|
+
success: boolean;
|
|
17
|
+
data?: T;
|
|
18
|
+
error?: ServiceErrorDetail;
|
|
19
|
+
}
|
|
20
|
+
export interface ServiceErrorDetail {
|
|
21
|
+
code: string;
|
|
22
|
+
message: string;
|
|
23
|
+
details?: Record<string, any>;
|
|
24
|
+
}
|
|
25
|
+
export declare abstract class BaseService<T extends BaseEntity> {
|
|
26
|
+
protected abstract entityName: string;
|
|
27
|
+
protected repository: BaseRepository<T>;
|
|
28
|
+
constructor(repository: BaseRepository<T>);
|
|
29
|
+
/**
|
|
30
|
+
* Create a new entity
|
|
31
|
+
*/
|
|
32
|
+
create(data: Partial<T>, context: RequestContext): Promise<ServiceResult<T>>;
|
|
33
|
+
/**
|
|
34
|
+
* Find entity by ID
|
|
35
|
+
*/
|
|
36
|
+
findById(id: string, context: RequestContext): Promise<ServiceResult<T>>;
|
|
37
|
+
/**
|
|
38
|
+
* Find all entities with filtering
|
|
39
|
+
*/
|
|
40
|
+
findAll(options: QueryOptions, context: RequestContext): Promise<ServiceResult<T[]>>;
|
|
41
|
+
/**
|
|
42
|
+
* Find entities with pagination
|
|
43
|
+
*/
|
|
44
|
+
findPaginated(page: number, pageSize: number, options: Omit<QueryOptions, 'limit' | 'offset'>, context: RequestContext): Promise<ServiceResult<PaginationResult<T>>>;
|
|
45
|
+
/**
|
|
46
|
+
* Update an entity
|
|
47
|
+
*/
|
|
48
|
+
update(id: string, data: Partial<T>, context: RequestContext): Promise<ServiceResult<T>>;
|
|
49
|
+
/**
|
|
50
|
+
* Delete an entity
|
|
51
|
+
*/
|
|
52
|
+
delete(id: string, context: RequestContext, hardDelete?: boolean): Promise<ServiceResult<void>>;
|
|
53
|
+
/**
|
|
54
|
+
* Lifecycle hooks (override in subclasses)
|
|
55
|
+
*/
|
|
56
|
+
protected beforeCreate(_data: Partial<T>, _context: RequestContext): Promise<void>;
|
|
57
|
+
protected afterCreate(_entity: T, _context: RequestContext): Promise<void>;
|
|
58
|
+
protected beforeUpdate(_existing: T, _data: Partial<T>, _context: RequestContext): Promise<void>;
|
|
59
|
+
protected afterUpdate(_entity: T, _context: RequestContext): Promise<void>;
|
|
60
|
+
protected beforeDelete(_entity: T, _context: RequestContext): Promise<void>;
|
|
61
|
+
protected afterDelete(_entity: T, _context: RequestContext): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Access control methods (override in subclasses)
|
|
64
|
+
*/
|
|
65
|
+
protected checkReadAccess(_entity: T, _context: RequestContext): Promise<boolean>;
|
|
66
|
+
protected checkUpdateAccess(_entity: T, _context: RequestContext): Promise<boolean>;
|
|
67
|
+
protected checkDeleteAccess(_entity: T, _context: RequestContext): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Apply user-specific filters (override in subclasses)
|
|
70
|
+
*/
|
|
71
|
+
protected applyUserFilters(options: QueryOptions, _context: RequestContext): Promise<QueryOptions>;
|
|
72
|
+
/**
|
|
73
|
+
* Build entity from partial data (must be implemented by subclasses)
|
|
74
|
+
*/
|
|
75
|
+
protected abstract buildEntity(data: Partial<T>): Promise<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Merge existing entity with updates (must be implemented by subclasses)
|
|
78
|
+
*/
|
|
79
|
+
protected abstract mergeEntity(existing: T, updates: Partial<T>): Promise<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Publish domain event
|
|
82
|
+
*/
|
|
83
|
+
protected publishEvent(action: string, entity: T, context: RequestContext): void;
|
|
84
|
+
/**
|
|
85
|
+
* Handle errors and convert to ServiceError
|
|
86
|
+
*/
|
|
87
|
+
protected handleError(error: unknown): ServiceErrorDetail;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=BaseService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseService.d.ts","sourceRoot":"","sources":["../../../../src/base/BaseService.ts"],"names":[],"mappings":"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"}
|