@venizia/ignis-docs 0.0.2 → 0.0.4-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 (134) hide show
  1. package/README.md +1 -1
  2. package/package.json +4 -2
  3. package/wiki/best-practices/api-usage-examples.md +591 -0
  4. package/wiki/best-practices/architectural-patterns.md +415 -0
  5. package/wiki/best-practices/architecture-decisions.md +488 -0
  6. package/wiki/{get-started/best-practices → best-practices}/code-style-standards.md +647 -182
  7. package/wiki/{get-started/best-practices → best-practices}/common-pitfalls.md +109 -4
  8. package/wiki/{get-started/best-practices → best-practices}/contribution-workflow.md +34 -7
  9. package/wiki/best-practices/data-modeling.md +376 -0
  10. package/wiki/best-practices/deployment-strategies.md +698 -0
  11. package/wiki/best-practices/index.md +27 -0
  12. package/wiki/best-practices/performance-optimization.md +196 -0
  13. package/wiki/best-practices/security-guidelines.md +218 -0
  14. package/wiki/{get-started/best-practices → best-practices}/troubleshooting-tips.md +97 -1
  15. package/wiki/changelogs/2025-12-16-initial-architecture.md +1 -1
  16. package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +1 -1
  17. package/wiki/changelogs/2025-12-17-refactor.md +1 -1
  18. package/wiki/changelogs/2025-12-18-performance-optimizations.md +5 -5
  19. package/wiki/changelogs/2025-12-18-repository-validation-security.md +13 -7
  20. package/wiki/changelogs/2025-12-26-nested-relations-and-generics.md +86 -0
  21. package/wiki/changelogs/2025-12-26-transaction-support.md +57 -0
  22. package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +104 -0
  23. package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +100 -0
  24. package/wiki/changelogs/2025-12-30-repository-enhancements.md +214 -0
  25. package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +214 -0
  26. package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +137 -0
  27. package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +418 -0
  28. package/wiki/changelogs/index.md +8 -1
  29. package/wiki/changelogs/planned-schema-migrator.md +2 -10
  30. package/wiki/{get-started/core-concepts → guides/core-concepts/application}/bootstrapping.md +18 -5
  31. package/wiki/{get-started/core-concepts/application.md → guides/core-concepts/application/index.md} +47 -104
  32. package/wiki/guides/core-concepts/components-guide.md +509 -0
  33. package/wiki/guides/core-concepts/components.md +122 -0
  34. package/wiki/{get-started → guides}/core-concepts/controllers.md +30 -13
  35. package/wiki/{get-started → guides}/core-concepts/dependency-injection.md +97 -0
  36. package/wiki/guides/core-concepts/persistent/datasources.md +179 -0
  37. package/wiki/guides/core-concepts/persistent/index.md +119 -0
  38. package/wiki/guides/core-concepts/persistent/models.md +241 -0
  39. package/wiki/guides/core-concepts/persistent/repositories.md +219 -0
  40. package/wiki/guides/core-concepts/persistent/transactions.md +170 -0
  41. package/wiki/{get-started → guides}/core-concepts/services.md +26 -3
  42. package/wiki/{get-started → guides/get-started}/5-minute-quickstart.md +59 -14
  43. package/wiki/guides/get-started/philosophy.md +682 -0
  44. package/wiki/guides/get-started/setup.md +157 -0
  45. package/wiki/guides/index.md +89 -0
  46. package/wiki/guides/reference/glossary.md +243 -0
  47. package/wiki/{get-started → guides/reference}/mcp-docs-server.md +0 -10
  48. package/wiki/{get-started → guides/tutorials}/building-a-crud-api.md +134 -132
  49. package/wiki/{get-started/quickstart.md → guides/tutorials/complete-installation.md} +107 -71
  50. package/wiki/guides/tutorials/ecommerce-api.md +1399 -0
  51. package/wiki/guides/tutorials/realtime-chat.md +1261 -0
  52. package/wiki/guides/tutorials/testing.md +723 -0
  53. package/wiki/index.md +176 -37
  54. package/wiki/references/base/application.md +27 -0
  55. package/wiki/references/base/bootstrapping.md +30 -26
  56. package/wiki/references/base/components.md +532 -31
  57. package/wiki/references/base/controllers.md +136 -38
  58. package/wiki/references/base/datasources.md +108 -5
  59. package/wiki/references/base/dependency-injection.md +39 -3
  60. package/wiki/references/base/filter-system/application-usage.md +224 -0
  61. package/wiki/references/base/filter-system/array-operators.md +132 -0
  62. package/wiki/references/base/filter-system/comparison-operators.md +109 -0
  63. package/wiki/references/base/filter-system/default-filter.md +428 -0
  64. package/wiki/references/base/filter-system/fields-order-pagination.md +155 -0
  65. package/wiki/references/base/filter-system/index.md +127 -0
  66. package/wiki/references/base/filter-system/json-filtering.md +197 -0
  67. package/wiki/references/base/filter-system/list-operators.md +71 -0
  68. package/wiki/references/base/filter-system/logical-operators.md +156 -0
  69. package/wiki/references/base/filter-system/null-operators.md +58 -0
  70. package/wiki/references/base/filter-system/pattern-matching.md +108 -0
  71. package/wiki/references/base/filter-system/quick-reference.md +431 -0
  72. package/wiki/references/base/filter-system/range-operators.md +63 -0
  73. package/wiki/references/base/filter-system/tips.md +190 -0
  74. package/wiki/references/base/filter-system/use-cases.md +452 -0
  75. package/wiki/references/base/index.md +90 -0
  76. package/wiki/references/base/middlewares.md +602 -0
  77. package/wiki/references/base/models.md +215 -23
  78. package/wiki/references/base/providers.md +732 -0
  79. package/wiki/references/base/repositories/advanced.md +555 -0
  80. package/wiki/references/base/repositories/index.md +228 -0
  81. package/wiki/references/base/repositories/mixins.md +331 -0
  82. package/wiki/references/base/repositories/relations.md +486 -0
  83. package/wiki/references/base/repositories.md +40 -549
  84. package/wiki/references/base/services.md +28 -4
  85. package/wiki/references/components/authentication.md +22 -2
  86. package/wiki/references/components/health-check.md +12 -0
  87. package/wiki/references/components/index.md +23 -0
  88. package/wiki/references/components/mail.md +687 -0
  89. package/wiki/references/components/request-tracker.md +16 -0
  90. package/wiki/references/components/socket-io.md +18 -0
  91. package/wiki/references/components/static-asset.md +14 -26
  92. package/wiki/references/components/swagger.md +17 -0
  93. package/wiki/references/configuration/environment-variables.md +427 -0
  94. package/wiki/references/configuration/index.md +73 -0
  95. package/wiki/references/helpers/cron.md +14 -0
  96. package/wiki/references/helpers/crypto.md +15 -0
  97. package/wiki/references/helpers/env.md +16 -0
  98. package/wiki/references/helpers/error.md +17 -0
  99. package/wiki/references/helpers/index.md +15 -0
  100. package/wiki/references/helpers/inversion.md +24 -4
  101. package/wiki/references/helpers/logger.md +19 -0
  102. package/wiki/references/helpers/network.md +11 -0
  103. package/wiki/references/helpers/queue.md +19 -0
  104. package/wiki/references/helpers/redis.md +21 -0
  105. package/wiki/references/helpers/socket-io.md +24 -5
  106. package/wiki/references/helpers/storage.md +18 -10
  107. package/wiki/references/helpers/testing.md +18 -0
  108. package/wiki/references/helpers/types.md +167 -0
  109. package/wiki/references/helpers/uid.md +167 -0
  110. package/wiki/references/helpers/worker-thread.md +16 -0
  111. package/wiki/references/index.md +177 -0
  112. package/wiki/references/quick-reference.md +634 -0
  113. package/wiki/references/src-details/boot.md +3 -3
  114. package/wiki/references/src-details/dev-configs.md +0 -4
  115. package/wiki/references/src-details/docs.md +2 -2
  116. package/wiki/references/src-details/index.md +86 -0
  117. package/wiki/references/src-details/inversion.md +1 -6
  118. package/wiki/references/src-details/mcp-server.md +3 -15
  119. package/wiki/references/utilities/index.md +86 -10
  120. package/wiki/references/utilities/jsx.md +577 -0
  121. package/wiki/references/utilities/request.md +0 -2
  122. package/wiki/references/utilities/statuses.md +740 -0
  123. package/wiki/changelogs/planned-transaction-support.md +0 -216
  124. package/wiki/get-started/best-practices/api-usage-examples.md +0 -266
  125. package/wiki/get-started/best-practices/architectural-patterns.md +0 -170
  126. package/wiki/get-started/best-practices/data-modeling.md +0 -177
  127. package/wiki/get-started/best-practices/deployment-strategies.md +0 -121
  128. package/wiki/get-started/best-practices/performance-optimization.md +0 -88
  129. package/wiki/get-started/best-practices/security-guidelines.md +0 -99
  130. package/wiki/get-started/core-concepts/components.md +0 -98
  131. package/wiki/get-started/core-concepts/persistent.md +0 -543
  132. package/wiki/get-started/index.md +0 -65
  133. package/wiki/get-started/philosophy.md +0 -296
  134. package/wiki/get-started/prerequisites.md +0 -113
@@ -2,7 +2,7 @@
2
2
 
3
3
  The Application class orchestrates your application's configuration, lifecycle, and resource registration (components, controllers, services).
4
4
 
5
- > **Deep Dive:** See [Application Reference](../../references/base/application.md) for technical details.
5
+ > **Deep Dive:** See [Application Reference](../../../references/base/application.md) for technical details.
6
6
 
7
7
  ## Creating an Application
8
8
 
@@ -42,13 +42,10 @@ export class Application extends BaseApplication {
42
42
  }
43
43
 
44
44
  preConfigure(): ValueOrPromise<void> {
45
- // Manual registration (traditional approach)
45
+ // Register your resources
46
46
  this.dataSource(MyDataSource);
47
47
  this.service(MyService);
48
48
  this.controller(MyController);
49
-
50
- // Or use boot system for auto-discovery (recommended for larger apps)
51
- // See Bootstrapping section below
52
49
  }
53
50
 
54
51
  postConfigure(): ValueOrPromise<void> {
@@ -78,109 +75,39 @@ The `BaseApplication` class provides several **overridable hook methods** that a
78
75
  | :--- | :--- |
79
76
  | `getAppInfo()` | **Required.** Return application metadata, usually from `package.json`. Used for OpenAPI docs. |
80
77
  | `staticConfigure()` | Configure static file serving. |
81
- | `preConfigure()` | **Most Important Hook.** Set up application resources like components, controllers, services, and datasources. Can be skipped if using boot system. |
78
+ | `preConfigure()` | **Most Important Hook.** Set up application resources like components, controllers, services, and datasources. Can be skipped if using [Bootstrapping](./bootstrapping). |
82
79
  | `postConfigure()` | Perform actions *after* all resources have been configured and instantiated. |
83
80
  | `setupMiddlewares()`| Add custom application-level middlewares to the Hono instance. |
84
81
 
85
- ## Bootstrapping (Auto-discovery)
86
-
87
- The boot system provides automatic artifact discovery and loading, eliminating manual registration. When enabled, it scans your project directory and automatically loads controllers, services, repositories, and datasources.
88
-
89
- > **Detailed Guide:** See [Bootstrapping Concepts](./bootstrapping.md) for complete documentation.
90
-
91
- ### Enabling Boot System
92
-
93
- Add `bootOptions` to your application config:
94
-
95
- ```typescript
96
- export const appConfigs: IApplicationConfigs = {
97
- host: process.env.APP_ENV_SERVER_HOST,
98
- port: +(process.env.APP_ENV_SERVER_PORT ?? 3000),
99
- // Enable boot system
100
- bootOptions: {
101
- datasources: { dirs: ['datasources'] },
102
- repositories: { dirs: ['repositories'] },
103
- services: { dirs: ['services'] },
104
- controllers: { dirs: ['controllers'] }
105
- }
106
- };
107
- ```
108
-
109
- With boot enabled, you can skip manual registration in `preConfigure()`:
110
-
111
- ```typescript
112
- export class Application extends BaseApplication {
113
- // No need to register artifacts manually!
114
- // Boot system handles it automatically
115
-
116
- preConfigure(): ValueOrPromise<void> {
117
- // Only register things that need custom configuration
118
- // Everything else is auto-discovered
119
- }
120
- }
121
- ```
122
-
123
- ### Boot vs Manual Registration
124
-
125
- | Approach | Use Case | Pros | Cons |
126
- |----------|----------|------|------|
127
- | **Boot System** | Apps with 10+ artifacts per type | Auto-discovery, scalable, clean code | Requires file naming conventions |
128
- | **Manual Registration** | Small apps (< 5 artifacts) | Fine-grained control, explicit | Tedious, maintenance burden |
129
-
130
- ### Project Structure for Boot
82
+ ## Lifecycle Diagram
131
83
 
132
- Follow naming conventions for auto-discovery:
84
+ This diagram shows the sequence of operations during application startup.
133
85
 
134
86
  ```
135
- src/
136
- ├── datasources/
137
- │ └── postgres.datasource.js
138
- ├── repositories/
139
- ├── user.repository.js
140
- │ └── product.repository.js
141
- ├── services/
142
- │ ├── auth.service.js
143
- │ └── user.service.js
144
- └── controllers/
145
- ├── auth.controller.js
146
- └── user.controller.js
147
- ```
148
-
149
- ## Lifecycle Diagram
150
-
151
- This diagram shows the sequence of operations during application startup. The methods you can override are highlighted.
152
-
153
- ```mermaid
154
- %%{init: { "flowchart": { "useMaxWidth": true } } }%%
155
- graph TD
156
- A["start()"] --> B["initialize()"];
157
-
158
- subgraph "initialize() Sequence"
159
- direction TB
160
- B --> B0["boot() - if bootOptions configured"];
161
- B0 --> B1["printStartUpInfo"];
162
- B1 --> B2["validateEnvs"];
163
- B2 --> B3["registerDefaultMiddlewares"];
164
- B3 --> B4["staticConfigure()"];
165
- B4 --> B5["preConfigure()"];
166
- B5 --> B6["registerDataSources"];
167
- B6 --> B7["registerComponents"];
168
- B7 --> B8["registerControllers"];
169
- B8 --> B9["postConfigure()"];
170
- end
171
-
172
- B9 --> C["setupMiddlewares()"];
173
- C --> D["Mount Root Router"];
174
- D --> E["Start HTTP Server"];
175
-
176
- subgraph "Overridable Hooks"
177
- style B4 fill:#ffc0cb,stroke:#333
178
- style B5 fill:#ffc0cb,stroke:#333
179
- style B9 fill:#ffc0cb,stroke:#333
180
- style C fill:#ffc0cb,stroke:#333
181
- end
182
-
183
- classDef default fill:#fff,stroke:#333,stroke-width:2px;
87
+ start()
88
+
89
+
90
+ initialize()
91
+
92
+ ├─► boot() (if bootOptions configured)
93
+ ├─► printStartUpInfo
94
+ ├─► validateEnvs
95
+ ├─► registerDefaultMiddlewares
96
+ ├─► staticConfigure() ← Override hook
97
+ ├─► preConfigure() ← Override hook
98
+ ├─► registerDataSources
99
+ ├─► registerComponents
100
+ ├─► registerControllers
101
+ └─► postConfigure() ← Override hook
102
+
103
+
104
+ setupMiddlewares() ← Override hook
105
+
106
+
107
+ Mount Root Router
108
+
109
+
110
+ Start HTTP Server
184
111
  ```
185
112
 
186
113
  ## Configuration
@@ -197,7 +124,7 @@ Application configuration is passed to the `BaseApplication` constructor via an
197
124
  | `path.isStrict`| `boolean`| `true` | If `true`, the router is strict about trailing slashes. |
198
125
  | `debug.showRoutes`| `boolean`| `false`| If `true`, prints all registered routes to the console on startup. |
199
126
  | `favicon` | `string` | `'🔥'` | An emoji to be used as the application's favicon. |
200
- | `bootOptions` | `IBootOptions` | `undefined` | Enable auto-discovery of artifacts. See [Bootstrapping](./bootstrapping.md). |
127
+ | `bootOptions` | `IBootOptions` | `undefined` | Enable auto-discovery of artifacts. See [Bootstrapping](./bootstrapping). |
201
128
 
202
129
  ### Example Configuration
203
130
 
@@ -234,4 +161,20 @@ Register resources in `preConfigure()` to tell the DI container about your class
234
161
  4. Controllers (depend on Services)
235
162
  5. Components last
236
163
 
237
- > **Deep Dive:** See [Dependency Injection](./dependency-injection.md) for how registration and injection work together.
164
+ > **Deep Dive:** See [Dependency Injection](../dependency-injection.md) for how registration and injection work together.
165
+
166
+ ## See Also
167
+
168
+ - **Related Concepts:**
169
+ - [Bootstrapping](./bootstrapping) - Auto-discovery of artifacts
170
+ - [Controllers](/guides/core-concepts/controllers) - Creating HTTP endpoints
171
+ - [Services](/guides/core-concepts/services) - Business logic layer
172
+ - [Dependency Injection](/guides/core-concepts/dependency-injection) - How DI works in IGNIS
173
+
174
+ - **References:**
175
+ - [BaseApplication API](/references/base/application) - Complete API reference
176
+ - [Environment Variables](/references/configuration/environment-variables) - Configuration management
177
+
178
+ - **Tutorials:**
179
+ - [5-Minute Quickstart](/guides/get-started/5-minute-quickstart) - Create your first app
180
+ - [Building a CRUD API](/guides/tutorials/building-a-crud-api) - Complete application example
@@ -0,0 +1,509 @@
1
+ # Creating Components Guide
2
+
3
+ This guide walks you through creating your own components step-by-step.
4
+
5
+ ## What Problem Do Components Solve?
6
+
7
+ Imagine you're building multiple applications that all need the same features: authentication, health checks, file uploads. Without components, you'd copy-paste code between projects:
8
+
9
+ ```typescript
10
+ // ❌ Without Components - Copy-paste everywhere
11
+ export class Application extends BaseApplication {
12
+ preConfigure() {
13
+ // Auth feature - copied to every project
14
+ this.service(TokenService);
15
+ this.service(AuthService);
16
+ this.controller(AuthController);
17
+ this.bind({ key: 'auth.secret' }).toValue(process.env.JWT_SECRET);
18
+
19
+ // Health check - copied to every project
20
+ this.controller(HealthController);
21
+ this.service(HealthService);
22
+
23
+ // Your actual app code...
24
+ }
25
+ }
26
+ ```
27
+
28
+ **Components solve this** by packaging related functionality into reusable, plug-and-play modules:
29
+
30
+ ```typescript
31
+ // ✅ With Components - Clean and reusable
32
+ export class Application extends BaseApplication {
33
+ preConfigure() {
34
+ this.component(AuthenticateComponent); // All auth features in one line
35
+ this.component(HealthCheckComponent); // Health check ready to go
36
+
37
+ // Your actual app code...
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Think of Components as "Feature Plugins"
43
+
44
+ A Component is a **self-contained feature package** that bundles:
45
+
46
+ | What It Bundles | Example |
47
+ |-----------------|---------|
48
+ | Services | `TokenService`, `AuthService` |
49
+ | Controllers | `AuthController` with login/logout endpoints |
50
+ | Repositories | `UserRepository` for auth data |
51
+ | Configuration | Default settings, binding keys |
52
+ | Middlewares | JWT validation middleware |
53
+
54
+ When you register a component, all of these get added to your application automatically.
55
+
56
+ ## When Should You Create a Component?
57
+
58
+ | Scenario | Use Component? | Why |
59
+ |----------|----------------|-----|
60
+ | Feature used in **one** project only | ❌ No | Just register services/controllers directly |
61
+ | Feature **shared across projects** | ✅ Yes | Package once, reuse everywhere |
62
+ | Feature with **multiple related parts** | ✅ Yes | Keep related code together |
63
+ | Building a **library/package** | ✅ Yes | Easy distribution and installation |
64
+ | **Configurable feature** with options | ✅ Yes | Components handle configuration elegantly |
65
+
66
+ ## Creating Your First Component
67
+
68
+ ### Step 1: Identify What to Bundle
69
+
70
+ Let's create a `NotificationComponent` that provides:
71
+ - A service to send notifications
72
+ - A controller with REST endpoints
73
+ - Configuration options
74
+
75
+ ### Step 2: Create the Component Class
76
+
77
+ ```typescript
78
+ // src/components/notification/component.ts
79
+ import {
80
+ BaseApplication,
81
+ BaseComponent,
82
+ CoreBindings,
83
+ inject,
84
+ ValueOrPromise,
85
+ } from '@venizia/ignis';
86
+ import { NotificationService } from './services';
87
+ import { NotificationController } from './controllers';
88
+
89
+ export class NotificationComponent extends BaseComponent {
90
+ constructor(
91
+ @inject({ key: CoreBindings.APPLICATION_INSTANCE })
92
+ private _application: BaseApplication,
93
+ ) {
94
+ super({
95
+ scope: NotificationComponent.name,
96
+ initDefault: { enable: true, container: _application },
97
+ });
98
+ }
99
+
100
+ override binding(): ValueOrPromise<void> {
101
+ // Register all component resources with the application
102
+ this._application.service(NotificationService);
103
+ this._application.controller(NotificationController);
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### Step 3: Create the Service
109
+
110
+ ```typescript
111
+ // src/components/notification/services/service.ts
112
+ import { BaseService } from '@venizia/ignis';
113
+
114
+ export class NotificationService extends BaseService {
115
+ constructor() {
116
+ super({ scope: NotificationService.name });
117
+ }
118
+
119
+ async send(opts: { userId: string; message: string }) {
120
+ // Send notification logic
121
+ console.log(`Sending to ${opts.userId}: ${opts.message}`);
122
+ return { success: true };
123
+ }
124
+ }
125
+ ```
126
+
127
+ ### Step 4: Create the Controller
128
+
129
+ ```typescript
130
+ // src/components/notification/controllers/controller.ts
131
+ import {
132
+ BaseController,
133
+ controller,
134
+ post,
135
+ inject,
136
+ HTTP,
137
+ jsonContent,
138
+ jsonResponse,
139
+ TRouteContext,
140
+ } from '@venizia/ignis';
141
+ import { z } from '@hono/zod-openapi';
142
+ import { NotificationService } from '../services';
143
+
144
+ const NotificationRoutes = {
145
+ SEND: {
146
+ method: HTTP.Methods.POST,
147
+ path: '/send',
148
+ request: {
149
+ body: jsonContent({
150
+ schema: z.object({
151
+ userId: z.string(),
152
+ message: z.string(),
153
+ }),
154
+ }),
155
+ },
156
+ responses: jsonResponse({
157
+ schema: z.object({ success: z.boolean() }),
158
+ }),
159
+ },
160
+ } as const;
161
+
162
+ @controller({ path: '/notifications' })
163
+ export class NotificationController extends BaseController {
164
+ constructor(
165
+ @inject({ key: 'services.NotificationService' })
166
+ private _notificationService: NotificationService,
167
+ ) {
168
+ super({ scope: NotificationController.name, path: '/notifications' });
169
+ }
170
+
171
+ @post({ configs: NotificationRoutes.SEND })
172
+ async send(c: TRouteContext<typeof NotificationRoutes.SEND>) {
173
+ const body = c.req.valid('json');
174
+ const result = await this._notificationService.send({
175
+ userId: body.userId,
176
+ message: body.message,
177
+ });
178
+ return c.json(result, HTTP.ResultCodes.RS_2.Ok);
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### Step 5: Use the Component
184
+
185
+ ```typescript
186
+ // src/application.ts
187
+ import { NotificationComponent } from './components/notification';
188
+
189
+ export class Application extends BaseApplication {
190
+ preConfigure() {
191
+ this.component(NotificationComponent);
192
+ // That's it! /notifications/send endpoint is now available
193
+ }
194
+ }
195
+ ```
196
+
197
+ ## Adding Configuration Options
198
+
199
+ Components become powerful when they accept options. Here's how:
200
+
201
+ ### Step 1: Define Types and Binding Keys in `common/`
202
+
203
+ **Types go in `types.ts`:**
204
+
205
+ ```typescript
206
+ // src/components/notification/common/types.ts
207
+ export interface INotificationOptions {
208
+ provider: 'email' | 'sms' | 'push';
209
+ defaultFrom?: string;
210
+ retryCount?: number;
211
+ }
212
+
213
+ export interface INotificationPayload {
214
+ userId: string;
215
+ message: string;
216
+ channel?: string;
217
+ }
218
+ ```
219
+
220
+ **Binding keys go in `keys.ts`:**
221
+
222
+ ```typescript
223
+ // src/components/notification/common/keys.ts
224
+ export const NotificationBindingKeys = {
225
+ OPTIONS: 'components.notification.options',
226
+ SERVICE: 'services.NotificationService',
227
+ CONTROLLER: 'controllers.NotificationController',
228
+ } as const;
229
+ ```
230
+
231
+ **Barrel export in `index.ts`:**
232
+
233
+ ```typescript
234
+ // src/components/notification/common/index.ts
235
+ export * from './types';
236
+ export * from './keys';
237
+ ```
238
+
239
+ ### Step 2: Use Options in Service
240
+
241
+ ```typescript
242
+ // src/components/notification/services/service.ts
243
+ import { BaseService, inject } from '@venizia/ignis';
244
+ import { INotificationOptions, NotificationBindingKeys } from '../common';
245
+
246
+ export class NotificationService extends BaseService {
247
+ constructor(
248
+ @inject({ key: NotificationBindingKeys.OPTIONS })
249
+ private _options: INotificationOptions,
250
+ ) {
251
+ super({ scope: NotificationService.name });
252
+ }
253
+
254
+ async send(opts: { userId: string; message: string }) {
255
+ console.log(`Sending via ${this._options.provider}: ${opts.message}`);
256
+ // Use this._options.retryCount, this._options.defaultFrom, etc.
257
+ return { success: true };
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### Step 3: Provide Default Options in Component
263
+
264
+ ```typescript
265
+ // src/components/notification/component.ts
266
+ import { NotificationBindingKeys, INotificationOptions } from './common';
267
+
268
+ export class NotificationComponent extends BaseComponent {
269
+ constructor(
270
+ @inject({ key: CoreBindings.APPLICATION_INSTANCE })
271
+ private _application: BaseApplication,
272
+ ) {
273
+ super({
274
+ scope: NotificationComponent.name,
275
+ initDefault: { enable: true, container: _application },
276
+ });
277
+ }
278
+
279
+ override binding(): ValueOrPromise<void> {
280
+ // Provide default options (can be overridden by user)
281
+ if (!this._application.isBound({ key: NotificationBindingKeys.OPTIONS })) {
282
+ this._application.bind<INotificationOptions>({ key: NotificationBindingKeys.OPTIONS })
283
+ .toValue({
284
+ provider: 'email',
285
+ defaultFrom: 'noreply@example.com',
286
+ retryCount: 3,
287
+ });
288
+ }
289
+
290
+ this._application.service(NotificationService);
291
+ this._application.controller(NotificationController);
292
+ }
293
+ }
294
+ ```
295
+
296
+ ### Step 4: Users Can Override Options
297
+
298
+ ```typescript
299
+ // In user's application.ts
300
+ export class Application extends BaseApplication {
301
+ preConfigure() {
302
+ // Override options BEFORE registering component
303
+ this.bind<INotificationOptions>({ key: NotificationBindingKeys.OPTIONS })
304
+ .toValue({
305
+ provider: 'sms', // Use SMS instead of email
306
+ retryCount: 5, // More retries
307
+ });
308
+
309
+ this.component(NotificationComponent);
310
+ }
311
+ }
312
+ ```
313
+
314
+ ## Component Lifecycle
315
+
316
+ ```
317
+ Application.preConfigure()
318
+
319
+
320
+ this.component(MyComponent)
321
+
322
+
323
+ ┌────────────────────────────────┐
324
+ │ 1. Constructor called │
325
+ │ - Inject application │
326
+ │ - Set up component scope │
327
+ └────────────────────────────────┘
328
+
329
+
330
+ ┌────────────────────────────────┐
331
+ │ 2. binding() called │
332
+ │ - Register services │
333
+ │ - Register controllers │
334
+ │ - Register repositories │
335
+ │ - Bind default options │
336
+ └────────────────────────────────┘
337
+
338
+
339
+ Component resources are now
340
+ available in the application
341
+ ```
342
+
343
+ ## Component Directory Structure
344
+
345
+ Organize your component files following IGNIS conventions:
346
+
347
+ **Simple Component:**
348
+
349
+ ```
350
+ src/components/notification/
351
+ ├── index.ts # Barrel exports
352
+ ├── component.ts # IoC binding setup
353
+ ├── controllers/
354
+ │ ├── index.ts # Barrel exports for controllers
355
+ │ └── controller.ts # Route handlers (or notification.controller.ts)
356
+ ├── services/
357
+ │ ├── index.ts # Barrel exports for services
358
+ │ └── service.ts # Business logic (or notification.service.ts)
359
+ └── common/
360
+ ├── index.ts # Barrel exports for common
361
+ ├── keys.ts # Binding key constants
362
+ ├── types.ts # Interfaces and types
363
+ └── rest-paths.ts # Route path constants (optional)
364
+ ```
365
+
366
+ **Complex Component (with multiple sub-features):**
367
+
368
+ ```
369
+ src/components/auth/
370
+ ├── index.ts
371
+ ├── component.ts
372
+ ├── controllers/
373
+ │ ├── index.ts
374
+ │ ├── auth.controller.ts
375
+ │ └── session.controller.ts
376
+ ├── services/
377
+ │ ├── index.ts
378
+ │ ├── token.service.ts
379
+ │ └── session.service.ts
380
+ ├── strategies/
381
+ │ ├── index.ts
382
+ │ ├── jwt.strategy.ts
383
+ │ └── basic.strategy.ts
384
+ ├── common/
385
+ │ ├── index.ts
386
+ │ ├── keys.ts
387
+ │ └── types.ts
388
+ └── models/
389
+ ├── entities/
390
+ └── requests/
391
+ ```
392
+
393
+ **Barrel exports at every level:**
394
+
395
+ ```typescript
396
+ // src/components/notification/index.ts
397
+ export * from './common';
398
+ export * from './component';
399
+ export * from './controllers';
400
+ export * from './services';
401
+
402
+ // src/components/notification/controllers/index.ts
403
+ export * from './controller';
404
+
405
+ // src/components/notification/services/index.ts
406
+ export * from './service';
407
+
408
+ // src/components/notification/common/index.ts
409
+ export * from './keys';
410
+ export * from './types';
411
+ ```
412
+
413
+ **File naming:**
414
+ - Use folders: `controllers/`, `services/`, `common/`
415
+ - Single file in folder: `controller.ts`, `service.ts`
416
+ - Multiple files in folder: `auth.controller.ts`, `token.service.ts`
417
+ - Types and keys always in `common/` folder
418
+
419
+ ## Quick Reference
420
+
421
+ ### Minimal Component Template
422
+
423
+ ```typescript
424
+ import { BaseApplication, BaseComponent, CoreBindings, inject, ValueOrPromise } from '@venizia/ignis';
425
+
426
+ export class MyComponent extends BaseComponent {
427
+ constructor(
428
+ @inject({ key: CoreBindings.APPLICATION_INSTANCE })
429
+ private _application: BaseApplication,
430
+ ) {
431
+ super({
432
+ scope: MyComponent.name,
433
+ initDefault: { enable: true, container: _application },
434
+ });
435
+ }
436
+
437
+ override binding(): ValueOrPromise<void> {
438
+ // Register your services, controllers, etc.
439
+ this._application.service(MyService);
440
+ this._application.controller(MyController);
441
+ }
442
+ }
443
+ ```
444
+
445
+ ### Component with Options Template
446
+
447
+ ```typescript
448
+ import { BaseApplication, BaseComponent, CoreBindings, inject, ValueOrPromise } from '@venizia/ignis';
449
+
450
+ // 1. Define options interface
451
+ export interface IMyComponentOptions {
452
+ enabled: boolean;
453
+ config: string;
454
+ }
455
+
456
+ // 2. Define binding keys
457
+ export const MyComponentKeys = {
458
+ OPTIONS: 'components.my.options',
459
+ } as const;
460
+
461
+ // 3. Create component
462
+ export class MyComponent extends BaseComponent {
463
+ constructor(
464
+ @inject({ key: CoreBindings.APPLICATION_INSTANCE })
465
+ private _application: BaseApplication,
466
+ ) {
467
+ super({
468
+ scope: MyComponent.name,
469
+ initDefault: { enable: true, container: _application },
470
+ });
471
+ }
472
+
473
+ override binding(): ValueOrPromise<void> {
474
+ // Provide defaults if not already bound
475
+ if (!this._application.isBound({ key: MyComponentKeys.OPTIONS })) {
476
+ this._application.bind<IMyComponentOptions>({ key: MyComponentKeys.OPTIONS })
477
+ .toValue({ enabled: true, config: 'default' });
478
+ }
479
+
480
+ this._application.service(MyService);
481
+ }
482
+ }
483
+ ```
484
+
485
+ ## Summary
486
+
487
+ | Concept | Description |
488
+ |---------|-------------|
489
+ | **Component** | A reusable package that bundles services, controllers, and configuration |
490
+ | **When to use** | Shared features, multi-part features, distributable packages |
491
+ | **Key method** | `binding()` - register all resources here |
492
+ | **Configuration** | Use binding keys + `isBound()` check for overridable options |
493
+ | **Registration** | `this.component(MyComponent)` in `preConfigure()` |
494
+
495
+ ## See Also
496
+
497
+ - **Related Concepts:**
498
+ - [Components Overview](/guides/core-concepts/components) - What components are
499
+ - [Application](/guides/core-concepts/application/) - Registering components
500
+ - [Dependency Injection](/guides/core-concepts/dependency-injection) - Component bindings
501
+
502
+ - **References:**
503
+ - [BaseComponent API](/references/base/components) - Complete API reference
504
+ - [Authentication Component](/references/components/authentication) - Real-world component example
505
+ - [Health Check Component](/references/components/health-check) - Simple component example
506
+
507
+ - **Best Practices:**
508
+ - [Architectural Patterns](/best-practices/architectural-patterns) - Component architecture patterns
509
+ - [Code Style Standards](/best-practices/code-style-standards) - Component coding standards