Remove the per-route 'export const instant = false' opt-outs now that the root layout carries the single Cache Components opt-out. Child pages inherit the opt-out, so admin/mod/radio leaf pages that only access cached or DB data stay instant while runtime-dependent pages remain dynamic. Update the staff-smoke contract test to assert the root-layout contract.
- Clone import: defer FurnitureData.json writes and append all entries in a
single batched write instead of one read-modify-write per item, removing
the main serialization bottleneck for large batches.
- Clone import: raise SSE batch concurrency cap from 5 to 10 and bump the
clone client/route default from 2 to 6.
- Add a flush hook to runSseBatch so callers can batch deferred work before
batch_complete is emitted, and surface flush errors as an error event.
- Enable Next.js Cache Components (instant: false opt-out) and silence the
related build warnings in next.config.ts.
- Switch isomorphic-dompurify to dompurify and refresh dependencies.
Gate pages and mutations on module PERMS instead of dashboard-only staff checks, add radio view/edit slugs with migration 0015, and expand the operations contract tests.
Co-authored-by: Cursor <[email protected]>
Introspected the live DB and fixed real drift between the hand-modeled
schema and the actual columns:
- Added missing @map("snake_case") on camelCase fields that silently
failed at query time: website_teams (rank_name/hidden_rank/...),
website_paypal_transactions/user_guestbooks/help_center_tickets(+replies)/
used_shop_vouchers/maintenance_tasks (user_id), website_rare_values
(currency_type).
- website_permissions was modeled as key/value/comment but is actually
permission/min_rank/description — fixed the model + the admin page/action.
- website_shop_articles.icon -> icon_url (+ added category_id, is_giftable);
updated the shop page + admin shop CRUD.
- website_shop_categories: dropped non-existent slug/timestamps, added the
real description/order columns; updated the shop page.
- website_shop_article_features.features(Json) -> content(Text).
Verified against amx_test: all website_* query errors gone; home renders
the real hotel_name ("Habbo"), rankings shows real users, /staff + /shop
200. tsc 0, vitest 49/49, next build 0. Remaining missing tables
(radio_*/game_*/staff_activities/alert_logs/article_comments+reactions)
don't exist in this DB and degrade gracefully via try/catch.