@lenne.tech/nest-server 11.21.2 → 11.22.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.
- package/.claude/rules/architecture.md +79 -0
- package/.claude/rules/better-auth.md +262 -0
- package/.claude/rules/configurable-features.md +308 -0
- package/.claude/rules/core-modules.md +205 -0
- package/.claude/rules/migration-guides.md +149 -0
- package/.claude/rules/module-deprecation.md +214 -0
- package/.claude/rules/module-inheritance.md +97 -0
- package/.claude/rules/package-management.md +112 -0
- package/.claude/rules/role-system.md +146 -0
- package/.claude/rules/testing.md +120 -0
- package/.claude/rules/versioning.md +53 -0
- package/CLAUDE.md +172 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +25 -25
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js +8 -4
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/error-code/error-code.module.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.guard.d.ts +1 -0
- package/dist/core/modules/tenant/core-tenant.guard.js +59 -4
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.helpers.js.map +1 -1
- package/dist/core.module.d.ts +3 -3
- package/dist/core.module.js +17 -4
- package/dist/core.module.js.map +1 -1
- package/dist/server/server.module.js +6 -6
- package/dist/server/server.module.js.map +1 -1
- package/dist/test/test.helper.d.ts +6 -2
- package/dist/test/test.helper.js +28 -6
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/REQUEST-LIFECYCLE.md +1256 -0
- package/docs/error-codes.md +446 -0
- package/migration-guides/11.10.x-to-11.11.x.md +266 -0
- package/migration-guides/11.11.x-to-11.12.x.md +323 -0
- package/migration-guides/11.12.x-to-11.13.0.md +612 -0
- package/migration-guides/11.13.x-to-11.14.0.md +348 -0
- package/migration-guides/11.14.x-to-11.15.0.md +262 -0
- package/migration-guides/11.15.0-to-11.15.3.md +118 -0
- package/migration-guides/11.15.x-to-11.16.0.md +497 -0
- package/migration-guides/11.16.x-to-11.17.0.md +130 -0
- package/migration-guides/11.17.x-to-11.18.0.md +393 -0
- package/migration-guides/11.18.x-to-11.19.0.md +151 -0
- package/migration-guides/11.19.x-to-11.20.0.md +170 -0
- package/migration-guides/11.20.x-to-11.21.0.md +216 -0
- package/migration-guides/11.21.0-to-11.21.1.md +194 -0
- package/migration-guides/11.21.1-to-11.21.2.md +114 -0
- package/migration-guides/11.21.2-to-11.21.3.md +175 -0
- package/migration-guides/11.21.x-to-11.22.0.md +224 -0
- package/migration-guides/11.3.x-to-11.4.x.md +233 -0
- package/migration-guides/11.6.x-to-11.7.x.md +394 -0
- package/migration-guides/11.7.x-to-11.8.x.md +318 -0
- package/migration-guides/11.8.x-to-11.9.x.md +322 -0
- package/migration-guides/11.9.x-to-11.10.x.md +571 -0
- package/migration-guides/TEMPLATE.md +113 -0
- package/package.json +8 -3
- package/src/core/common/interfaces/server-options.interface.ts +83 -16
- package/src/core/modules/better-auth/CUSTOMIZATION.md +24 -17
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +5 -5
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +29 -25
- package/src/core/modules/better-auth/core-better-auth.service.ts +13 -9
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +42 -12
- package/src/core/modules/error-code/error-code.module.ts +4 -9
- package/src/core/modules/tenant/INTEGRATION-CHECKLIST.md +13 -2
- package/src/core/modules/tenant/README.md +26 -1
- package/src/core/modules/tenant/core-tenant.guard.ts +142 -11
- package/src/core/modules/tenant/core-tenant.helpers.ts +6 -2
- package/src/core.module.ts +52 -10
- package/src/server/server.module.ts +7 -9
- package/src/test/README.md +47 -0
- package/src/test/test.helper.ts +55 -6
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Migration Guide: 11.21.2 → 11.21.3
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
|----------|---------|
|
|
7
|
+
| **Breaking Changes** | None |
|
|
8
|
+
| **New Features** | System role early-returns in CoreTenantGuard, S_NO_ONE defense-in-depth, account collection indices, TestHelper download cookie auth |
|
|
9
|
+
| **Bugfixes** | CoreTenantGuard: class-level roles no longer shadow method-level system roles; admin bypass log level changed to `debug` |
|
|
10
|
+
| **Migration Effort** | < 5 minutes |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Quick Migration
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Update package
|
|
18
|
+
pnpm add @lenne.tech/nest-server@11.21.3
|
|
19
|
+
|
|
20
|
+
# Verify build
|
|
21
|
+
pnpm run build
|
|
22
|
+
|
|
23
|
+
# Run tests
|
|
24
|
+
pnpm test
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
No code changes required. The bugfix and new features are fully backward compatible.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What's New in 11.21.3
|
|
32
|
+
|
|
33
|
+
### 1. CoreTenantGuard: System Role Early-Returns (Bugfix)
|
|
34
|
+
|
|
35
|
+
**Affects:** Projects with `multiTenancy` enabled that use class-level `@Roles()` combined with method-level system roles.
|
|
36
|
+
|
|
37
|
+
**Problem:** When a controller class had `@Roles(ADMIN)` and a method had `@Roles(S_USER)`, the guard merged both into `[S_USER, ADMIN]`, then filtered out system roles — leaving `checkableRoles = [ADMIN]`. This blocked non-admin users even though the method explicitly allowed any authenticated user.
|
|
38
|
+
|
|
39
|
+
**Fix:** `CoreTenantGuard` now checks system roles (S_EVERYONE → S_USER → S_VERIFIED) **before** filtering to real roles. If a system role grants access, the guard returns immediately without requiring real role checks.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// This pattern now works correctly:
|
|
43
|
+
@Roles(RoleEnum.ADMIN) // Class: admin can always access
|
|
44
|
+
@Controller('users')
|
|
45
|
+
class UserController {
|
|
46
|
+
|
|
47
|
+
@Get('profile')
|
|
48
|
+
@Roles(RoleEnum.S_USER) // Method: any authenticated user can access
|
|
49
|
+
getProfile() { ... } // Previously: blocked non-admin users ❌
|
|
50
|
+
// Now: any authenticated user passes ✅
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Role resolution semantics:**
|
|
55
|
+
|
|
56
|
+
| Role Type | Resolution | Example |
|
|
57
|
+
|-----------|-----------|---------|
|
|
58
|
+
| System roles (S_EVERYONE, S_USER, S_VERIFIED) | Method takes precedence | Class `S_EVERYONE` + Method `S_USER` → `S_USER` applies |
|
|
59
|
+
| Real roles (ADMIN, hierarchy, custom) | OR/merged (class extends method) | Class `ADMIN` + Method `'editor'` → ADMIN or editor |
|
|
60
|
+
|
|
61
|
+
**Tenant header behavior with system roles:**
|
|
62
|
+
|
|
63
|
+
| System Role | No Header | Header Present |
|
|
64
|
+
|-------------|-----------|----------------|
|
|
65
|
+
| S_EVERYONE | Pass (public) | Pass + optional tenant context enrichment |
|
|
66
|
+
| S_USER | Pass if authenticated | Pass if member (403 if not a member); admin bypass applies |
|
|
67
|
+
| S_VERIFIED | Pass if verified | Pass if verified member (403 if not a member); admin bypass applies |
|
|
68
|
+
|
|
69
|
+
Admin users with `adminBypass: true` (default) always pass tenant membership checks, even when a system role early-return handles the request.
|
|
70
|
+
|
|
71
|
+
### 2. Admin Bypass Log Level Changed to `debug`
|
|
72
|
+
|
|
73
|
+
Admin bypass log messages (`Admin bypass: user X accessing tenant Y`) have been downgraded from `log` to `debug` level. This reduces log noise in production. To see admin bypass activity, enable debug-level logging for the `CoreTenantGuard` context.
|
|
74
|
+
|
|
75
|
+
### 3. S_NO_ONE Defense-in-Depth
|
|
76
|
+
|
|
77
|
+
`CoreTenantGuard` now explicitly checks for `S_NO_ONE` and throws `ForbiddenException` — previously it relied solely on `RolesGuard`/`BetterAuthRolesGuard` catching `S_NO_ONE` upstream. This adds defense-in-depth for custom guard chain configurations.
|
|
78
|
+
|
|
79
|
+
### 4. TestHelper: Cookie Auth for Download Methods
|
|
80
|
+
|
|
81
|
+
**Affects:** Projects using `TestHelper.download()` or `TestHelper.downloadBuffer()` in tests.
|
|
82
|
+
|
|
83
|
+
The download methods now support cookie-based authentication via a new `TestDownloadOptions` interface:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// String form (backward compatible)
|
|
87
|
+
await testHelper.download('/files/id/abc', jwtToken);
|
|
88
|
+
|
|
89
|
+
// Options object with JWT token
|
|
90
|
+
await testHelper.download('/files/id/abc', { token: jwtToken });
|
|
91
|
+
|
|
92
|
+
// Options object with cookie-based session auth
|
|
93
|
+
await testHelper.download('/files/id/abc', { cookies: sessionToken });
|
|
94
|
+
|
|
95
|
+
// Both simultaneously (like rest())
|
|
96
|
+
await testHelper.download('/files/id/abc', {
|
|
97
|
+
cookies: sessionToken,
|
|
98
|
+
token: jwtToken,
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The same options apply to `downloadBuffer()`.
|
|
103
|
+
|
|
104
|
+
### 5. Performance: Account Collection Indices
|
|
105
|
+
|
|
106
|
+
New MongoDB indices are automatically created on application startup (via `onModuleInit`) for the `account` collection:
|
|
107
|
+
|
|
108
|
+
- `{ userId: 1 }` — accelerates `$lookup` joins in `getMigrationStatus()` and session lookups
|
|
109
|
+
- `{ providerId: 1, userId: 1 }` — accelerates credential account filtering
|
|
110
|
+
|
|
111
|
+
**No manual action required** — indices are created idempotently (no-op if they already exist). The indices significantly improve `betterAuthMigrationStatus` query performance (up to 97% faster in test environments).
|
|
112
|
+
|
|
113
|
+
### 6. Documentation: System Role OR Semantics
|
|
114
|
+
|
|
115
|
+
`docs/REQUEST-LIFECYCLE.md` has been updated with:
|
|
116
|
+
- Clarified OR semantics for system roles in `CoreTenantGuard`
|
|
117
|
+
- Corrected `S_VERIFIED` check logic (now includes `verifiedAt`)
|
|
118
|
+
- Added notes that `S_CREATOR` and `S_SELF` are object-level checks (handled by interceptors, not guards)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Compatibility Notes
|
|
123
|
+
|
|
124
|
+
### Existing Patterns — No Changes Needed
|
|
125
|
+
|
|
126
|
+
| Pattern | Status |
|
|
127
|
+
|---------|--------|
|
|
128
|
+
| Class `@Roles(ADMIN)` + Method `@Roles(S_EVERYONE)` | ✅ Works as before |
|
|
129
|
+
| Class `@Roles(ADMIN)` + Method `@Roles(S_USER)` | ✅ Works as before (and now also correct in CoreTenantGuard) |
|
|
130
|
+
| Class `@Roles(ADMIN)` + Method `@Roles(ADMIN)` | ✅ Works as before |
|
|
131
|
+
| Class `@Roles(ADMIN)` + no method `@Roles()` | ✅ Class fallback applies |
|
|
132
|
+
| `download(url, token)` string form | ✅ Backward compatible |
|
|
133
|
+
| `@SkipTenantCheck()` decorator | ✅ Works as before |
|
|
134
|
+
| BetterAuth auto-skip (`skipTenantCheck`) | ✅ Works as before |
|
|
135
|
+
|
|
136
|
+
### Edge Case: Class S_EVERYONE + Method S_USER
|
|
137
|
+
|
|
138
|
+
Previously, class `@Roles(S_EVERYONE)` combined with method `@Roles(S_USER)` resulted in public access (S_EVERYONE overrode S_USER). Now, the method-level `S_USER` takes precedence — the endpoint requires authentication.
|
|
139
|
+
|
|
140
|
+
This edge case is unlikely in practice (class-level S_EVERYONE with method-level S_USER contradicts intent), but if you intentionally relied on this behavior, add `S_EVERYONE` to the method:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Before: S_EVERYONE on class made this endpoint public
|
|
144
|
+
@Roles(RoleEnum.S_USER)
|
|
145
|
+
getProfile() { ... }
|
|
146
|
+
|
|
147
|
+
// After: If you want it public, be explicit on the method
|
|
148
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
149
|
+
getProfile() { ... }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Module Documentation
|
|
155
|
+
|
|
156
|
+
### Tenant Module
|
|
157
|
+
|
|
158
|
+
- **README:** [src/core/modules/tenant/README.md](../src/core/modules/tenant/README.md) — New "System Roles as OR Alternatives" section, updated Tenant Context Rule and @SkipTenantCheck documentation
|
|
159
|
+
- **Integration Checklist:** [src/core/modules/tenant/INTEGRATION-CHECKLIST.md](../src/core/modules/tenant/INTEGRATION-CHECKLIST.md)
|
|
160
|
+
- **Key Files:**
|
|
161
|
+
- `core-tenant.guard.ts` — System role early-returns, hybrid role resolution, S_NO_ONE defense-in-depth, admin bypass audit log (debug level)
|
|
162
|
+
- `core-tenant.helpers.ts` — Updated JSDoc for `mergeRolesMetadata`, `isSystemRole`
|
|
163
|
+
|
|
164
|
+
### TestHelper
|
|
165
|
+
|
|
166
|
+
- **README:** [src/test/README.md](../src/test/README.md) — New download/downloadBuffer section with cookie auth examples
|
|
167
|
+
- **Key Files:**
|
|
168
|
+
- `test.helper.ts` — `TestDownloadOptions` interface, cookie auth for downloads
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## References
|
|
173
|
+
|
|
174
|
+
- [Request Lifecycle Documentation](../docs/REQUEST-LIFECYCLE.md) — Updated system role semantics
|
|
175
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Migration Guide: 11.21.x → 11.22.0
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
|----------|---------|
|
|
7
|
+
| **Breaking Changes** | None |
|
|
8
|
+
| **New Features** | `ICoreModuleOverrides` — dedicated parameter for customizing core module components; npm package now includes `CLAUDE.md`, `.claude/rules/`, `docs/`, and `migration-guides/` for AI-assisted development |
|
|
9
|
+
| **Bugfixes** | Prevents duplicate controller registration when extending ErrorCodeModule |
|
|
10
|
+
| **Migration Effort** | ~5 minutes (optional, backward compatible) |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Quick Migration (No Breaking Changes)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Update package
|
|
18
|
+
pnpm add @lenne.tech/nest-server@11.22.0
|
|
19
|
+
|
|
20
|
+
# Verify build
|
|
21
|
+
pnpm run build
|
|
22
|
+
|
|
23
|
+
# Run tests
|
|
24
|
+
pnpm test
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
No code changes required. All existing patterns continue to work.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What's New in 11.22.0
|
|
32
|
+
|
|
33
|
+
### 1. Module Override Parameter (`ICoreModuleOverrides`)
|
|
34
|
+
|
|
35
|
+
`CoreModule.forRoot()` now accepts an optional second parameter for replacing default controllers,
|
|
36
|
+
resolvers, or services of auto-registered core modules.
|
|
37
|
+
|
|
38
|
+
This solves the duplicate controller registration problem that occurred when projects called
|
|
39
|
+
`ErrorCodeModule.forRoot()` or `CoreBetterAuthModule.forRoot()` separately alongside CoreModule's
|
|
40
|
+
auto-registration.
|
|
41
|
+
|
|
42
|
+
**Before (caused duplicate routes):**
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
@Module({
|
|
46
|
+
imports: [
|
|
47
|
+
CoreModule.forRoot(envConfig),
|
|
48
|
+
// ❌ This caused duplicate controller registration because CoreModule
|
|
49
|
+
// already called ErrorCodeModule.forRoot() internally
|
|
50
|
+
ErrorCodeModule.forRoot({
|
|
51
|
+
controller: ErrorCodeController,
|
|
52
|
+
service: ErrorCodeService,
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
})
|
|
56
|
+
export class ServerModule {}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**After (single registration, clean):**
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
@Module({
|
|
63
|
+
imports: [
|
|
64
|
+
CoreModule.forRoot(envConfig, {
|
|
65
|
+
errorCode: {
|
|
66
|
+
controller: ErrorCodeController,
|
|
67
|
+
service: ErrorCodeService,
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
})
|
|
72
|
+
export class ServerModule {}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Available Override Fields
|
|
76
|
+
|
|
77
|
+
| Module | Fields | Description |
|
|
78
|
+
|--------|--------|-------------|
|
|
79
|
+
| `errorCode` | `controller`, `service` | Custom error code endpoint and/or service |
|
|
80
|
+
| `betterAuth` | `controller`, `resolver` | Custom IAM REST controller and/or GraphQL resolver |
|
|
81
|
+
|
|
82
|
+
### Legacy Mode (3-parameter signature)
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig, {
|
|
86
|
+
errorCode: {
|
|
87
|
+
controller: ErrorCodeController,
|
|
88
|
+
service: ErrorCodeService,
|
|
89
|
+
},
|
|
90
|
+
betterAuth: {
|
|
91
|
+
resolver: BetterAuthResolver,
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Framework Documentation in npm Package
|
|
97
|
+
|
|
98
|
+
The npm package now includes `CLAUDE.md`, `.claude/rules/`, `docs/`, and `migration-guides/`.
|
|
99
|
+
This enables AI-assisted development tools (like Claude Code) to read the framework's
|
|
100
|
+
architecture documentation, configuration interfaces, and integration checklists directly
|
|
101
|
+
from `node_modules/@lenne.tech/nest-server/`.
|
|
102
|
+
|
|
103
|
+
**For AI-assisted development:** Add this to your project's `CLAUDE.md`:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
## Framework: @lenne.tech/nest-server
|
|
107
|
+
When working with framework features, read source and docs from:
|
|
108
|
+
node_modules/@lenne.tech/nest-server/CLAUDE.md
|
|
109
|
+
node_modules/@lenne.tech/nest-server/src/core/common/interfaces/server-options.interface.ts
|
|
110
|
+
node_modules/@lenne.tech/nest-server/src/core/modules/*/INTEGRATION-CHECKLIST.md
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Recommended Migration
|
|
116
|
+
|
|
117
|
+
While not required, migrating to the overrides pattern is recommended to prevent potential
|
|
118
|
+
duplicate controller registration issues.
|
|
119
|
+
|
|
120
|
+
### Step 1: Move ErrorCodeModule customization to overrides
|
|
121
|
+
|
|
122
|
+
If your project has a separate `ErrorCodeModule.forRoot()` call:
|
|
123
|
+
|
|
124
|
+
**Before:**
|
|
125
|
+
```typescript
|
|
126
|
+
imports: [
|
|
127
|
+
CoreModule.forRoot(envConfig),
|
|
128
|
+
ErrorCodeModule.forRoot({
|
|
129
|
+
controller: ErrorCodeController,
|
|
130
|
+
service: ErrorCodeService,
|
|
131
|
+
}),
|
|
132
|
+
]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**After:**
|
|
136
|
+
```typescript
|
|
137
|
+
imports: [
|
|
138
|
+
CoreModule.forRoot(envConfig, {
|
|
139
|
+
errorCode: {
|
|
140
|
+
controller: ErrorCodeController,
|
|
141
|
+
service: ErrorCodeService,
|
|
142
|
+
},
|
|
143
|
+
}),
|
|
144
|
+
// Remove the separate ErrorCodeModule.forRoot() call
|
|
145
|
+
]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Step 2: Move BetterAuth customization to overrides (optional)
|
|
149
|
+
|
|
150
|
+
If your project uses `betterAuth.controller` or `betterAuth.resolver` in config:
|
|
151
|
+
|
|
152
|
+
**Before:**
|
|
153
|
+
```typescript
|
|
154
|
+
// config.env.ts
|
|
155
|
+
betterAuth: {
|
|
156
|
+
controller: BetterAuthController,
|
|
157
|
+
resolver: BetterAuthResolver,
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**After:**
|
|
162
|
+
```typescript
|
|
163
|
+
// config.env.ts — remove controller/resolver from betterAuth config
|
|
164
|
+
betterAuth: { /* ... other config ... */ }
|
|
165
|
+
|
|
166
|
+
// server.module.ts
|
|
167
|
+
CoreModule.forRoot(envConfig, {
|
|
168
|
+
betterAuth: {
|
|
169
|
+
controller: BetterAuthController,
|
|
170
|
+
resolver: BetterAuthResolver,
|
|
171
|
+
},
|
|
172
|
+
})
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Both approaches work — the overrides parameter takes precedence. The config fields remain
|
|
176
|
+
for backward compatibility.
|
|
177
|
+
|
|
178
|
+
### Step 3: Acknowledge deprecation warnings (no action required)
|
|
179
|
+
|
|
180
|
+
The `betterAuth.controller` and `betterAuth.resolver` fields in the config interface are now
|
|
181
|
+
marked as `@deprecated`. TypeScript will show strikethrough/warnings when these fields are used.
|
|
182
|
+
|
|
183
|
+
**No action required** — the fields still work. But when you have time, move them to the
|
|
184
|
+
`overrides` parameter (Step 2 above) to silence the warnings. This keeps class references
|
|
185
|
+
(code) separate from environment configuration (strings/numbers).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Deprecations
|
|
190
|
+
|
|
191
|
+
| Field | Deprecated Since | Replacement | Removal |
|
|
192
|
+
|-------|-----------------|-------------|---------|
|
|
193
|
+
| `betterAuth.controller` | 11.22.0 | `CoreModule.forRoot(config, { betterAuth: { controller } })` | Not planned (backward compatible) |
|
|
194
|
+
| `betterAuth.resolver` | 11.22.0 | `CoreModule.forRoot(config, { betterAuth: { resolver } })` | Not planned (backward compatible) |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Compatibility Notes
|
|
199
|
+
|
|
200
|
+
| Pattern | Status |
|
|
201
|
+
|---------|--------|
|
|
202
|
+
| `CoreModule.forRoot(envConfig)` without overrides | ✅ Works unchanged |
|
|
203
|
+
| `betterAuth.controller`/`resolver` in config | ✅ Works, overrides take precedence |
|
|
204
|
+
| `errorCode.autoRegister: false` + separate import | ✅ Works unchanged |
|
|
205
|
+
| `betterAuth.autoRegister: false` + separate import | ✅ Works unchanged |
|
|
206
|
+
| Separate `ErrorCodeModule.forRoot()` alongside CoreModule | ⚠️ Still works but causes duplicate controllers — use overrides instead. If your project already had this pattern, the duplicate registration still occurs but is harmless at runtime (NestJS deduplicates providers). The recommended migration is to use the overrides parameter. |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Troubleshooting
|
|
211
|
+
|
|
212
|
+
| Issue | Solution |
|
|
213
|
+
|-------|----------|
|
|
214
|
+
| Duplicate route handlers after update | Move `ErrorCodeModule.forRoot()` to `CoreModule.forRoot()` overrides parameter |
|
|
215
|
+
| TypeScript error on overrides parameter | Ensure `@lenne.tech/nest-server@11.22.0` is installed |
|
|
216
|
+
| Custom ErrorCode controller not registered | Check that `errorCode.autoRegister` is not set to `false` when using overrides |
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Module Documentation
|
|
221
|
+
|
|
222
|
+
- [ErrorCode INTEGRATION-CHECKLIST](../src/core/modules/error-code/INTEGRATION-CHECKLIST.md)
|
|
223
|
+
- [BetterAuth CUSTOMIZATION](../src/core/modules/better-auth/CUSTOMIZATION.md)
|
|
224
|
+
- [Configurable Features](../.claude/rules/configurable-features.md)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Migration Guide: 11.3.x → 11.4.x
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
|
|
5
|
+
**Not using `@nodepit/migrate-state-store-mongodb`?**
|
|
6
|
+
```bash
|
|
7
|
+
npm install @lenne.tech/nest-server@11.4.x
|
|
8
|
+
npm run build && npm test # Done! No breaking changes.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Using `@nodepit/migrate-state-store-mongodb`?** Follow the migration steps below to switch to the built-in system.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
| Category | Details |
|
|
18
|
+
|----------|---------|
|
|
19
|
+
| **Breaking Changes** | None (backward compatible) |
|
|
20
|
+
| **New Features** | Built-in migration CLI, MongoStateStore, helper functions |
|
|
21
|
+
| **Bugfixes** | Various MapAndValidatePipe improvements (11.4.2-11.4.5) |
|
|
22
|
+
| **Migration Effort** | ~5 min (no @nodepit) / ~15 min (with @nodepit migration) |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Prerequisites
|
|
27
|
+
|
|
28
|
+
### ts-node (Required for TypeScript migrations)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install --save-dev ts-node
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## What's New in 11.4.x
|
|
37
|
+
|
|
38
|
+
### 1. Built-in Migration CLI
|
|
39
|
+
|
|
40
|
+
No external `migrate` package required - CLI included in nest-server:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx migrate --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Migration Helper Functions
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { getDb, uploadFileToGridFS, createMigrationStore } from '@lenne.tech/nest-server';
|
|
50
|
+
|
|
51
|
+
const db = await getDb('mongodb://localhost/mydb');
|
|
52
|
+
const fileId = await uploadFileToGridFS('mongodb://localhost/mydb', './assets/logo.png');
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. MongoStateStore
|
|
56
|
+
|
|
57
|
+
Drop-in replacement for `@nodepit/migrate-state-store-mongodb` with MongoDB 7.x support and cluster locking.
|
|
58
|
+
|
|
59
|
+
### 4. S_VERIFIED System Role (11.4.8)
|
|
60
|
+
|
|
61
|
+
New system role for checking user verification status:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
@Roles(RoleEnum.S_VERIFIED) // Requires verified user
|
|
65
|
+
async someMethod() { }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Checks: `user.verified || user.verifiedAt || user.emailVerified`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Migration from @nodepit
|
|
73
|
+
|
|
74
|
+
### Step 1: Remove Old Packages
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm uninstall migrate @nodepit/migrate-state-store-mongodb ts-migrate-mongoose
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Step 2: Update nest-server
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm install @lenne.tech/nest-server@11.4.x
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 3: Update `migrations-utils/migrate.js`
|
|
87
|
+
|
|
88
|
+
**Before:**
|
|
89
|
+
```javascript
|
|
90
|
+
import config from '../src/config.env';
|
|
91
|
+
const { MongoStateStore } = require('@nodepit/migrate-state-store-mongodb');
|
|
92
|
+
|
|
93
|
+
module.exports = class MyMongoStateStore extends MongoStateStore {
|
|
94
|
+
constructor() {
|
|
95
|
+
super({ uri: config.mongoose.uri, collectionName: 'migrations' });
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**After:**
|
|
101
|
+
```javascript
|
|
102
|
+
const { createMigrationStore } = require('@lenne.tech/nest-server');
|
|
103
|
+
const config = require('../src/config.env');
|
|
104
|
+
|
|
105
|
+
module.exports = createMigrationStore(
|
|
106
|
+
config.default.mongoose.uri,
|
|
107
|
+
'migrations'
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Step 4: Update `migrations-utils/db.ts`
|
|
112
|
+
|
|
113
|
+
**Before:**
|
|
114
|
+
```typescript
|
|
115
|
+
import { GridFSBucket, MongoClient, ObjectId } from 'mongodb';
|
|
116
|
+
import config from '../src/config.env';
|
|
117
|
+
|
|
118
|
+
const MONGO_URL = config.mongoose.uri;
|
|
119
|
+
|
|
120
|
+
export const getDb = async () => {
|
|
121
|
+
const client: MongoClient = await MongoClient.connect(MONGO_URL);
|
|
122
|
+
return client.db();
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const uploadFile = async (relativePath, options?) => {
|
|
126
|
+
// ... custom implementation
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**After:**
|
|
131
|
+
```typescript
|
|
132
|
+
/**
|
|
133
|
+
* Legacy compatibility layer - allows existing migrations to work unchanged
|
|
134
|
+
*/
|
|
135
|
+
import {
|
|
136
|
+
createMigrationStore,
|
|
137
|
+
getDb as nestServerGetDb,
|
|
138
|
+
uploadFileToGridFS,
|
|
139
|
+
} from '@lenne.tech/nest-server';
|
|
140
|
+
import config from '../src/config.env';
|
|
141
|
+
|
|
142
|
+
export { createMigrationStore, uploadFileToGridFS };
|
|
143
|
+
|
|
144
|
+
// Wrapper: existing migrations call getDb() without parameters
|
|
145
|
+
export const getDb = async () => nestServerGetDb(config.mongoose.uri);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Step 5: Delete Obsolete Files
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
rm migrations-utils/template.ts migrations-utils/ts-compiler.js
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Step 6: Update package.json Scripts
|
|
155
|
+
|
|
156
|
+
**Key changes:**
|
|
157
|
+
- Command (`up`, `down`, `create`) comes **first**, then options
|
|
158
|
+
- Use nest-server paths for template and compiler
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"scripts": {
|
|
163
|
+
"migrate:create": "f() { migrate create \"$1\" --template-file ./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/templates/migration-project.template.ts --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js; }; f",
|
|
164
|
+
"migrate:up": "migrate up --store ./migrations-utils/migrate.js --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js",
|
|
165
|
+
"migrate:down": "migrate down --store ./migrations-utils/migrate.js --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js",
|
|
166
|
+
"migrate:list": "migrate list --store ./migrations-utils/migrate.js --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Environment-specific scripts (optional):**
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"migrate:develop:up": "NODE_ENV=develop migrate up --store ./migrations-utils/migrate.js --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js",
|
|
175
|
+
"migrate:prod:up": "NODE_ENV=production migrate up --store ./migrations-utils/migrate.js --migrations-dir ./migrations --compiler ts:./node_modules/@lenne.tech/nest-server/dist/core/modules/migrate/helpers/ts-compiler.js"
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Step 7: Verify
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npm install
|
|
183
|
+
npm run migrate:list # Should show existing migrations
|
|
184
|
+
npm run migrate:create test # Should create new migration
|
|
185
|
+
rm migrations/*-test.ts # Clean up
|
|
186
|
+
npm run build && npm test
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Compatibility Notes
|
|
192
|
+
|
|
193
|
+
| What | Status |
|
|
194
|
+
|------|--------|
|
|
195
|
+
| Existing migration files | ✅ Unchanged |
|
|
196
|
+
| Migration state in MongoDB | ✅ Same format, no data loss |
|
|
197
|
+
| Projects without @nodepit | ✅ No action needed |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Troubleshooting
|
|
202
|
+
|
|
203
|
+
| Issue | Solution |
|
|
204
|
+
|-------|----------|
|
|
205
|
+
| `migrate` command not found | Use `npx migrate` or ensure nest-server is installed |
|
|
206
|
+
| `ts-node is required` | `npm install --save-dev ts-node` |
|
|
207
|
+
| `Cannot find module '../src/config.env'` | Use `require('../src/config.env')` and access `config.default.mongoose.uri` |
|
|
208
|
+
| Migrations run on multiple nodes | Add lock collection: `createMigrationStore(uri, 'migrations', 'migration_lock')` |
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## File Structure After Migration
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
migrations-utils/
|
|
216
|
+
├── migrate.js # Required (7 lines) - uses createMigrationStore
|
|
217
|
+
└── db.ts # Optional (5 lines) - compatibility wrapper for old migrations
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Deleted:** `template.ts`, `ts-compiler.js` (now provided by nest-server)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Module Documentation
|
|
225
|
+
|
|
226
|
+
- **README:** [src/core/modules/migrate/README.md](../src/core/modules/migrate/README.md)
|
|
227
|
+
- **@nodepit Migration:** [src/core/modules/migrate/MIGRATION_FROM_NODEPIT.md](../src/core/modules/migrate/MIGRATION_FROM_NODEPIT.md)
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## References
|
|
232
|
+
|
|
233
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
|