- Create Economist SubmissionTracking package correctly: * mainArticle = full blog post content * coverLetter = 216-word SIR— letter * Links to blog post via blogPostId - Archive 'Letter to The Economist' from blog posts (it's the cover letter) - Fix date display on article cards (use published_at) - Target publication already displaying via blue badge Database changes: - Make blogPostId optional in SubmissionTracking model - Economist package ID: 68fa85ae49d4900e7f2ecd83 - Le Monde package ID: 68fa2abd2e6acd5691932150 Next: Enhanced modal with tabs, validation, export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
418 lines
12 KiB
Markdown
418 lines
12 KiB
Markdown
# Coding Best Practices - Governance Rules Summary
|
|
|
|
**Created**: 2025-10-11
|
|
**Context**: Lessons learned from Phase 2 Migration API validation error
|
|
**Analysis Document**: `docs/analysis/PHASE_2_ERROR_ANALYSIS.md`
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Following the Phase 2 migration API validation error (`source: 'claude_md_migration' is not a valid enum value`), a comprehensive root cause analysis was conducted. This analysis identified **5 major categories of preventable errors**:
|
|
|
|
1. **Schema-Code Mismatch** - Controller code not aligned with database schema
|
|
2. **Magic Strings** - Hardcoded string literals instead of constants
|
|
3. **Development Environment Cache** - Stale model definitions after schema changes
|
|
4. **Insufficient Testing** - No integration tests before declaring code complete
|
|
5. **Documentation Gaps** - Enum values not centrally documented
|
|
|
|
Based on this analysis, **10 governance rules** were created to prevent similar errors in future development.
|
|
|
|
---
|
|
|
|
## Created Governance Rules
|
|
|
|
### 1. **inst_021** - Centralized Constants for Enums
|
|
**Quadrant**: SYSTEM | **Persistence**: HIGH | **Priority**: 95
|
|
|
|
```
|
|
ALL database enum values MUST be defined in a centralized constants file
|
|
(src/constants/*.constants.js). Controllers and services MUST import constants,
|
|
NEVER use string literals for enum values.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `source: GOVERNANCE_SOURCES.CLAUDE_MD_MIGRATION`
|
|
- ❌ BAD: `source: 'claude_md_migration'`
|
|
|
|
**Prevents**: Schema-code mismatches, typos, refactoring errors
|
|
|
|
---
|
|
|
|
### 2. **inst_022** - Pre-Save Validation
|
|
**Quadrant**: TACTICAL | **Persistence**: HIGH | **Priority**: 90
|
|
|
|
```
|
|
BEFORE saving any Mongoose model instance, code MUST validate enum field values
|
|
against the schema's allowed values. Use pre-save validation or explicit checks.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `if (!ENUM_VALUES.includes(value)) throw new Error(...)`
|
|
- ❌ BAD: Directly calling `newModel.save()` without validation
|
|
|
|
**Prevents**: Runtime database validation errors, silent failures
|
|
|
|
---
|
|
|
|
### 3. **inst_023** - JSDoc Type Annotations
|
|
**Quadrant**: TACTICAL | **Persistence**: HIGH | **Priority**: 85
|
|
|
|
```
|
|
ALL functions that create or update database models MUST include JSDoc type
|
|
annotations specifying allowed enum values. Use @typedef for complex types.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `@property {'user_instruction'|'framework_default'|'claude_md_migration'} source`
|
|
- ❌ BAD: `@property {string} source` (too vague)
|
|
|
|
**Prevents**: IDE type checking catches enum mismatches at dev-time
|
|
|
|
---
|
|
|
|
### 4. **inst_024** - Server Restart After Model Changes
|
|
**Quadrant**: OPERATIONAL | **Persistence**: HIGH | **Priority**: 80
|
|
|
|
```
|
|
AFTER modifying any Mongoose model schema (*.model.js files), developer MUST
|
|
restart the Node.js server to clear require() cache. Use nodemon for automatic restarts.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `npm run dev` (uses nodemon, auto-restarts)
|
|
- ❌ BAD: Editing model and testing without restart
|
|
|
|
**Prevents**: Testing against stale cached models
|
|
|
|
---
|
|
|
|
### 5. **inst_025** - Constants File Structure
|
|
**Quadrant**: TACTICAL | **Persistence**: HIGH | **Priority**: 85
|
|
|
|
```
|
|
WHEN creating constants files for enums, MUST export both:
|
|
(1) Named object with constants (e.g., GOVERNANCE_SOURCES),
|
|
(2) Array of values (e.g., GOVERNANCE_SOURCE_VALUES).
|
|
Array MUST be used in model schema enum definition.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `module.exports = { GOVERNANCE_SOURCES, GOVERNANCE_SOURCE_VALUES }`
|
|
- ✅ GOOD: Model uses `enum: GOVERNANCE_SOURCE_VALUES`
|
|
|
|
**Prevents**: Duplication of enum definitions
|
|
|
|
---
|
|
|
|
### 6. **inst_026** - Clear Validation Error Messages
|
|
**Quadrant**: TACTICAL | **Persistence**: MEDIUM | **Priority**: 70
|
|
|
|
```
|
|
ALL validation errors from Mongoose MUST include the invalid value and list of
|
|
valid values in the error message. Use custom error messages with {VALUES} placeholder.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `enum: { values: [...], message: '{VALUE} not valid. Must be: {VALUES}' }`
|
|
- ❌ BAD: Generic "Validation failed" with no context
|
|
|
|
**Prevents**: Lengthy debugging sessions, unclear errors
|
|
|
|
---
|
|
|
|
### 7. **inst_027** - Integration Tests Before Completion
|
|
**Quadrant**: OPERATIONAL | **Persistence**: HIGH | **Priority**: 90
|
|
|
|
```
|
|
ALL new API endpoints MUST have integration tests that hit the real database
|
|
BEFORE marking the implementation complete. Test MUST include both success and failure cases.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `tests/integration/migration.test.js` with database operations
|
|
- ❌ BAD: Marking API complete without integration tests
|
|
|
|
**Prevents**: Production deployment of broken code
|
|
|
|
---
|
|
|
|
### 8. **inst_028** - Schema Change Checklist
|
|
**Quadrant**: OPERATIONAL | **Persistence**: HIGH | **Priority**: 95
|
|
|
|
```
|
|
WHEN adding or modifying database schema enum fields, developer MUST:
|
|
(1) Update/create constants file,
|
|
(2) Update model to use constants,
|
|
(3) Write validation tests,
|
|
(4) Follow Schema Change Checklist in docs/developer/SCHEMA_CHANGE_CHECKLIST.md
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: Updated constants, model, wrote tests
|
|
- ❌ BAD: Updated code without writing tests
|
|
|
|
**Prevents**: Forgotten steps in schema changes
|
|
|
|
---
|
|
|
|
### 9. **inst_029** - Enum Documentation
|
|
**Quadrant**: OPERATIONAL | **Persistence**: MEDIUM | **Priority**: 75
|
|
|
|
```
|
|
ALL enum value additions or changes MUST be documented in docs/developer/ENUM_VALUES.md
|
|
with table showing value, constant name, and description. Include instructions for adding new values.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: Updated ENUM_VALUES.md table when adding `claude_md_migration`
|
|
- ❌ BAD: Adding enum value without documentation
|
|
|
|
**Prevents**: Developers inventing new values without checking existing ones
|
|
|
|
---
|
|
|
|
### 10. **inst_030** - Test Before Declaring Complete
|
|
**Quadrant**: OPERATIONAL | **Persistence**: HIGH | **Priority**: 90
|
|
|
|
```
|
|
BEFORE declaring any code implementation 'complete', developer MUST run all relevant tests
|
|
and verify they pass. For database code, this MUST include integration tests with real database operations.
|
|
```
|
|
|
|
**Examples**:
|
|
- ✅ GOOD: `npm test && curl POST /api/endpoint` (verify works)
|
|
- ❌ BAD: Writing code and marking complete without testing
|
|
|
|
**Prevents**: Discovering errors during final testing phase instead of immediately
|
|
|
|
---
|
|
|
|
## Rule Categories by Quadrant
|
|
|
|
### SYSTEM (1 rule)
|
|
- **inst_021**: Centralized constants for enums
|
|
|
|
### TACTICAL (4 rules)
|
|
- **inst_022**: Pre-save validation
|
|
- **inst_023**: JSDoc type annotations
|
|
- **inst_025**: Constants file structure
|
|
- **inst_026**: Clear validation error messages
|
|
|
|
### OPERATIONAL (5 rules)
|
|
- **inst_024**: Server restart after model changes
|
|
- **inst_027**: Integration tests before completion
|
|
- **inst_028**: Schema change checklist
|
|
- **inst_029**: Enum documentation
|
|
- **inst_030**: Test before declaring complete
|
|
|
|
---
|
|
|
|
## Rule Categories by Persistence
|
|
|
|
### HIGH (8 rules)
|
|
- inst_021, inst_022, inst_023, inst_024, inst_025, inst_027, inst_028, inst_030
|
|
|
|
### MEDIUM (2 rules)
|
|
- inst_026, inst_029
|
|
|
|
---
|
|
|
|
## Implementation Checklist
|
|
|
|
When implementing these rules in a new project:
|
|
|
|
### Phase 1: File Structure Setup
|
|
- [ ] Create `src/constants/` directory
|
|
- [ ] Create constants files for all enum types
|
|
- [ ] Export both named object and values array
|
|
- [ ] Update models to import constants
|
|
|
|
### Phase 2: Code Quality
|
|
- [ ] Add JSDoc annotations to all database functions
|
|
- [ ] Add pre-save validation for enum fields
|
|
- [ ] Update error messages with {VALUES} placeholder
|
|
|
|
### Phase 3: Development Environment
|
|
- [ ] Install nodemon: `npm install --save-dev nodemon`
|
|
- [ ] Add dev script: `"dev": "nodemon src/server.js"`
|
|
- [ ] Document restart requirements in README
|
|
|
|
### Phase 4: Testing
|
|
- [ ] Write integration tests for all API endpoints
|
|
- [ ] Test success and failure cases
|
|
- [ ] Add test-before-complete to workflow
|
|
|
|
### Phase 5: Documentation
|
|
- [ ] Create `docs/developer/ENUM_VALUES.md`
|
|
- [ ] Create `docs/developer/SCHEMA_CHANGE_CHECKLIST.md`
|
|
- [ ] Document all enum values with tables
|
|
- [ ] Add "To Add New Value" instructions
|
|
|
|
---
|
|
|
|
## Real-World Application
|
|
|
|
### Example: Adding New Enum Value
|
|
|
|
**Scenario**: Need to add new source type `'api_import'` for rules imported from external API
|
|
|
|
**Following the Rules**:
|
|
|
|
1. **inst_021** - Update constants file:
|
|
```javascript
|
|
// src/constants/governance.constants.js
|
|
const GOVERNANCE_SOURCES = {
|
|
USER_INSTRUCTION: 'user_instruction',
|
|
FRAMEWORK_DEFAULT: 'framework_default',
|
|
AUTOMATED: 'automated',
|
|
MIGRATION: 'migration',
|
|
CLAUDE_MD_MIGRATION: 'claude_md_migration',
|
|
API_IMPORT: 'api_import', // ✅ NEW
|
|
TEST: 'test'
|
|
};
|
|
```
|
|
|
|
2. **inst_028** - Follow checklist:
|
|
- ✅ Updated constants file
|
|
- ✅ Model already uses `GOVERNANCE_SOURCE_VALUES` (auto-includes new value)
|
|
- ✅ Write validation test
|
|
|
|
3. **inst_023** - Update JSDoc:
|
|
```javascript
|
|
/**
|
|
* @property {'user_instruction'|'framework_default'|'automated'|'migration'|'claude_md_migration'|'api_import'|'test'} source
|
|
*/
|
|
```
|
|
|
|
4. **inst_027** - Write integration test:
|
|
```javascript
|
|
it('should create rule with api_import source', async () => {
|
|
const rule = new GovernanceRule({
|
|
source: GOVERNANCE_SOURCES.API_IMPORT // ✅ Using constant
|
|
});
|
|
await expect(rule.save()).resolves.not.toThrow();
|
|
});
|
|
```
|
|
|
|
5. **inst_029** - Update documentation:
|
|
```markdown
|
|
| `api_import` | `GOVERNANCE_SOURCES.API_IMPORT` | Imported from external API |
|
|
```
|
|
|
|
6. **inst_024** - Restart server:
|
|
```bash
|
|
npm run dev # Nodemon auto-restarts
|
|
```
|
|
|
|
7. **inst_030** - Test before declaring complete:
|
|
```bash
|
|
npm test # All tests pass
|
|
curl POST /api/endpoint # Verify endpoint works
|
|
```
|
|
|
|
**Result**: New enum value added safely with zero errors! 🎉
|
|
|
|
---
|
|
|
|
## Prevention Effectiveness
|
|
|
|
### Time Comparison
|
|
|
|
**Without These Rules** (Phase 2 actual experience):
|
|
- Writing code: 15 minutes
|
|
- Testing and discovering error: 5 minutes
|
|
- Debugging root cause: 15 minutes
|
|
- Fixing model: 2 minutes
|
|
- Discovering server cache issue: 10 minutes
|
|
- Restarting and re-testing: 3 minutes
|
|
- **Total: ~50 minutes**
|
|
|
|
**With These Rules** (estimated):
|
|
- Writing code with constants: 15 minutes
|
|
- Writing JSDoc annotations: 5 minutes
|
|
- Writing integration test: 10 minutes
|
|
- Running test (catches error immediately): 1 minute
|
|
- **Total: ~31 minutes**
|
|
|
|
**Time Saved**: 19 minutes per incident
|
|
**Error Rate**: Near zero (caught by tests before deployment)
|
|
|
|
---
|
|
|
|
## Error Prevention Matrix
|
|
|
|
| Error Type | Prevented By | How |
|
|
|------------|--------------|-----|
|
|
| **Schema-Code Mismatch** | inst_021, inst_022, inst_025 | Constants + validation |
|
|
| **Magic Strings** | inst_021, inst_023 | Centralized constants + types |
|
|
| **Stale Cache** | inst_024 | Auto-restart with nodemon |
|
|
| **Missing Tests** | inst_027, inst_030 | Required integration tests |
|
|
| **Unclear Errors** | inst_026 | Descriptive error messages |
|
|
| **Forgotten Steps** | inst_028 | Schema change checklist |
|
|
| **Undocumented Enums** | inst_029 | Mandatory documentation |
|
|
|
|
---
|
|
|
|
## Metrics & Monitoring
|
|
|
|
### Compliance Checks
|
|
|
|
**Automated (CI/CD Pipeline)**:
|
|
```bash
|
|
# Check for magic strings in controllers
|
|
grep -r "'user_instruction'" src/controllers/ && exit 1
|
|
|
|
# Verify constants files exist
|
|
test -f src/constants/governance.constants.js || exit 1
|
|
|
|
# Check JSDoc coverage
|
|
npm run check-jsdoc || exit 1
|
|
|
|
# Run integration tests
|
|
npm run test:integration || exit 1
|
|
```
|
|
|
|
**Manual Code Review**:
|
|
- [ ] All new enum values have constants
|
|
- [ ] All database functions have JSDoc
|
|
- [ ] All API endpoints have integration tests
|
|
- [ ] ENUM_VALUES.md updated
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
These rules are successful when:
|
|
|
|
1. ✅ Zero schema-code mismatch errors in production
|
|
2. ✅ All enum values defined in constants files
|
|
3. ✅ 100% integration test coverage for API endpoints
|
|
4. ✅ All database errors include helpful context
|
|
5. ✅ Developer onboarding time reduced (clear documentation)
|
|
6. ✅ Code review time reduced (self-checking code)
|
|
|
|
---
|
|
|
|
## Related Documents
|
|
|
|
- **Root Cause Analysis**: `docs/analysis/PHASE_2_ERROR_ANALYSIS.md`
|
|
- **Phase 2 Test Results**: `docs/testing/PHASE_2_TEST_RESULTS.md`
|
|
- **Schema Change Checklist**: `docs/developer/SCHEMA_CHANGE_CHECKLIST.md` (to be created)
|
|
- **Enum Values Reference**: `docs/developer/ENUM_VALUES.md` (to be created)
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
The Phase 2 migration API error was a **blessing in disguise**. It revealed systemic weaknesses in development practices that, if left unchecked, would have caused repeated errors.
|
|
|
|
By creating these 10 governance rules, we've transformed a debugging session into a **permanent improvement** to code quality and developer experience.
|
|
|
|
**Prevention is cheaper than debugging.**
|
|
|
|
---
|
|
|
|
**Created By**: Claude Code Assistant
|
|
**Date**: 2025-10-11
|
|
**Status**: ✅ Active - All 10 rules enforced in tractatus_dev database
|