import fs from 'fs'; import path from 'path'; import bcrypt from 'bcryptjs'; import { User, Course, Module, Lesson, Note, LessonProgress, WebhookLog, SubscriptionPayment } from '../types'; const DATA_DIR = process.env.DATA_DIR || (fs.existsSync('/app/data') ? '/app/data' : process.cwd()); const DB_FILE = path.join(DATA_DIR, 'database.json'); export interface DatabaseSchema { users: User[]; courses: Course[]; modules: Module[]; lessons: Lesson[]; notes: Note[]; progress: LessonProgress[]; webhookLogs: WebhookLog[]; payments: SubscriptionPayment[]; activities: any[]; moduleGrades: any[]; certificates: any[]; notifications: any[]; settings: any; // SystemSettings } const DEFAULT_DB: DatabaseSchema = { users: [], courses: [], modules: [], lessons: [], notes: [], progress: [], webhookLogs: [], payments: [], activities: [], moduleGrades: [], certificates: [], notifications: [], settings: { trialDurationDays: 7, asaasEnvironment: 'sandbox', asaasApiKey: '', asaasWebhookUrl: '', asaasWebhookSecret: '', helpText: '# Central de Ajuda\n\nAqui você encontra todas as informações sobre os cursos e funcionamento da plataforma.' } }; // Helper to load db export function loadDb(): DatabaseSchema { try { if (!fs.existsSync(DB_FILE)) { const db = createInitialDb(); saveDb(db); return db; } const data = fs.readFileSync(DB_FILE, 'utf-8'); return JSON.parse(data); } catch (err) { console.error('Error loading database:', err); return DEFAULT_DB; } } // Helper to save db export function saveDb(data: DatabaseSchema): void { try { fs.writeFileSync(DB_FILE, JSON.stringify(data, null, 2), 'utf-8'); } catch (err) { console.error('Error saving database:', err); } } function createInitialDb(): DatabaseSchema { const salt = bcrypt.genSaltSync(10); const adminPasswordHash = bcrypt.hashSync('admin123', salt); const studentPasswordHash = bcrypt.hashSync('aluno123', salt); const now = new Date().toISOString(); const users: User[] = [ { id: 'usr_admin', name: 'Sidney Gomes (Admin)', email: 'sidney.gomes1989@gmail.com', password: adminPasswordHash, role: 'admin', subscriptionStatus: 'ACTIVE', asaasCustomerId: null, cpf: '691.238.910-40', unlockedCourses: [], createdAt: now }, { id: 'usr_student1', name: 'João Silva', email: 'joao@microtecflix.com', password: studentPasswordHash, role: 'student', subscriptionStatus: 'ACTIVE', asaasCustomerId: 'cus_00001', cpf: '691.238.910-40', unlockedCourses: ['crs_excel'], // Excel starts unlocked for Joao createdAt: new Date(Date.now() - 30 * 24 * 3600 * 1000).toISOString() }, { id: 'usr_student2', name: 'Maria Santos', email: 'maria@microtecflix.com', password: studentPasswordHash, role: 'student', subscriptionStatus: 'ACTIVE', asaasCustomerId: 'cus_00002', cpf: '691.238.910-40', unlockedCourses: [], createdAt: new Date(Date.now() - 15 * 24 * 3600 * 1000).toISOString() }, { id: 'usr_student3', name: 'Pedro Oliveira', email: 'pedro@microtecflix.com', password: studentPasswordHash, role: 'student', subscriptionStatus: 'OVERDUE', asaasCustomerId: 'cus_00003', cpf: '691.238.910-40', unlockedCourses: [], createdAt: new Date(Date.now() - 45 * 24 * 3600 * 1000).toISOString() }, { id: 'usr_student4', name: 'Ana Costa', email: 'ana@microtecflix.com', password: studentPasswordHash, role: 'student', subscriptionStatus: 'CANCELED', asaasCustomerId: 'cus_00004', cpf: '691.238.910-40', unlockedCourses: [], createdAt: new Date(Date.now() - 60 * 24 * 3600 * 1000).toISOString() }, { id: 'usr_student_test', name: 'Aluno de Teste', email: 'aluno@microtecflix.com', password: studentPasswordHash, role: 'student', subscriptionStatus: 'ACTIVE', asaasCustomerId: 'cus_test', cpf: '691.238.910-40', unlockedCourses: [], // Starts with only the free courses unlocked createdAt: now } ]; const courses: Course[] = [ { id: 'crs_windows', title: 'Sistema Operacional Windows 11 para Escritório', description: 'Domine o sistema operacional mais utilizado no mundo corporativo. Aprenda a organizar arquivos, configurar o painel de controle, gerenciar usuários e utilizar ferramentas de produtividade para escritório de forma ágil e segura.', thumbnail: 'https://images.unsplash.com/photo-1624555130581-1d9cca783bc0?q=80&w=600&auto=format&fit=crop', category: 'Sistemas Operacionais', isLocked: false, price: 0, createdAt: now }, { id: 'crs_word', title: 'Microsoft Word Profissional', description: 'Crie relatórios, contratos, trabalhos acadêmicos nas normas ABNT e documentos de escritório altamente profissionais. Domine formatação avançada, tabelas, sumários automáticos e malas diretas dinâmicas.', thumbnail: 'https://images.unsplash.com/photo-1586075010923-2dd4570fb338?q=80&w=600&auto=format&fit=crop', category: 'Pacote Office', isLocked: false, price: 0, createdAt: now }, { id: 'crs_excel', title: 'Microsoft Excel - Do Básico ao Dashboard', description: 'O software de planilhas mais exigido pelo mercado de trabalho mundial. Aprenda desde fórmulas fundamentais (SOMA, SE, PROCV, CONT.SE) até tabelas dinâmicas, gráficos executivos, automações e dashboards de impacto profissional.', thumbnail: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=600&auto=format&fit=crop', category: 'Pacote Office', isLocked: true, price: 89.90, createdAt: now }, { id: 'crs_powerpoint', title: 'PowerPoint para Apresentações de Impacto', description: 'Aprenda a estruturar e desenhar apresentações profissionais e persuasivas para reuniões de negócios, projetos ou aulas. Domine o efeito de transição Transformar (Morph), inserção de mídias inteligentes e animações profissionais.', thumbnail: 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?q=80&w=600&auto=format&fit=crop', category: 'Pacote Office', isLocked: true, price: 59.90, createdAt: now } ]; const modules: Module[] = [ // Windows 11 { id: 'mdl_win_1', courseId: 'crs_windows', title: 'Fundamentos e Área de Trabalho', order: 1, createdAt: now }, { id: 'mdl_win_2', courseId: 'crs_windows', title: 'Configurações e Segurança de Dados', order: 2, createdAt: now }, // Word { id: 'mdl_wrd_1', courseId: 'crs_word', title: 'Interface e Formatação de Textos', order: 1, createdAt: now }, { id: 'mdl_wrd_2', courseId: 'crs_word', title: 'Layouts, Tabelas e Sumários', order: 2, createdAt: now }, // Excel { id: 'mdl_exc_1', courseId: 'crs_excel', title: 'Células, Fórmulas e Funções Principais', order: 1, createdAt: now }, { id: 'mdl_exc_2', courseId: 'crs_excel', title: 'Tabelas Dinâmicas e Dashboards', order: 2, createdAt: now }, // PowerPoint { id: 'mdl_ppt_1', courseId: 'crs_powerpoint', title: 'Layout de Slides e Formas', order: 1, createdAt: now }, { id: 'mdl_ppt_2', courseId: 'crs_powerpoint', title: 'Transições Especiais e Apresentação', order: 2, createdAt: now } ]; const lessons: Lesson[] = [ // Windows - Módulo 1 { id: 'lsn_win_1_1', moduleId: 'mdl_win_1', title: 'Dominando a Nova Área de Trabalho e Barra de Tarefas do Windows 11', videoUrl: 'https://www.youtube.com/embed/9e9D_bZfT8o', videoType: 'youtube', order: 1, content: 'Nesta aula, você aprenderá a se localizar e customizar a nova barra de tarefas centralizada e a área de trabalho do Windows 11.', createdAt: now }, { id: 'lsn_win_1_2', moduleId: 'mdl_win_1', title: 'Gerenciador de Arquivos e Organização Eficiente de Pastas', videoUrl: 'https://www.youtube.com/embed/Pj1_bAn_m4Y', videoType: 'youtube', order: 2, content: 'Aprenda a criar estruturas de pastas organizadas, atalhos rápidos e a usar o novo explorador de arquivos com abas do Windows.', createdAt: now }, // Windows - Módulo 2 { id: 'lsn_win_2_1', moduleId: 'mdl_win_2', title: 'Painel de Configurações e Segurança com Windows Defender', videoUrl: 'https://www.youtube.com/embed/K8w3m_pM6lA', videoType: 'youtube', order: 1, content: 'Como configurar rede wi-fi, dispositivos bluetooth, impressoras e garantir que seu antivírus integrado esteja sempre atualizado.', createdAt: now }, // Word - Módulo 1 { id: 'lsn_wrd_1_1', moduleId: 'mdl_wrd_1', title: 'Conhecendo a Faixa de Opções e Formatando Fontes e Parágrafos', videoUrl: 'https://www.youtube.com/embed/Epn879GkIis', videoType: 'youtube', order: 1, content: 'Entenda os principais comandos da guia Página Inicial e como aplicar formatações essenciais de texto.', createdAt: now }, // Word - Módulo 2 { id: 'lsn_wrd_2_1', moduleId: 'mdl_wrd_2', title: 'Criação de Sumários Automáticos com Estilos de Título', videoUrl: 'https://www.youtube.com/embed/2_W6C3vjD1s', videoType: 'youtube', order: 1, content: 'Evite o trabalho manual! Aprenda a usar os Estilos (Título 1, Título 2) para que o Microsoft Word gere seu sumário em um clique.', createdAt: now }, // Excel - Módulo 1 { id: 'lsn_exc_1_1', moduleId: 'mdl_exc_1', title: 'Dominando Fórmulas Básicas: SOMA, MÉDIA e Função Lógica SE', videoUrl: 'https://www.youtube.com/embed/3S-F9h-gRjA', videoType: 'youtube', order: 1, content: 'Entenda a sintaxe de fórmulas no Excel, referências relativas/absolutas ($) e como aplicar a famosa função SE.', createdAt: now }, // Excel - Módulo 2 { id: 'lsn_exc_2_1', moduleId: 'mdl_exc_2', title: 'Criando sua Primeira Tabela Dinâmica e Gráficos de Vendas', videoUrl: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4', videoType: 'direct', order: 1, content: 'Aprenda a consolidar milhares de linhas de dados em resumos inteligentes usando tabelas dinâmicas.', createdAt: now }, // PowerPoint - Módulo 1 { id: 'lsn_ppt_1_1', moduleId: 'mdl_ppt_1', title: 'Trabalhando com Layouts Próprios e Inserção de Imagens e Ícones', videoUrl: 'https://www.youtube.com/embed/Y0iI9wzY_L4', videoType: 'youtube', order: 1, content: 'Esqueça os designs prontos e ultrapassados! Aprenda a criar layouts autorais limpos, modernos e profissionais.', createdAt: now }, // PowerPoint - Módulo 2 { id: 'lsn_ppt_2_1', moduleId: 'mdl_ppt_2', title: 'O Poder da Transição Transformar (Morph) em Apresentações', videoUrl: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4', videoType: 'direct', order: 1, content: 'Aprenda a criar animações fluidas e dinâmicas dignas de cinema utilizando o Morph do PowerPoint.', createdAt: now } ]; const notes: Note[] = [ { id: 'note_1', userId: 'usr_student_test', lessonId: 'lsn_win_1_1', content: 'Anotação de Teste: Atalho Windows + D serve para mostrar ou ocultar a Área de Trabalho instantaneamente!', createdAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString() } ]; const progress: LessonProgress[] = [ { id: 'prog_1', userId: 'usr_student_test', lessonId: 'lsn_win_1_1', watchedPercentage: 95, completed: true, updatedAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString() }, { id: 'prog_2', userId: 'usr_student_test', lessonId: 'lsn_win_1_2', watchedPercentage: 45, completed: false, updatedAt: now } ]; const payments: SubscriptionPayment[] = [ { id: 'pay_1', userId: 'usr_student1', value: 49.90, status: 'CONFIRMED', billingType: 'PIX', invoiceUrl: 'https://www.asaas.com/i/fake_invoice_1', dueDate: new Date(Date.now() - 5 * 24 * 3600 * 1000).toISOString().split('T')[0], paidAt: new Date(Date.now() - 5 * 24 * 3600 * 1000).toISOString(), createdAt: new Date(Date.now() - 6 * 24 * 3600 * 1000).toISOString() }, { id: 'pay_2', userId: 'usr_student2', value: 49.90, status: 'CONFIRMED', billingType: 'CREDIT_CARD', invoiceUrl: 'https://www.asaas.com/i/fake_invoice_2', dueDate: new Date(Date.now() - 2 * 24 * 3600 * 1000).toISOString().split('T')[0], paidAt: new Date(Date.now() - 2 * 24 * 3600 * 1000).toISOString(), createdAt: new Date(Date.now() - 2 * 24 * 3600 * 1000).toISOString() }, { id: 'pay_3', userId: 'usr_student3', value: 49.90, status: 'OVERDUE', billingType: 'BOLETO', invoiceUrl: 'https://www.asaas.com/i/fake_invoice_3', dueDate: new Date(Date.now() - 10 * 24 * 3600 * 1000).toISOString().split('T')[0], paidAt: null, createdAt: new Date(Date.now() - 10 * 24 * 3600 * 1000).toISOString() }, { id: 'pay_test_1', userId: 'usr_student_test', value: 49.90, status: 'CONFIRMED', billingType: 'PIX', invoiceUrl: 'https://www.asaas.com/i/fake_invoice_test', dueDate: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString().split('T')[0], paidAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString(), createdAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString() } ]; const webhookLogs: WebhookLog[] = [ { id: 'wh_log_1', event: 'PAYMENT_RECEIVED', payload: JSON.stringify({ id: 'pay_1', subscription: 'sub_0001', value: 49.90, customer: 'cus_00001' }), receivedAt: new Date(Date.now() - 5 * 24 * 3600 * 1000).toISOString() }, { id: 'wh_log_2', event: 'PAYMENT_CONFIRMED', payload: JSON.stringify({ id: 'pay_2', subscription: 'sub_0002', value: 49.90, customer: 'cus_00002' }), receivedAt: new Date(Date.now() - 2 * 24 * 3600 * 1000).toISOString() }, { id: 'wh_log_3', event: 'PAYMENT_OVERDUE', payload: JSON.stringify({ id: 'pay_3', subscription: 'sub_0003', value: 49.90, customer: 'cus_00003' }), receivedAt: new Date(Date.now() - 10 * 24 * 3600 * 1000).toISOString() } ]; return { users, courses, modules, lessons, notes, progress, webhookLogs, payments, activities: [], moduleGrades: [], certificates: [], notifications: [], settings: { trialDurationDays: 7, asaasEnvironment: 'sandbox', asaasApiKey: '', asaasWebhookUrl: '', asaasWebhookSecret: '', helpText: '# Central de Ajuda\n\nAqui você encontra todas as informações sobre os cursos e funcionamento da plataforma.' } }; }