Shallow clone (depth 1) only has one commit, so git log was empty. Now generates changelog from the bare repo before cloning, and uses Python to build the JSON payload for proper multiline escaping.
EpicNext-CMS
A modern, high-performance content management system for Habbo hotel emulators, built on Next.js 16 (App Router) with Prisma 7 and React 19. Designed to integrate seamlessly with Polaris / Arcturus Morningstar MySQL/MariaDB databases.
Features a full public-facing website, an administrative panel, NextAuth authentication (argon2id/bcrypt with MD5-to-argon2id upgrade), real-time RCON communication with the emulator, Server-Sent Events for live radio data, smooth page transitions, and extensive extensibility.
System Requirements
| Component | Version | Notes |
|---|---|---|
| Node.js | >= 22 | Required by Next.js 16 |
| pnpm | >= 10.33.4 | Package manager (npm/yarn not supported) |
| MySQL / MariaDB | 8.0+ / 10.6+ | Shared with the emulator |
| Redis | 7.x+ | Optional — caching, rate limiting, SSE |
| Java | 17+ | Required only if building the emulator |
| Maven | 3.9+ | Required only if building the emulator |
Quick Start
1. Clone & Install
git clone https://gitlab.epicnabbo.nl/remco/EpicNext-Cms.git
cd EpicNext-Cms
pnpm install
2. Database Setup
The CMS shares a database with the Polaris/Arcturus emulator. Use an existing database or create a new one:
CREATE DATABASE IF NOT EXISTS epicnext_cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
The CMS reads emulator-owned tables (users, items, rooms, bans, etc.) directly. It never creates, alters, or drops them.
3. Configure Environment
cp .env.example .env
Edit .env with at minimum:
DATABASE_URL=mysql://user:[email protected]:3306/epicnext_cms
AUTH_SECRET=<random 32+ character string>
HOTEL_NAME=YourHotel
APP_URL=http://localhost:3000
See .env.example for all optional variables (RCON, email, Redis, OAuth, PayPal, etc.).
4. Generate Prisma Client
pnpm prisma:generate
Generates TypeScript types in src/generated/prisma/.
5. Run CMS Migrations
pnpm db:migrate
Creates all CMS-owned tables (website_*, radio_*, acl_*, admin_audit_log, etc.) via idempotent SQL files in prisma/migrations/. Emulator tables are never touched.
Check migration status:
pnpm db:migrate:status
6. Build & Start
# Development (hot reload)
pnpm dev
# Production
pnpm build && pnpm start
Open http://localhost:3000 in your browser.
7. First Login
- Register an account at
/register, or log in with an existing emulator account. - Grant yourself admin access:
UPDATE users SET rank = 7 WHERE username = 'yourname'; - Visit
/adminand configure your hotel via Admin → CMS Settings.
Scripts
| Command | Description |
|---|---|
pnpm dev |
Start development server (hot reload) |
pnpm build |
Production build |
pnpm start |
Start production server |
pnpm typecheck |
Run TypeScript type checking |
pnpm test |
Run all tests (Vitest) |
pnpm db:migrate |
Apply pending SQL migrations |
pnpm db:migrate:status |
Show migration status |
pnpm analyze |
Build + open bundle analyzer |
pnpm jobs:worker |
Start background task worker (systemd / PM2) |
pnpm biome:check |
Lint and format code |
Performance Features
| Feature | Description |
|---|---|
| React Compiler | Automatic memoization — reduces unnecessary re-renders |
| View Transitions API | Native browser transitions between page navigations |
| Lenis Smooth Scroll | Fluid, customizable scrolling (respects prefers-reduced-motion) |
| Server-Sent Events | Real-time radio now-playing & listeners via SSE (no polling) |
| Redis Caching | Caches API responses (home, radio config) up to 30s in Redis |
| Bundle Analyzer | Run pnpm analyze to visualize and optimize bundle sizes |
| AnimatePresence | Framer Motion exit animations on modals, dialogs, and lightbox |
| RCON (TCP Socket) | Live commands to the emulator (credits, badges, kick, ban) |
| Streaming & Suspense | Next.js App Router streaming for fast page loads |
| Automatic Image Optimization | next/image with Sharp for resizing and WebP/AVIF |
| CSS-based Animations | Base UI components use data-open/data-closed CSS animations |
| Compression | Gzip compression enabled on all responses |
| Stale Times | Optimized router cache (30s dynamic, 180s static) |
Architecture
├── prisma/
│ ├── schema.prisma # ~190 models (emulator + CMS)
│ └── migrations/ # 16 SQL migrations for CMS tables
├── scripts/
│ ├── apply-migrations.ts # Custom migration runner
│ ├── jobs-worker.ts # Background task scheduler
│ └── sql-statements.ts # SQL parsing utilities
├── src/
│ ├── app/ # Next.js App Router (pages & API routes)
│ ├── actions/ # Server Actions
│ ├── components/ # UI components
│ ├── lib/
│ │ ├── auth/ # NextAuth, password hashing, 2FA, SSO tickets
│ │ ├── services/ # RCON, email, currency, PayPal, alerts
│ │ ├── prisma.ts # Database connection singleton
│ │ ├── redis.ts # Redis client (ioredis)
│ │ ├── redis-cache.ts # Redis caching utility for API routes
│ │ ├── cache.ts # In-memory cache fallback
│ │ ├── motion.ts # Framer Motion animation variants
│ │ └── use-event-source.ts # React hook for SSE subscriptions
│ ├── messages/ # i18n translations (en, nl, de, fr, es, it)
│ └── env.ts # Zod-validated environment schema
├── public/
│ ├── assets/ # Images, icons, fonts
│ └── scripts/ # Client-side scripts (theme-init.js)
├── update-Nitrov3.sh # Emulator & Nitro updater utility
├── next.config.ts # Next.js configuration
└── .env.example # Environment template with all options
Database Ownership
| Component | Type | Migrations |
|---|---|---|
Emulator tables (users, items, rooms, etc.) |
Existing Polaris schema | None — CMS reads/writes only |
CMS tables (website_*, radio_*, etc.) |
CMS-owned | prisma/migrations/*.sql (16 files) |
| Migration tracking | cms_migrations table |
Auto-created by migration runner |
Optional Integrations
Emulator — RCON
For live actions (credits, badges, rank changes, kick, ban, hotel alerts). The emulator must be running with RCON enabled at RCON_HOST:RCON_PORT.
Client — Nitro
The /client page loads the Nitro client. Configure the client URL via Admin → CMS Settings (nitro_client_url). See update-Nitrov3.sh for deployment.
Radio
Supports any streaming radio (e.g., Azuracast). Configure endpoints via CMS Settings:
radio_now_playing_api_urlradio_listeners_api_url
The radio player uses SSE for real-time updates (10s interval, no polling).
Background Jobs
Run as a persistent process:
pnpm jobs:worker
Scheduled tasks:
- Daily 03:00 — Emulator JAR backup (requires
EMULATOR_JAR_PATH+EMULATOR_BACKUP_DIR) - Daily 04:00 — Cleanup login logs (>30 days) and expired password reset tokens (>7 days)
CAPTCHA
Supports Cloudflare Turnstile and Google reCAPTCHA. Configure via CMS Settings.
Theming
12 preset themes with fully customizable colors via Admin → Theme (/admin/theme).
AI Content Moderation
Optional OpenAI-powered moderation for comments and guestbook posts. Set OPENAI_API_KEY.
Development
pnpm dev # Start with hot reload
pnpm typecheck # Type check all files
pnpm test # Run test suite (312+ tests)
pnpm analyze # Build and analyze bundle sizes
pnpm biome:check # Lint and format
Contributing
- Ensure typecheck and tests pass:
pnpm typecheck && pnpm test - Follow existing code conventions (Server Components where possible, minimal client boundaries)
- Use the
src/lib/motion.tsanimation variants for consistent animations - SQL migrations in
prisma/migrations/must be idempotent
License
CC BY-NC-SA 4.0. See LICENSE for details.