The rendering_video status was defined in job.py and frontend types but was missing from the MongoDB schema validator, causing document update failures when jobs transitioned to the rendering_video state. Changes: - Add migration script to update existing databases - Update mongodb-init.js for new database setups 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
148 lines
5.6 KiB
JavaScript
148 lines
5.6 KiB
JavaScript
// =============================================================================
|
||
// MongoDB Initialization Script for Accessible Video Platform
|
||
// =============================================================================
|
||
// Run this script ONCE after starting the MongoDB container
|
||
// Usage: docker-compose exec mongodb mongosh < scripts/mongodb-init.js
|
||
// =============================================================================
|
||
|
||
// Connect to the accessible_video database
|
||
db = db.getSiblingDB('accessible_video');
|
||
|
||
print('=============================================================================');
|
||
print('MongoDB Initialization for Accessible Video Platform');
|
||
print('=============================================================================');
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Create Collections with Validation
|
||
// -----------------------------------------------------------------------------
|
||
print('\n1. Creating collections with schema validation...');
|
||
|
||
// Jobs collection
|
||
db.createCollection('jobs', {
|
||
validator: {
|
||
$jsonSchema: {
|
||
bsonType: 'object',
|
||
required: ['_id', 'title', 'status', 'client_id', 'created_at', 'updated_at'],
|
||
properties: {
|
||
_id: { bsonType: 'string' },
|
||
title: { bsonType: 'string' },
|
||
status: {
|
||
enum: ['created', 'ingesting', 'ai_processing', 'pending_qc',
|
||
'approved_english', 'approved_source', 'rejected', 'qc_feedback',
|
||
'translating', 'tts_generating', 'rendering_video',
|
||
'pending_final_review', 'completed']
|
||
},
|
||
client_id: { bsonType: 'string' },
|
||
created_at: { bsonType: 'date' },
|
||
updated_at: { bsonType: 'date' }
|
||
}
|
||
}
|
||
}
|
||
});
|
||
print(' Created jobs collection');
|
||
|
||
// Users collection
|
||
db.createCollection('users', {
|
||
validator: {
|
||
$jsonSchema: {
|
||
bsonType: 'object',
|
||
required: ['_id', 'email', 'hashed_password', 'role', 'created_at'],
|
||
properties: {
|
||
_id: { bsonType: 'string' },
|
||
email: { bsonType: 'string' },
|
||
hashed_password: { bsonType: 'string' },
|
||
role: { enum: ['client', 'reviewer', 'admin'] },
|
||
is_active: { bsonType: 'bool' },
|
||
created_at: { bsonType: 'date' }
|
||
}
|
||
}
|
||
}
|
||
});
|
||
print(' Created users collection');
|
||
|
||
// Audit logs collection
|
||
db.createCollection('audit_logs');
|
||
print(' Created audit_logs collection');
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Create Indexes for Performance
|
||
// -----------------------------------------------------------------------------
|
||
print('\n2. Creating indexes for optimized queries...');
|
||
|
||
// Jobs collection indexes
|
||
db.jobs.createIndex({ 'status': 1, 'created_at': -1 }, { name: 'idx_status_created' });
|
||
print(' Created index: jobs.idx_status_created');
|
||
|
||
db.jobs.createIndex({ 'client_id': 1 }, { name: 'idx_client_id' });
|
||
print(' Created index: jobs.idx_client_id');
|
||
|
||
db.jobs.createIndex({ 'created_at': -1 }, { name: 'idx_created_at' });
|
||
print(' Created index: jobs.idx_created_at');
|
||
|
||
// Users collection indexes
|
||
db.users.createIndex({ 'email': 1 }, { unique: true, name: 'idx_email_unique' });
|
||
print(' Created index: users.idx_email_unique (unique)');
|
||
|
||
db.users.createIndex({ 'role': 1 }, { name: 'idx_role' });
|
||
print(' Created index: users.idx_role');
|
||
|
||
// Audit logs collection indexes
|
||
db.audit_logs.createIndex({ 'timestamp': -1 }, { name: 'idx_timestamp' });
|
||
print(' Created index: audit_logs.idx_timestamp');
|
||
|
||
db.audit_logs.createIndex({ 'action': 1, 'timestamp': -1 }, { name: 'idx_action_timestamp' });
|
||
print(' Created index: audit_logs.idx_action_timestamp');
|
||
|
||
db.audit_logs.createIndex({ 'user_id': 1, 'timestamp': -1 }, { name: 'idx_user_timestamp' });
|
||
print(' Created index: audit_logs.idx_user_timestamp');
|
||
|
||
db.audit_logs.createIndex({ 'severity': 1, 'timestamp': -1 }, { name: 'idx_severity_timestamp' });
|
||
print(' Created index: audit_logs.idx_severity_timestamp');
|
||
|
||
db.audit_logs.createIndex({ 'resource_type': 1, 'resource_id': 1 }, { name: 'idx_resource' });
|
||
print(' Created index: audit_logs.idx_resource');
|
||
|
||
// Text search index for audit logs
|
||
db.audit_logs.createIndex(
|
||
{
|
||
'description': 'text',
|
||
'details': 'text',
|
||
'error_message': 'text'
|
||
},
|
||
{
|
||
name: 'idx_text_search',
|
||
weights: {
|
||
'description': 10,
|
||
'details': 5,
|
||
'error_message': 8
|
||
}
|
||
}
|
||
);
|
||
print(' Created index: audit_logs.idx_text_search (full-text)');
|
||
|
||
// -----------------------------------------------------------------------------
|
||
// Display Database Statistics
|
||
// -----------------------------------------------------------------------------
|
||
print('\n3. Database initialization complete!');
|
||
print('\nDatabase statistics:');
|
||
print('-------------------');
|
||
|
||
const stats = db.stats();
|
||
print('Database: ' + stats.db);
|
||
print('Collections: ' + stats.collections);
|
||
print('Indexes: ' + stats.indexes);
|
||
print('Data Size: ' + (stats.dataSize / 1024).toFixed(2) + ' KB');
|
||
print('Storage Size: ' + (stats.storageSize / 1024).toFixed(2) + ' KB');
|
||
|
||
print('\nCollections created:');
|
||
db.getCollectionNames().forEach(function(collName) {
|
||
const collStats = db.getCollection(collName).stats();
|
||
const indexCount = db.getCollection(collName).getIndexes().length;
|
||
print(' - ' + collName + ' (indexes: ' + indexCount + ')');
|
||
});
|
||
|
||
print('\n=============================================================================');
|
||
print('Next steps:');
|
||
print('1. Run migrations: docker-compose exec api python migrate.py');
|
||
print('2. Create admin user: docker-compose exec api python create_test_users.py');
|
||
print('=============================================================================');
|