@venizia/ignis-docs 0.0.8 → 0.2.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.
Files changed (180) hide show
  1. package/README.md +7 -7
  2. package/content/best-practices/api-usage-examples.md +15 -12
  3. package/content/best-practices/architectural-patterns.md +70 -78
  4. package/content/best-practices/architecture-decisions.md +91 -60
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
  6. package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
  7. package/content/best-practices/code-style-standards/control-flow.md +5 -2
  8. package/content/best-practices/code-style-standards/documentation.md +13 -13
  9. package/content/best-practices/code-style-standards/function-patterns.md +9 -10
  10. package/content/best-practices/code-style-standards/index.md +1 -1
  11. package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
  12. package/content/best-practices/code-style-standards/route-definitions.md +30 -12
  13. package/content/best-practices/code-style-standards/tooling.md +8 -5
  14. package/content/best-practices/code-style-standards/type-safety.md +13 -12
  15. package/content/best-practices/common-pitfalls.md +56 -37
  16. package/content/best-practices/contribution-workflow.md +13 -14
  17. package/content/best-practices/data-modeling.md +46 -22
  18. package/content/best-practices/deployment-strategies.md +28 -27
  19. package/content/best-practices/error-handling.md +48 -24
  20. package/content/best-practices/index.md +5 -5
  21. package/content/best-practices/performance-optimization.md +40 -31
  22. package/content/best-practices/security-guidelines.md +52 -23
  23. package/content/best-practices/testing-strategies.md +65 -51
  24. package/content/best-practices/troubleshooting-tips.md +24 -24
  25. package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
  26. package/content/extensions/components/authentication/api.md +19 -19
  27. package/content/extensions/components/authentication/errors.md +7 -7
  28. package/content/extensions/components/authentication/index.md +10 -8
  29. package/content/extensions/components/authentication/usage.md +101 -6
  30. package/content/extensions/components/authorization/api.md +45 -25
  31. package/content/extensions/components/authorization/errors.md +6 -6
  32. package/content/extensions/components/authorization/index.md +11 -10
  33. package/content/extensions/components/authorization/usage.md +21 -21
  34. package/content/extensions/components/health-check.md +1 -1
  35. package/content/extensions/components/index.md +5 -5
  36. package/content/extensions/components/mail/errors.md +15 -15
  37. package/content/extensions/components/mail/index.md +1 -2
  38. package/content/extensions/components/mail/usage.md +1 -1
  39. package/content/extensions/components/request-tracker.md +1 -1
  40. package/content/extensions/components/socket-io/api.md +9 -9
  41. package/content/extensions/components/socket-io/errors.md +5 -5
  42. package/content/extensions/components/socket-io/index.md +8 -8
  43. package/content/extensions/components/socket-io/usage.md +1 -1
  44. package/content/extensions/components/static-asset/api.md +17 -4
  45. package/content/extensions/components/static-asset/errors.md +4 -4
  46. package/content/extensions/components/static-asset/index.md +26 -28
  47. package/content/extensions/components/static-asset/usage.md +13 -12
  48. package/content/extensions/components/template/index.md +2 -2
  49. package/content/extensions/components/template/setup-page.md +1 -1
  50. package/content/extensions/components/websocket/api.md +3 -3
  51. package/content/extensions/components/websocket/errors.md +5 -5
  52. package/content/extensions/components/websocket/index.md +5 -5
  53. package/content/extensions/components/websocket/usage.md +3 -3
  54. package/content/extensions/helpers/cron/index.md +2 -2
  55. package/content/extensions/helpers/crypto/index.md +1 -1
  56. package/content/extensions/helpers/env/index.md +27 -12
  57. package/content/extensions/helpers/error/index.md +81 -25
  58. package/content/extensions/helpers/index.md +2 -3
  59. package/content/extensions/helpers/inversion/index.md +15 -7
  60. package/content/extensions/helpers/kafka/compile-binary.md +92 -0
  61. package/content/extensions/helpers/kafka/examples.md +1 -1
  62. package/content/extensions/helpers/kafka/index.md +3 -0
  63. package/content/extensions/helpers/logger/index.md +32 -2
  64. package/content/extensions/helpers/network/index.md +6 -0
  65. package/content/extensions/helpers/queue/index.md +14 -17
  66. package/content/extensions/helpers/redis/index.md +548 -323
  67. package/content/extensions/helpers/socket-io/index.md +14 -10
  68. package/content/extensions/helpers/storage/api.md +44 -8
  69. package/content/extensions/helpers/storage/index.md +43 -7
  70. package/content/extensions/helpers/template/index.md +6 -3
  71. package/content/extensions/helpers/types/index.md +11 -8
  72. package/content/extensions/helpers/websocket/api.md +9 -9
  73. package/content/extensions/helpers/websocket/index.md +7 -7
  74. package/content/extensions/helpers/worker-thread/index.md +2 -2
  75. package/content/extensions/index.md +3 -4
  76. package/content/extensions/src-details/mcp-server.md +18 -24
  77. package/content/guides/core-concepts/application/bootstrapping.md +11 -14
  78. package/content/guides/core-concepts/application/index.md +3 -3
  79. package/content/guides/core-concepts/components.md +19 -10
  80. package/content/guides/core-concepts/dependency-injection.md +6 -3
  81. package/content/guides/core-concepts/grpc-controllers.md +6 -5
  82. package/content/guides/core-concepts/persistent/datasources.md +42 -43
  83. package/content/guides/core-concepts/persistent/index.md +16 -7
  84. package/content/guides/core-concepts/persistent/models.md +24 -20
  85. package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
  86. package/content/guides/core-concepts/persistent/repositories.md +40 -23
  87. package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
  88. package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
  89. package/content/guides/core-concepts/persistent/transactions.md +61 -25
  90. package/content/guides/core-concepts/rest-controllers.md +12 -9
  91. package/content/guides/core-concepts/services.md +330 -60
  92. package/content/guides/get-started/5-minute-quickstart.md +15 -15
  93. package/content/guides/get-started/philosophy.md +36 -36
  94. package/content/guides/get-started/setup.md +3 -3
  95. package/content/guides/index.md +3 -3
  96. package/content/guides/migrations/redis-helpers-migration.md +177 -0
  97. package/content/guides/migrations/scoped-rbac-migration.md +17 -17
  98. package/content/guides/migrations/unified-connectors-migration.md +113 -0
  99. package/content/guides/reference/glossary.md +19 -12
  100. package/content/guides/reference/mcp-docs-server.md +22 -18
  101. package/content/guides/tutorials/building-a-crud-api.md +37 -44
  102. package/content/guides/tutorials/complete-installation.md +17 -17
  103. package/content/guides/tutorials/ecommerce-api.md +163 -124
  104. package/content/guides/tutorials/realtime-chat.md +181 -135
  105. package/content/guides/tutorials/testing.md +65 -523
  106. package/content/index.md +2 -180
  107. package/content/public/apple-touch-icon.png +0 -0
  108. package/content/public/og-image.png +0 -0
  109. package/content/public/site.webmanifest +11 -0
  110. package/content/references/base/application.md +4 -5
  111. package/content/references/base/bootstrapping.md +18 -5
  112. package/content/references/base/components.md +149 -120
  113. package/content/references/base/connectors.md +178 -0
  114. package/content/references/base/controllers.md +41 -30
  115. package/content/references/base/datasources.md +163 -92
  116. package/content/references/base/dependency-injection.md +34 -22
  117. package/content/references/base/filter-system/application-usage.md +17 -14
  118. package/content/references/base/filter-system/array-operators.md +7 -2
  119. package/content/references/base/filter-system/comparison-operators.md +3 -0
  120. package/content/references/base/filter-system/default-filter.md +89 -71
  121. package/content/references/base/filter-system/fields-order-pagination.md +22 -22
  122. package/content/references/base/filter-system/index.md +6 -3
  123. package/content/references/base/filter-system/json-filtering.md +20 -1
  124. package/content/references/base/filter-system/list-operators.md +1 -1
  125. package/content/references/base/filter-system/logical-operators.md +33 -1
  126. package/content/references/base/filter-system/null-operators.md +30 -1
  127. package/content/references/base/filter-system/quick-reference.md +23 -4
  128. package/content/references/base/filter-system/tips.md +5 -5
  129. package/content/references/base/filter-system/use-cases.md +12 -12
  130. package/content/references/base/grpc-controllers.md +13 -13
  131. package/content/references/base/index.md +24 -12
  132. package/content/references/base/middlewares.md +265 -327
  133. package/content/references/base/models.md +63 -49
  134. package/content/references/base/providers.md +136 -130
  135. package/content/references/base/repositories/advanced.md +59 -58
  136. package/content/references/base/repositories/index.md +115 -91
  137. package/content/references/base/repositories/mixins.md +55 -291
  138. package/content/references/base/repositories/relations.md +54 -64
  139. package/content/references/base/repositories/soft-deletable.md +31 -30
  140. package/content/references/base/services.md +296 -93
  141. package/content/references/configuration/environment-variables.md +49 -31
  142. package/content/references/configuration/index.md +6 -6
  143. package/content/references/index.md +17 -12
  144. package/content/references/quick-reference.md +65 -106
  145. package/content/references/utilities/crypto.md +65 -23
  146. package/content/references/utilities/index.md +3 -3
  147. package/content/references/utilities/jsx.md +6 -4
  148. package/content/references/utilities/module.md +68 -20
  149. package/content/references/utilities/parse.md +4 -14
  150. package/content/references/utilities/promise.md +9 -7
  151. package/content/references/utilities/schema.md +5 -3
  152. package/dist/mcp-server/common/guards.d.ts +8 -0
  153. package/dist/mcp-server/common/guards.d.ts.map +1 -0
  154. package/dist/mcp-server/common/guards.js +14 -0
  155. package/dist/mcp-server/common/guards.js.map +1 -0
  156. package/dist/mcp-server/common/index.d.ts +1 -0
  157. package/dist/mcp-server/common/index.d.ts.map +1 -1
  158. package/dist/mcp-server/common/index.js +1 -0
  159. package/dist/mcp-server/common/index.js.map +1 -1
  160. package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
  161. package/dist/mcp-server/helpers/docs.helper.js +4 -2
  162. package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
  163. package/dist/mcp-server/helpers/github.helper.js +1 -1
  164. package/dist/mcp-server/index.js +7 -2
  165. package/dist/mcp-server/index.js.map +1 -1
  166. package/dist/mcp-server/tools/base.tool.d.ts +6 -2
  167. package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
  168. package/dist/mcp-server/tools/base.tool.js.map +1 -1
  169. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
  170. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  171. package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
  172. package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
  173. package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
  174. package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
  175. package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
  176. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
  177. package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
  178. package/package.json +9 -9
  179. package/content/extensions/helpers/testing/index.md +0 -510
  180. package/content/references/base/middleware.md +0 -347
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  # :fire: IGNIS - @venizia/ignis-docs
4
4
 
5
- **Documentation site and MCP server for the Ignis Framework**
5
+ **Documentation site and MCP server for the IGNIS Framework**
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@venizia/ignis-docs.svg?style=flat-square&color=cb3837)](https://www.npmjs.com/package/@venizia/ignis-docs)
8
8
  [![License](https://img.shields.io/badge/License-MIT-3DA639.svg?style=flat-square)](https://opensource.org/licenses/MIT)
9
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6.svg?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
10
10
  [![MCP](https://img.shields.io/badge/MCP-Compatible-8B5CF6.svg?style=flat-square)](https://modelcontextprotocol.io/)
11
11
 
12
- VitePress-powered documentation site and an MCP server with 11 tools that gives AI assistants real-time access to Ignis knowledge -- search docs, browse source code, and verify dependencies.
12
+ VitePress-powered documentation site and an MCP server with 11 tools that gives AI assistants real-time access to IGNIS knowledge -- search docs, browse source code, and verify dependencies.
13
13
 
14
14
  [Installation](#installation) • [MCP Setup](#mcp-server-setup) • [Available Tools](#available-mcp-tools) • [Online Docs](https://venizia-ai.github.io/ignis)
15
15
 
@@ -106,13 +106,13 @@ Add to your Claude Code MCP settings:
106
106
  | **listDocs** | List all available documentation pages |
107
107
  | **listCategories** | List documentation categories and their structure |
108
108
  | **getDocMetadata** | Get metadata (title, path, category) for a document |
109
- | **getPackageOverview** | Get an overview of a specific Ignis package |
109
+ | **getPackageOverview** | Get an overview of a specific IGNIS package |
110
110
 
111
111
  ### GitHub Tools
112
112
 
113
113
  | Tool | Description |
114
114
  | --- | --- |
115
- | **searchCode** | Search the Ignis source code by keyword |
115
+ | **searchCode** | Search the IGNIS source code by keyword |
116
116
  | **listProjectFiles** | List files in a specific directory of the repository |
117
117
  | **viewSourceFile** | View the contents of a source file |
118
118
  | **verifyDependencies** | Check dependency versions and compatibility |
@@ -140,7 +140,7 @@ bun run docs:preview
140
140
  wiki/
141
141
  ├── guides/ # Getting started, core concepts, tutorials
142
142
  ├── references/ # API documentation
143
- │ ├── base/ # BaseApplication, BaseController, BaseEntity, etc.
143
+ │ ├── base/ # BaseApplication, BaseRestController, BaseEntity, etc.
144
144
  │ ├── components/ # HealthCheck, Swagger, Auth, Mail, SocketIO, etc.
145
145
  │ ├── helpers/ # Logger, Redis, Queue, Storage, Crypto, etc.
146
146
  │ └── utilities/ # Parse, Date, Promise, Performance utilities
@@ -184,9 +184,9 @@ bun run mcp:rebuild
184
184
 
185
185
  ## Related Links
186
186
 
187
- - [Ignis Framework](https://github.com/VENIZIA-AI/ignis) -- Main repository
187
+ - [IGNIS Framework](https://github.com/VENIZIA-AI/ignis) -- Main repository
188
188
  - [Online Documentation](https://venizia-ai.github.io/ignis) -- Full documentation site
189
- - [MCP Server Guide](https://github.com/VENIZIA-AI/ignis/blob/main/packages/docs/wiki/get-started/mcp-docs-server.md) -- Detailed setup guide
189
+ - [MCP Server Guide](https://github.com/VENIZIA-AI/ignis/blob/main/docs/wiki/content/guides/reference/mcp-docs-server.md) -- Detailed setup guide
190
190
  - [Model Context Protocol](https://modelcontextprotocol.io/) -- MCP specification
191
191
 
192
192
  ---
@@ -1,6 +1,6 @@
1
1
  # API Usage Examples
2
2
 
3
- Practical examples for defining endpoints and working with data in Ignis applications.
3
+ Practical examples for defining endpoints and working with data in IGNIS applications.
4
4
 
5
5
  ## Routing Patterns
6
6
 
@@ -28,7 +28,7 @@ export const RouteConfigs = {
28
28
  CREATE_ITEM: {
29
29
  method: HTTP.Methods.POST,
30
30
  path: '/items',
31
- authStrategies: [Authentication.STRATEGY_JWT], // Secure this endpoint
31
+ authenticate: { strategies: [Authentication.STRATEGY_JWT] }, // Secure this endpoint
32
32
  request: {
33
33
  body: jsonContent({
34
34
  description: 'Request body for POST',
@@ -229,7 +229,7 @@ const deleted = await configurationRepository.deleteById({
229
229
 
230
230
  ## Server-Side Rendering (JSX)
231
231
 
232
- Ignis supports server-side rendering using Hono's JSX middleware. This is useful for returning HTML content, such as landing pages or simple admin views.
232
+ IGNIS supports server-side rendering using Hono's JSX middleware. This is useful for returning HTML content, such as landing pages or simple admin views.
233
233
 
234
234
  **Usage:**
235
235
 
@@ -250,7 +250,7 @@ export class PageController extends BaseRestController {
250
250
  responses: htmlResponse({ description: 'HTML Welcome Page' }),
251
251
  },
252
252
  handler: (c) => {
253
- const title = 'Welcome to Ignis';
253
+ const title = 'Welcome to IGNIS';
254
254
 
255
255
  // Return JSX directly
256
256
  return c.html(
@@ -378,18 +378,20 @@ export class UserService extends BaseService {
378
378
  }
379
379
 
380
380
  async getUserWithOrders(userId: string) {
381
+ // findById returns the record or null (no wrapper object)
381
382
  const user = await this.userRepository.findById({ id: userId });
382
- if (!user.data) {
383
+ if (!user) {
383
384
  return null;
384
385
  }
385
386
 
387
+ // find returns a plain array
386
388
  const orders = await this.orderRepository.find({
387
389
  filter: { where: { userId } },
388
390
  });
389
391
 
390
392
  return {
391
- ...user.data,
392
- orders: orders.data,
393
+ ...user,
394
+ orders,
393
395
  };
394
396
  }
395
397
 
@@ -502,7 +504,7 @@ import { getError, HTTP } from '@venizia/ignis-helpers';
502
504
 
503
505
  // Basic error
504
506
  throw getError({ message: 'Something went wrong' });
505
- // Returns: { statusCode: 400, message: 'Something went wrong' }
507
+ // Returns: { statusCode: 400, message: 'Something went wrong', messageCode: 'core.system_error' }
506
508
 
507
509
  // With status code
508
510
  throw getError({
@@ -514,7 +516,7 @@ throw getError({
514
516
  throw getError({
515
517
  statusCode: 404,
516
518
  message: 'User not found',
517
- messageCode: 'USER_NOT_FOUND',
519
+ messageCode: 'core.user.not_found',
518
520
  });
519
521
  ```
520
522
 
@@ -527,14 +529,14 @@ async getUser(c: TRouteContext) {
527
529
 
528
530
  const user = await this.userRepository.findById({ id });
529
531
 
530
- if (!user.data) {
532
+ if (!user) {
531
533
  throw getError({
532
534
  statusCode: 404,
533
535
  message: `User with ID '${id}' not found`,
534
536
  });
535
537
  }
536
538
 
537
- return c.json(user.data, HTTP.ResultCodes.RS_2.Ok);
539
+ return c.json(user, HTTP.ResultCodes.RS_2.Ok);
538
540
  }
539
541
  ```
540
542
 
@@ -546,7 +548,7 @@ All errors are automatically formatted:
546
548
  {
547
549
  "statusCode": 404,
548
550
  "message": "User not found",
549
- "messageCode": "USER_NOT_FOUND",
551
+ "messageCode": "core.user.not_found",
550
552
  "requestId": "abc123"
551
553
  }
552
554
  ```
@@ -592,3 +594,4 @@ async processOrder(c: Context) {
592
594
  });
593
595
  }
594
596
  }
597
+ ```
@@ -1,10 +1,10 @@
1
1
  # Architectural Patterns
2
2
 
3
- Ignis promotes separation of concerns, dependency injection, and modularity for scalable, maintainable applications.
3
+ IGNIS promotes separation of concerns, dependency injection, and modularity for scalable, maintainable applications.
4
4
 
5
5
  ## 1. Layered Architecture
6
6
 
7
- Each layer has a single responsibility. Ignis supports **two architectural approaches**:
7
+ Each layer has a single responsibility. IGNIS supports **two architectural approaches**:
8
8
 
9
9
  ```mermaid
10
10
  graph TD
@@ -117,11 +117,11 @@ REST controllers extend `BaseRestController`, while gRPC controllers extend `Bas
117
117
 
118
118
  ## 3. Component-Based Modularity
119
119
 
120
- Components bundle a group of related, reusable, and pluggable features into self-contained modules. A single component can encapsulate multiple providers, services, controllers, and repositories, essentially functioning as a mini-application that can be easily "plugged in" to any Ignis project.
120
+ Components bundle a group of related, reusable, and pluggable features into self-contained modules. A single component can encapsulate multiple providers, services, controllers, and repositories, essentially functioning as a mini-application that can be easily "plugged in" to any IGNIS project.
121
121
 
122
122
  **Built-in Components:**
123
123
  - `AuthenticateComponent` - JWT authentication
124
- - `SwaggerComponent` - OpenAPI documentation
124
+ - `ApiReferenceComponent` - OpenAPI documentation
125
125
  - `HealthCheckComponent` - Health check endpoint
126
126
  - `RequestTrackerComponent` - Request logging
127
127
 
@@ -135,7 +135,7 @@ export class Application extends BaseApplication {
135
135
  // ...
136
136
  // Registering components plugs their functionality into the application.
137
137
  this.component(HealthCheckComponent);
138
- this.component(SwaggerComponent);
138
+ this.component(ApiReferenceComponent);
139
139
  // ...
140
140
  }
141
141
  }
@@ -154,7 +154,7 @@ You can encapsulate your own logic or third-party integrations (like Socket.IO,
154
154
  **Example (`SocketIOComponent`):**
155
155
 
156
156
  ```typescript
157
- import { BaseComponent, inject, CoreBindings, Binding } from '@venizia/ignis';
157
+ import { BaseApplication, BaseComponent, inject, CoreBindings, Binding } from '@venizia/ignis';
158
158
 
159
159
  export class MySocketComponent extends BaseComponent {
160
160
  constructor(
@@ -171,7 +171,7 @@ export class MySocketComponent extends BaseComponent {
171
171
  });
172
172
  }
173
173
 
174
- // The binding method is called during application startup (preConfigure)
174
+ // The binding method is called when the application configures components (registerComponents)
175
175
  override binding(): void {
176
176
  const options = this.application.get({ key: 'my.socket.options' });
177
177
 
@@ -185,7 +185,7 @@ export class MySocketComponent extends BaseComponent {
185
185
 
186
186
  ## 5. Application Lifecycle Hooks
187
187
 
188
- Ignis applications follow a predictable startup sequence with hooks for customization:
188
+ IGNIS applications follow a predictable startup sequence with hooks for customization:
189
189
 
190
190
  ```
191
191
  ┌─────────────────────────────────────────────────────────────┐
@@ -248,25 +248,25 @@ export class Application extends BaseApplication {
248
248
 
249
249
  // Components
250
250
  this.component(AuthenticateComponent);
251
- this.component(SwaggerComponent);
251
+ this.component(ApiReferenceComponent);
252
252
  }
253
253
 
254
254
  // Called after all registrations complete
255
255
  async postConfigure(): Promise<void> {
256
256
  // Access registered services
257
- const userRepo = this.get<UserRepository>({
257
+ const userRepository = this.get<UserRepository>({
258
258
  key: BindingKeys.build({
259
259
  namespace: BindingNamespaces.REPOSITORY,
260
260
  key: UserRepository.name,
261
261
  }),
262
262
  });
263
263
 
264
- // Seed initial data
265
- const adminExists = await userRepo.findOne({
264
+ // Seed initial data (findOne returns the record or null)
265
+ const adminExists = await userRepository.findOne({
266
266
  filter: { where: { role: 'admin' } },
267
267
  });
268
- if (!adminExists.data) {
269
- await userRepo.create({ data: { name: 'Admin', role: 'admin' } });
268
+ if (!adminExists) {
269
+ await userRepository.create({ data: { name: 'Admin', role: 'admin' } });
270
270
  }
271
271
  }
272
272
 
@@ -280,55 +280,40 @@ export class Application extends BaseApplication {
280
280
  > [!WARNING]
281
281
  > Do not register new datasources, components, or controllers in `postConfigure()`. They will not be automatically initialized. Use `preConfigure()` for all registrations.
282
282
 
283
- ## 6. Mixin Pattern
283
+ ## 6. Registration Surface & Capability Interfaces
284
284
 
285
- Mixins enable class composition without deep inheritance hierarchies. Ignis uses mixins to add capabilities to the `BaseApplication` class.
285
+ `BaseApplication` implements the full resource-registration surface directly - `service()`, `repository()`, `dataSource()`, `controller()`, `component()`, and `booter()`. Extend `BaseApplication` and call these methods straight from your lifecycle hooks; there is nothing to compose.
286
286
 
287
- **How Mixins Work:**
287
+ **How registration works:**
288
288
  ```typescript
289
- // A mixin is a function that takes a class and returns an extended class
290
- const ServiceMixin = <T extends TMixinTarget<AbstractApplication>>(baseClass: T) => {
291
- return class extends baseClass {
292
- service<Base extends IService>(ctor: TClass<Base>): Binding<Base> {
293
- return this.bind<Base>({
294
- key: BindingKeys.build({
295
- namespace: BindingNamespaces.SERVICE,
296
- key: ctor.name,
297
- }),
298
- }).toClass(ctor);
299
- }
300
- };
301
- };
289
+ // BaseApplication implements service() directly (no mixin composition):
290
+ service<Base extends IService>(ctor: TClass<Base>): Binding<Base> {
291
+ return this.bind<Base>({
292
+ key: BindingKeys.build({
293
+ namespace: BindingNamespaces.SERVICE,
294
+ key: ctor.name,
295
+ }),
296
+ }).toClass(ctor);
297
+ }
302
298
  ```
303
299
 
304
- **Available Mixins:**
300
+ **Capability interfaces:**
305
301
 
306
- | Mixin | Methods Added | Purpose |
307
- |-------|---------------|---------|
308
- | `ServiceMixin` | `service()` | Register service classes |
309
- | `RepositoryMixin` | `repository()`, `dataSource()`, `registerDataSources()` | Register data layer |
310
- | `ControllerMixin` | `controller()` | Register HTTP controllers |
311
- | `ComponentMixin` | `component()` | Register modular components |
302
+ Each registration capability is declared as a TypeScript interface that `IRestApplication` (and therefore `BaseApplication`) implements. Reference these when you type your own application contracts:
312
303
 
313
- **Composing Mixins:**
314
- ```typescript
315
- // The framework composes mixins like this:
316
- class AbstractApplication extends ComponentMixin(
317
- ControllerMixin(
318
- ServiceMixin(
319
- RepositoryMixin(BaseClass)
320
- )
321
- )
322
- ) {
323
- // Now has: service(), repository(), dataSource(), controller(), component()
324
- }
325
- ```
304
+ | Interface | Methods | Purpose |
305
+ |-----------|---------|---------|
306
+ | `IServiceMixin` | `service()` | Register service classes |
307
+ | `IRepositoryMixin` | `repository()`, `dataSource()`, `registerDataSources()` | Register data layer |
308
+ | `IComponentMixin` | `component()`, `registerComponents()` | Register modular components |
326
309
 
327
- **Why Mixins?**
328
- - Avoid "diamond inheritance" problems
329
- - Add capabilities selectively
330
- - Keep base classes focused
331
- - Enable code reuse across unrelated classes
310
+ > [!NOTE]
311
+ > Earlier releases also exported `ServiceMixin`, `RepositoryMixin`, and `ComponentMixin` as class-mixin **functions** you composed onto `AbstractApplication`. They duplicated `BaseApplication`'s own methods verbatim, drifted out of sync, and had no known consumers, so they were removed. The `IServiceMixin` / `IRepositoryMixin` / `IComponentMixin` **interfaces** remain - extend `BaseApplication` and call its registration methods directly.
312
+
313
+ **Why direct methods over composed mixins?**
314
+ - One implementation, no drift between a mixin and the base class
315
+ - Registration is available the moment you extend `BaseApplication`
316
+ - The interfaces still express each capability for typed contracts
332
317
 
333
318
  ## 7. Controller Factory Pattern
334
319
 
@@ -337,13 +322,13 @@ class AbstractApplication extends ComponentMixin(
337
322
  **Basic Usage:**
338
323
  ```typescript
339
324
  const _Controller = ControllerFactory.defineCrudController({
340
- entity: () => User,
325
+ entity: () => User, // Entity class or resolver function
341
326
  repository: { name: UserRepository.name },
342
327
  controller: {
343
328
  name: 'UserController',
344
329
  basePath: '/users',
345
- isStrict: true, // Enable strict validation
346
- defaultLimit: 50, // Default pagination limit
330
+ // Default: { path: true, requestSchema: true }
331
+ isStrict: { path: true, requestSchema: true },
347
332
  },
348
333
  });
349
334
 
@@ -366,14 +351,14 @@ const _Controller = ControllerFactory.defineCrudController({
366
351
  controller: { name: 'UserController', basePath: '/users' },
367
352
 
368
353
  // Apply JWT to all routes by default
369
- authStrategies: [Authentication.STRATEGY_JWT],
354
+ authenticate: { strategies: [Authentication.STRATEGY_JWT] },
370
355
 
371
356
  // Override per-route
372
357
  routes: {
373
358
  // Public read endpoints
374
- find: { skipAuth: true },
375
- findById: { skipAuth: true },
376
- count: { skipAuth: true },
359
+ find: { authenticate: { skip: true } },
360
+ findById: { authenticate: { skip: true } },
361
+ count: { authenticate: { skip: true } },
377
362
 
378
363
  // Protected write endpoints (use controller-level auth)
379
364
  create: {},
@@ -393,22 +378,26 @@ const _Controller = ControllerFactory.defineCrudController({
393
378
  routes: {
394
379
  // Custom request body schema for create
395
380
  create: {
396
- authStrategies: [Authentication.STRATEGY_JWT],
397
- requestBody: z.object({
398
- email: z.string().email(),
399
- name: z.string().min(2),
400
- // Exclude sensitive fields from client input
401
- }),
381
+ authenticate: { strategies: [Authentication.STRATEGY_JWT] },
382
+ request: {
383
+ body: z.object({
384
+ email: z.string().email(),
385
+ name: z.string().min(2),
386
+ // Exclude sensitive fields from client input
387
+ }),
388
+ },
402
389
  },
403
390
 
404
391
  // Custom response schema
405
392
  find: {
406
- skipAuth: true,
407
- schema: z.array(z.object({
408
- id: z.string(),
409
- name: z.string(),
410
- // Exclude internal fields from response
411
- })),
393
+ authenticate: { skip: true },
394
+ response: {
395
+ schema: z.array(z.object({
396
+ id: z.string(),
397
+ name: z.string(),
398
+ // Exclude internal fields from response
399
+ })),
400
+ },
412
401
  },
413
402
  },
414
403
  });
@@ -420,10 +409,13 @@ const _Controller = ControllerFactory.defineCrudController({
420
409
  |-------|--------|------|-------------|
421
410
  | `count` | GET | `/count` | Count records matching filter |
422
411
  | `find` | GET | `/` | List records with filter |
423
- | `findById` | GET | `/:id` | Get single record |
412
+ | `findById` | GET | `/{id}` | Get single record |
424
413
  | `findOne` | GET | `/find-one` | Get first matching record |
425
414
  | `create` | POST | `/` | Create new record |
426
- | `updateById` | PATCH | `/:id` | Update record by ID |
415
+ | `updateById` | PATCH | `/{id}` | Update record by ID |
427
416
  | `updateBy` | PATCH | `/` | Bulk update by filter |
428
- | `deleteById` | DELETE | `/:id` | Delete by ID |
429
- | `deleteBy` | DELETE | `/` | Bulk delete by filter |
417
+ | `deleteById` | DELETE | `/{id}` | Delete by ID |
418
+ | `deleteBy` | DELETE | `/` | Bulk delete by filter |
419
+
420
+ > [!TIP]
421
+ > `TDataObject`/`TPersistObject` cannot be inferred from `entity` - pass them explicitly for typed handlers: `ControllerFactory.defineCrudController<TUserRecord>({ ... })`. Use `controller.enabledRoutes` to whitelist routes and `controller.readonly` to disable all write routes.