Commit Graph
1622 Commits
Author SHA1 Message Date
Simo e96b606e1e Add remaining public + admin pages (parallel build, 26 files)
Built via two parallel agent workflows reading the real Prisma schema, then
integrated + verified.

Public: /shop (categories + storefront), /community hub, /rankings (top by
credits), /staff, /photos (camera_web gallery), /help (categories + rules),
/help/tickets (auth-gated user tickets + create), /settings (auth-gated, update
motto via RCON).

Admin: /admin/catalog (+[id] items), /admin/radio (shouts/apps/schedules +
delete shout), /admin/teams (CRUD), /admin/permissions (read), /admin/wordfilter
(CRUD + RCON push), /admin/ip (whitelist/blacklist CRUD), /admin/applications
(list + dismiss), /admin/logs (chat/command/alert read), /admin/achievements
(read). Server actions all staff-gated.

Header + admin nav extended. Verified: tsc exit 0, vitest 48/48, next build
exit 0 (33 routes); curl-probed every route — public 200/<main>, auth+admin
correctly 307-redirect when unauthorized.
2026-06-28 13:24:55 +02:00
Simo 9a79acebe7 Add atom-theme visual design (header/footer, theme system, restyled pages)
Faithful port of AtomCMS's "atom" theme look (light, Habbo-retro, golden
#eeb425 / amber #f59e0b accents, white cards, 12px radii, Nunito-first stack):
- globals.css: full token set + components (.site-header/.nav-item, .btn-*,
  .card, .hero, currency pills, article cards, inputs, tables, footer).
- SiteHeader (brand + nav + currency pills + auth box, staff-aware) + SiteFooter;
  layout wraps header/content/footer. Removed the bare SiteNav.
- Restyled home (hero + article cards), login (centered card).
- siteSettings now falls back to DEFAULTS on missing key OR DB error, so pages
  render without a DB; DATABASE_CONNECT_TIMEOUT_MS env + pool acquireTimeout make
  the no-DB fallback fast.

Verified in a real browser (computed styles): header white/sticky, golden logo
gradient, uppercase nav, amber primary button @12px radius, golden outline,
hero gradient — all correct. tsc exit 0, vitest 48/48, next build exit 0.
2026-06-28 13:13:00 +02:00
Simo 5f8b465451 Add admin CMS Settings editor (website_settings)
/admin/settings: list all website_settings, inline value edit, add/overwrite,
delete; staff-gated server actions that bust the siteSettings cache after each
write. Admin nav extended (Settings).

Verified: tsc exit 0, vitest 48/48, next build exit 0.
2026-06-28 12:54:18 +02:00
Simo 5861d9f1f5 Add admin Articles (CRUD) + Bans resources
- Articles: list / new / edit / delete (websiteArticles), unique-slug
  generation via slugify() (pure, unit-tested); staff-gated server actions.
- Bans: list active bans (ban_expire > now), create ban (writes the bans row +
  RCON disconnect) with type/duration/reason, lift ban; staff-gated actions.
- Admin nav extended (Articles, Bans).

Verified: tsc exit 0, vitest 48/48, next build exit 0 (7 /admin routes).
2026-06-28 12:52:38 +02:00
Simo 9f81096f05 Add admin foundation + Users resource (Filament replacement, slice 1)
Plain App Router admin (aligned to habbo-next, no Refine):
- rank surfaced on the NextAuth session; staff guard isStaff() [pure,
  unit-tested] + requireStaff() reading min_staff_rank, gating /admin.
- /admin dashboard (counts), /admin/users (paginated + search),
  /admin/users/[id] detail.
- src/actions/admin-users.ts: staff-gated server actions wiring the user editor
  to the existing services — giveCurrency (RCON or DB fallback), setMotto/setRank
  (DB + RCON), alertUser, disconnectUser.

Verified: tsc exit 0, vitest 45/45, next build exit 0 (/admin routes).
2026-06-27 16:51:47 +02:00
Simo d9a8ce532f Add /client launcher page (auth-gated SSO ticket + embed)
Faithful to AtomCMS's NitroController: requires a session (redirects to /login),
issues + persists the SSO ticket via issueSsoTicket (auth_ticket + ip_current
from x-forwarded-for), and embeds the configured client URL with ?sso=. Ties
auth + SSO + settings together.

Verified: tsc exit 0, next build exit 0 (/client route).
2026-06-27 16:44:30 +02:00
Simo 6e34d485d4 Add data-driven public pages (home, news, profile)
Real App Router pages reading the converted Prisma models:
- home: latest 4 articles (websiteArticles) + hotel_name from settings
- /news + /news/[slug]: article index and detail
- /u/[username]: profile (avatar via imager helper, motto, rank, credits, online)
- shared SiteNav (reads session via auth() + hotel_name), globals.css
- src/lib/format.ts: avatarImageUrl + excerpt helpers (unit-tested)

Verified: tsc exit 0, vitest 43/43, next build exit 0 (7 routes). Pages render
against a live DB (deferred until DATABASE_URL is provided). i18n to be layered
on next.
2026-06-27 16:42:59 +02:00
Simo 8fca407f0f Add RCON client + SendCurrency service (AtomCMS-faithful)
- rcon.ts: Node net.Socket transport speaking AtomCMS's exact protocol (raw
  JSON {"key","data"} over rcon_ip:rcon_port, fire-and-forget) with a bounded
  timeout + backoff retry; typed commands matching RconService EXACTLY
  (sendgift `itemid`, disconnect `username`, no-data => data:null, givepoints
  numeric `type`, forwarduser, setmotto/setrank/alertuser, give*). Injectable
  transport keeps command shapes unit-testable.
- send-currency.ts: mirrors the SendCurrency action — RCON deliver, else DB
  fallback (credits -> users.credits; duckets/diamonds/points -> users_currency
  by type 0/5/101).
- env: RCON_HOST/PORT/TIMEOUT/RETRIES. vitest: SKIP_ENV_VALIDATION for unit tests.

Verified: tsc exit 0, vitest 39/39, next build exit 0. Live TCP test deferred
(needs a running emulator).
2026-06-27 16:37:42 +02:00
Simo 443d908909 Scaffold Next.js 16 app + wire NextAuth Credentials to auth core
Minimal but real App Router app that builds (next build exit 0):
- src/lib/auth.ts: NextAuth v5 Credentials provider calling checkLogin()
  (argon2id/bcrypt + md5->argon2id upgrade gated by CONVERT_PASSWORDS), JWT
  session, /api/auth/[...nextauth] route handler.
- src/app: root layout, home (force-dynamic, reads hotel_name via siteSettings),
  /login client form (signIn).
- next.config.ts: pinned turbopack.root, serverExternalPackages for the Prisma
  MariaDB adapter; tsconfig set up for Next.

Routes: / (dynamic), /login, /api/auth. Verified: next build exit 0, 28 tests.
Still needs DB+APP_KEY to run auth end-to-end. i18n/middleware/pages to follow.
2026-06-27 16:11:52 +02:00
Simo ec2d46e583 Add byte-compatible Auth & SSO core primitives
Pure, unit-tested primitives the AtomCMS->Next.js login must reproduce exactly
(verified now with round-trip + known vectors; full end-to-end check deferred
until a real DB + APP_KEY + live emulator are available):

- password.ts: argon2id (m=65536,t=4,p=1 via hash-wasm) + bcrypt ($2y$ accepted)
  verify, and the md5->argon2id on-login upgrade gated by convert_passwords
  (mirrors RedirectIfTwoFactorAuthenticatable).
- sso-ticket.ts: '{hotel_name without spaces}-{uuidv4}' written to auth_ticket +
  ip_current (mirrors User::ssoTicket()).
- laravel-encrypter.ts: AES-256-CBC + HMAC-SHA256 payload compatible with
  Laravel encrypt()/encryptString (for existing 2FA secrets) incl. PHP string
  (de)serialization.
- totp.ts: otplib Google2FA-compatible TOTP verify (SHA1/6/30).

Libs: hash-wasm + bcryptjs + otplib (pure JS/WASM, no native build). 28 tests.
2026-06-27 16:00:25 +02:00
Simo 5fd40feaa6 Add CMS tables to Prisma schema (data layer complete: 190 models)
Models the Laravel-migration CMS tables (website_*, radio_*, game_*,
social_accounts, staff_activities, tags/taggables, alert_logs,
email_templates, referrals, ...) via Blueprint->Prisma mapping. Excludes
emulator-owned collisions (permissions/website_settings already modeled) and
Laravel-only infra the Next.js app replaces (cache/sessions/failed_jobs/
password_resets).

Data layer now covers the whole AtomCMS schema: 190 models (4 hand-authored +
119 emulator + ~67 CMS). Verified: prisma validate clean, generate OK,
tsc exit 0, vitest 6/6.
2026-06-27 15:48:12 +02:00
Simo f7e2cc4998 Convert full emulator schema to Prisma (119 tables from default.sql)
Models every Arcturus-owned table in default.sql (catalog, items, rooms,
guilds, pets, messenger, navigator, support, users_*, etc.) as flat Prisma
models — enum columns as String, @@id/@@unique/@@ignore per the real keys,
@@map to the exact table names. Assembled from a parallel modeling pass and
normalized (id de-dup, @db.Enum/Double/Decimal fixes).

123 models total (4 hand-authored + 119 generated). Verified: prisma validate
clean, prisma generate OK, tsc exit 0, vitest 6/6.
2026-06-27 15:43:06 +02:00
Simo b5bc7f6daf Rebuild atomcms-next foundation on Prisma (align to habbo-next reference)
Replace the superseded Drizzle monorepo scaffold with a single-app Prisma 7
data layer, mirroring the proven habbo-next approach to the shared Arcturus
emulator DB (introspect/conform only, idempotent SQL migrations via a custom
runner; never migrate-diff).

- prisma/schema.prisma: User, UsersCurrency (composite PK), Ban, WebsiteSetting
  mapped to AtomCMS's default.sql columns; client generated to src/generated/prisma
- src/lib/prisma.ts: PrismaMariaDb adapter singleton; src/env.ts zod env
- src/lib/services: siteSettings (cached setting() equivalent) + CurrencyType enum
- prisma/migrations + scripts/apply-migrations.ts: idempotent CMS-table runner

Verified: prisma generate OK, tsc --noEmit exit 0, vitest 6/6 pass.
2026-06-27 15:26:40 +02:00
Simo 7bd4f2b28e test(db): add env-gated integration smoke test for real-schema reads 2026-06-27 14:37:13 +02:00
Simo 2a304c94a4 docs(db): add introspect-only drizzle config and DB README 2026-06-27 14:35:25 +02:00
Simo d04ed42586 feat(db): add users/currency/bans/settings read repositories 2026-06-27 14:34:59 +02:00
Simo 3e3776b477 feat(db): add pure isBanActive predicate matching Laravel ban filtering 2026-06-27 14:33:51 +02:00
Simo 5369f99b07 feat(db): hand-author drizzle schema for users, users_currency, bans, website_settings 2026-06-27 14:33:25 +02:00
Simo 0966aa7dda feat(db): add @atomcms/db package skeleton + mysql2/drizzle client 2026-06-27 14:32:45 +02:00
Simo c2366fe6c9 feat(settings): add cached SettingsService (setting() equivalent) 2026-06-27 14:31:35 +02:00
Simo edbd5c89ba feat(settings): add emulator-fixed CurrencyType enum 2026-06-27 14:30:47 +02:00
Simo 8e0ad40c19 chore(next): scaffold atomcms-next monorepo (pnpm + turborepo) 2026-06-27 14:29:24 +02:00