lad-website/mongo-init/01-init.js
TheMaddax edb6faa351 feat: create project structure and update implementation files
- Created complete project directory structure:
  - Frontend with Next.js 15.2.3 app router structure
  - Backend with Express API endpoints
  - Docker configurations with security best practices
  - MongoDB initialization with schema validation
  - Nginx configuration with security headers

- Implemented core file templates:
  - Custom video player with transcript display options
  - MongoDB schemas with validation for Videos and Members
  - JWT authentication middleware with role-based access control
  - Docker Compose with resource limits and security
  - Frontend/backend package.json with dependencies

- Updated documentation:
  - Enhanced TECH_STACK with latest version details
  - Updated TO_DO.txt with WCAG 2.2 AA requirements
  - Updated planned_implementation.txt with current best practices
  - Refreshed all Memory Bank files with current state

- Security and accessibility improvements:
  - Added MongoDB 7.0 schema validation with
  - Enhanced video requirements with mandatory transcripts and thumbnails
  - Updated accessibility to WCAG 2.2 AA standards
  - Added security best practices for Docker deployments
2025-03-25 09:28:10 -05:00

217 lines
6.4 KiB
JavaScript

// MongoDB initialization script - runs when container starts
// Create database
db = db.getSiblingDB('ocd_db');
// Create admin user if it doesn't exist
if (db.getUser('admin') == null) {
db.createUser({
user: 'admin',
pwd: process.env.MONGO_ADMIN_PASSWORD || 'admin',
roles: [{ role: 'readWrite', db: 'ocd_db' }]
});
}
// Create video collection with validation
db.createCollection('videos', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['title', 'fileUrl', 'thumbnailUrl', 'transcriptText'],
properties: {
title: {
bsonType: 'string',
minLength: 3,
description: 'Title is required and must be at least 3 characters'
},
description: {
bsonType: 'string',
description: 'Description of the video'
},
fileUrl: {
bsonType: 'string',
description: 'URL to the video file (required)'
},
thumbnailUrl: {
bsonType: 'string',
description: 'URL to the thumbnail image (required)'
},
duration: {
bsonType: 'number',
description: 'Duration of the video in seconds'
},
uploadDate: {
bsonType: 'date',
description: 'Date when the video was uploaded'
},
category: {
bsonType: 'string',
description: 'Category of the video'
},
subtitleUrl: {
bsonType: 'string',
description: 'URL to the WebVTT subtitle file'
},
transcriptText: {
bsonType: 'string',
description: 'Full text transcript of the video (required)'
},
transcriptFormat: {
enum: ['plain', 'html', 'json'],
description: 'Format of the transcript (plain, html, or json)'
},
isPublished: {
bsonType: 'bool',
description: 'Whether the video is published or not'
},
relatedPageId: {
bsonType: 'objectId',
description: 'Reference to a related page'
},
tags: {
bsonType: 'array',
items: { bsonType: 'string' },
description: 'Tags for categorizing the video'
}
}
}
},
validationLevel: 'strict'
});
// Create indexes for video collection
db.videos.createIndex({ 'title': 'text', 'transcriptText': 'text' });
db.videos.createIndex({ 'category': 1, 'uploadDate': -1 });
db.videos.createIndex({ 'tags': 1 });
// Create members collection with validation
db.createCollection('members', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['firstName', 'lastName', 'email', 'membershipType', 'joinDate', 'status'],
properties: {
firstName: {
bsonType: 'string',
description: 'First name is required'
},
lastName: {
bsonType: 'string',
description: 'Last name is required'
},
email: {
bsonType: 'string',
pattern: '^.+@.+\\..+$',
description: 'Email must be a valid email address'
},
phone: {
bsonType: 'string',
description: 'Phone number'
},
address: {
bsonType: 'object',
properties: {
street: { bsonType: 'string' },
city: { bsonType: 'string' },
state: { bsonType: 'string' },
zip: { bsonType: 'string' }
}
},
membershipType: {
enum: ['regular', 'lifetime', 'honorary'],
description: 'Membership type must be one of: regular, lifetime, honorary'
},
joinDate: {
bsonType: 'date',
description: 'Date when the member joined'
},
expirationDate: {
bsonType: 'date',
description: 'Date when the membership expires'
},
status: {
enum: ['active', 'expired', 'pending'],
description: 'Status must be one of: active, expired, pending'
},
notificationPreference: {
enum: ['email', 'sms', 'both'],
description: 'Notification preference must be one of: email, sms, both'
},
lastRenewalDate: {
bsonType: 'date',
description: 'Date of the last membership renewal'
},
boardMember: {
bsonType: 'bool',
description: 'Whether the member is part of the board'
},
boardPosition: {
bsonType: 'string',
description: 'Position on the board, if applicable'
},
emergencyContact: {
bsonType: 'object',
properties: {
name: { bsonType: 'string' },
relationship: { bsonType: 'string' },
phone: { bsonType: 'string' }
}
}
}
}
},
validationLevel: 'strict'
});
// Create indexes for members collection
db.members.createIndex({ 'email': 1 }, { unique: true });
db.members.createIndex({ 'lastName': 1, 'firstName': 1 });
db.members.createIndex({ 'status': 1, 'expirationDate': 1 });
db.members.createIndex({ 'boardMember': 1 });
// Create admin user collection with validation
db.createCollection('adminUsers', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['username', 'passwordHash', 'email'],
properties: {
username: {
bsonType: 'string',
minLength: 3,
maxLength: 50,
description: 'Username is required and must be between 3 and 50 characters'
},
passwordHash: {
bsonType: 'string',
description: 'Password hash is required'
},
email: {
bsonType: 'string',
pattern: '^.+@.+\\..+$',
description: 'Email must be a valid email address'
},
lastLogin: {
bsonType: 'date',
description: 'Date of the last login'
},
resetToken: {
bsonType: 'string',
description: 'Token for password reset'
},
resetTokenExpiry: {
bsonType: 'date',
description: 'Expiry date for password reset token'
}
}
}
},
validationLevel: 'strict'
});
// Create indexes for admin users collection
db.adminUsers.createIndex({ 'username': 1 }, { unique: true });
db.adminUsers.createIndex({ 'email': 1 }, { unique: true });
db.adminUsers.createIndex({ 'resetToken': 1 }, { sparse: true });
console.log('MongoDB initialization completed');