siesa-agents 2.1.22 → 2.1.23

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.
@@ -112,3 +112,150 @@ Use MCP to install Shadcn components instead of creating manually.
112
112
  **Exceptions**: Only use pure React + Vite when user specifically mentions offline-first functionality or requests non-Next.js setup.
113
113
 
114
114
  **Reasoning**: Next.js provides better developer experience, built-in optimization, and easier deployment while maintaining PWA capabilities.
115
+
116
+ ## Backend Architecture
117
+
118
+ ### Architecture Style
119
+ - **Hexagonal Architecture** (Ports & Adapters) + **Domain-Driven Design (DDD)**
120
+
121
+ ### Folder Structure
122
+
123
+ MonoRepo Structure with Hexagonal Architecture + DDD:
124
+
125
+ ```
126
+ ├── apps/ # Microservices applications
127
+ │ ├── sales-service/ # Sales domain microservice
128
+ │ │ ├── src/
129
+ │ │ │ ├── modules/
130
+ │ │ │ │ ├── quotes/ # Quote bounded context
131
+ │ │ │ │ │ ├── application/
132
+ │ │ │ │ │ │ ├── ports/ # Interfaces (secondary ports)
133
+ │ │ │ │ │ │ │ ├── repositories/
134
+ │ │ │ │ │ │ │ └── services/
135
+ │ │ │ │ │ │ ├── use-cases/ # Primary ports
136
+ │ │ │ │ │ │ ├── commands/
137
+ │ │ │ │ │ │ ├── queries/
138
+ │ │ │ │ │ │ └── dto/
139
+ │ │ │ │ │ ├── domain/
140
+ │ │ │ │ │ │ ├── entities/
141
+ │ │ │ │ │ │ ├── value-objects/
142
+ │ │ │ │ │ │ ├── aggregates/
143
+ │ │ │ │ │ │ ├── events/
144
+ │ │ │ │ │ │ └── services/ # Domain services
145
+ │ │ │ │ │ └── infrastructure/ # Adapters (secondary adapters)
146
+ │ │ │ │ │ ├── repositories/ # Prisma implementations
147
+ │ │ │ │ │ ├── services/ # External service adapters
148
+ │ │ │ │ │ └── events/
149
+ │ │ │ │ └── products/ # Product bounded context
150
+ │ │ │ ├── api/ # Primary adapters
151
+ │ │ │ │ ├── controllers/
152
+ │ │ │ │ ├── guards/
153
+ │ │ │ │ ├── middlewares/
154
+ │ │ │ │ └── filters/
155
+ │ │ │ ├── config/
156
+ │ │ │ ├── main.ts
157
+ │ │ │ └── app.module.ts
158
+ │ │ ├── test/
159
+ │ │ ├── prisma/
160
+ │ │ │ ├── schema.prisma
161
+ │ │ │ └── migrations/
162
+ │ │ └── package.json
163
+ │ │
164
+ │ ├── inventory-service/ # Inventory domain microservice
165
+ │ └── user-service/ # User domain microservice
166
+
167
+ ├── libs/ # Shared libraries
168
+ │ ├── common/ # Common utilities
169
+ │ │ ├── src/
170
+ │ │ │ ├── decorators/
171
+ │ │ │ ├── filters/
172
+ │ │ │ ├── guards/
173
+ │ │ │ ├── interceptors/
174
+ │ │ │ ├── pipes/
175
+ │ │ │ ├── types/
176
+ │ │ │ └── utils/
177
+ │ │ └── package.json
178
+ │ │
179
+ │ ├── domain-core/ # Shared domain concepts
180
+ │ │ ├── src/
181
+ │ │ │ ├── base/
182
+ │ │ │ │ ├── aggregate-root.ts
183
+ │ │ │ │ ├── entity.ts
184
+ │ │ │ │ ├── value-object.ts
185
+ │ │ │ │ └── domain-event.ts
186
+ │ │ │ ├── interfaces/
187
+ │ │ │ └── exceptions/
188
+ │ │ └── package.json
189
+ │ │
190
+ │ └── database/ # Shared database utilities
191
+ │ ├── src/
192
+ │ │ ├── base-repository.ts
193
+ │ │ ├── transaction.decorator.ts
194
+ │ │ └── prisma.service.ts
195
+ │ └── package.json
196
+
197
+ ├── tools/ # Development tools
198
+ ├── nx.json # Nx workspace configuration
199
+ ├── package.json # Root package.json
200
+ └── tsconfig.base.json # Base TypeScript config
201
+ ```
202
+
203
+ ### Core Principles
204
+
205
+ #### Hexagonal Architecture First
206
+ Strict separation of concerns following ports & adapters pattern:
207
+ - **Domain Layer**: Pure business logic with entities, value objects, aggregates, and domain services
208
+ - **Application Layer**: Use cases orchestrating domain logic, defining ports (interfaces)
209
+ - **Infrastructure Layer**: Adapters implementing ports (Prisma repos, HTTP clients, message publishers)
210
+ - **API Layer**: Primary adapters exposing application via REST/GraphQL (controllers, resolvers)
211
+
212
+ #### Domain-Driven Design
213
+ Business logic drives all architectural decisions:
214
+ - **Bounded Contexts**: Each module represents a bounded context (quotes, products, billing)
215
+ - **Ubiquitous Language**: Code reflects business terminology
216
+ - **Aggregates**: Consistency boundaries for domain entities
217
+ - **Domain Events**: Communicate changes across bounded contexts
218
+ - **Repository Pattern**: Abstract data access behind interfaces
219
+
220
+ #### Dependency Rules
221
+ - Domain layer has zero dependencies on frameworks or external libraries
222
+ - All dependencies point inward toward the domain core
223
+ - Use dependency inversion for all external concerns (databases, APIs, messaging)
224
+ - Interfaces defined in application layer, implementations in infrastructure layer
225
+
226
+ #### Microservices Independence
227
+ - Each microservice has its own database (no shared databases)
228
+ - Shared code through libraries only (common, domain-core, database)
229
+ - Independent deployment pipelines per service
230
+ - Service-to-service communication via events (async messaging)
231
+ - No direct database access between services
232
+
233
+ #### Test-Driven Development
234
+ - Unit tests for domain entities, value objects, and use cases
235
+ - Integration tests for repository implementations
236
+ - E2E tests for complete API workflows
237
+ - TDD approach: write tests before implementation
238
+
239
+ #### Type Safety & Validation
240
+ - Leverage TypeScript strict mode for compile-time safety
241
+ - Domain validation in value objects and entities
242
+ - DTO validation at API boundaries with class-validator
243
+ - No `any` types allowed
244
+
245
+ #### Security by Design
246
+ - Authentication and authorization at every layer
247
+ - Input validation on all endpoints
248
+ - OWASP Top 10 compliance
249
+ - Audit logging for critical operations
250
+
251
+ ### Framework Selection Rules
252
+
253
+ **Default**: Always use NestJS 10+ with TypeScript for backend services.
254
+
255
+ **Database**: Prisma ORM only - no raw SQL queries allowed.
256
+
257
+ **Testing**: Jest + Supertest with TDD approach.
258
+
259
+ **Documentation**: Swagger/OpenAPI auto-generated from decorators.
260
+
261
+ **Reasoning**: NestJS provides excellent DI container, decorator-based development, and native support for microservices patterns while enforcing SOLID principles.
@@ -1,43 +1,32 @@
1
1
  # Backend Development Standards
2
2
 
3
- ## Architecture Principles
4
-
5
- ### Hexagonal Architecture Implementation
6
- - **Application Core**: Domain entities, value objects, aggregates, and domain services
7
- - **Primary Ports**: Use cases, commands, queries, and application services
8
- - **Primary Adapters**: REST controllers, GraphQL resolvers, message handlers
9
- - **Secondary Ports**: Repository interfaces, external service interfaces
10
- - **Secondary Adapters**: Prisma repositories, HTTP clients, message publishers
11
-
12
- ### Dependency Rules
13
- - Application core must not depend on external frameworks
14
- - All dependencies point inward toward the domain
15
- - Use dependency inversion for all external concerns
16
- - Interfaces defined in application layer, implementations in infrastructure
3
+ > **Note**: For architecture patterns and principles (Hexagonal Architecture, DDD, folder structure), see [architecture-patterns.md](./architecture-patterns.md)
17
4
 
18
5
  ## Technology Stack Standards
19
6
 
20
7
  ### Core Technologies
21
8
  - **NestJS**: 10+ with TypeScript and decorators
22
9
  - **TypeScript**: Strict mode enabled, no `any` types
23
- - **Prisma**: ORM for database operations (no raw queries)
24
- - **Jest**: Unit and integration testing
25
- - **Class-validator**: Request validation and transformation
10
+ - **Prisma**: ORM for database operations (no raw queries allowed)
11
+ - **Jest + Supertest**: Unit, integration, and E2E testing
12
+ - **Class-validator + Class-transformer**: DTO validation
26
13
 
27
- ### Framework Selection Rules
28
- - **Default**: Always use NestJS 10+ with TypeScript
29
- - **Database**: Prisma ORM only - no raw SQL queries allowed
30
- - **Testing**: TDD approach with Jest and Supertest
31
- - **Documentation**: Swagger/OpenAPI for all endpoints
14
+ ### Framework Standards
15
+ - **Default Framework**: NestJS 10+ with TypeScript
16
+ - **Database**: Prisma ORM only - no raw SQL queries
17
+ - **Testing**: TDD approach with comprehensive test coverage
18
+ - **Documentation**: Swagger/OpenAPI auto-generated from decorators
19
+ - **Messaging**: NestJS Microservices (Redis, RabbitMQ, or gRPC)
32
20
 
33
21
  ### Development Tools
34
- - **Nx**: MonoRepo management and build system
22
+ - **Nx**: MonoRepo management and build orchestration
35
23
  - **ESLint + Prettier**: Code quality and formatting
36
- - **Husky**: Git hooks for pre-commit validation
37
- - **Winston**: Structured logging
38
- - **Redis**: Caching and message transport
24
+ - **Husky**: Pre-commit hooks for quality gates
25
+ - **Winston**: Structured logging with log levels
26
+ - **Redis**: Caching, session storage, and message transport
27
+ - **Passport + JWT**: Authentication and authorization
39
28
 
40
- ## Domain-Driven Design Standards
29
+ ## Domain-Driven Design Implementation
41
30
 
42
31
  ### Entity Structure
43
32
  ```typescript
@@ -46,7 +35,6 @@ export class UserEntity extends AggregateRoot {
46
35
  public readonly id: UserId,
47
36
  private _email: EmailValueObject,
48
37
  private _name: NameValueObject,
49
- private _createdAt: Date,
50
38
  ) {
51
39
  super();
52
40
  }
@@ -56,7 +44,6 @@ export class UserEntity extends AggregateRoot {
56
44
  UserId.generate(),
57
45
  EmailValueObject.create(props.email),
58
46
  NameValueObject.create(props.name),
59
- new Date(),
60
47
  );
61
48
  user.addDomainEvent(new UserCreatedEvent(user.id));
62
49
  return user;
@@ -91,11 +78,6 @@ export class EmailValueObject {
91
78
  }
92
79
  }
93
80
 
94
- private isValidEmail(email: string): boolean {
95
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
96
- return emailRegex.test(email);
97
- }
98
-
99
81
  equals(other: EmailValueObject): boolean {
100
82
  return this.value === other.value;
101
83
  }
@@ -106,15 +88,45 @@ export class EmailValueObject {
106
88
  }
107
89
  ```
108
90
 
109
- ### Repository Interface Pattern
91
+ ### Repository Pattern
110
92
  ```typescript
93
+ // Interface (in application/ports/repositories)
111
94
  export interface UserRepositoryInterface {
112
95
  save(user: UserEntity): Promise<UserEntity>;
113
96
  findById(id: UserId): Promise<UserEntity | null>;
114
97
  findByEmail(email: EmailValueObject): Promise<UserEntity | null>;
115
- findAll(criteria: FindUsersCriteria): Promise<UserEntity[]>;
116
98
  delete(id: UserId): Promise<void>;
117
99
  }
100
+
101
+ // Implementation (in infrastructure/repositories)
102
+ @Injectable()
103
+ export class PrismaUserRepository implements UserRepositoryInterface {
104
+ constructor(private readonly prisma: PrismaService) {}
105
+
106
+ async save(user: UserEntity): Promise<UserEntity> {
107
+ const data = {
108
+ id: user.id.toString(),
109
+ email: user.email.toString(),
110
+ name: user.name.toString(),
111
+ };
112
+
113
+ const savedUser = await this.prisma.user.upsert({
114
+ where: { id: data.id },
115
+ update: data,
116
+ create: data,
117
+ });
118
+
119
+ return this.toDomain(savedUser);
120
+ }
121
+
122
+ private toDomain(prismaUser: User): UserEntity {
123
+ return UserEntity.reconstitute({
124
+ id: UserId.create(prismaUser.id),
125
+ email: EmailValueObject.create(prismaUser.email),
126
+ name: NameValueObject.create(prismaUser.name),
127
+ });
128
+ }
129
+ }
118
130
  ```
119
131
 
120
132
  ## Use Case Standards
@@ -133,20 +145,19 @@ export class CreateUserUseCase {
133
145
  async execute(command: CreateUserCommand): Promise<UserResponseDto> {
134
146
  // 1. Validate business rules
135
147
  await this.validateUserDoesNotExist(command.email);
136
-
148
+
137
149
  // 2. Create domain entity
138
150
  const user = UserEntity.create({
139
151
  email: command.email,
140
152
  name: command.name,
141
153
  });
142
-
154
+
143
155
  // 3. Persist entity
144
156
  const savedUser = await this.userRepository.save(user);
145
-
157
+
146
158
  // 4. Publish domain events
147
159
  await this.eventBus.publishAll(savedUser.getUncommittedEvents());
148
- savedUser.markEventsAsCommitted();
149
-
160
+
150
161
  // 5. Return response DTO
151
162
  return UserResponseDto.fromEntity(savedUser);
152
163
  }
@@ -172,20 +183,16 @@ export class CreateUserCommand {
172
183
  @IsNotEmpty()
173
184
  @Length(2, 50)
174
185
  readonly name: string;
175
-
176
- @IsOptional()
177
- @IsString()
178
- readonly organizationId?: string;
179
186
  }
180
187
  ```
181
188
 
182
189
  ## Testing Standards
183
190
 
184
191
  ### Testing Strategy
185
- - **Unit Tests**: Domain entities, value objects, use cases
186
- - **Integration Tests**: Repository implementations, external services
187
- - **E2E Tests**: Complete API workflows
188
- - **Contract Tests**: External service integrations
192
+ - **Unit Tests**: Domain entities, value objects, use cases (isolated logic)
193
+ - **Integration Tests**: Repository implementations, database operations
194
+ - **E2E Tests**: Complete API workflows with Supertest
195
+ - **TDD Approach**: Write tests before implementation
189
196
 
190
197
  ### Test Structure
191
198
  ```typescript
@@ -198,19 +205,8 @@ describe('CreateUserUseCase', () => {
198
205
  const module = await Test.createTestingModule({
199
206
  providers: [
200
207
  CreateUserUseCase,
201
- {
202
- provide: USER_REPOSITORY,
203
- useValue: {
204
- save: jest.fn(),
205
- findByEmail: jest.fn(),
206
- },
207
- },
208
- {
209
- provide: EVENT_BUS,
210
- useValue: {
211
- publishAll: jest.fn(),
212
- },
213
- },
208
+ { provide: USER_REPOSITORY, useValue: { save: jest.fn(), findByEmail: jest.fn() } },
209
+ { provide: EVENT_BUS, useValue: { publishAll: jest.fn() } },
214
210
  ],
215
211
  }).compile();
216
212
 
@@ -219,46 +215,33 @@ describe('CreateUserUseCase', () => {
219
215
  eventBus = module.get(EVENT_BUS);
220
216
  });
221
217
 
222
- describe('execute', () => {
223
- it('should create user successfully', async () => {
224
- // Arrange
225
- const command = new CreateUserCommand();
226
- command.email = 'test@example.com';
227
- command.name = 'Test User';
228
-
229
- const expectedUser = UserEntity.create({
230
- email: command.email,
231
- name: command.name,
232
- });
233
-
234
- userRepository.findByEmail.mockResolvedValue(null);
235
- userRepository.save.mockResolvedValue(expectedUser);
218
+ it('should create user successfully', async () => {
219
+ // Arrange
220
+ const command = new CreateUserCommand();
221
+ command.email = 'test@example.com';
222
+ command.name = 'Test User';
236
223
 
237
- // Act
238
- const result = await useCase.execute(command);
224
+ userRepository.findByEmail.mockResolvedValue(null);
225
+ userRepository.save.mockResolvedValue(UserEntity.create(command));
239
226
 
240
- // Assert
241
- expect(result.email).toBe(command.email);
242
- expect(userRepository.save).toHaveBeenCalledWith(expect.any(UserEntity));
243
- expect(eventBus.publishAll).toHaveBeenCalled();
244
- });
227
+ // Act
228
+ const result = await useCase.execute(command);
245
229
 
246
- it('should throw error when user already exists', async () => {
247
- // Arrange
248
- const command = new CreateUserCommand();
249
- command.email = 'existing@example.com';
250
- command.name = 'Test User';
230
+ // Assert
231
+ expect(result.email).toBe(command.email);
232
+ expect(userRepository.save).toHaveBeenCalledWith(expect.any(UserEntity));
233
+ expect(eventBus.publishAll).toHaveBeenCalled();
234
+ });
251
235
 
252
- const existingUser = UserEntity.create({
253
- email: command.email,
254
- name: 'Existing User',
255
- });
236
+ it('should throw error when user already exists', async () => {
237
+ // Arrange
238
+ const command = new CreateUserCommand();
239
+ command.email = 'existing@example.com';
256
240
 
257
- userRepository.findByEmail.mockResolvedValue(existingUser);
241
+ userRepository.findByEmail.mockResolvedValue(UserEntity.create(command));
258
242
 
259
- // Act & Assert
260
- await expect(useCase.execute(command)).rejects.toThrow(UserAlreadyExistsException);
261
- });
243
+ // Act & Assert
244
+ await expect(useCase.execute(command)).rejects.toThrow(UserAlreadyExistsException);
262
245
  });
263
246
  });
264
247
  ```
@@ -277,23 +260,20 @@ export class UserController {
277
260
 
278
261
  @Post()
279
262
  @ApiOperation({ summary: 'Create a new user' })
280
- @ApiResponse({ status: 201, description: 'User created successfully', type: UserResponseDto })
263
+ @ApiResponse({ status: 201, type: UserResponseDto })
281
264
  @ApiResponse({ status: 400, description: 'Bad request' })
282
- @ApiResponse({ status: 409, description: 'User already exists' })
283
- async createUser(@Body() createUserDto: CreateUserDto): Promise<UserResponseDto> {
265
+ async createUser(@Body() dto: CreateUserDto): Promise<UserResponseDto> {
284
266
  const command = new CreateUserCommand();
285
- Object.assign(command, createUserDto);
267
+ Object.assign(command, dto);
286
268
  return this.createUserUseCase.execute(command);
287
269
  }
288
270
 
289
271
  @Get(':id')
290
272
  @ApiOperation({ summary: 'Get user by ID' })
291
- @ApiParam({ name: 'id', description: 'User ID' })
292
- @ApiResponse({ status: 200, description: 'User found', type: UserResponseDto })
273
+ @ApiResponse({ status: 200, type: UserResponseDto })
293
274
  @ApiResponse({ status: 404, description: 'User not found' })
294
275
  async getUser(@Param('id', ParseUUIDPipe) id: string): Promise<UserResponseDto> {
295
- const query = new GetUserQuery(id);
296
- return this.getUserUseCase.execute(query);
276
+ return this.getUserUseCase.execute(new GetUserQuery(id));
297
277
  }
298
278
  }
299
279
  ```
@@ -308,9 +288,7 @@ model User {
308
288
  name String
309
289
  createdAt DateTime @default(now())
310
290
  updatedAt DateTime @updatedAt
311
-
312
- // Relationships
313
- orders Order[]
291
+ orders Order[]
314
292
 
315
293
  @@map("users")
316
294
  }
@@ -320,8 +298,6 @@ model Order {
320
298
  total Decimal @db.Decimal(10, 2)
321
299
  status OrderStatus
322
300
  userId String
323
-
324
- // Relationships
325
301
  user User @relation(fields: [userId], references: [id])
326
302
  items OrderItem[]
327
303
 
@@ -337,104 +313,60 @@ enum OrderStatus {
337
313
  }
338
314
  ```
339
315
 
340
- ### Repository Implementation
341
- ```typescript
342
- @Injectable()
343
- export class PrismaUserRepository implements UserRepositoryInterface {
344
- constructor(private readonly prisma: PrismaService) {}
345
-
346
- async save(user: UserEntity): Promise<UserEntity> {
347
- const data = {
348
- id: user.id.toString(),
349
- email: user.email.toString(),
350
- name: user.name.toString(),
351
- };
352
-
353
- const savedUser = await this.prisma.user.upsert({
354
- where: { id: data.id },
355
- update: data,
356
- create: data,
357
- });
358
-
359
- return this.toDomain(savedUser);
360
- }
361
-
362
- async findById(id: UserId): Promise<UserEntity | null> {
363
- const user = await this.prisma.user.findUnique({
364
- where: { id: id.toString() },
365
- });
366
-
367
- return user ? this.toDomain(user) : null;
368
- }
369
-
370
- private toDomain(prismaUser: User): UserEntity {
371
- return UserEntity.reconstitute({
372
- id: UserId.create(prismaUser.id),
373
- email: EmailValueObject.create(prismaUser.email),
374
- name: NameValueObject.create(prismaUser.name),
375
- createdAt: prismaUser.createdAt,
376
- });
377
- }
378
- }
379
- ```
316
+ ### Prisma Best Practices
317
+ - Use enums for fixed value sets
318
+ - Always add indexes on foreign keys
319
+ - Use `@@map` for table naming (plural snake_case)
320
+ - Include `createdAt` and `updatedAt` timestamps
321
+ - Use `cuid()` for primary keys
322
+ - No raw SQL queries - use Prisma Client only
380
323
 
381
324
  ## Security Standards
382
325
 
383
326
  ### Authentication & Authorization
384
- - JWT tokens with proper expiration
385
- - Role-based access control (RBAC)
386
- - Input validation on all endpoints
387
- - Rate limiting for public endpoints
388
- - HTTPS only in production
327
+ - **JWT Tokens**: Proper expiration and refresh token handling
328
+ - **RBAC**: Role-based access control with Guards
329
+ - **Validation**: Input validation on all endpoints (class-validator)
330
+ - **Rate Limiting**: Throttle public endpoints to prevent abuse
331
+ - **Environment**: HTTPS only in production, secrets in env variables
389
332
 
390
333
  ### Data Protection
391
- - Encrypt sensitive data at rest
392
- - Use environment variables for secrets
393
- - Implement audit logging
394
- - Regular security updates
395
- - OWASP compliance
334
+ - Encrypt sensitive data at rest and in transit
335
+ - Never commit secrets to repository
336
+ - Implement audit logging for critical operations
337
+ - OWASP Top 10 compliance
338
+ - Regular dependency security audits
396
339
 
397
340
  ## Performance Standards
398
341
 
399
342
  ### Database Optimization
400
- - Proper indexing strategies
401
- - Connection pooling
402
- - Query optimization
403
- - Pagination for large datasets
404
- - Database monitoring
343
+ - Proper indexing on frequently queried fields
344
+ - Connection pooling via Prisma
345
+ - Pagination for large datasets (cursor-based preferred)
346
+ - Avoid N+1 queries with Prisma `include`
347
+ - Query monitoring and slow query logging
405
348
 
406
349
  ### Caching Strategy
407
- - Redis for session data
408
- - Application-level caching
409
- - HTTP caching headers
410
- - CDN for static assets
411
- - Cache invalidation patterns
350
+ - **Redis**: Session data, rate limiting, and frequently accessed data
351
+ - **Application Cache**: In-memory caching for configuration
352
+ - **TTL Strategy**: Appropriate time-to-live for different data types
353
+ - **Invalidation**: Event-driven cache invalidation
412
354
 
413
- ## MonoRepo Organization
355
+ ## Error Handling
414
356
 
415
- ### Shared Libraries Structure
416
- ```
417
- libs/
418
- ├── common/
419
- │ ├── decorators/
420
- │ ├── filters/
421
- │ ├── guards/
422
- │ ├── interceptors/
423
- │ ├── pipes/
424
- │ └── utils/
425
- ├── domain-core/
426
- │ ├── base/
427
- │ ├── interfaces/
428
- │ └── exceptions/
429
- └── database/
430
- ├── base-repository.ts
431
- ├── transaction.decorator.ts
432
- └── prisma.service.ts
433
- ```
357
+ ### Exception Hierarchy
358
+ - Domain exceptions for business rule violations
359
+ - Application exceptions for use case errors
360
+ - Infrastructure exceptions for external service failures
361
+ - HTTP exception filters for API responses
434
362
 
435
- ### Service Independence
436
- - Each microservice has its own database
437
- - Shared code through libraries only
438
- - Independent deployment pipelines
439
- - Service-to-service communication via events
440
- - No direct database access between services
363
+ ### Error Response Format
364
+ ```typescript
365
+ {
366
+ "statusCode": 400,
367
+ "message": "User with email already exists",
368
+ "error": "UserAlreadyExistsException",
369
+ "timestamp": "2024-01-15T10:30:00Z",
370
+ "path": "/api/users"
371
+ }
372
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siesa-agents",
3
- "version": "2.1.22",
3
+ "version": "2.1.23",
4
4
  "description": "Paquete para instalar y configurar agentes SIESA en tu proyecto",
5
5
  "main": "index.js",
6
6
  "bin": {