tractatus/scripts/migrations/001-enhance-governance-rules.js
TheFlow 0e6be3eaf1 refactor: remove website code and fix critical startup crashes (Phase 8)
CRITICAL FIX: Server would CRASH ON STARTUP (multiple import errors)

REMOVED (2 scripts):
1. scripts/framework-watchdog.js
   - Monitored .claude/session-state.json (OUR Claude Code setup)
   - Monitored .claude/token-checkpoints.json (OUR file structure)
   - Implementers won't have our .claude/ directory

2. scripts/init-db.js
   - Created website collections: blog_posts, media_inquiries, case_submissions
   - Created website collections: resources, moderation_queue, users, citations
   - Created website collections: translations, koha_donations
   - Next steps referenced deleted scripts (npm run seed:admin)

REWRITTEN (2 files):

src/models/index.js (29 lines → 27 lines)
- REMOVED imports: Document, BlogPost, MediaInquiry, CaseSubmission, Resource
- REMOVED imports: ModerationQueue, User (all deleted in Phase 2)
- KEPT imports: AuditLog, DeliberationSession, GovernanceLog, GovernanceRule
- KEPT imports: Precedent, Project, SessionState, VariableValue, VerificationLog
- Result: Only framework models exported

src/server.js (284 lines → 163 lines, 43% reduction)
- REMOVED: Imports to deleted middleware (csrf-protection, response-sanitization)
- REMOVED: Stripe webhook handling (/api/koha/webhook)
- REMOVED: Static file caching (for deleted public/ directory)
- REMOVED: Static file serving (public/ deleted in Phase 6)
- REMOVED: CSRF token endpoint
- REMOVED: Website homepage with "auth, documents, blog, admin" references
- REMOVED: Instruction sync (scripts/sync-instructions-to-db.js reference)
- REMOVED: Hardcoded log path (${process.env.HOME}/var/log/tractatus/...)
- REMOVED: Website-specific security middleware
- KEPT: Security headers, rate limiting, CORS, body parsers
- KEPT: API routes, governance services, MongoDB connections
- RESULT: Clean framework-only server

RESULT: Repository can now start without crashes, all imports resolve

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 22:17:02 +13:00

174 lines
5.1 KiB
JavaScript

/**
* Migration: Enhance Governance Rules Schema
* Adds multi-project governance fields to existing rules
*
* New fields:
* - scope (UNIVERSAL | PROJECT_SPECIFIC)
* - applicableProjects (array)
* - variables (array)
* - clarityScore, specificityScore, actionabilityScore
* - validationStatus, lastValidated, validationResults
* - usageStats
* - optimizationHistory
*/
const mongoose = require('mongoose');
const GovernanceRule = require('../../src/models/GovernanceRule.model');
// Database connection
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/tractatus_dev';
async function up() {
console.log('🔄 Starting migration: 001-enhance-governance-rules');
console.log(' Database:', MONGODB_URI);
try {
await mongoose.connect(MONGODB_URI);
console.log('✓ Connected to MongoDB');
// Get all existing rules (use lean() to get raw documents without schema defaults)
const rules = await GovernanceRule.find({}).lean();
console.log(`\n📊 Found ${rules.length} rules to migrate`);
let updatedCount = 0;
let skippedCount = 0;
for (const ruleDoc of rules) {
// Check if rule already has new fields in database (not just schema defaults)
if (ruleDoc.scope !== undefined && ruleDoc.scope !== null) {
console.log(` ⏩ Skipping ${ruleDoc.id} (already migrated)`);
skippedCount++;
continue;
}
// Load the rule with Mongoose model to apply schema methods
const rule = await GovernanceRule.findById(ruleDoc._id);
// Auto-detect variables in rule text (${VAR_NAME} pattern)
const variables = [];
const varPattern = /\$\{([A-Z_]+)\}/g;
let match;
while ((match = varPattern.exec(rule.text)) !== null) {
if (!variables.includes(match[1])) {
variables.push(match[1]);
}
}
// Determine scope based on variables
// If rule has variables, it's likely UNIVERSAL (will be customized per project)
// If no variables and rule mentions specific values, it's PROJECT_SPECIFIC
const hasVariables = variables.length > 0;
const scope = hasVariables ? 'UNIVERSAL' : 'PROJECT_SPECIFIC';
// Update rule with new fields
rule.scope = scope;
rule.applicableProjects = ['*']; // Apply to all projects by default
rule.variables = variables;
// Initialize AI optimization fields
rule.clarityScore = null; // Will be calculated by AI optimizer
rule.specificityScore = null;
rule.actionabilityScore = null;
rule.lastOptimized = null;
rule.optimizationHistory = [];
// Initialize validation fields
rule.validationStatus = 'NOT_VALIDATED';
rule.lastValidated = null;
rule.validationResults = null;
// Initialize usage stats
rule.usageStats = {
referencedInProjects: [],
timesEnforced: 0,
conflictsDetected: 0,
lastEnforced: null
};
await rule.save();
console.log(`${rule.id}: ${scope} (${variables.length} variables)`);
updatedCount++;
}
console.log(`\n✅ Migration complete!`);
console.log(` Updated: ${updatedCount}`);
console.log(` Skipped: ${skippedCount}`);
console.log(` Total: ${rules.length}`);
// Create indexes for new fields
console.log('\n📊 Creating indexes for new fields...');
await GovernanceRule.createIndexes();
console.log(' ✓ Indexes created');
return { success: true, updated: updatedCount, skipped: skippedCount };
} catch (error) {
console.error('\n❌ Migration failed:', error);
throw error;
} finally {
await mongoose.disconnect();
console.log('\n✓ Disconnected from MongoDB');
}
}
async function down() {
console.log('🔄 Rolling back migration: 001-enhance-governance-rules');
try {
await mongoose.connect(MONGODB_URI);
console.log('✓ Connected to MongoDB');
// Remove new fields from all rules
const result = await GovernanceRule.updateMany(
{},
{
$unset: {
scope: '',
applicableProjects: '',
variables: '',
clarityScore: '',
specificityScore: '',
actionabilityScore: '',
lastOptimized: '',
optimizationHistory: '',
validationStatus: '',
lastValidated: '',
validationResults: '',
usageStats: ''
}
}
);
console.log(`✓ Rollback complete! Removed fields from ${result.modifiedCount} rules`);
return { success: true, modified: result.modifiedCount };
} catch (error) {
console.error('❌ Rollback failed:', error);
throw error;
} finally {
await mongoose.disconnect();
console.log('✓ Disconnected from MongoDB');
}
}
// CLI interface
if (require.main === module) {
const command = process.argv[2] || 'up';
if (command === 'up') {
up()
.then(() => process.exit(0))
.catch(() => process.exit(1));
} else if (command === 'down') {
down()
.then(() => process.exit(0))
.catch(() => process.exit(1));
} else {
console.error('Usage: node 001-enhance-governance-rules.js [up|down]');
process.exit(1);
}
}
module.exports = { up, down };