tractatus/scripts/test-deliberation-session.js
TheFlow ac2db33732 fix(submissions): restructure Economist package and fix article display
- 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>
2025-10-24 08:47:42 +13:00

208 lines
8.6 KiB
JavaScript

/**
* Test Script: DeliberationSession Model
* Validates MongoDB schema and all model methods work correctly
*/
const { DeliberationSession } = require('../src/models');
async function testDeliberationSession() {
console.log('╔════════════════════════════════════════════════════════════════╗');
console.log('║ Testing DeliberationSession Model ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
let sessionId = null;
try {
// Test 1: Create session
console.log('Test 1: Creating test deliberation session...');
const session = await DeliberationSession.create({
decision: {
description: 'Test decision for model validation',
scenario: 'test_scenario',
context: {
geographic: 'United States',
temporal: 'test'
}
},
stakeholders: [
{
id: 'stakeholder-test-001',
name: 'Test Stakeholder 1',
type: 'individual',
represents: 'Test Stakeholder 1',
contact: { email: 'test1@example.com' }
},
{
id: 'stakeholder-test-002',
name: 'Test Stakeholder 2',
type: 'organization',
represents: 'Test Stakeholder 2',
contact: { email: 'test2@example.com' }
}
],
configuration: {
format: 'hybrid',
ai_role: 'ai_led',
visibility: 'private_to_public',
output_framing: 'pluralistic_accommodation'
}
});
sessionId = session.session_id;
console.log('✅ Session created:', sessionId);
console.log(' Status:', session.status);
console.log(' Stakeholders:', session.stakeholders.length);
console.log(' Created at:', session.created_at.toISOString());
// Test 2: Record AI facilitation action
console.log('\nTest 2: Recording AI facilitation action...');
await DeliberationSession.recordFacilitationAction(sessionId, {
actor: 'ai',
action_type: 'round_opening',
round_number: 1,
content: 'Test Round 1 opening by AI facilitator',
reason: 'Starting deliberation Round 1'
});
console.log('✅ AI action logged (round_opening)');
// Test 3: Record another AI action
console.log('\nTest 3: Recording stakeholder invitation...');
await DeliberationSession.recordFacilitationAction(sessionId, {
actor: 'ai',
action_type: 'stakeholder_invitation',
round_number: 1,
content: 'Invited stakeholder-test-001 to present',
reason: 'Facilitating position statement presentation'
});
console.log('✅ AI action logged (stakeholder_invitation)');
// Test 4: Record human intervention
console.log('\nTest 4: Recording human intervention...');
await DeliberationSession.recordHumanIntervention(sessionId, {
intervener: 'Test Observer',
trigger: 'pattern_bias',
round_number: 1,
description: 'AI used stigmatizing framing toward test stakeholder',
ai_action_overridden: 'Original AI prompt that was problematic',
corrective_action: 'Reframed neutrally',
stakeholder_informed: true,
resolution: 'AI resumed with corrected framing'
});
console.log('✅ Human intervention logged');
// Test 5: Record safety escalation
console.log('\nTest 5: Recording safety escalation...');
await DeliberationSession.recordSafetyEscalation(sessionId, {
detected_by: 'human',
escalation_type: 'pattern_bias',
severity: 'moderate',
round_number: 1,
description: 'Pattern bias detected in AI framing',
stakeholders_affected: ['stakeholder-test-001'],
immediate_action_taken: 'Human intervened and reframed',
requires_session_pause: false,
resolved: true,
resolution_details: 'Reframed successfully, deliberation continued'
});
console.log('✅ Safety escalation logged');
// Test 6: Add deliberation round
console.log('\nTest 6: Adding deliberation round...');
await DeliberationSession.addRound(sessionId, {
round_number: 1,
round_type: 'position_statements',
facilitator: 'ai',
contributions: [
{
stakeholder_id: 'stakeholder-test-001',
stakeholder_name: 'Test Stakeholder 1',
content: 'Test contribution from stakeholder 1',
timestamp: new Date()
}
]
});
console.log('✅ Round 1 added');
// Test 7: Retrieve session
console.log('\nTest 7: Retrieving session...');
const retrieved = await DeliberationSession.findBySessionId(sessionId);
console.log('✅ Session retrieved');
console.log(' Facilitation log entries:', retrieved.facilitation_log.length);
console.log(' Human interventions:', retrieved.human_interventions.length);
console.log(' Safety escalations:', retrieved.safety_escalations.length);
console.log(' Deliberation rounds:', retrieved.deliberation_rounds.length);
// Test 8: Get AI safety metrics
console.log('\nTest 8: Getting AI safety metrics...');
const metrics = await DeliberationSession.getAISafetyMetrics(sessionId);
console.log('✅ Safety metrics retrieved');
console.log(' Total interventions:', metrics.total_interventions);
console.log(' Total escalations:', metrics.total_escalations);
console.log(' Recommendation level:', metrics.recommendation.level);
// Test 9: Set outcome
console.log('\nTest 9: Setting deliberation outcome...');
await DeliberationSession.setOutcome(sessionId, {
decision_made: 'Test decision reached',
values_prioritized: ['fairness', 'transparency'],
values_deprioritized: ['efficiency'],
deliberation_summary: 'Test deliberation summary',
consensus_level: 'strong_accommodation',
dissenting_perspectives: [],
justification: 'Test justification',
moral_remainder: 'Some values could not be fully satisfied',
generated_by: 'ai'
});
console.log('✅ Outcome set');
// Test 10: Verify status changed to completed
const final = await DeliberationSession.findBySessionId(sessionId);
console.log('✅ Final status:', final.status);
console.log('\n╔════════════════════════════════════════════════════════════════╗');
console.log('║ ✅ ALL TESTS PASSED ║');
console.log('║ DeliberationSession model working correctly ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
// Clean up
console.log('Cleaning up test data...');
const { getCollection } = require('../src/utils/db.util');
const collection = await getCollection('deliberation_sessions');
await collection.deleteOne({ session_id: sessionId });
console.log('✅ Test data cleaned up\n');
return true;
} catch (error) {
console.error('\n╔════════════════════════════════════════════════════════════════╗');
console.error('║ ❌ TEST FAILED ║');
console.error('╚════════════════════════════════════════════════════════════════╝\n');
console.error('Error:', error.message);
console.error('Stack:', error.stack);
// Clean up even on failure
if (sessionId) {
try {
const { getCollection } = require('../src/utils/db.util');
const collection = await getCollection('deliberation_sessions');
await collection.deleteOne({ session_id: sessionId });
console.log('✅ Test data cleaned up after failure\n');
} catch (cleanupError) {
console.error('❌ Cleanup failed:', cleanupError.message);
}
}
throw error;
}
}
// Run test
testDeliberationSession()
.then(() => {
console.log('Test script completed successfully');
process.exit(0);
})
.catch((error) => {
console.error('Test script failed:', error);
process.exit(1);
});