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
2025-11-18 04:23:31 +04:00
2023-10-01 20:18:37 +04:00
2023-10-01 18:53:04 +04:00
2025-11-18 03:36:47 +04:00
2025-11-18 03:57:22 +04:00
2025-11-24 02:47:32 +04:00
2023-10-01 18:53:04 +04:00

Schedule for College of Communication Volga State Goverment University of ICT (КС ПГУТИ)

Reskin of https://lk.ks.psuti.ru/ since it lacks mobile support.

Screenshot

Screenshot

Visit website

Tech stack & features

  • React 19.2.0 with Next.js 16.0.3 (pages router)
  • Tailwind CSS
  • @shadcn/ui components (built with Radix UI)
  • JSDOM for parsing scraped pages, rehydration strategy for cache
  • TypeScript 5.9.3 with types for each package
  • SQLite database (better-sqlite3) for storing groups and settings
  • bcrypt for secure password hashing
  • Telegram Bot API (via [node-telegram-bot-api]) for parsing failure notifications
  • Custom js parser for teachers' photos
  • Accessibility & tab navigation support
  • Dark theme with automatic switching based on system settings
  • Admin panel for managing groups and settings
  • Optimized code structure with reusable utilities and components

Architecture & Code Organization

The project follows a feature-sliced design pattern with clear separation of concerns:

Code Structure:

  • Shared utilities (src/shared/utils/):
    • auth.ts - Authentication and session management
    • api-wrapper.ts - Reusable API route wrappers with auth and error handling
    • validation.ts - Centralized validation functions
  • Data layer (src/shared/data/):
    • SQLite database for persistent storage
    • Data loaders with caching (1-minute TTL)
    • Automatic cache invalidation on updates
  • API routes (src/pages/api/admin/):
    • Unified authentication via withAuth wrapper
    • Consistent error handling
    • Method validation
  • Components:
    • Reusable UI components in src/shared/ui/
    • Feature-specific components in src/features/
    • Complex widgets in src/widgets/

Optimizations:

  • Toggle switch component reused across admin panel
  • Unified data loading functions
  • Centralized validation logic
  • Consistent API error handling
  • Optimized cache management

Known issues

  • Previous week cannot be accessed if you enter from main "/"

Workaround: Locate to next week, then enter previous twice.

Project structure

kspguti-schedule/
├── src/                          # Source code
│   ├── app/                      # App-level code
│   │   ├── agregator/           # Schedule fetching logic
│   │   ├── parser/              # HTML parsing for schedule
│   │   └── utils/               # App-level utilities
│   ├── pages/                    # Pages router (Next.js)
│   │   ├── api/                 # API routes
│   │   │   └── admin/          # Admin panel API endpoints
│   │   │       ├── groups.ts   # Groups CRUD operations
│   │   │       ├── settings.ts # Settings management
│   │   │       ├── login.ts     # Authentication
│   │   │       ├── check-auth.ts # Auth verification
│   │   │       ├── change-password.ts # Password change
│   │   │       └── logs.ts      # Error logs viewer
│   │   ├── [group].tsx         # Dynamic group schedule page
│   │   ├── admin.tsx           # Admin panel page
│   │   └── index.tsx           # Home page
│   ├── entities/                # Business entities
│   ├── features/                # Feature modules
│   │   ├── add-group/          # Add group feature
│   │   └── theme-switch/       # Theme switcher
│   ├── shared/                 # Shared code
│   │   ├── constants/          # App constants
│   │   ├── context/            # React contexts
│   │   ├── data/               # Data layer
│   │   │   ├── database.ts     # SQLite database operations
│   │   │   ├── groups-loader.ts # Groups data loader
│   │   │   └── settings-loader.ts # Settings data loader
│   │   ├── model/              # Data models
│   │   ├── providers/          # React providers
│   │   ├── ui/                 # Shared UI components
│   │   └── utils/              # Utility functions
│   │       ├── auth.ts         # Authentication utilities
│   │       ├── api-wrapper.ts  # API route wrappers
│   │       └── validation.ts   # Validation utilities
│   ├── shadcn/                 # shadcn/ui components
│   └── widgets/                # Complex UI widgets
│       ├── navbar/             # Navigation bar
│       └── schedule/          # Schedule display components
├── public/                      # Static assets
│   └── teachers/               # Teacher photos
├── old/                         # Deprecated/archived files
│   ├── data/                   # Old data files (groups.ts, groups.json)
│   └── README.md               # Documentation for old files
├── scripts/                     # Deployment scripts
├── systemd/                    # Systemd service file
├── data/                       # SQLite database files
├── components.json             # shadcn/ui config
├── docker-compose.yml          # Docker Compose config
├── Dockerfile                 # Docker image definition
├── next.config.js             # Next.js configuration
├── tailwind.config.js         # Tailwind CSS config
└── tsconfig.json               # TypeScript config

Development

Prerequisites

  • Node.js 20+ (see .nvmrc)
  • npm 10+ or pnpm

Local development

# Install dependencies
npm install

# Run development server
npm run dev

Admin Panel

The application includes an admin panel for managing groups and application settings. Access it at /admin route.

Features:

  • Manage groups (add, edit, delete)
  • Configure application settings (e.g., week navigation)
  • Password-protected access with session management (24-hour sessions)
  • Change admin password from the admin panel
  • View error logs
  • Debug options (development mode only)

Security:

  • Passwords are hashed using bcrypt
  • Session-based authentication with secure cookies
  • Rate limiting on login attempts (5 attempts per 15 minutes)
  • Default password warning if not changed

Default password:

  • On first launch, the default password is ksadmin
  • ⚠️ Important: Change the default password immediately after first login for security!
  • The admin panel will show a warning if the default password is still in use

Environment variables for admin panel:

  • ADMIN_SESSION_SECRET - Secret key for session tokens (optional, defaults to 'change-me-in-production')
  • ADMIN_PASSWORD - Initial admin password (optional, defaults to 'ksadmin')

⚠️ Important: Always set a strong ADMIN_SESSION_SECRET in production!

API Endpoints:

  • GET /api/admin/groups - Get all groups
  • POST /api/admin/groups - Create new group
  • PUT /api/admin/groups/[id] - Update group
  • DELETE /api/admin/groups/[id] - Delete group
  • GET /api/admin/settings - Get settings
  • PUT /api/admin/settings - Update settings
  • POST /api/admin/login - Authenticate
  • GET /api/admin/check-auth - Check authentication status
  • POST /api/admin/logout - Logout
  • POST /api/admin/change-password - Change password
  • GET /api/admin/logs - Get error logs

Docker deployment

Build and run with Docker

# Build the image
docker build -t kspguti-schedule .

# Run the container
docker run -p 3000:3000 kspguti-schedule

Using Docker Compose

# Build and start
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

Environment variables: Edit docker-compose.yml to add your environment variables:

  • PROXY_URL - URL for schedule parsing (optional)
  • PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_BOTAPI_TOKEN - Telegram bot token (optional)
  • PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_CHAT_ID - Telegram chat ID (optional)
  • ADMIN_SESSION_SECRET - Secret key for session tokens (optional, but recommended in production)
  • NEXT_PUBLIC_SITE_URL - Site URL for canonical links and sitemap (optional)

Database:

  • The application uses SQLite database (data/schedule-app.db) for storing:
    • Groups configuration
    • Application settings
    • Admin password (hashed with bcrypt)
  • Database is automatically created on first run
  • No additional database setup required

Note: Admin password is stored in SQLite database. Default password is ksadmin - change it after first login!

Production deployment

Netlify

The project includes netlify.toml for automatic deployment configuration.

Docker

The Dockerfile uses Next.js standalone output for optimized production builds. The image includes:

  • Multi-stage build for smaller image size
  • Non-root user for security
  • Health checks
  • Production optimizations

System installation (Linux systemd)

Install the application directly on a Linux system as a systemd service:

Prerequisites:

  • Linux system with systemd
  • Node.js 20+ installed
  • Root/sudo access
  • ICU library (for Node.js):
    • Arch Linux: sudo pacman -S icu
    • Ubuntu/Debian: sudo apt-get install libicu-dev
    • Fedora/RHEL/CentOS: sudo dnf install libicu or sudo yum install libicu

Installation:

# Clone the repository
git clone <repository-url>
cd kspguti-schedule
# Copy example and edit .env
cp .env.production.example .env
nano .env
# Run the installation script
sudo ./scripts/install.sh

The installation script will:

  • Check Node.js and npm versions
  • Copy files to /opt/kspguti-schedule
  • Install dependencies
  • Build the production version
  • Install and enable systemd service

Configuration:

  1. Edit environment variables:
sudo nano /opt/kspguti-schedule/.env

The installation script will:

  • Copy .env file from source directory if it exists
  • Preserve existing .env in installation directory if it already exists
  • Create .env from .env.production.example if no .env file is found
  1. Update systemd service if needed:
sudo nano /etc/systemd/system/kspguti-schedule.service

Managing the service:

Use the management script for easy service control:

# Start the service
sudo ./scripts/manage.sh start

# Stop the service
sudo ./scripts/manage.sh stop

# Restart the service
sudo ./scripts/manage.sh restart

# Check status
./scripts/manage.sh status

# View logs
./scripts/manage.sh logs
./scripts/manage.sh logs -f  # Follow logs

# Update application
sudo ./scripts/manage.sh update

# Enable/disable autostart
sudo ./scripts/manage.sh enable
sudo ./scripts/manage.sh disable

Service configuration:

  • Installation directory: /opt/kspguti-schedule
  • Service user: www-data
  • Port: 3000 (configurable via environment variables)
  • Logs: journalctl -u kspguti-schedule

Environment variables:

See .env.production.example for available options. The application uses .env file in production:

Schedule parsing:

  • PROXY_URL - URL for schedule parsing (optional, defaults to https://lk.ks.psuti.ru)
  • PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_BOTAPI_TOKEN - Telegram bot token for parsing failure notifications (optional)
  • PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_CHAT_ID - Telegram chat ID for receiving notifications (optional)

Admin panel:

  • ADMIN_PASSWORD - Initial password for admin panel access (optional, defaults to 'ksadmin')
  • ADMIN_SESSION_SECRET - Secret key for session tokens (optional, defaults to 'change-me-in-production', but should be changed in production)

Note: The admin password is stored in SQLite database and can be changed from the admin panel. The ADMIN_PASSWORD environment variable is only used for initial setup.

Site configuration:

Other platforms

The project can be deployed to any platform supporting Node.js 20+:

  • Vercel
  • Railway
  • DigitalOcean App Platform
  • AWS App Runner
  • Any Docker-compatible platform
Description
No description provided
Readme AGPL-3.0 1.7 MiB
Languages
TypeScript 81.4%
JavaScript 11.7%
Shell 5.1%
CSS 1.2%
Dockerfile 0.5%
Other 0.1%