Files
kspguti-schedule/src/app/logger.ts
kilyabin e46a2419c3 refactor: optimize project structure, migrate to SQLite, and add new features
fix:
  - Fix TypeScript type errors in api-wrapper.ts (ApiResponse type)
  - Fix backward compatibility in database.ts getSettings() for missing fields
  - Fix default value for weekNavigationEnabled (changed from true to false)
  - Fix API routes error handling with unified wrapper
  - Fix duplicate toggle switch code in admin.tsx (6 instances)
  - Fix inconsistent authentication check in API routes (unified with withAuth)
  - Fix error message text in loading-context.tsx (improved user experience)

add:
  - Add database.ts: SQLite database layer with better-sqlite3 for persistent storage
    * Groups management (CRUD operations)
    * Settings management with caching
    * Admin password hashing with bcrypt
    * Automatic database initialization and migration
  - Add api-wrapper.ts utility for unified API route handling
    * withAuth wrapper for protected routes
    * withMethods wrapper for public routes
    * Consistent error handling and method validation
  - Add validation.ts utility with centralized validation functions
    * validateCourse - course validation (1-5)
    * validateGroupId - group ID format validation
    * validatePassword - password strength validation
  - Add showAddGroupButton setting to control visibility of 'Add Group' button on homepage
  - Add toggle switch component in admin.tsx for reusable UI (replaces 6 duplicate instances)
  - Add CourseSelect component in admin.tsx for reusable course selection
  - Add DialogFooterButtons component in admin.tsx for reusable dialog footer
  - Add unified loadData function in admin.tsx to reduce code duplication
  - Add change-password.ts API endpoint for admin password management
  - Add logs.ts API endpoint for viewing error logs in admin panel
  - Add logErrorToFile function in logger.ts for persistent error logging
  - Add comprehensive error logging in schedule.ts (parsing, fetch, timeout, network errors)
  - Add comprehensive project structure documentation in README.md
  - Add architecture and code organization section in README.md
  - Add database information section in README.md
  - Add SQLite and bcrypt to tech stack documentation
  - Add better-sqlite3 and bcrypt dependencies to package.json
  - Add .gitignore rules for error.log and database files (data/, *.db, *.db-shm, *.db-wal)

refactor:
  - Refactor admin.tsx: extract reusable components (toggle, select, dialog footer)
  - Refactor API routes to use withAuth wrapper for consistent authentication
  - Refactor API routes to use validation utilities instead of inline validation
  - Refactor groups.ts and groups.json: move to old/data/ directory (deprecated, now using SQLite)
  - Refactor settings-loader.ts: migrate from JSON to SQLite database
  - Refactor groups-loader.ts: migrate from JSON to SQLite database
  - Refactor database.ts: improve backward compatibility for settings migration
  - Refactor admin.tsx: unify data loading functions (loadGroupsList, loadSettingsList)
  - Refactor index.tsx: add showAddGroupButton prop and conditional rendering
  - Refactor API routes: consistent error handling and method validation
  - Refactor README.md: update tech stack, project structure, and admin panel documentation
  - Refactor auth.ts: improve session management and cookie handling
  - Refactor schedule.ts: improve error handling with detailed logging and error types
  - Refactor logger.ts: add file-based error logging functionality
  - Refactor loading-context.tsx: improve error message clarity

remove:
  - Remove hello.ts test API endpoint
  - Remove groups.ts and groups.json (moved to old/data/, replaced by SQLite)

update:
  - Update .gitignore to exclude old data files, database files, and error logs
  - Update package.json: add better-sqlite3, bcrypt and their type definitions
  - Update README.md with new features, architecture, and database information
  - Update all API routes to use new wrapper system
  - Update admin panel with new settings and improved UI
  - Update sitemap.xml with cache usage comment
2025-12-03 21:44:07 +04:00

59 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import TelegramBot from 'node-telegram-bot-api'
import fs from 'fs'
import path from 'path'
const token = process.env.PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_BOTAPI_TOKEN
const ownerID = process.env.PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_CHAT_ID
let bot: TelegramBot
if (!token || !ownerID) {
console.warn('Telegram Token is not specified. This means you won\'t get any notifications about parsing failures.')
} else {
bot = new TelegramBot(token, { polling: false })
}
// Путь к файлу логов (в корне проекта)
const getErrorLogPath = () => {
// В production (standalone) используем текущую рабочую директорию
// В development используем корень проекта (process.cwd())
return path.join(process.cwd(), 'error.log')
}
/**
* Логирует ошибку в файл error.log
* @param error - Объект ошибки или строка с описанием ошибки
* @param context - Дополнительный контекст (опционально)
*/
export function logErrorToFile(error: Error | string, context?: Record<string, unknown>): void {
try {
const logPath = getErrorLogPath()
const timestamp = new Date().toISOString()
const errorMessage = error instanceof Error ? error.message : error
const errorStack = error instanceof Error ? error.stack : undefined
const errorName = error instanceof Error ? error.name : 'Error'
let logEntry = `[${timestamp}] ${errorName}: ${errorMessage}\n`
if (errorStack) {
logEntry += `Stack: ${errorStack}\n`
}
if (context && Object.keys(context).length > 0) {
logEntry += `Context: ${JSON.stringify(context, null, 2)}\n`
}
logEntry += '---\n'
// Используем appendFileSync для надежности (не блокирует надолго)
fs.appendFileSync(logPath, logEntry, 'utf8')
} catch (logError) {
// Если не удалось записать в файл, выводим в консоль
console.error('Failed to write to error.log:', logError)
}
}
export async function reportParserError(...text: string[]) {
if (!token || !ownerID) return
await bot.sendMessage(ownerID, text.join(' '))
}