openhands cb683b7322
Local Build and Deploy / deploy (push) Successful in 1m29s
chore: remove test workflow, clean up test tags
2026-07-20 15:36:55 +02:00
2026-07-13 21:57:41 +02:00
2026-07-13 21:57:41 +02:00
2026-07-13 21:57:41 +02:00
2026-07-13 21:57:41 +02:00
2026-07-13 21:57:41 +02:00

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

  1. Register an account at /register, or log in with an existing emulator account.
  2. Grant yourself admin access: UPDATE users SET rank = 7 WHERE username = 'yourname';
  3. Visit /admin and 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_url
  • radio_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

  1. Ensure typecheck and tests pass: pnpm typecheck && pnpm test
  2. Follow existing code conventions (Server Components where possible, minimal client boundaries)
  3. Use the src/lib/motion.ts animation variants for consistent animations
  4. SQL migrations in prisma/migrations/ must be idempotent

License

CC BY-NC-SA 4.0. See LICENSE for details.

S
Description
No description provided
Readme CC-BY-SA-4.0
172 MiB
1 Stars 1 Watchers 0 Forks
Languages
TypeScript 95.9%
JavaScript 1.4%
Shell 1.1%
CSS 1.1%
PHP 0.3%
Other 0.1%