@breadstone/archipel-mcp 0.0.21 → 0.0.22

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 (136) hide show
  1. package/data/guides/cryptography-and-otp.md +2 -2
  2. package/data/guides/database-setup.md +4 -3
  3. package/data/guides/email-templates.md +3 -3
  4. package/data/guides/getting-started.md +6 -6
  5. package/data/guides/resource-management.md +9 -9
  6. package/data/packages/platform-blob-storage/api/Variable.AWS_S3_PROVIDER_OPTIONS.md +1 -1
  7. package/data/packages/platform-blob-storage/api/Variable.AZURE_BLOB_PROVIDER_OPTIONS.md +1 -1
  8. package/data/packages/platform-blob-storage/api/Variable.BLOB_PROVIDER.md +1 -1
  9. package/data/packages/platform-blob-storage/api/Variable.VERCEL_BLOB_PROVIDER_OPTIONS.md +1 -1
  10. package/data/packages/platform-core/api/Class.ErrorTemplateService.md +1 -1
  11. package/data/packages/platform-core/api/Class.HostService.md +1 -1
  12. package/data/packages/platform-core/api/Variable.ID_GENERATOR_TOKEN.md +1 -1
  13. package/data/packages/platform-core/api/index.md +0 -27
  14. package/data/packages/platform-core/index.md +7 -4
  15. package/data/packages/platform-cryptography/api/Class.BcryptService.md +4 -4
  16. package/data/packages/platform-cryptography/api/Class.OtpService.md +6 -6
  17. package/data/packages/platform-cryptography/api/Variable.BCRYPT_OPTIONS.md +2 -2
  18. package/data/packages/platform-cryptography/api/Variable.MAX_BCRYPT_PASSWORD_BYTES.md +1 -1
  19. package/data/packages/platform-cryptography/api/Variable.MIN_BCRYPT_ROUNDS.md +1 -1
  20. package/data/packages/platform-cryptography/api/Variable.OTP_OPTIONS.md +2 -2
  21. package/data/packages/platform-cryptography/api/Variable.OTP_SERVICE_TOKEN.md +2 -2
  22. package/data/packages/platform-cryptography/api/Variable.TOTP_EPOCH_TOLERANCE.md +1 -1
  23. package/data/packages/platform-cryptography/api/index.md +3 -3
  24. package/data/packages/platform-documents/api/Class.BaseDocumentRenderer.md +32 -1
  25. package/data/packages/platform-documents/api/Class.DocumentEngine.md +4 -4
  26. package/data/packages/platform-documents/api/Class.DocumentModule.md +2 -2
  27. package/data/packages/platform-documents/api/Class.DocxDocumentRenderer2.md +333 -0
  28. package/data/packages/platform-documents/api/Class.PdfDocumentRenderer.md +355 -0
  29. package/data/packages/platform-documents/api/Interface.IDocumentModuleOptions.md +31 -5
  30. package/data/packages/platform-documents/api/Variable.DOCUMENT_MODULE_OPTIONS.md +1 -1
  31. package/data/packages/platform-documents/api/Variable.DOCUMENT_PARSER_TOKEN.md +1 -1
  32. package/data/packages/platform-documents/api/Variable.DOCUMENT_RENDERER_TOKEN.md +1 -1
  33. package/data/packages/platform-documents/api/Variable.IMAGE_PROCESSOR_TOKEN.md +1 -1
  34. package/data/packages/platform-documents/api/index.md +2 -0
  35. package/data/packages/platform-esigning/api/Class.EsigningClientPort.md +1 -1
  36. package/data/packages/platform-health/index.md +128 -0
  37. package/data/packages/platform-mailing/api/Class.DeliveryStrategyBase.md +0 -1
  38. package/data/packages/platform-mailing/api/Class.MailModule.md +1 -1
  39. package/data/packages/platform-mailing/api/Class.TemplateFetchStrategyBase.md +0 -5
  40. package/data/packages/platform-mailing/api/Variable.SMTP_CONFIG_ENTRIES.md +14 -0
  41. package/data/packages/platform-mailing/api/Variable.SMTP_HOST.md +14 -0
  42. package/data/packages/platform-mailing/api/Variable.SMTP_PASSWORD.md +14 -0
  43. package/data/packages/platform-mailing/api/Variable.SMTP_PORT.md +14 -0
  44. package/data/packages/platform-mailing/api/Variable.SMTP_SECURE.md +14 -0
  45. package/data/packages/platform-mailing/api/Variable.SMTP_USER.md +14 -0
  46. package/data/packages/platform-mailing/api/index.md +6 -3
  47. package/data/packages/platform-mapping/index.md +121 -0
  48. package/data/packages/platform-mcp/api/Variable.MCP_MODULE_OPTIONS.md +1 -1
  49. package/data/packages/platform-openapi/api/Class.SwaggerMultiDocumentService.md +4 -4
  50. package/data/packages/platform-resources/index.md +135 -0
  51. package/data/packages/platform-telemetry/api/Variable.TELEMETRY_ENABLED.md +1 -1
  52. package/data/packages/platform-telemetry/api/Variable.TELEMETRY_FACADE.md +1 -1
  53. package/data/packages/platform-telemetry/api/Variable.TELEMETRY_OPTIONS.md +1 -1
  54. package/{src/knowledge/configPattern.js → data/patterns/config-pattern.md} +44 -47
  55. package/{src/knowledge/dtoPattern.js → data/patterns/dto-pattern.md} +58 -61
  56. package/{src/knowledge/errorHandlingPattern.js → data/patterns/error-handling-pattern.md} +35 -38
  57. package/{src/knowledge/guardPattern.js → data/patterns/guard-pattern.md} +35 -38
  58. package/{src/knowledge/mappingPattern.js → data/patterns/mapping-pattern.md} +43 -144
  59. package/data/patterns/module-pattern.md +182 -0
  60. package/data/patterns/query-pattern.md +137 -0
  61. package/data/patterns/repository-pattern.md +208 -0
  62. package/{src/knowledge/testingPattern.js → data/patterns/testing-pattern.md} +37 -40
  63. package/package.json +1 -1
  64. package/src/PatternsLoader.d.ts +12 -0
  65. package/src/PatternsLoader.js +65 -0
  66. package/src/generators/mappingPatternGenerator.d.ts +5 -0
  67. package/src/generators/mappingPatternGenerator.js +107 -0
  68. package/src/generators/modulePatternGenerator.d.ts +5 -0
  69. package/src/generators/modulePatternGenerator.js +107 -0
  70. package/src/generators/queryPatternGenerator.d.ts +4 -0
  71. package/src/generators/queryPatternGenerator.js +83 -0
  72. package/src/generators/repositoryPatternGenerator.d.ts +5 -0
  73. package/src/generators/repositoryPatternGenerator.js +165 -0
  74. package/src/main.js +15 -9
  75. package/src/models/IPatternDoc.d.ts +15 -0
  76. package/src/models/IPatternDoc.js +3 -0
  77. package/src/tools/registerGetConfigPatternTool.d.ts +2 -1
  78. package/src/tools/registerGetConfigPatternTool.js +4 -3
  79. package/src/tools/registerGetDtoPatternTool.d.ts +2 -1
  80. package/src/tools/registerGetDtoPatternTool.js +4 -3
  81. package/src/tools/registerGetErrorHandlingPatternTool.d.ts +2 -1
  82. package/src/tools/registerGetErrorHandlingPatternTool.js +4 -3
  83. package/src/tools/registerGetGuardPatternTool.d.ts +2 -1
  84. package/src/tools/registerGetGuardPatternTool.js +4 -3
  85. package/src/tools/registerGetMappingPatternTool.d.ts +2 -1
  86. package/src/tools/registerGetMappingPatternTool.js +5 -4
  87. package/src/tools/registerGetModulePatternTool.d.ts +2 -1
  88. package/src/tools/registerGetModulePatternTool.js +5 -4
  89. package/src/tools/registerGetQueryPatternTool.d.ts +2 -1
  90. package/src/tools/registerGetQueryPatternTool.js +5 -4
  91. package/src/tools/registerGetRepositoryPatternTool.d.ts +2 -1
  92. package/src/tools/registerGetRepositoryPatternTool.js +5 -4
  93. package/src/tools/registerGetTestingPatternTool.d.ts +2 -1
  94. package/src/tools/registerGetTestingPatternTool.js +4 -3
  95. package/data/packages/platform-core/api/Class.BlobResourceStrategy.md +0 -195
  96. package/data/packages/platform-core/api/Class.EmbeddedResourceStrategy.md +0 -215
  97. package/data/packages/platform-core/api/Class.FileResourceStrategy.md +0 -192
  98. package/data/packages/platform-core/api/Class.HealthModule.md +0 -42
  99. package/data/packages/platform-core/api/Class.HealthOrchestrator.md +0 -64
  100. package/data/packages/platform-core/api/Class.MappingBuilder.md +0 -110
  101. package/data/packages/platform-core/api/Class.MappingModule.md +0 -46
  102. package/data/packages/platform-core/api/Class.MappingNotRegisteredError.md +0 -56
  103. package/data/packages/platform-core/api/Class.MappingProfileBase.md +0 -52
  104. package/data/packages/platform-core/api/Class.MappingService.md +0 -284
  105. package/data/packages/platform-core/api/Class.ResourceManager.md +0 -565
  106. package/data/packages/platform-core/api/Class.ResourceModule.md +0 -46
  107. package/data/packages/platform-core/api/Class.TypeMappingNotRegisteredError.md +0 -57
  108. package/data/packages/platform-core/api/Function.createMappingKey.md +0 -39
  109. package/data/packages/platform-core/api/Interface.IBlobResourceStrategyConfig.md +0 -28
  110. package/data/packages/platform-core/api/Interface.IBlobServiceAdapter.md +0 -40
  111. package/data/packages/platform-core/api/Interface.IFileResourceStrategyConfig.md +0 -72
  112. package/data/packages/platform-core/api/Interface.IHealthCheckResult.md +0 -46
  113. package/data/packages/platform-core/api/Interface.IHealthIndicator.md +0 -41
  114. package/data/packages/platform-core/api/Interface.IMappingBuilder.md +0 -76
  115. package/data/packages/platform-core/api/Interface.IMappingKey.md +0 -58
  116. package/data/packages/platform-core/api/Interface.IMappingProfile.md +0 -32
  117. package/data/packages/platform-core/api/Interface.IResourceManagerConfig.md +0 -89
  118. package/data/packages/platform-core/api/Interface.IResourceMetadata.md +0 -94
  119. package/data/packages/platform-core/api/Interface.IResourceResult.md +0 -34
  120. package/data/packages/platform-core/api/Interface.IResourceStrategy.md +0 -134
  121. package/data/packages/platform-core/api/Variable.HEALTH_INDICATORS_TOKEN.md +0 -14
  122. package/data/packages/platform-mailing/api/Class.BlobTemplateFetchStrategy.md +0 -60
  123. package/data/packages/platform-mailing/api/Class.FileTemplateFetchStrategy.md +0 -58
  124. package/data/packages/platform-mailing/api/Class.LogDeliveryStrategy.md +0 -71
  125. package/src/knowledge/configPattern.d.ts +0 -5
  126. package/src/knowledge/dtoPattern.d.ts +0 -5
  127. package/src/knowledge/errorHandlingPattern.d.ts +0 -5
  128. package/src/knowledge/guardPattern.d.ts +0 -5
  129. package/src/knowledge/mappingPattern.d.ts +0 -6
  130. package/src/knowledge/modulePattern.d.ts +0 -6
  131. package/src/knowledge/modulePattern.js +0 -283
  132. package/src/knowledge/queryPattern.d.ts +0 -6
  133. package/src/knowledge/queryPattern.js +0 -215
  134. package/src/knowledge/repositoryPattern.d.ts +0 -6
  135. package/src/knowledge/repositoryPattern.js +0 -367
  136. package/src/knowledge/testingPattern.d.ts +0 -5
@@ -0,0 +1,208 @@
1
+ ---
2
+ title: Repository Pattern
3
+ description: RepositoryBase subclasses, DelegateArgs/DelegateReturnTypes helpers, module registration, and service injection.
4
+ order: 8
5
+ ---
6
+
7
+ # Archipel Repository Pattern
8
+
9
+ ## Overview
10
+
11
+ Every Prisma model gets a dedicated **Repository class** extending `RepositoryBase`.
12
+ Repositories are the ONLY code that touches Prisma delegates. Services never call
13
+ Prisma directly — they call `repository.execute(someQuery(...))` or
14
+ `repository.executeTransactional(someTxQuery(...))`.
15
+
16
+ ## RepositoryBase Signature
17
+
18
+ ```typescript
19
+ import { RepositoryBase } from '@breadstone/archipel-platform-database';
20
+
21
+ export abstract class RepositoryBase<
22
+ TDelegate extends Record<RepositoryOperations, (args: any) => Promise<any>>,
23
+ TArgs extends Record<RepositoryOperations, unknown>,
24
+ TReturn extends Record<RepositoryOperations, unknown>,
25
+ TEntity = unknown
26
+ >
27
+ ```
28
+
29
+ ### Generic Parameters
30
+
31
+ | Param | Purpose | Example |
32
+ |-------|---------|---------|
33
+ | `TDelegate` | Prisma delegate type from generated client | `Prisma.UserDelegate` |
34
+ | `TArgs` | Argument shapes for each operation | `Prisma.UserFindManyArgs`, etc. |
35
+ | `TReturn` | Return shapes for each operation | `User`, `User[]`, etc. |
36
+ | `TEntity` | Domain entity interface (optional) | `IUserEntity` |
37
+
38
+ ### Helper Types
39
+
40
+ ```typescript
41
+ import { DelegateArgs, DelegateReturnTypes } from '@breadstone/archipel-platform-database';
42
+
43
+ // These extract args and return types from a delegate automatically:
44
+ type UserArgs = DelegateArgs<Prisma.UserDelegate>;
45
+ type UserReturns = DelegateReturnTypes<Prisma.UserDelegate>;
46
+ ```
47
+
48
+ ## How to Create a Repository
49
+
50
+ ### Step 1: Create the repository class
51
+
52
+ ```typescript
53
+ // repositories/UserRepository.ts
54
+ import { Injectable } from '@nestjs/common';
55
+ import { Prisma } from '@prisma/client';
56
+ import {
57
+ DatabaseService,
58
+ DelegateArgs,
59
+ DelegateReturnTypes,
60
+ RepositoryBase,
61
+ } from '@breadstone/archipel-platform-database';
62
+
63
+ @Injectable()
64
+ export class UserRepository extends RepositoryBase<
65
+ Prisma.UserDelegate,
66
+ DelegateArgs<Prisma.UserDelegate>,
67
+ DelegateReturnTypes<Prisma.UserDelegate>,
68
+ IUserEntity
69
+ > {
70
+
71
+ // #region Ctor
72
+
73
+ public constructor(db: DatabaseService) {
74
+ super(db, db.client.user);
75
+ }
76
+
77
+ // #endregion
78
+
79
+ }
80
+ ```
81
+
82
+ The constructor receives `DatabaseService` and passes both the service and the
83
+ Prisma delegate (`db.client.user`) to the base class.
84
+
85
+ ### Step 2: Register as a provider in a module
86
+
87
+ ```typescript
88
+ @Module({
89
+ imports: [DatabaseModule.register()],
90
+ providers: [UserRepository, UserService],
91
+ exports: [UserService],
92
+ })
93
+ export class UserModule {}
94
+ ```
95
+
96
+ ### Step 3: Inject into a service
97
+
98
+ ```typescript
99
+ @Injectable()
100
+ export class UserService {
101
+
102
+ // #region Fields
103
+
104
+ private readonly _userRepository: UserRepository;
105
+
106
+ // #endregion
107
+
108
+ // #region Ctor
109
+
110
+ public constructor(userRepository: UserRepository) {
111
+ this._userRepository = userRepository;
112
+ }
113
+
114
+ // #endregion
115
+
116
+ // #region Methods
117
+
118
+ public async findById(id: string): Promise<IUserEntity | null> {
119
+ return this._userRepository.execute(findUserByIdQuery(id));
120
+ }
121
+
122
+ public async findAll(skip = 0, take = 20): Promise<IUserEntity[]> {
123
+ return this._userRepository.execute(findAllUsersQuery(skip, take));
124
+ }
125
+
126
+ // #endregion
127
+
128
+ }
129
+ ```
130
+
131
+ ## Key Methods on RepositoryBase
132
+
133
+ ### execute(query)
134
+
135
+ Primary method for data access. Delegates to a query object.
136
+
137
+ ```typescript
138
+ public execute<TResult>(query: IRepositoryQuery<TDelegate, TResult>): Promise<TResult>
139
+ ```
140
+
141
+ ### executeTransactional(query)
142
+
143
+ For multi-model operations within a transaction.
144
+
145
+ ```typescript
146
+ public executeTransactional<TResult>(query: ITransactionalRepositoryQuery<TResult>): Promise<TResult>
147
+ ```
148
+
149
+ ### Direct Methods (for legacy or internal use only)
150
+
151
+ The base class also exposes `findUnique`, `findMany`, `findFirst`, `create`,
152
+ `createMany`, `update`, `updateMany`, `upsert`, `delete`, `deleteMany`,
153
+ `aggregate`, `count`, `groupBy`, `merge`.
154
+
155
+ **Important:** New code should use `execute(query)` exclusively.
156
+ Direct method calls are available but violate the query pattern convention.
157
+
158
+ ### findMany with Pagination
159
+
160
+ ```typescript
161
+ // Direct method (legacy)
162
+ const results = await this._repository.findMany(args, { page: 1, perPage: 20 });
163
+ ```
164
+
165
+ ## Error Handling
166
+
167
+ All Prisma errors are caught by the base class `tryCatch` wrapper and re-thrown
168
+ as `RepositoryError`:
169
+
170
+ - `PrismaClientKnownRequestError` → `RepositoryError` with code `'R_KNOWN'`
171
+ - `PrismaClientUnknownRequestError` → `RepositoryError` with code `'R_UNKNOWN'`
172
+ - Other errors are re-thrown unchanged
173
+
174
+ The global `RepositoryExceptionFilter` catches `RepositoryError` and returns
175
+ HTTP 500 with a structured envelope.
176
+
177
+ ## Query Integration
178
+
179
+ Repositories work with query factories from the query pattern:
180
+
181
+ ```typescript
182
+ // queries/findUserByIdQuery.ts
183
+ import { Prisma } from '@prisma/client';
184
+ import { query } from '@breadstone/archipel-platform-database';
185
+
186
+ export function findUserByIdQuery(id: string) {
187
+ return query<Prisma.UserDelegate, IUserEntity | null>(
188
+ 'findUserById',
189
+ (model) => model.findFirst({
190
+ where: { id },
191
+ select: { id: true, email: true, name: true, createdAt: true },
192
+ }),
193
+ );
194
+ }
195
+
196
+ // Service usage:
197
+ const user = await this._userRepository.execute(findUserByIdQuery(id));
198
+ ```
199
+
200
+ ## Rules
201
+
202
+ 1. **One repository per Prisma model** — e.g. `UserRepository`, `OrderRepository`.
203
+ 2. **Constructor receives `DatabaseService`** and passes the delegate via `db.client.<model>`.
204
+ 3. **Use `DelegateArgs` and `DelegateReturnTypes`** helper types for the RepositoryBase generics.
205
+ 4. **New code uses `execute(query)`** — never direct calls like `repository.findFirst()` from services.
206
+ 5. **Register as provider** in the feature module, import `DatabaseModule.register()`.
207
+ 6. **Repositories are `@Injectable()`** — they participate in NestJS DI.
208
+ 7. **Domain entity interface as fourth generic** (`TEntity`) is optional but recommended.
@@ -1,35 +1,34 @@
1
- "use strict";
2
- /**
3
- * Static knowledge content for the Archipel testing pattern.
4
- * Returned by the get-testing-pattern tool.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.TESTING_PATTERN_KNOWLEDGE = void 0;
8
- exports.TESTING_PATTERN_KNOWLEDGE = `# Archipel Testing Pattern
1
+ ---
2
+ title: Testing Pattern
3
+ description: Vitest conventions, mocking patterns for repositories/services/delegates, AAA structure, and test naming conventions.
4
+ order: 9
5
+ ---
6
+
7
+ # Archipel Testing Pattern
9
8
 
10
9
  ## Overview
11
10
 
12
11
  Archipel uses **Vitest** for unit and integration tests with **vi mocking**. Tests follow
13
- the Arrange-Act-Assert (AAA) pattern with descriptive \`describe\`/\`it\` blocks. Each test
12
+ the Arrange-Act-Assert (AAA) pattern with descriptive `describe`/`it` blocks. Each test
14
13
  file covers a single class or module.
15
14
 
16
15
  ## Test Framework
17
16
 
18
17
  - **Runner:** Vitest
19
- - **Mocking:** \`vi.fn()\`, \`vi.mock()\`, \`vi.spyOn()\`
20
- - **Assertions:** Vitest built-in (\`expect\`)
18
+ - **Mocking:** `vi.fn()`, `vi.mock()`, `vi.spyOn()`
19
+ - **Assertions:** Vitest built-in (`expect`)
21
20
  - **E2E:** Supertest against a bootstrapped NestJS app
22
21
 
23
22
  ## File Naming & Location
24
23
 
25
24
  | Test Type | File Pattern | Location |
26
25
  |-----------|-------------|----------|
27
- | Unit test | \`*.spec.ts\` | Next to the source file |
28
- | E2E test | \`*.e2e-spec.ts\` | \`test/\` directory |
26
+ | Unit test | `*.spec.ts` | Next to the source file |
27
+ | E2E test | `*.e2e-spec.ts` | `test/` directory |
29
28
 
30
29
  ## Basic Test Structure
31
30
 
32
- \`\`\`typescript
31
+ ```typescript
33
32
  import { beforeEach, describe, expect, it, vi } from 'vitest';
34
33
 
35
34
  describe('UserService', () => {
@@ -88,13 +87,13 @@ describe('UserService', () => {
88
87
  // #endregion
89
88
 
90
89
  });
91
- \`\`\`
90
+ ```
92
91
 
93
92
  ## Mocking Patterns
94
93
 
95
94
  ### Mocking Prisma Delegates (for Repository Tests)
96
95
 
97
- \`\`\`typescript
96
+ ```typescript
98
97
  vi.mock('@prisma/client/runtime/client', () => ({
99
98
  PrismaClientKnownRequestError: class PrismaClientKnownRequestError extends Error {
100
99
  public code: string;
@@ -117,11 +116,11 @@ vi.mock('@prisma/client/runtime/client', () => ({
117
116
  }
118
117
  },
119
118
  }));
120
- \`\`\`
119
+ ```
121
120
 
122
121
  ### Creating a Mock Delegate
123
122
 
124
- \`\`\`typescript
123
+ ```typescript
125
124
  type MockDelegate = Record<
126
125
  | 'aggregate' | 'count' | 'create' | 'createMany' | 'createManyAndReturn'
127
126
  | 'delete' | 'deleteMany' | 'findFirst' | 'findFirstOrThrow'
@@ -150,31 +149,31 @@ function createMockDelegate(): MockDelegate {
150
149
  findUniqueOrThrow: vi.fn(),
151
150
  };
152
151
  }
153
- \`\`\`
152
+ ```
154
153
 
155
154
  ### Mocking DatabaseService
156
155
 
157
- \`\`\`typescript
156
+ ```typescript
158
157
  const mockDb = {
159
158
  transactionCallback: vi.fn(),
160
159
  client: {
161
160
  user: createMockDelegate(),
162
161
  },
163
162
  } as unknown as DatabaseService;
164
- \`\`\`
163
+ ```
165
164
 
166
165
  ### Mocking a Query
167
166
 
168
- \`\`\`typescript
167
+ ```typescript
169
168
  const mockQuery = {
170
169
  name: 'findUserById',
171
170
  run: vi.fn().mockResolvedValue({ id: '1', email: 'test@example.com' }),
172
171
  };
173
- \`\`\`
172
+ ```
174
173
 
175
174
  ## Repository Test Pattern
176
175
 
177
- \`\`\`typescript
176
+ ```typescript
178
177
  import { beforeEach, describe, expect, it, vi } from 'vitest';
179
178
 
180
179
  // Mock Prisma runtime errors BEFORE importing test subject
@@ -228,11 +227,11 @@ describe('UserRepository', () => {
228
227
  });
229
228
 
230
229
  });
231
- \`\`\`
230
+ ```
232
231
 
233
232
  ## Service Test Pattern
234
233
 
235
- \`\`\`typescript
234
+ ```typescript
236
235
  describe('ProductService', () => {
237
236
 
238
237
  let service: ProductService;
@@ -268,11 +267,11 @@ describe('ProductService', () => {
268
267
  });
269
268
 
270
269
  });
271
- \`\`\`
270
+ ```
272
271
 
273
272
  ## Mapping Profile Test Pattern
274
273
 
275
- \`\`\`typescript
274
+ ```typescript
276
275
  describe('ProductMappingProfile', () => {
277
276
 
278
277
  let mappingService: MappingService;
@@ -304,23 +303,23 @@ describe('ProductMappingProfile', () => {
304
303
  });
305
304
 
306
305
  });
307
- \`\`\`
306
+ ```
308
307
 
309
308
  ## Test Conventions
310
309
 
311
310
  ### Comments
312
311
 
313
- \`\`\`typescript
312
+ ```typescript
314
313
  // Use AAA comments:
315
314
  // arrange — set up test data and mocks
316
315
  // act — call the method under test
317
316
  // act & assert — when the assertion is on the thrown error
318
317
  // assert — verify the outcome
319
- \`\`\`
318
+ ```
320
319
 
321
320
  ### Regions
322
321
 
323
- \`\`\`typescript
322
+ ```typescript
324
323
  describe('MyClass', () => {
325
324
 
326
325
  // #region Fields
@@ -334,23 +333,21 @@ describe('MyClass', () => {
334
333
  // #endregion
335
334
 
336
335
  });
337
- \`\`\`
336
+ ```
338
337
 
339
338
  ### Naming
340
339
 
341
- - \`describe\` blocks: Class name or method name
342
- - \`it\` blocks: \`'should <expected behavior> when <condition>'\`
340
+ - `describe` blocks: Class name or method name
341
+ - `it` blocks: `'should <expected behavior> when <condition>'`
343
342
 
344
343
  ## Rules
345
344
 
346
345
  1. **Every public service method needs at least one happy-path and one failure-path test.**
347
- 2. **Use \`vi.restoreAllMocks()\` in \`beforeEach\`** — prevent mock leakage between tests.
346
+ 2. **Use `vi.restoreAllMocks()` in `beforeEach`** — prevent mock leakage between tests.
348
347
  3. **Mock at the boundary** — mock repositories in service tests, mock delegates in repository tests.
349
348
  4. **AAA pattern** — clearly separate arrange, act, assert with comments.
350
- 5. **\`vi.mock()\` for modules must appear before imports** of the mocked module.
349
+ 5. **`vi.mock()` for modules must appear before imports** of the mocked module.
351
350
  6. **No real database in unit tests** — use mocks. Use Testcontainers for integration tests.
352
351
  7. **Assert on behavior, not implementation** — verify return values and thrown errors, not internal calls
353
352
  (unless the call IS the behavior, e.g., verifying a repository was called).
354
- 8. **Use \`mockResolvedValue\` / \`mockRejectedValue\`** for async mocks.
355
- `;
356
- //# sourceMappingURL=testingPattern.js.map
353
+ 8. **Use `mockResolvedValue` / `mockRejectedValue`** for async mocks.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breadstone/archipel-mcp",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "MCP server providing Archipel platform knowledge — documentation, query patterns, and coding conventions — to AI development tools.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/main.js",
@@ -0,0 +1,12 @@
1
+ import type { IPatternDoc } from './models/IPatternDoc';
2
+ /**
3
+ * Loads and indexes Archipel code patterns from the `.docs/patterns/`
4
+ * directory (monorepo dev) or from the bundled `data/patterns/` directory
5
+ * (published npm package).
6
+ */
7
+ export declare class PatternsLoader {
8
+ private readonly _patterns;
9
+ get patterns(): ReadonlyMap<string, IPatternDoc>;
10
+ load(): void;
11
+ private resolvePatternsDirectory;
12
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PatternsLoader = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const gray_matter_1 = tslib_1.__importDefault(require("gray-matter"));
6
+ const fs = tslib_1.__importStar(require("node:fs"));
7
+ const path = tslib_1.__importStar(require("node:path"));
8
+ /**
9
+ * Loads and indexes Archipel code patterns from the `.docs/patterns/`
10
+ * directory (monorepo dev) or from the bundled `data/patterns/` directory
11
+ * (published npm package).
12
+ */
13
+ class PatternsLoader {
14
+ // #region Fields
15
+ _patterns = new Map();
16
+ // #endregion
17
+ // #region Properties
18
+ get patterns() {
19
+ return this._patterns;
20
+ }
21
+ // #endregion
22
+ // #region Methods
23
+ load() {
24
+ const patternsDirectory = this.resolvePatternsDirectory();
25
+ if (!patternsDirectory) {
26
+ process.stderr.write('[archipel-mcp] Warning: Could not locate patterns directory.\n');
27
+ return;
28
+ }
29
+ const files = fs.readdirSync(patternsDirectory).filter((file) => file.endsWith('.md') && file !== 'index.md');
30
+ for (const file of files) {
31
+ const filePath = path.join(patternsDirectory, file);
32
+ const raw = fs.readFileSync(filePath, 'utf-8');
33
+ const parsed = (0, gray_matter_1.default)(raw);
34
+ const name = path.basename(file, '.md');
35
+ this._patterns.set(name, {
36
+ name,
37
+ title: parsed.data['title'] || name,
38
+ description: parsed.data['description'] || '',
39
+ order: parsed.data['order'] || 999,
40
+ content: parsed.content.trim(),
41
+ });
42
+ }
43
+ process.stderr.write(`[archipel-mcp] Loaded ${this._patterns.size} pattern(s)\n`);
44
+ }
45
+ resolvePatternsDirectory() {
46
+ // 1. Bundled data (published npm package)
47
+ const bundledPath = path.resolve(__dirname, '..', 'data', 'patterns');
48
+ if (fs.existsSync(bundledPath)) {
49
+ return bundledPath;
50
+ }
51
+ // 2. Workspace root (monorepo dev)
52
+ const cwdPath = path.resolve(process.cwd(), '.docs', 'patterns');
53
+ if (fs.existsSync(cwdPath)) {
54
+ return cwdPath;
55
+ }
56
+ // 3. Relative from compiled source (dist/tools/mcp/src/)
57
+ const relativePath = path.resolve(__dirname, '..', '..', '..', '..', '.docs', 'patterns');
58
+ if (fs.existsSync(relativePath)) {
59
+ return relativePath;
60
+ }
61
+ return null;
62
+ }
63
+ }
64
+ exports.PatternsLoader = PatternsLoader;
65
+ //# sourceMappingURL=PatternsLoader.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generates a full mapping example (input interface, key, profile, module registration,
3
+ * controller usage) for a given entity and its target response class.
4
+ */
5
+ export declare function MAPPING_PATTERN_WITH_CONTEXT(entityName: string, fields: string[], responseName: string): string;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAPPING_PATTERN_WITH_CONTEXT = MAPPING_PATTERN_WITH_CONTEXT;
4
+ /**
5
+ * Generates a full mapping example (input interface, key, profile, module registration,
6
+ * controller usage) for a given entity and its target response class.
7
+ */
8
+ function MAPPING_PATTERN_WITH_CONTEXT(entityName, fields, responseName) {
9
+ return `
10
+ ## Example: Mapping for "${entityName}" → "${responseName}"
11
+
12
+ Given an entity \`${entityName}\` with fields: ${fields.map((f) => `\`${f}\``).join(', ')}
13
+
14
+ ### 1. Input Interface
15
+
16
+ \`\`\`typescript
17
+ // models/mapping-inputs/I${entityName}MappingInput.ts
18
+
19
+ export interface I${entityName}MappingInput {
20
+ ${fields.map((f) => ` readonly ${f}: ${inferMappingFieldType(f)};`).join('\n')}
21
+ }
22
+ \`\`\`
23
+
24
+ ### 2. Mapping Key
25
+
26
+ \`\`\`typescript
27
+ // constants/MappingKeys.ts
28
+ import { createMappingKey } from '@breadstone/archipel-platform-mapping';
29
+ import { I${entityName}MappingInput } from '../models/mapping-inputs/I${entityName}MappingInput';
30
+ import { ${responseName} } from '../dtos/${responseName}';
31
+
32
+ export const ${toConstantCase(entityName)}_MAPPING_KEY = createMappingKey<I${entityName}MappingInput, ${responseName}>('${toDotNotation(entityName)}');
33
+ \`\`\`
34
+
35
+ ### 3. Mapping Profile
36
+
37
+ \`\`\`typescript
38
+ // mappers/${entityName}MappingProfile.ts
39
+ import { MappingProfileBase, IMappingBuilder } from '@breadstone/archipel-platform-mapping';
40
+ import { ${toConstantCase(entityName)}_MAPPING_KEY } from '../constants/MappingKeys';
41
+ import { I${entityName}MappingInput } from '../models/mapping-inputs/I${entityName}MappingInput';
42
+ import { ${responseName} } from '../dtos/${responseName}';
43
+
44
+ export class ${entityName}MappingProfile extends MappingProfileBase {
45
+
46
+ // #region Methods
47
+
48
+ public configure(builder: IMappingBuilder): void {
49
+ builder.createKeyedMap(${toConstantCase(entityName)}_MAPPING_KEY, (input: I${entityName}MappingInput) => {
50
+ const response = new ${responseName}();
51
+ ${fields.map((f) => ` response.${f} = input.${f};`).join('\n')}
52
+
53
+ return response;
54
+ });
55
+ }
56
+
57
+ // #endregion
58
+
59
+ }
60
+ \`\`\`
61
+
62
+ ### 4. Module Registration
63
+
64
+ \`\`\`typescript
65
+ import { MappingModule } from '@breadstone/archipel-platform-mapping';
66
+ import { ${entityName}MappingProfile } from './mappers/${entityName}MappingProfile';
67
+
68
+ @Module({
69
+ imports: [
70
+ MappingModule.withProfiles([${entityName}MappingProfile]),
71
+ ],
72
+ })
73
+ export class ${entityName}Module {}
74
+ \`\`\`
75
+
76
+ ### 5. Controller Usage
77
+
78
+ \`\`\`typescript
79
+ // In a controller method:
80
+ const entity = await this._${lowerFirst(entityName)}Service.findById(id);
81
+ const response = this._mappingService.map(${toConstantCase(entityName)}_MAPPING_KEY, entity);
82
+ \`\`\`
83
+ `;
84
+ }
85
+ function inferMappingFieldType(fieldName) {
86
+ if (fieldName === 'id')
87
+ return 'string';
88
+ if (fieldName.endsWith('Id'))
89
+ return 'string';
90
+ if (fieldName.endsWith('At') || fieldName === 'createdAt' || fieldName === 'updatedAt')
91
+ return 'Date';
92
+ if (fieldName.startsWith('is') || fieldName.startsWith('has'))
93
+ return 'boolean';
94
+ if (fieldName === 'count' || fieldName === 'quantity' || fieldName === 'amount' || fieldName === 'price')
95
+ return 'number';
96
+ return 'string';
97
+ }
98
+ function toConstantCase(name) {
99
+ return name.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
100
+ }
101
+ function toDotNotation(name) {
102
+ return name.replace(/([a-z])([A-Z])/g, '$1.$2').toLowerCase();
103
+ }
104
+ function lowerFirst(str) {
105
+ return str.charAt(0).toLowerCase() + str.slice(1);
106
+ }
107
+ //# sourceMappingURL=mappingPatternGenerator.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generates a dynamic NestJS module example with ports, options interface,
3
+ * module class, and consumer registration for the given module and port names.
4
+ */
5
+ export declare function MODULE_PATTERN_WITH_CONTEXT(moduleName: string, ports: string[]): string;