@sylphx/flow 1.7.0 → 1.8.1

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.
Files changed (131) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/assets/agents/coder.md +72 -119
  3. package/assets/agents/orchestrator.md +26 -90
  4. package/assets/agents/reviewer.md +76 -47
  5. package/assets/agents/writer.md +82 -63
  6. package/assets/output-styles/silent.md +141 -8
  7. package/assets/rules/code-standards.md +9 -33
  8. package/assets/rules/core.md +67 -59
  9. package/package.json +2 -12
  10. package/src/commands/flow/execute.ts +470 -0
  11. package/src/commands/flow/index.ts +11 -0
  12. package/src/commands/flow/prompt.ts +35 -0
  13. package/src/commands/flow/setup.ts +312 -0
  14. package/src/commands/flow/targets.ts +18 -0
  15. package/src/commands/flow/types.ts +47 -0
  16. package/src/commands/flow-command.ts +18 -967
  17. package/src/commands/flow-orchestrator.ts +14 -5
  18. package/src/commands/hook-command.ts +1 -1
  19. package/src/commands/init-core.ts +12 -3
  20. package/src/commands/run-command.ts +1 -1
  21. package/src/config/rules.ts +1 -1
  22. package/src/core/error-handling.ts +1 -1
  23. package/src/core/loop-controller.ts +1 -1
  24. package/src/core/state-detector.ts +1 -1
  25. package/src/core/target-manager.ts +1 -1
  26. package/src/index.ts +1 -1
  27. package/src/shared/files/index.ts +1 -1
  28. package/src/shared/processing/index.ts +1 -1
  29. package/src/targets/claude-code.ts +3 -3
  30. package/src/targets/opencode.ts +3 -3
  31. package/src/utils/agent-enhancer.ts +2 -2
  32. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  33. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  34. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  35. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  36. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  37. package/src/utils/display/banner.ts +25 -0
  38. package/src/utils/display/status.ts +55 -0
  39. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  40. package/src/utils/files/jsonc.ts +36 -0
  41. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  42. package/src/utils/index.ts +42 -61
  43. package/src/utils/version.ts +47 -0
  44. package/src/components/benchmark-monitor.tsx +0 -331
  45. package/src/components/reindex-progress.tsx +0 -261
  46. package/src/composables/functional/index.ts +0 -14
  47. package/src/composables/functional/useEnvironment.ts +0 -171
  48. package/src/composables/functional/useFileSystem.ts +0 -139
  49. package/src/composables/index.ts +0 -4
  50. package/src/composables/useEnv.ts +0 -13
  51. package/src/composables/useRuntimeConfig.ts +0 -27
  52. package/src/core/ai-sdk.ts +0 -603
  53. package/src/core/app-factory.ts +0 -381
  54. package/src/core/builtin-agents.ts +0 -9
  55. package/src/core/command-system.ts +0 -550
  56. package/src/core/config-system.ts +0 -550
  57. package/src/core/connection-pool.ts +0 -390
  58. package/src/core/di-container.ts +0 -155
  59. package/src/core/headless-display.ts +0 -96
  60. package/src/core/interfaces/index.ts +0 -22
  61. package/src/core/interfaces/repository.interface.ts +0 -91
  62. package/src/core/interfaces/service.interface.ts +0 -133
  63. package/src/core/interfaces.ts +0 -96
  64. package/src/core/result.ts +0 -351
  65. package/src/core/service-config.ts +0 -252
  66. package/src/core/session-service.ts +0 -121
  67. package/src/core/storage-factory.ts +0 -115
  68. package/src/core/stream-handler.ts +0 -288
  69. package/src/core/type-utils.ts +0 -427
  70. package/src/core/unified-storage.ts +0 -456
  71. package/src/core/validation/limit.ts +0 -46
  72. package/src/core/validation/query.ts +0 -20
  73. package/src/db/auto-migrate.ts +0 -322
  74. package/src/db/base-database-client.ts +0 -144
  75. package/src/db/cache-db.ts +0 -218
  76. package/src/db/cache-schema.ts +0 -75
  77. package/src/db/database.ts +0 -70
  78. package/src/db/index.ts +0 -252
  79. package/src/db/memory-db.ts +0 -153
  80. package/src/db/memory-schema.ts +0 -29
  81. package/src/db/schema.ts +0 -289
  82. package/src/db/session-repository.ts +0 -733
  83. package/src/domains/index.ts +0 -6
  84. package/src/domains/utilities/index.ts +0 -6
  85. package/src/domains/utilities/time/index.ts +0 -5
  86. package/src/domains/utilities/time/tools.ts +0 -291
  87. package/src/services/agent-service.ts +0 -273
  88. package/src/services/evaluation-service.ts +0 -271
  89. package/src/services/functional/evaluation-logic.ts +0 -296
  90. package/src/services/functional/file-processor.ts +0 -273
  91. package/src/services/functional/index.ts +0 -12
  92. package/src/services/memory.service.ts +0 -476
  93. package/src/types/api/batch.ts +0 -108
  94. package/src/types/api/errors.ts +0 -118
  95. package/src/types/api/index.ts +0 -55
  96. package/src/types/api/requests.ts +0 -76
  97. package/src/types/api/responses.ts +0 -180
  98. package/src/types/api/websockets.ts +0 -85
  99. package/src/types/benchmark.ts +0 -49
  100. package/src/types/database.types.ts +0 -510
  101. package/src/types/memory-types.ts +0 -63
  102. package/src/utils/advanced-tokenizer.ts +0 -191
  103. package/src/utils/ai-model-fetcher.ts +0 -19
  104. package/src/utils/async-file-operations.ts +0 -516
  105. package/src/utils/audio-player.ts +0 -345
  106. package/src/utils/codebase-helpers.ts +0 -211
  107. package/src/utils/console-ui.ts +0 -79
  108. package/src/utils/database-errors.ts +0 -140
  109. package/src/utils/debug-logger.ts +0 -49
  110. package/src/utils/file-scanner.ts +0 -259
  111. package/src/utils/help.ts +0 -20
  112. package/src/utils/immutable-cache.ts +0 -106
  113. package/src/utils/jsonc.ts +0 -158
  114. package/src/utils/memory-tui.ts +0 -414
  115. package/src/utils/models-dev.ts +0 -91
  116. package/src/utils/parallel-operations.ts +0 -487
  117. package/src/utils/process-manager.ts +0 -155
  118. package/src/utils/prompts.ts +0 -120
  119. package/src/utils/search-tool-builder.ts +0 -214
  120. package/src/utils/session-manager.ts +0 -168
  121. package/src/utils/session-title.ts +0 -87
  122. package/src/utils/simplified-errors.ts +0 -410
  123. package/src/utils/template-engine.ts +0 -94
  124. package/src/utils/test-audio.ts +0 -71
  125. package/src/utils/todo-context.ts +0 -46
  126. package/src/utils/token-counter.ts +0 -288
  127. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  128. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  129. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  130. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  131. /package/src/utils/{security.ts → security/security.ts} +0 -0
@@ -1,476 +0,0 @@
1
- /**
2
- * Memory Service Layer
3
- *
4
- * Business logic layer for memory operations
5
- * Handles memory management with validation, caching, and business rules
6
- * Uses functional Result type for error handling
7
- */
8
-
9
- import { type Result, tryCatchAsync } from '../core/functional/result.js';
10
- import type { ILogger } from '../core/interfaces.js';
11
- import {
12
- MemoryError,
13
- type MemoryErrorType,
14
- MemoryNotFoundError,
15
- MemorySizeError,
16
- MemoryValidationError,
17
- } from '../errors/memory-errors.js';
18
- import type {
19
- CreateMemoryData,
20
- MemoryEntry,
21
- MemoryRepository,
22
- MemorySearchParams,
23
- } from '../repositories/memory.repository.js';
24
- import type { MemoryStatsResult, MemoryValue } from '../types/memory-types.js';
25
- import {
26
- type CacheState,
27
- cacheDelete,
28
- cacheDeleteWhere,
29
- cacheEnforceLimit,
30
- cacheGet,
31
- cacheSet,
32
- createCache,
33
- } from '../utils/immutable-cache.js';
34
-
35
- export interface MemoryServiceConfig {
36
- defaultNamespace?: string;
37
- maxEntrySize?: number;
38
- enableCaching?: boolean;
39
- cacheMaxSize?: number;
40
- retentionPolicy?: {
41
- enabled: boolean;
42
- maxAge: number; // milliseconds
43
- cleanupInterval?: number; // milliseconds
44
- };
45
- }
46
-
47
- /**
48
- * Dependencies for MemoryService
49
- */
50
- export interface MemoryServiceDeps {
51
- readonly repository: MemoryRepository;
52
- readonly logger: ILogger;
53
- }
54
-
55
- /**
56
- * Internal state for MemoryService
57
- */
58
- interface MemoryServiceState {
59
- readonly cache: CacheState<string, MemoryEntry>;
60
- readonly cleanupTimer?: NodeJS.Timeout;
61
- }
62
-
63
- /**
64
- * MemoryService Interface
65
- * Business logic layer for memory operations
66
- */
67
- export interface MemoryService {
68
- readonly get: (key: string, namespace?: string) => Promise<Result<MemoryValue, MemoryErrorType>>;
69
- readonly set: (
70
- key: string,
71
- value: string,
72
- namespace?: string
73
- ) => Promise<Result<MemoryEntry, MemoryErrorType>>;
74
- readonly delete: (key: string, namespace?: string) => Promise<Result<boolean, MemoryError>>;
75
- readonly list: (namespace?: string) => Promise<Result<string[], MemoryError>>;
76
- readonly search: (params: MemorySearchParams) => Promise<Result<MemoryEntry[], MemoryError>>;
77
- readonly clear: (namespace?: string) => Promise<Result<number, MemoryError>>;
78
- readonly getStats: () => Promise<Result<MemoryStatsResult, MemoryError>>;
79
- readonly bulkSet: (
80
- entries: Array<{ key: string; value: string; namespace?: string }>,
81
- namespace?: string
82
- ) => Promise<Result<MemoryEntry[], MemoryError>>;
83
- readonly dispose: () => Promise<void>;
84
- }
85
-
86
- /**
87
- * Create Memory Service (Factory Function)
88
- * Handles memory management with validation, caching, and business rules
89
- */
90
- export const createMemoryService = (
91
- deps: MemoryServiceDeps,
92
- config: MemoryServiceConfig = {}
93
- ): MemoryService => {
94
- // Service configuration in closure
95
- const serviceConfig: MemoryServiceConfig = {
96
- defaultNamespace: 'default',
97
- enableCaching: true,
98
- cacheMaxSize: 1000,
99
- ...config,
100
- };
101
-
102
- // Mutable state in closure (will be updated immutably)
103
- let state: MemoryServiceState = {
104
- cache: createCache(),
105
- cleanupTimer: undefined,
106
- };
107
-
108
- // Helper: Update state immutably
109
- const updateState = (updates: Partial<MemoryServiceState>): void => {
110
- state = { ...state, ...updates };
111
- };
112
-
113
- /**
114
- * Get a memory value
115
- */
116
- const get = async (
117
- key: string,
118
- namespace: string = serviceConfig.defaultNamespace || 'default'
119
- ): Promise<Result<MemoryValue, MemoryErrorType>> => {
120
- return await tryCatchAsync(
121
- async () => {
122
- // Check cache first if enabled
123
- if (serviceConfig.enableCaching) {
124
- const cacheKey = `${namespace}:${key}`;
125
- // FUNCTIONAL: Use immutable cache get
126
- const cached = cacheGet(state.cache, cacheKey);
127
- if (cached) {
128
- return {
129
- value: cached.value,
130
- metadata: {
131
- namespace,
132
- timestamp: cached.timestamp,
133
- size: cached.value.length,
134
- },
135
- };
136
- }
137
- }
138
-
139
- // Fetch from repository
140
- const entry = await deps.repository.getByKey(key, namespace);
141
-
142
- if (!entry) {
143
- throw new MemoryNotFoundError(key, namespace);
144
- }
145
-
146
- // Cache the result if enabled
147
- if (serviceConfig.enableCaching) {
148
- updateCache(entry);
149
- }
150
-
151
- return {
152
- value: entry.value,
153
- metadata: {
154
- namespace,
155
- timestamp: entry.timestamp,
156
- size: entry.value.length,
157
- },
158
- };
159
- },
160
- (error) => {
161
- if (error instanceof MemoryNotFoundError) {
162
- return error;
163
- }
164
- deps.logger.error(`Failed to get memory entry: ${key}`, error);
165
- return new MemoryError(`Failed to get memory entry: ${key}`, error);
166
- }
167
- );
168
- };
169
-
170
- /**
171
- * Set a memory value
172
- */
173
- const set = async (
174
- key: string,
175
- value: string,
176
- namespace: string = serviceConfig.defaultNamespace || 'default'
177
- ): Promise<Result<MemoryEntry, MemoryErrorType>> => {
178
- return await tryCatchAsync(
179
- async () => {
180
- // Validate inputs
181
- const validationError = validateMemoryEntry(key, value);
182
- if (validationError) {
183
- throw validationError;
184
- }
185
-
186
- const timestamp = Date.now();
187
- const data: CreateMemoryData = {
188
- key,
189
- namespace,
190
- value,
191
- timestamp,
192
- };
193
-
194
- // Store in repository
195
- const entry = await deps.repository.setMemory(data);
196
-
197
- // Update cache if enabled
198
- if (serviceConfig.enableCaching) {
199
- updateCache(entry);
200
- enforceCacheLimit();
201
- }
202
-
203
- deps.logger.debug(`Memory entry set: ${key} in namespace: ${namespace}`);
204
-
205
- return entry;
206
- },
207
- (error) => {
208
- if (error instanceof MemoryValidationError || error instanceof MemorySizeError) {
209
- return error;
210
- }
211
- deps.logger.error(`Failed to set memory entry: ${key}`, error);
212
- return new MemoryError(`Failed to set memory entry: ${key}`, error);
213
- }
214
- );
215
- };
216
-
217
- /**
218
- * Delete a memory entry
219
- */
220
- const deleteEntry = async (
221
- key: string,
222
- namespace: string = serviceConfig.defaultNamespace || 'default'
223
- ): Promise<Result<boolean, MemoryError>> => {
224
- return await tryCatchAsync(
225
- async () => {
226
- const deleted = await deps.repository.deleteMemory(key, namespace);
227
-
228
- // Remove from cache if present
229
- if (serviceConfig.enableCaching) {
230
- const cacheKey = `${namespace}:${key}`;
231
- // FUNCTIONAL: Use immutable cache delete, returns new state
232
- updateState({ cache: cacheDelete(state.cache, cacheKey) });
233
- }
234
-
235
- deps.logger.debug(`Memory entry deleted: ${key} in namespace: ${namespace}`);
236
-
237
- return deleted;
238
- },
239
- (error) => {
240
- deps.logger.error(`Failed to delete memory entry: ${key}`, error);
241
- return new MemoryError(`Failed to delete memory entry: ${key}`, error);
242
- }
243
- );
244
- };
245
-
246
- /**
247
- * List all keys in a namespace
248
- */
249
- const list = async (
250
- namespace: string = serviceConfig.defaultNamespace || 'default'
251
- ): Promise<Result<string[], MemoryError>> => {
252
- return await tryCatchAsync(
253
- async () => {
254
- const keys = await deps.repository.listKeys(namespace);
255
- return keys;
256
- },
257
- (error) => {
258
- deps.logger.error(`Failed to list keys in namespace: ${namespace}`, error);
259
- return new MemoryError(`Failed to list keys in namespace: ${namespace}`, error);
260
- }
261
- );
262
- };
263
-
264
- /**
265
- * Search memory entries
266
- */
267
- const search = async (
268
- params: MemorySearchParams
269
- ): Promise<Result<MemoryEntry[], MemoryError>> => {
270
- return await tryCatchAsync(
271
- async () => {
272
- const entries = await deps.repository.searchMemory(params);
273
- return entries;
274
- },
275
- (error) => {
276
- deps.logger.error('Failed to search memory entries', error);
277
- return new MemoryError('Failed to search memory entries', error);
278
- }
279
- );
280
- };
281
-
282
- /**
283
- * Clear all entries in a namespace
284
- */
285
- const clear = async (
286
- namespace: string = serviceConfig.defaultNamespace || 'default'
287
- ): Promise<Result<number, MemoryError>> => {
288
- return await tryCatchAsync(
289
- async () => {
290
- const deletedCount = await deps.repository.clearNamespace(namespace);
291
-
292
- // Clear cache entries for this namespace
293
- if (serviceConfig.enableCaching) {
294
- // FUNCTIONAL: Use immutable cache deleteWhere, returns new state
295
- updateState({
296
- cache: cacheDeleteWhere(state.cache, (key) => key.startsWith(`${namespace}:`)),
297
- });
298
- }
299
-
300
- deps.logger.info(`Cleared ${deletedCount} entries from namespace: ${namespace}`);
301
-
302
- return deletedCount;
303
- },
304
- (error) => {
305
- deps.logger.error(`Failed to clear namespace: ${namespace}`, error);
306
- return new MemoryError(`Failed to clear namespace: ${namespace}`, error);
307
- }
308
- );
309
- };
310
-
311
- /**
312
- * Get memory statistics
313
- */
314
- const getStats = async (): Promise<Result<MemoryStatsResult, MemoryError>> => {
315
- return await tryCatchAsync(
316
- async () => {
317
- const stats = await deps.repository.getStats();
318
-
319
- return {
320
- totalEntries: stats.totalEntries,
321
- totalSize: stats.totalSize,
322
- namespaces: stats.namespaces,
323
- oldestEntry: stats.oldestEntry,
324
- newestEntry: stats.newestEntry,
325
- };
326
- },
327
- (error) => {
328
- deps.logger.error('Failed to get memory statistics', error);
329
- return new MemoryError('Failed to get memory statistics', error);
330
- }
331
- );
332
- };
333
-
334
- /**
335
- * Perform bulk operations
336
- */
337
- const bulkSet = async (
338
- entries: Array<{ key: string; value: string; namespace?: string }>,
339
- namespace: string = serviceConfig.defaultNamespace || 'default'
340
- ): Promise<Result<MemoryEntry[], MemoryError>> => {
341
- return await tryCatchAsync(
342
- async () => {
343
- const results: MemoryEntry[] = [];
344
- const errors: string[] = [];
345
-
346
- for (const entry of entries) {
347
- const result = await set(entry.key, entry.value, entry.namespace || namespace);
348
- if (result._tag === 'Success') {
349
- results.push(result.value);
350
- } else {
351
- errors.push(`${entry.key}: ${result.error.message}`);
352
- }
353
- }
354
-
355
- if (errors.length > 0) {
356
- deps.logger.warn(`Bulk set completed with ${errors.length} errors`, { errors });
357
- throw new MemoryError(`Bulk set completed with errors: ${errors.join('; ')}`);
358
- }
359
-
360
- return results;
361
- },
362
- (error) => {
363
- if (error instanceof MemoryError) {
364
- return error;
365
- }
366
- deps.logger.error('Failed to perform bulk set', error);
367
- return new MemoryError('Failed to perform bulk set', error);
368
- }
369
- );
370
- };
371
-
372
- /**
373
- * Validate memory entry data
374
- */
375
- const validateMemoryEntry = (
376
- key: string,
377
- value: string
378
- ): MemoryValidationError | MemorySizeError | null => {
379
- if (!key || key.trim().length === 0) {
380
- return new MemoryValidationError('Key cannot be empty', 'key', key);
381
- }
382
-
383
- if (key.length > 255) {
384
- return new MemoryValidationError('Key cannot exceed 255 characters', 'key', key);
385
- }
386
-
387
- if (serviceConfig.maxEntrySize && value.length > serviceConfig.maxEntrySize) {
388
- return new MemorySizeError(value.length, serviceConfig.maxEntrySize);
389
- }
390
-
391
- // Validate key format (no special characters that could cause issues)
392
- if (!/^[a-zA-Z0-9._-]+$/.test(key)) {
393
- return new MemoryValidationError(
394
- 'Key can only contain alphanumeric characters, dots, hyphens, and underscores',
395
- 'key',
396
- key
397
- );
398
- }
399
-
400
- return null;
401
- };
402
-
403
- /**
404
- * Update cache with new entry
405
- * FUNCTIONAL: Returns new cache state instead of mutating
406
- */
407
- const updateCache = (entry: MemoryEntry): void => {
408
- const cacheKey = `${entry.namespace}:${entry.key}`;
409
- // FUNCTIONAL: Use immutable cache set, returns new state
410
- updateState({ cache: cacheSet(state.cache, cacheKey, entry) });
411
- };
412
-
413
- /**
414
- * Enforce cache size limit
415
- * FUNCTIONAL: Uses immutable cache operations
416
- */
417
- const enforceCacheLimit = (): void => {
418
- if (serviceConfig.cacheMaxSize && state.cache.size > serviceConfig.cacheMaxSize) {
419
- // FUNCTIONAL: Use immutable cache enforceLimit, returns new state
420
- const entriesToRemove = state.cache.size - serviceConfig.cacheMaxSize;
421
- updateState({ cache: cacheEnforceLimit(state.cache, serviceConfig.cacheMaxSize) });
422
- deps.logger.debug(`Cache eviction: removed ${entriesToRemove} entries`);
423
- }
424
- };
425
-
426
- /**
427
- * Setup cleanup timer for retention policy
428
- */
429
- const setupCleanupTimer = (): void => {
430
- if (serviceConfig.retentionPolicy?.enabled && serviceConfig.retentionPolicy.cleanupInterval) {
431
- const timer = setInterval(async () => {
432
- try {
433
- const deletedCount = await deps.repository.cleanupOldEntries(
434
- serviceConfig.retentionPolicy?.maxAge
435
- );
436
- if (deletedCount > 0) {
437
- deps.logger.info(`Automatic cleanup: removed ${deletedCount} old entries`);
438
- }
439
- } catch (error) {
440
- deps.logger.error('Automatic cleanup failed', error);
441
- }
442
- }, serviceConfig.retentionPolicy.cleanupInterval);
443
- updateState({ cleanupTimer: timer });
444
- }
445
- };
446
-
447
- /**
448
- * Cleanup resources
449
- */
450
- const dispose = async (): Promise<void> => {
451
- if (state.cleanupTimer) {
452
- clearInterval(state.cleanupTimer);
453
- updateState({ cleanupTimer: undefined });
454
- }
455
-
456
- // FUNCTIONAL: Replace cache with new empty cache instead of clearing
457
- updateState({ cache: createCache() });
458
- deps.logger.info('Memory service disposed');
459
- };
460
-
461
- // Initialize cleanup timer
462
- setupCleanupTimer();
463
-
464
- // Return service interface
465
- return {
466
- get,
467
- set,
468
- delete: deleteEntry,
469
- list,
470
- search,
471
- clear,
472
- getStats,
473
- bulkSet,
474
- dispose,
475
- };
476
- };
@@ -1,108 +0,0 @@
1
- import { z } from 'zod';
2
- import type { ApiError } from './errors.js';
3
-
4
- // ============================================================================
5
- // BATCH API INTERFACES
6
- // ============================================================================
7
-
8
- /**
9
- * Batch API result for processing multiple operations
10
- */
11
- export interface BatchApiResult<T = unknown> {
12
- /** Batch operation ID */
13
- batchId: string;
14
- /** Total number of operations */
15
- total: number;
16
- /** Number of successful operations */
17
- successful: number;
18
- /** Number of failed operations */
19
- failed: number;
20
- /** Results for individual operations */
21
- results: BatchOperationResult<T>[];
22
- /** Batch operation metadata */
23
- metadata?: {
24
- /** Batch start timestamp */
25
- startedAt: string;
26
- /** Batch completion timestamp */
27
- completedAt?: string;
28
- /** Total processing time in milliseconds */
29
- duration?: number;
30
- /** Processing batch size */
31
- batchSize?: number;
32
- /** Number of concurrent operations */
33
- concurrency?: number;
34
- };
35
- }
36
-
37
- /**
38
- * Individual batch operation result
39
- */
40
- export interface BatchOperationResult<T = unknown> {
41
- /** Operation index in the batch */
42
- index: number;
43
- /** Operation ID */
44
- id: string;
45
- /** Operation success status */
46
- success: boolean;
47
- /** Operation result data */
48
- data?: T;
49
- /** Operation error (if failed) */
50
- error?: ApiError;
51
- /** Operation processing time in milliseconds */
52
- processingTime?: number;
53
- /** Operation retry attempts */
54
- retryCount?: number;
55
- }
56
-
57
- // ============================================================================
58
- // ZOD SCHEMAS
59
- // ============================================================================
60
-
61
- export const BatchOperationResultSchema = z.object({
62
- index: z.number().min(0),
63
- id: z.string(),
64
- success: z.boolean(),
65
- data: z.unknown().optional(),
66
- error: z
67
- .object({
68
- code: z.string(),
69
- message: z.string(),
70
- statusCode: z.number().optional(),
71
- type: z.enum([
72
- 'validation',
73
- 'authentication',
74
- 'authorization',
75
- 'not_found',
76
- 'conflict',
77
- 'rate_limit',
78
- 'server_error',
79
- 'network',
80
- 'timeout',
81
- ]),
82
- description: z.string().optional(),
83
- fieldErrors: z.record(z.array(z.string())).optional(),
84
- stack: z.string().optional(),
85
- context: z.record(z.unknown()).optional(),
86
- suggestions: z.array(z.string()).optional(),
87
- })
88
- .optional(),
89
- processingTime: z.number().min(0).optional(),
90
- retryCount: z.number().min(0).optional(),
91
- });
92
-
93
- export const BatchApiResultSchema = z.object({
94
- batchId: z.string(),
95
- total: z.number().min(0),
96
- successful: z.number().min(0),
97
- failed: z.number().min(0),
98
- results: z.array(BatchOperationResultSchema),
99
- metadata: z
100
- .object({
101
- startedAt: z.string(),
102
- completedAt: z.string().optional(),
103
- duration: z.number().min(0).optional(),
104
- batchSize: z.number().positive().optional(),
105
- concurrency: z.number().positive().optional(),
106
- })
107
- .optional(),
108
- });
@@ -1,118 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- // ============================================================================
4
- // API ERROR INTERFACES
5
- // ============================================================================
6
-
7
- /**
8
- * API error information
9
- */
10
- export interface ApiError {
11
- /** Error code */
12
- code: string;
13
- /** Error message */
14
- message: string;
15
- /** HTTP status code */
16
- statusCode?: number;
17
- /** Error type for categorization */
18
- type:
19
- | 'validation'
20
- | 'authentication'
21
- | 'authorization'
22
- | 'not_found'
23
- | 'conflict'
24
- | 'rate_limit'
25
- | 'server_error'
26
- | 'network'
27
- | 'timeout';
28
- /** Detailed error description */
29
- description?: string;
30
- /** Field-specific errors (for validation errors) */
31
- fieldErrors?: Record<string, string[]>;
32
- /** Stack trace (development only) */
33
- stack?: string;
34
- /** Error context information */
35
- context?: Record<string, unknown>;
36
- /** Suggestions for resolution */
37
- suggestions?: string[];
38
- }
39
-
40
- /**
41
- * Enhanced error with additional context
42
- */
43
- export interface EnhancedError extends Error {
44
- /** Error code */
45
- code: string;
46
- /** HTTP status code */
47
- statusCode?: number;
48
- /** Error type */
49
- type: ApiError['type'];
50
- /** Error context */
51
- context?: ErrorContext;
52
- /** Suggestions for resolution */
53
- suggestions?: string[];
54
- /** Original error that caused this error */
55
- originalError?: Error;
56
- /** Timestamp when error occurred */
57
- timestamp: string;
58
- /** Request ID for tracing */
59
- requestId?: string;
60
- }
61
-
62
- /**
63
- * Error context information
64
- */
65
- export interface ErrorContext {
66
- /** User ID if available */
67
- userId?: string;
68
- /** Session ID if available */
69
- sessionId?: string;
70
- /** IP address if available */
71
- ipAddress?: string;
72
- /** User agent if available */
73
- userAgent?: string;
74
- /** Request path */
75
- path?: string;
76
- /** HTTP method */
77
- method?: string;
78
- /** Additional context data */
79
- data?: Record<string, unknown>;
80
- }
81
-
82
- // ============================================================================
83
- // ZOD SCHEMAS
84
- // ============================================================================
85
-
86
- export const ErrorContextSchema = z.object({
87
- userId: z.string().optional(),
88
- sessionId: z.string().optional(),
89
- ipAddress: z.string().optional(),
90
- userAgent: z.string().optional(),
91
- path: z.string().optional(),
92
- method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']).optional(),
93
- data: z.record(z.unknown()).optional(),
94
- });
95
-
96
- export const EnhancedErrorSchema = z.object({
97
- name: z.string(),
98
- message: z.string(),
99
- code: z.string(),
100
- statusCode: z.number().optional(),
101
- type: z.enum([
102
- 'validation',
103
- 'authentication',
104
- 'authorization',
105
- 'not_found',
106
- 'conflict',
107
- 'rate_limit',
108
- 'server_error',
109
- 'network',
110
- 'timeout',
111
- ]),
112
- context: ErrorContextSchema.optional(),
113
- suggestions: z.array(z.string()).optional(),
114
- originalError: z.instanceof(Error).optional(),
115
- timestamp: z.string(),
116
- requestId: z.string().optional(),
117
- stack: z.string().optional(),
118
- });