Skip to content

Commit 7dea582

Browse files
committed
11.7.1: Add BetterAuth parallel operation with migration status tracking, legacy endpoint controls, and bidirectional user sync
1 parent ee18534 commit 7dea582

File tree

51 files changed

+9267
-282
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+9267
-282
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Create Migration Guide
2+
3+
Create a migration guide for the current version changes.
4+
5+
## Instructions
6+
7+
### Step 1: Check Version Status
8+
9+
First, check if the package version has been modified since the last release:
10+
11+
```bash
12+
# Get current version from package.json
13+
CURRENT_VERSION=$(node -p "require('./package.json').version")
14+
15+
# Get the last released version (latest git tag)
16+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")
17+
18+
# Check if package.json was modified
19+
git diff --name-only HEAD~10 | grep -q "package.json" && echo "package.json modified" || echo "package.json unchanged"
20+
```
21+
22+
### Step 2: Determine Version
23+
24+
Compare the current version with the last tag:
25+
26+
- If versions match: Suggest incrementing PATCH version (e.g., 11.7.1 → 11.7.2)
27+
- If MINOR already incremented: Use current version for migration guide
28+
- Present options to the user:
29+
- Use current version
30+
- Increment PATCH (bugfix)
31+
- Increment MINOR (breaking change / new features)
32+
33+
### Step 3: Check for Existing Migration Guide
34+
35+
Check if a migration guide already exists for this version range:
36+
37+
```bash
38+
ls migration-guides/*.md
39+
```
40+
41+
If a guide exists for the current MINOR version range (e.g., 11.6.x-to-11.7.x), ask user:
42+
- Update existing guide
43+
- Create new guide for next version
44+
45+
### Step 4: Analyze Changes
46+
47+
Analyze changes since last release:
48+
49+
```bash
50+
# Get commits since last tag
51+
git log $LAST_TAG..HEAD --oneline
52+
53+
# Get changed files
54+
git diff --name-only $LAST_TAG..HEAD
55+
```
56+
57+
Focus on:
58+
- `src/core/` changes (breaking changes, new features)
59+
- `src/core/modules/` changes (module-specific updates)
60+
- `package.json` dependency changes
61+
62+
### Step 5: Gather Project Information
63+
64+
Ask the user:
65+
> Which projects should I analyze for migration compatibility?
66+
> Please provide paths to projects using @lenne.tech/nest-server.
67+
> (Leave empty to only analyze src/server/ and nest-server-starter)
68+
69+
Always analyze:
70+
1. Local `src/server/`
71+
2. [nest-server-starter](https://github.com/lenneTech/nest-server-starter)
72+
73+
### Step 6: Create Migration Guide
74+
75+
Use the template at `migration-guides/TEMPLATE.md` and follow the process in `.claude/rules/migration-guides.md`.
76+
77+
Required sections:
78+
1. Overview table
79+
2. Quick Migration
80+
3. What's New
81+
4. Breaking Changes (if any)
82+
5. Compatibility Notes
83+
6. Troubleshooting
84+
7. Module Documentation (link to affected module READMEs and INTEGRATION-CHECKLISTs)
85+
86+
### Step 7: Verify
87+
88+
After creating the guide:
89+
1. Run `npm run build` to verify no build errors
90+
2. Run `npm test` to verify all tests pass
91+
3. Present summary to user
92+
93+
## Output Format
94+
95+
Present the analysis as:
96+
97+
```
98+
## Version Analysis
99+
100+
Current version: X.Y.Z
101+
Last release: X.Y.W (tag: vX.Y.W)
102+
Version status: [unchanged | patch needed | minor needed]
103+
104+
## Suggested Version: X.Y.Z
105+
106+
## Changes Since Last Release
107+
- [List of significant changes]
108+
109+
## Migration Guide: X.Y.x → X.Z.x
110+
- Breaking Changes: [count]
111+
- New Features: [count]
112+
- Bugfixes: [count]
113+
```
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Configurable Features Pattern
2+
3+
This document describes the standard pattern for implementing optional, configurable features in @lenne.tech/nest-server.
4+
5+
## "Presence Implies Enabled" Pattern
6+
7+
When implementing configurable features, follow this pattern for activation logic:
8+
9+
### Rules
10+
11+
1. **No configuration** (`undefined` or `null`): Feature is **disabled** (backward compatible)
12+
2. **Empty object** (`{}`): Feature is **enabled** with all default values
13+
3. **Partial configuration** (`{ max: 5 }`): Feature is **enabled**, missing values use defaults
14+
4. **Explicit disable** (`{ enabled: false, ... }`): Feature is **disabled**, allows pre-configuration
15+
16+
### Benefits
17+
18+
- **Backward Compatible**: Existing projects without config continue to work unchanged
19+
- **Efficient**: No need to set `enabled: true` redundantly when already providing config
20+
- **Flexible**: Can pre-configure without activating via `enabled: false`
21+
- **Intuitive**: Providing a config object signals intent to use the feature
22+
23+
### Implementation Example
24+
25+
```typescript
26+
interface IFeatureConfig {
27+
enabled?: boolean; // Optional - presence of config implies true
28+
max?: number;
29+
windowSeconds?: number;
30+
}
31+
32+
const DEFAULT_CONFIG: Required<IFeatureConfig> = {
33+
enabled: false, // Default is false, but overridden by presence
34+
max: 10,
35+
windowSeconds: 60,
36+
};
37+
38+
class FeatureService {
39+
private config: Required<IFeatureConfig> = DEFAULT_CONFIG;
40+
41+
/**
42+
* Configure the feature
43+
*
44+
* Follows the "presence implies enabled" pattern:
45+
* - If config is undefined/null: feature stays disabled (backward compatible)
46+
* - If config is an object (even empty {}): feature is enabled by default
47+
* - Unless `enabled: false` is explicitly set
48+
*/
49+
configure(config: IFeatureConfig | undefined | null): void {
50+
// No config = stay disabled (backward compatible)
51+
if (config === undefined || config === null) {
52+
return;
53+
}
54+
55+
// Presence of config implies enabled, unless explicitly disabled
56+
const enabled = config.enabled !== false;
57+
58+
this.config = {
59+
...DEFAULT_CONFIG,
60+
...config,
61+
enabled,
62+
};
63+
}
64+
}
65+
```
66+
67+
### Usage Examples
68+
69+
```typescript
70+
// config.env.ts
71+
72+
// Feature disabled (no config)
73+
// rateLimit: undefined // or just don't define it
74+
75+
// Feature enabled with all defaults
76+
auth: {
77+
rateLimit: {}
78+
}
79+
80+
// Feature enabled with custom max
81+
auth: {
82+
rateLimit: { max: 20 }
83+
}
84+
85+
// Feature enabled with full configuration
86+
auth: {
87+
rateLimit: {
88+
max: 10,
89+
windowSeconds: 60,
90+
message: 'Too many requests'
91+
}
92+
}
93+
94+
// Pre-configured but disabled (for testing or gradual rollout)
95+
auth: {
96+
rateLimit: {
97+
enabled: false,
98+
max: 10,
99+
windowSeconds: 60
100+
}
101+
}
102+
```
103+
104+
## Applied Features
105+
106+
This pattern is currently applied to:
107+
108+
| Feature | Config Path | Default Values |
109+
|---------|-------------|----------------|
110+
| Legacy Auth Rate Limiting | `auth.rateLimit` | `max: 10`, `windowSeconds: 60` |
111+
| BetterAuth Rate Limiting | `betterAuth.rateLimit` | `max: 10`, `windowSeconds: 60` |
112+
113+
## Checklist for New Configurable Features
114+
115+
When adding a new configurable feature:
116+
117+
- [ ] Define interface with `enabled?: boolean` as optional property
118+
- [ ] Set `enabled: false` in DEFAULT_CONFIG
119+
- [ ] Implement "presence implies enabled" logic in configure method
120+
- [ ] Document all default values in interface JSDoc
121+
- [ ] Add tests for: undefined config, empty object, partial config, explicit disable
122+
- [ ] Update this document with the new feature

.claude/rules/core-modules.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,120 @@ this.logger.error('Error occurred'); // Errors
6767
this.logger.debug('Debug info'); // Development only (sparingly)
6868
```
6969

70+
## Optional Constructor Parameters
71+
72+
Use the **options object pattern** for optional constructor parameters in Core classes:
73+
74+
```typescript
75+
// Define options interface
76+
export interface CoreUserServiceOptions {
77+
betterAuthUserMapper?: BetterAuthUserMapper;
78+
// Future optional params can be added without breaking changes
79+
}
80+
81+
// Core class constructor
82+
protected constructor(
83+
// Required params first
84+
protected readonly configService: ConfigService,
85+
protected readonly emailService: EmailService,
86+
// Options object last
87+
protected readonly options?: CoreUserServiceOptions,
88+
) {
89+
super();
90+
}
91+
92+
// Usage in methods
93+
if (this.options?.betterAuthUserMapper) {
94+
await this.options.betterAuthUserMapper.syncEmail(...);
95+
}
96+
```
97+
98+
**Why this pattern:**
99+
- New optional parameters can be added without breaking existing implementations
100+
- No need to pass `null` or `undefined` for unused optional parameters
101+
- Order of optional parameters doesn't matter
102+
- Clear distinction between required and optional dependencies
103+
104+
**Implementation in extending classes:**
105+
```typescript
106+
constructor(
107+
// ... required params ...
108+
@Optional() private readonly betterAuthUserMapper?: BetterAuthUserMapper,
109+
) {
110+
super(configService, emailService, mainDbModel, mainModelConstructor, { betterAuthUserMapper });
111+
}
112+
```
113+
70114
## Testing
71115

72116
- Create story tests in `tests/stories/`
73117
- Test through API (REST/GraphQL), not direct service calls
74118
- Include security tests for authentication/authorization
119+
120+
## Integration Documentation (Required for All Core Modules)
121+
122+
Every core module that requires project integration MUST have an `INTEGRATION-CHECKLIST.md` file.
123+
124+
### Purpose
125+
126+
This checklist helps developers (and AI assistants like Claude Code) integrate the module into their projects. It should be optimized for:
127+
- Quick understanding of required steps
128+
- Clear references to working code (no duplicates)
129+
- Critical "WHY" explanations for non-obvious steps
130+
131+
### Required Structure
132+
133+
```markdown
134+
# [ModuleName] Integration Checklist
135+
136+
## Reference Implementation
137+
- Local: `node_modules/@lenne.tech/nest-server/src/server/modules/[module]/`
138+
- GitHub: https://github.com/lenneTech/nest-server/tree/develop/src/server/modules/[module]
139+
140+
## Required Files (Create in Order)
141+
### 1. [FileName]
142+
**Create:** `src/server/modules/[module]/[file].ts`
143+
**Copy from:** Reference implementation
144+
[Optional: WHY explanation for critical/non-obvious steps]
145+
146+
## Verification Checklist
147+
- [ ] Build succeeds
148+
- [ ] Tests pass
149+
- [ ] [Module-specific checks]
150+
151+
## Common Mistakes
152+
| Mistake | Symptom | Fix |
153+
```
154+
155+
### Key Principles
156+
157+
1. **No Code Duplication**: Never include full code examples that duplicate `src/server/`
158+
- Reference files exist in `src/server/modules/` and are included in the npm package
159+
- Claude Code can read these files directly from `node_modules/`
160+
- Only include small code snippets for DIFFs (changes to existing files)
161+
162+
2. **Single Source of Truth**: The reference implementation in `src/server/` is always current
163+
- Documentation never becomes outdated
164+
- Copy-paste from reference is always correct
165+
166+
3. **WHY Explanations**: Include for critical/non-obvious steps
167+
- Example: "WHY must decorators be re-declared?" → GraphQL schema registration
168+
- Example: "WHY inject this mapper?" → Bidirectional sync between systems
169+
170+
4. **Verification Checklist**: Help verify successful integration
171+
- Build/test commands
172+
- Module-specific functional checks
173+
174+
5. **Common Mistakes Table**: Document known pitfalls with symptoms and fixes
175+
176+
### Example
177+
178+
See `src/core/modules/better-auth/INTEGRATION-CHECKLIST.md` as the reference template.
179+
180+
### When to Create
181+
182+
Create an `INTEGRATION-CHECKLIST.md` when the module:
183+
- Requires files to be created in the consuming project
184+
- Has non-obvious integration steps
185+
- Extends Core classes that need decorator re-declaration
186+
- Requires changes to existing project files (UserService, ServerModule, etc.)

0 commit comments

Comments
 (0)