@venizia/ignis-docs 0.0.1-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/mcp-server/dist/common/config.d.ts +27 -0
  2. package/mcp-server/dist/common/config.d.ts.map +1 -0
  3. package/mcp-server/dist/common/config.js +27 -0
  4. package/mcp-server/dist/common/config.js.map +1 -0
  5. package/mcp-server/dist/common/index.d.ts +3 -0
  6. package/mcp-server/dist/common/index.d.ts.map +1 -0
  7. package/mcp-server/dist/common/index.js +19 -0
  8. package/mcp-server/dist/common/index.js.map +1 -0
  9. package/mcp-server/dist/common/paths.d.ts +13 -0
  10. package/mcp-server/dist/common/paths.d.ts.map +1 -0
  11. package/mcp-server/dist/common/paths.js +23 -0
  12. package/mcp-server/dist/common/paths.js.map +1 -0
  13. package/mcp-server/dist/helpers/docs.helper.d.ts +81 -0
  14. package/mcp-server/dist/helpers/docs.helper.d.ts.map +1 -0
  15. package/mcp-server/dist/helpers/docs.helper.js +171 -0
  16. package/mcp-server/dist/helpers/docs.helper.js.map +1 -0
  17. package/mcp-server/dist/helpers/index.d.ts +3 -0
  18. package/mcp-server/dist/helpers/index.d.ts.map +1 -0
  19. package/mcp-server/dist/helpers/index.js +19 -0
  20. package/mcp-server/dist/helpers/index.js.map +1 -0
  21. package/mcp-server/dist/helpers/logger.helper.d.ts +7 -0
  22. package/mcp-server/dist/helpers/logger.helper.d.ts.map +1 -0
  23. package/mcp-server/dist/helpers/logger.helper.js +22 -0
  24. package/mcp-server/dist/helpers/logger.helper.js.map +1 -0
  25. package/mcp-server/dist/index.d.ts +3 -0
  26. package/mcp-server/dist/index.d.ts.map +1 -0
  27. package/mcp-server/dist/index.js +62 -0
  28. package/mcp-server/dist/index.js.map +1 -0
  29. package/mcp-server/dist/tools/base.tool.d.ts +98 -0
  30. package/mcp-server/dist/tools/base.tool.d.ts.map +1 -0
  31. package/mcp-server/dist/tools/base.tool.js +47 -0
  32. package/mcp-server/dist/tools/base.tool.js.map +1 -0
  33. package/mcp-server/dist/tools/get-doc-content.tool.d.ts +30 -0
  34. package/mcp-server/dist/tools/get-doc-content.tool.d.ts.map +1 -0
  35. package/mcp-server/dist/tools/get-doc-content.tool.js +127 -0
  36. package/mcp-server/dist/tools/get-doc-content.tool.js.map +1 -0
  37. package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts +40 -0
  38. package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts.map +1 -0
  39. package/mcp-server/dist/tools/get-doc-metadata.tool.js +121 -0
  40. package/mcp-server/dist/tools/get-doc-metadata.tool.js.map +1 -0
  41. package/mcp-server/dist/tools/index.d.ts +8 -0
  42. package/mcp-server/dist/tools/index.d.ts.map +1 -0
  43. package/mcp-server/dist/tools/index.js +18 -0
  44. package/mcp-server/dist/tools/index.js.map +1 -0
  45. package/mcp-server/dist/tools/list-categories.tool.d.ts +20 -0
  46. package/mcp-server/dist/tools/list-categories.tool.d.ts.map +1 -0
  47. package/mcp-server/dist/tools/list-categories.tool.js +105 -0
  48. package/mcp-server/dist/tools/list-categories.tool.js.map +1 -0
  49. package/mcp-server/dist/tools/list-docs.tool.d.ts +32 -0
  50. package/mcp-server/dist/tools/list-docs.tool.d.ts.map +1 -0
  51. package/mcp-server/dist/tools/list-docs.tool.js +121 -0
  52. package/mcp-server/dist/tools/list-docs.tool.js.map +1 -0
  53. package/mcp-server/dist/tools/search-docs.tool.d.ts +32 -0
  54. package/mcp-server/dist/tools/search-docs.tool.d.ts.map +1 -0
  55. package/mcp-server/dist/tools/search-docs.tool.js +120 -0
  56. package/mcp-server/dist/tools/search-docs.tool.js.map +1 -0
  57. package/package.json +102 -0
  58. package/wiki/get-started/5-minute-quickstart.md +266 -0
  59. package/wiki/get-started/best-practices/api-usage-examples.md +222 -0
  60. package/wiki/get-started/best-practices/architectural-patterns.md +129 -0
  61. package/wiki/get-started/best-practices/code-style-standards.md +122 -0
  62. package/wiki/get-started/best-practices/common-pitfalls.md +136 -0
  63. package/wiki/get-started/best-practices/contribution-workflow.md +145 -0
  64. package/wiki/get-started/best-practices/deployment-strategies.md +121 -0
  65. package/wiki/get-started/best-practices/performance-optimization.md +88 -0
  66. package/wiki/get-started/best-practices/security-guidelines.md +97 -0
  67. package/wiki/get-started/best-practices/troubleshooting-tips.md +100 -0
  68. package/wiki/get-started/building-a-crud-api.md +717 -0
  69. package/wiki/get-started/core-concepts/application.md +168 -0
  70. package/wiki/get-started/core-concepts/components.md +96 -0
  71. package/wiki/get-started/core-concepts/controllers.md +441 -0
  72. package/wiki/get-started/core-concepts/dependency-injection.md +160 -0
  73. package/wiki/get-started/core-concepts/persistent.md +591 -0
  74. package/wiki/get-started/core-concepts/services.md +88 -0
  75. package/wiki/get-started/index.md +65 -0
  76. package/wiki/get-started/mcp-docs-server.md +840 -0
  77. package/wiki/get-started/philosophy.md +123 -0
  78. package/wiki/get-started/prerequisites.md +113 -0
  79. package/wiki/get-started/quickstart.md +382 -0
  80. package/wiki/index.md +48 -0
  81. package/wiki/references/base/application.md +67 -0
  82. package/wiki/references/base/components.md +80 -0
  83. package/wiki/references/base/controllers.md +361 -0
  84. package/wiki/references/base/datasources.md +105 -0
  85. package/wiki/references/base/dependency-injection.md +83 -0
  86. package/wiki/references/base/models.md +104 -0
  87. package/wiki/references/base/repositories.md +118 -0
  88. package/wiki/references/base/services.md +97 -0
  89. package/wiki/references/components/authentication.md +224 -0
  90. package/wiki/references/components/health-check.md +190 -0
  91. package/wiki/references/components/index.md +61 -0
  92. package/wiki/references/components/request-tracker.md +35 -0
  93. package/wiki/references/components/socket-io.md +127 -0
  94. package/wiki/references/components/swagger.md +175 -0
  95. package/wiki/references/helpers/cron.md +94 -0
  96. package/wiki/references/helpers/crypto.md +117 -0
  97. package/wiki/references/helpers/env.md +67 -0
  98. package/wiki/references/helpers/error.md +80 -0
  99. package/wiki/references/helpers/index.md +21 -0
  100. package/wiki/references/helpers/inversion.md +141 -0
  101. package/wiki/references/helpers/logger.md +98 -0
  102. package/wiki/references/helpers/network.md +143 -0
  103. package/wiki/references/helpers/queue.md +131 -0
  104. package/wiki/references/helpers/redis.md +121 -0
  105. package/wiki/references/helpers/socket-io.md +103 -0
  106. package/wiki/references/helpers/storage.md +130 -0
  107. package/wiki/references/helpers/testing.md +115 -0
  108. package/wiki/references/helpers/worker-thread.md +162 -0
  109. package/wiki/references/src-details/core.md +249 -0
  110. package/wiki/references/src-details/dev-configs.md +302 -0
  111. package/wiki/references/src-details/docs.md +61 -0
  112. package/wiki/references/src-details/helpers.md +211 -0
  113. package/wiki/references/src-details/inversion.md +345 -0
  114. package/wiki/references/src-details/mcp-server.md +726 -0
  115. package/wiki/references/utilities/crypto.md +39 -0
  116. package/wiki/references/utilities/date.md +72 -0
  117. package/wiki/references/utilities/index.md +12 -0
  118. package/wiki/references/utilities/module.md +40 -0
  119. package/wiki/references/utilities/parse.md +68 -0
  120. package/wiki/references/utilities/performance.md +64 -0
  121. package/wiki/references/utilities/promise.md +83 -0
  122. package/wiki/references/utilities/request.md +66 -0
  123. package/wiki/references/utilities/schema.md +88 -0
@@ -0,0 +1,222 @@
1
+ # API Usage Examples
2
+
3
+ Practical examples for defining endpoints and working with data in Ignis applications.
4
+
5
+ ## Routing Patterns
6
+
7
+ ### Decorator-Based Routing (Recommended)
8
+
9
+ Use `@get`, `@post` decorators with `as const` route configs for full type safety:
10
+
11
+ **`src/controllers/test/definitions.ts`**
12
+ ```typescript
13
+ import { z } from '@hono/zod-openapi';
14
+ import { Authentication, HTTP, jsonContent, jsonResponse } from '@venizia/ignis';
15
+
16
+ // Define route configs as const for type inference
17
+ export const ROUTE_CONFIGS = {
18
+ // ... (other routes)
19
+ ['/4']: {
20
+ method: HTTP.Methods.GET,
21
+ path: '/4',
22
+ responses: jsonResponse({
23
+ description: 'Test decorator GET endpoint',
24
+ schema: z.object({ message: z.string(), method: z.string() }),
25
+ }),
26
+ },
27
+ ['/5']: {
28
+ method: HTTP.Methods.POST,
29
+ path: '/5',
30
+ authStrategies: [Authentication.STRATEGY_JWT], // Secure this endpoint
31
+ request: {
32
+ body: jsonContent({
33
+ description: 'Request body for POST',
34
+ schema: z.object({ name: z.string(), age: z.number().int().positive() }),
35
+ }),
36
+ },
37
+ responses: jsonResponse({
38
+ description: 'Test decorator POST endpoint',
39
+ schema: z.object({ id: z.string(), name: z.string(), age: z.number() }),
40
+ }),
41
+ },
42
+ } as const;
43
+ ```
44
+
45
+ Then, use the decorators in your controller class. The `TRouteContext` type provides a fully typed context, including request parameters, body, and response types.
46
+
47
+ **`src/controllers/test/controller.ts`**
48
+ ```typescript
49
+ import {
50
+ BaseController,
51
+ controller,
52
+ get,
53
+ post,
54
+ TRouteContext,
55
+ } from '@venizia/ignis';
56
+ import { ROUTE_CONFIGS } from './definitions';
57
+
58
+ @controller({ path: '/test' })
59
+ export class TestController extends BaseController {
60
+ // ...
61
+
62
+ @get({ configs: ROUTE_CONFIGS['/4'] })
63
+ getWithDecorator(context: TRouteContext<(typeof ROUTE_CONFIGS)['/4']>) {
64
+ // context is fully typed!
65
+ return context.json({ message: 'Hello from decorator', method: 'GET' });
66
+ }
67
+
68
+ @post({ configs: ROUTE_CONFIGS['/5'] })
69
+ createWithDecorator(context: TRouteContext<(typeof ROUTE_CONFIGS)['/5']>) {
70
+ // context.req.valid('json') is automatically typed as { name: string, age: number }
71
+ const body = context.req.valid('json');
72
+
73
+ // The response is validated against the schema
74
+ return context.json({
75
+ id: crypto.randomUUID(),
76
+ name: body.name,
77
+ age: body.age,
78
+ });
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### Example 2: Manual Route Definition in `binding()`
84
+
85
+ You can also define routes manually within the controller's `binding()` method using `defineRoute` or `bindRoute`. This is useful for more complex scenarios or for developers who prefer a non-decorator syntax.
86
+
87
+ **`src/controllers/test/controller.ts`**
88
+ ```typescript
89
+ import { BaseController, controller, HTTP, ValueOrPromise } from '@venizia/ignis';
90
+ import { ROUTE_CONFIGS } from './definitions';
91
+
92
+ @controller({ path: '/test' })
93
+ export class TestController extends BaseController {
94
+ // ...
95
+ override binding(): ValueOrPromise<void> {
96
+ // Using 'defineRoute'
97
+ this.defineRoute({
98
+ configs: ROUTE_CONFIGS['/1'],
99
+ handler: context => {
100
+ return context.json({ message: 'Hello' });
101
+ },
102
+ });
103
+
104
+ // Using 'bindRoute' for a fluent API
105
+ this.bindRoute({
106
+ configs: ROUTE_CONFIGS['/3'],
107
+ }).to({
108
+ handler: context => {
109
+ return context.json({ message: 'Hello 3' });
110
+ },
111
+ });
112
+ }
113
+ // ...
114
+ }
115
+ ```
116
+
117
+ ### Example 3: Auto-Generated CRUD Controller
118
+
119
+ For standard database entities, you can use `ControllerFactory.defineCrudController` to instantly generate a controller with a full set of CRUD endpoints.
120
+
121
+ **`src/controllers/configuration.controller.ts`**
122
+ ```typescript
123
+ import { Configuration } from '@/models';
124
+ import { ConfigurationRepository } from '@/repositories';
125
+ import {
126
+ BindingKeys,
127
+ BindingNamespaces,
128
+ controller,
129
+ ControllerFactory,
130
+ inject,
131
+ } from '@venizia/ignis';
132
+
133
+ const BASE_PATH = '/configurations';
134
+
135
+ // 1. The factory generates a controller class with all CRUD routes
136
+ const _Controller = ControllerFactory.defineCrudController({
137
+ repository: { name: ConfigurationRepository.name },
138
+ controller: {
139
+ name: 'ConfigurationController',
140
+ basePath: BASE_PATH,
141
+ },
142
+ entity: () => Configuration, // The entity is used to generate OpenAPI schemas
143
+ });
144
+
145
+ // 2. Extend the generated controller to inject the repository
146
+ @controller({ path: BASE_PATH })
147
+ export class ConfigurationController extends _Controller {
148
+ constructor(
149
+ @inject({
150
+ key: BindingKeys.build({
151
+ namespace: BindingNamespaces.REPOSITORY,
152
+ key: ConfigurationRepository.name,
153
+ }),
154
+ })
155
+ repository: ConfigurationRepository,
156
+ ) {
157
+ super(repository);
158
+ }
159
+ }
160
+ ```
161
+ This automatically creates endpoints like `GET /configurations`, `POST /configurations`, `GET /configurations/:id`, etc.
162
+
163
+ ## Repository (Data Access) Usage
164
+
165
+ Repositories are used to interact with your database. The `DefaultCRUDRepository` provides a rich set of methods for data manipulation. Here are examples from the `postConfigure` method in `src/application.ts`, which demonstrates how to use an injected repository.
166
+
167
+ ```typescript
168
+ // In src/application.ts
169
+
170
+ // Get the repository instance from the DI container
171
+ const configurationRepository = this.get<ConfigurationRepository>({
172
+ key: BindingKeys.build({
173
+ namespace: BindingNamespaces.REPOSITORY,
174
+ key: ConfigurationRepository.name,
175
+ }),
176
+ });
177
+
178
+ // --- Find One Record ---
179
+ const record = await configurationRepository.findOne({
180
+ filter: { where: { code: 'CODE_1' } },
181
+ });
182
+
183
+ // --- Find Multiple Records with Relations ---
184
+ const records = await configurationRepository.find({
185
+ filter: {
186
+ where: { code: 'CODE_2' },
187
+ fields: { id: true, code: true, createdBy: true },
188
+ limit: 100,
189
+ include: [{ relation: 'creator' }], // Eager load the 'creator' relation
190
+ },
191
+ });
192
+
193
+ // --- Create a Single Record ---
194
+ const newRecord = await configurationRepository.create({
195
+ data: {
196
+ code: 'NEW_CODE',
197
+ group: 'SYSTEM',
198
+ dataType: 'TEXT',
199
+ tValue: 'some value',
200
+ },
201
+ });
202
+
203
+ // --- Create Multiple Records ---
204
+ const newRecords = await configurationRepository.createAll({
205
+ data: [
206
+ { code: 'CODE_A', group: 'SYSTEM' },
207
+ { code: 'CODE_B', group: 'SYSTEM' },
208
+ ],
209
+ });
210
+
211
+ // --- Update a Record by ID ---
212
+ const updated = await configurationRepository.updateById({
213
+ id: 'some-uuid',
214
+ data: { tValue: 'new value' },
215
+ });
216
+
217
+ // --- Delete a Record by ID ---
218
+ const deleted = await configurationRepository.deleteById({
219
+ id: newRecord.data!.id,
220
+ options: { shouldReturn: true }, // Option to return the deleted record
221
+ });
222
+ ```
@@ -0,0 +1,129 @@
1
+ # Architectural Patterns
2
+
3
+ Ignis promotes separation of concerns, dependency injection, and modularity for scalable, maintainable applications.
4
+
5
+ > **Deep Dive:** See [Core Framework Reference](../../references/src-details/core.md) for implementation details.
6
+
7
+ ## 1. Layered Architecture
8
+
9
+ Each layer has a single responsibility. Ignis supports **two architectural approaches**:
10
+
11
+ ```mermaid
12
+ graph TD
13
+ Client[Client/API Consumer]
14
+
15
+ Client -->|HTTP Request| Controller[Controllers]
16
+
17
+ Controller -->|Simple CRUD| Repo[Repositories]
18
+ Controller -->|Complex Logic| Service[Services]
19
+
20
+ Service --> Repo
21
+
22
+ Repo --> DataSource[DataSources]
23
+ DataSource --> DB[(Database)]
24
+
25
+ style Service fill:#e1f5ff
26
+ style Repo fill:#fff4e1
27
+ style Controller fill:#ffe1f5
28
+ ```
29
+
30
+ | Layer | Responsibility | Example |
31
+ |-------|---------------|---------|
32
+ | **Controllers** | Handle HTTP - parse requests, validate, format responses | `ConfigurationController` (uses `ControllerFactory`) |
33
+ | **Services** | Business logic - orchestrate operations | `AuthenticationService` (auth logic) |
34
+ | **Repositories** | Data access - CRUD operations | `ConfigurationRepository` (extends `DefaultCRUDRepository`) |
35
+ | **DataSources** | Database connections | `PostgresDataSource` (connects to PostgreSQL) |
36
+ | **Models** | Data structure - Drizzle schemas + Entity classes | `Configuration`, `User` models |
37
+
38
+ **Key Principle - Two Approaches:**
39
+
40
+ ```
41
+ Simple CRUD (no business logic):
42
+ ┌────────────┐
43
+ │ Controller │──────────────┐
44
+ └────────────┘ │
45
+
46
+ ┌──────────────┐
47
+ │ Repository │
48
+ └──────────────┘
49
+
50
+
51
+ Database
52
+
53
+ Complex Logic (validation, orchestration):
54
+ ┌────────────┐
55
+ │ Controller │────┐
56
+ └────────────┘ │
57
+
58
+ ┌─────────┐
59
+ │ Service │
60
+ └─────────┘
61
+
62
+
63
+ ┌──────────────┐
64
+ │ Repository │
65
+ └──────────────┘
66
+
67
+
68
+ Database
69
+ ```
70
+
71
+ **When to use each:**
72
+ - **Controller → Repository** - Simple CRUD (list, get by ID, create, update, delete)
73
+ - **Controller → Service → Repository** - Business logic, validation, orchestrating multiple repositories
74
+
75
+ ## 2. Dependency Injection (DI)
76
+
77
+ Classes declare dependencies in their constructor - the framework automatically provides them at runtime.
78
+
79
+ **Benefits:**
80
+ - Loosely coupled code
81
+ - Easy to test (mock dependencies)
82
+ - Easy to swap implementations
83
+
84
+ **Example:**
85
+ ```typescript
86
+ @controller({ path: BASE_PATH })
87
+ export class ConfigurationController extends _Controller {
88
+ constructor(
89
+ // The @inject decorator tells the container to provide
90
+ // an instance of ConfigurationRepository here.
91
+ @inject({
92
+ key: BindingKeys.build({
93
+ namespace: BindingNames...REPOSITORY,
94
+ key: ConfigurationRepository.name,
95
+ }),
96
+ })
97
+ repository: ConfigurationRepository,
98
+ ) {
99
+ super(repository);
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## 3. Component-Based Modularity
105
+
106
+ Components bundle related features into self-contained, pluggable modules.
107
+
108
+ **Built-in Components:**
109
+ - `AuthenticateComponent` - JWT authentication
110
+ - `SwaggerComponent` - OpenAPI documentation
111
+ - `HealthCheckComponent` - Health check endpoint
112
+ - `RequestTrackerComponent` - Request logging
113
+
114
+ **Example:**
115
+ ```typescript
116
+ // src/application.ts
117
+
118
+ export class Application extends BaseApplication {
119
+ // ...
120
+ preConfigure(): ValueOrPromise<void> {
121
+ // ...
122
+ // Registering components plugs their functionality into the application.
123
+ this.component(HealthCheckComponent);
124
+ this.component(SwaggerComponent);
125
+ // ...
126
+ }
127
+ }
128
+ ```
129
+ This architecture keeps the main `Application` class clean and focused on high-level assembly, while the details of each feature are neatly encapsulated within their respective components.
@@ -0,0 +1,122 @@
1
+ # Code Style Standards
2
+
3
+ Maintain consistent code style using **Prettier** (formatting) and **ESLint** (code quality). Ignis provides centralized configurations via the `@venizia/dev-configs` package.
4
+
5
+ ## Using @venizia/dev-configs
6
+
7
+ Install the centralized development configurations:
8
+
9
+ ```bash
10
+ bun add -d @venizia/dev-configs
11
+ ```
12
+
13
+ This package provides:
14
+ - **ESLint rules** - Pre-configured for Node.js/TypeScript projects
15
+ - **Prettier settings** - Consistent formatting across all Ignis projects
16
+ - **TypeScript configs** - Shared base and common configurations
17
+
18
+ ## Prettier Configuration
19
+
20
+ Automatic code formatting eliminates style debates.
21
+
22
+ **`.prettierrc.mjs`:**
23
+ ```javascript
24
+ import { prettierConfigs } from '@venizia/dev-configs';
25
+
26
+ export default prettierConfigs;
27
+ ```
28
+
29
+ **Default Settings:**
30
+ - `bracketSpacing: true` - `{ foo: bar }`
31
+ - `singleQuote: false` - `"string"` (double quotes)
32
+ - `printWidth: 100` - Maximum line length
33
+ - `trailingComma: 'all'` - `[1, 2, 3,]`
34
+ - `arrowParens: 'avoid'` - `x => x` not `(x) => x`
35
+ - `semi: true` - Semicolons required
36
+
37
+ **Customization:**
38
+ ```javascript
39
+ import { prettierConfigs } from '@venizia/dev-configs';
40
+
41
+ export default {
42
+ ...prettierConfigs,
43
+ printWidth: 120, // Override specific settings
44
+ };
45
+ ```
46
+
47
+ **Usage:**
48
+ ```bash
49
+ bun run prettier:cli # Check formatting
50
+ bun run prettier:fix # Auto-fix
51
+ ```
52
+
53
+ **IDE Integration:** Configure your editor to format on save.
54
+
55
+ ## ESLint Configuration
56
+
57
+ Prevents common errors and enforces best practices.
58
+
59
+ **`eslint.config.mjs`:**
60
+ ```javascript
61
+ import { eslintConfigs } from '@venizia/dev-configs';
62
+
63
+ export default eslintConfigs;
64
+ ```
65
+
66
+ **Includes:**
67
+ - Pre-configured rules for Node.js/TypeScript (via `@minimaltech/eslint-node`)
68
+ - Disables `@typescript-eslint/no-explicit-any` by default
69
+
70
+ **Customization:**
71
+ ```javascript
72
+ import { eslintConfigs } from '@venizia/dev-configs';
73
+
74
+ export default [
75
+ ...eslintConfigs,
76
+ {
77
+ rules: {
78
+ 'no-console': 'warn', // Add project-specific rules
79
+ },
80
+ },
81
+ ];
82
+ ```
83
+
84
+ **Usage:**
85
+ ```bash
86
+ bun run eslint # Check for issues
87
+ bun run eslint --fix # Auto-fix issues
88
+ bun run lint:fix # Run both ESLint + Prettier
89
+ ```
90
+
91
+ **Pre-commit Hook:** Add ESLint to your pre-commit hooks to catch issues before committing.
92
+
93
+ ## TypeScript Configuration
94
+
95
+ Use the centralized TypeScript configs:
96
+
97
+ **`tsconfig.json`:**
98
+ ```json
99
+ {
100
+ "$schema": "http://json.schemastore.org/tsconfig",
101
+ "extends": "@venizia/dev-configs/tsconfig.common.json",
102
+ "compilerOptions": {
103
+ "outDir": "dist",
104
+ "rootDir": "src",
105
+ "baseUrl": "src",
106
+ "paths": {
107
+ "@/*": ["./*"]
108
+ }
109
+ },
110
+ "include": ["src"],
111
+ "exclude": ["node_modules", "dist"]
112
+ }
113
+ ```
114
+
115
+ **What's Included:**
116
+ - `target: ES2022` - Modern JavaScript features
117
+ - `experimentalDecorators: true` - Required for Ignis decorators
118
+ - `emitDecoratorMetadata: true` - Metadata reflection for DI
119
+ - `strict: true` - Strict type checking with selective relaxations
120
+ - `skipLibCheck: true` - Faster compilation
121
+
122
+ See [`@venizia/dev-configs` documentation](../../references/src-details/dev-configs.md) for full details.
@@ -0,0 +1,136 @@
1
+ # Common Pitfalls
2
+
3
+ Avoid these common mistakes when building Ignis applications.
4
+
5
+ ## 1. Forgetting to Register Resources
6
+
7
+ **Problem:** Created a Controller/Service/Repository but getting `Binding not found` errors.
8
+
9
+ **Solution:** Register in `application.ts` → `preConfigure()`:
10
+
11
+ **Example (`src/application.ts`):**
12
+ ```typescript
13
+ // ...
14
+ import { MyNewController } from './controllers';
15
+ import { MyNewService } from './services';
16
+ // ...
17
+
18
+ export class Application extends BaseApplication {
19
+ // ...
20
+ preConfigure(): ValueOrPromise<void> {
21
+ // DataSources
22
+ this.dataSource(PostgresDataSource);
23
+
24
+ // Repositories
25
+ this.repository(ConfigurationRepository);
26
+
27
+ // Services
28
+ this.service(MyNewService); // <-- Don't forget this line
29
+ this.registerAuth();
30
+
31
+ // Controllers
32
+ this.controller(TestController);
33
+ this.controller(MyNewController); // <-- Or this line
34
+
35
+ // Components
36
+ this.component(HealthCheckComponent);
37
+ }
38
+ // ...
39
+ }
40
+ ```
41
+
42
+ ## 2. Incorrect Injection Keys
43
+
44
+ **Problem:** `Binding not found` when using `@inject`.
45
+
46
+ **Solution:** Use `BindingKeys.build()` helper:
47
+
48
+ ```typescript
49
+ // ✅ GOOD
50
+ @inject({
51
+ key: BindingKeys.build({
52
+ namespace: BindingNamespaces.REPOSITORY,
53
+ key: ConfigurationRepository.name,
54
+ }),
55
+ })
56
+
57
+ // ❌ BAD - typo in string
58
+ @inject({ key: 'repositories.ConfigurationRepositry' })
59
+ ```
60
+
61
+ ## 3. Business Logic in Controllers
62
+
63
+ **Problem:** Complex logic in controller methods makes them hard to test and maintain.
64
+
65
+ **Solution:** Move business logic to Services. Controllers should only handle HTTP.
66
+
67
+ - **Bad:**
68
+ ```typescript
69
+ // In a Controller
70
+ async createUser(c: Context) {
71
+ const { name, email, companyName } = c.req.valid('json');
72
+
73
+ // Complex logic inside the controller
74
+ const existingUser = await this.userRepository.findByEmail(email);
75
+ if (existingUser) {
76
+ throw new ApplicationError({ message: 'Email already exists' });
77
+ }
78
+
79
+ const company = await this.companyRepository.findOrCreate(companyName);
80
+ const user = await this.userRepository.create({ name, email, companyId: company.id });
81
+
82
+ return c.json(user);
83
+ }
84
+ ```
85
+ - **Good:**
86
+ ```typescript
87
+ // In a Controller
88
+ async createUser(c: Context) {
89
+ const userData = c.req.valid('json');
90
+ // Delegate to the service
91
+ const newUser = await this.userService.createUser(userData);
92
+ return c.json(newUser);
93
+ }
94
+
95
+ // In UserService
96
+ async createUser(data) {
97
+ // All the complex logic now resides in the service
98
+ const existingUser = await this.userRepository.findByEmail(data.email);
99
+ // ...
100
+ return await this.userRepository.create(...);
101
+ }
102
+ ```
103
+
104
+ ### 4. Missing Environment Variables
105
+
106
+ **Pitfall:** The application fails to start or behaves unexpectedly because required environment variables are not defined in your `.env` file. The framework validates variables prefixed with `APP_ENV_` by default.
107
+
108
+ **Solution:** Always create a `.env` file for your local development by copying `.env.example`. Ensure all required variables, especially secrets and database connection details, are filled in.
109
+
110
+ **Example (`.env.example`):**
111
+ ```
112
+ # Ensure these have strong, unique values in your .env file
113
+ APP_ENV_APPLICATION_SECRET=
114
+ APP_ENV_JWT_SECRET=
115
+
116
+ # Ensure these point to your local database
117
+ APP_ENV_POSTGRES_HOST=0.0.0.0
118
+ APP_ENV_POSTGRES_PORT=5432
119
+ APP_ENV_POSTGRES_USERNAME=postgres
120
+ APP_ENV_POSTGRES_PASSWORD=password
121
+ APP_ENV_POSTGRES_DATABASE=db
122
+ ```
123
+
124
+ ### 5. Not Using `as const` for Route Definitions
125
+
126
+ **Pitfall:** When using the decorator-based routing with a shared `ROUTE_CONFIGS` object, you forget to add `as const` to the object definition. TypeScript will infer the types too broadly, and you will lose the benefits of type-safe contexts (`TRouteContext`).
127
+
128
+ **Solution:** Always use `as const` when exporting a shared route configuration object.
129
+
130
+ **Example (`src/controllers/test/definitions.ts`):**
131
+ ```typescript
132
+ export const ROUTE_CONFIGS = {
133
+ // ... your route definitions
134
+ } as const; // <-- This is crucial!
135
+ ```
136
+ This ensures that `TRouteContext<typeof ROUTE_CONFIGS['/path']>` has the precise types for request body, params, and response.