Commit Graph
157 Commits
Author SHA1 Message Date
Simo cbaa115d56 fix(deploy): verify Docker clone updates against the served release
CI / check (push) Successful in 59s
CI / deploy (push) Failing after 1m21s
2026-09-07 21:17:34 +02:00
Simo 193b6686a9 refactor(catalog): unify commands and embed guarded catalog workspace
CI / check (push) Successful in 1m16s
CI / deploy (push) Successful in 28s
2026-09-06 19:40:52 +02:00
Simo 9b0ea2fb16 fix(news): restore publication flow and deduplicate dashboard friends
CI / check (push) Successful in 1m6s
CI / deploy (push) Successful in 59s
2026-09-06 18:32:43 +02:00
Simo a070004e7b feat(admin): reorganize housekeeping and strengthen shared workflows
CI / check (push) Successful in 1m5s
CI / deploy (push) Successful in 1m4s
2026-09-06 17:17:30 +02:00
openhands 9dc9d1fa4b perf: pre-compress gamedata JSON, tune MariaDB, fix avatar imager, docs
CI / check (push) Successful in 1m3s
CI / deploy (push) Successful in 1m12s
- scripts/compress-gamedata.mjs: pre-compress large gamedata JSON to .gz
  (gzip level 9, idempotent mtime check) served via nginx gzip_static
  (48 MB FurnitureData.json -> ~2.4 MB, ~0.3s -> ~0.005s per request)
- package.json: add gamedata:compress script
- fix(imaging): accept real Habbo figure strings in avatar route
  (allow optional second number per part, e.g. hd-180-1.ch-210-66)
- README: document avatar imager container (avatar-imaging-pixinode,
  port 8082, /docker/Polaris-imager), nginx /imaging proxying, MariaDB
  tuning, gamedata pre-compression cron and caching layers
2026-09-06 12:06:38 +02:00
openhands 8c12fc6c60 refactor(cms): deduplicate shared admin components and fix studio batch completion
CI / check (push) Failing after 1m35s
CI / deploy (push) Skipped
CI / e2e (push) Skipped
- fix(studio): stop markBatchDone infinite recursion so batches complete
- refactor(api): merge api-response into api and drop the duplicate module
- refactor(media): extract shared media loader and URL validator
- refactor(ui): extract shared LoadingSpinner for site and admin groups
- refactor(dates): consolidate raw date formatting into formatDate util
- refactor(logs): share a single generic log-list loader across tables
- refactor(theme): merge both ColorField components and reuse contrast helpers
- refactor(import): extract shared ImportErrorBanner and SearchInput
- chore(): remove dead theme-editor-tabs after inlining tab components
2026-09-05 20:58:42 +02:00
Simo 816e3875c2 feat(admin): add production error center and refresh CMS dependencies 2026-09-05 19:53:09 +02:00
Simo 570f3dde44 feat(catalog): repair missing furniture components with verified status
CI / check (push) Successful in 1m33s
CI / deploy (push) Successful in 1m22s
CI / e2e (push) Successful in 24s
2026-09-05 18:12:34 +02:00
Simo cd75361b9f feat(catalog): generate derived scale 32 with preview and backup restore
CI / check (push) Successful in 1m32s
CI / deploy (push) Successful in 1m12s
CI / e2e (push) Successful in 21s
2026-09-05 17:36:22 +02:00
Simo 08b0b5021e feat(catalog): inspect Nitro scales and preview original sprites
CI / check (push) Successful in 1m47s
CI / deploy (push) Successful in 1m30s
CI / e2e (push) Successful in 22s
2026-09-05 17:22:27 +02:00
Simo 2619bec165 feat(catalog): queue furniture imports with history and matching file attachments
CI / check (push) Successful in 1m30s
CI / deploy (push) Successful in 1m26s
CI / e2e (push) Successful in 25s
2026-09-05 17:02:26 +02:00
Simo 33b6d1520e fix(catalog): stream single imports and preserve response errors
CI / check (push) Successful in 1m31s
CI / deploy (push) Successful in 1m13s
CI / e2e (push) Successful in 21s
2026-09-05 15:16:42 +02:00
Simo f0dcbee162 fix(ci): normalize source asset test formatting
CI / check (push) Successful in 1m30s
CI / deploy (push) Successful in 1m9s
CI / e2e (push) Successful in 21s
2026-09-05 15:07:26 +02:00
Simo 159b1f7d1b fix(catalog): check source assets and offer reachable import alternatives
CI / check (push) Failing after 19s
CI / deploy (push) Skipped
CI / e2e (push) Skipped
2026-09-05 14:56:04 +02:00
Simo 8a919f85b2 Preserve furniture revisions when downloading source assets
CI / check (push) Successful in 1m31s
CI / deploy (push) Successful in 1m21s
CI / e2e (push) Successful in 21s
2026-09-05 14:29:48 +02:00
Simo a78d8256e0 Recognize imported furniture by normalized classname and local IDs
CI / check (push) Successful in 1m30s
CI / deploy (push) Successful in 1m21s
CI / e2e (push) Successful in 22s
2026-09-05 14:04:52 +02:00
Simo 9f791ba284 Support Gitea configuration and safe Catalog Studio furniture completion
CI / check (push) Successful in 1m31s
CI / deploy (push) Successful in 1m18s
CI / e2e (push) Successful in 21s
2026-09-05 13:33:40 +02:00
Simo 26f071117b Add Catalog Studio inspection and guided import review
CI / check (push) Successful in 1m39s
CI / deploy (push) Successful in 1m18s
CI / e2e (push) Successful in 25s
2026-09-05 13:10:43 +02:00
Simo 9ec9ab31ad feat: export Catalog Studio assets and SQL to catalog repository
CI / check (pull_request) Failing after 1m21s
CI / deploy (pull_request) Skipped
CI / e2e (pull_request) Skipped
2026-09-05 11:49:00 +02:00
openhands 458972fdfd fix: improve batch import error handling and resilience
CI / check (push) Successful in 1m25s
CI / deploy (push) Successful in 1m57s
CI / e2e (push) Successful in 26s
- Add retries for furnidata fetch (3 attempts, 1s delay)
- Better error messages for user (distinguish 502/400/other)
- Client-side: show detailed error from SSE stream when available
- Remove unused admin-helpers.test.ts
2026-09-04 18:28:14 +02:00
openhands 399c047515 fix: harden admin actions, search, sanitization and repo hygiene
CI / check (push) Successful in 1m21s
CI / deploy (push) Successful in 1m25s
- Split approve/dismiss application workflows with distinct audit logs,
  rate-limited guards and real error logging
- Validate article status/date/id input and stop resetting publishedAt
  on every update
- Validate guild updates (state, forum enums, non-empty name) behind
  rate-limited guard
- Fix scheduled-article publishing (ignore NULL dates, set updatedAt,
  type-safe predicates)
- Harden admin search API (LIKE escaping, query cap, per-user
  rate limit, round-robin result cap) and fix search dialog
  abort/res.ok/loading races
- Lock down HTML sanitizer to an allowlist profile and add XSS tests
- Improve mobile nav accessibility (unique id, dialog role, focus
  management, scroll lock, outside close)
- Log swallowed server errors instead of silent catch blocks
- Remove dead eslint config, drop unused dompurify deps, restore knip
  CI step, add Playwright config with smoke spec
2026-09-04 13:04:08 +02:00
openhands 30c95b1a5c feat: comprehensive CMS improvements
CI / runtime-diagnostics (push) Skipped
CI / release (push) Skipped
CI / check (push) Failing after 0s
CI / deploy (push) Skipped
- Fix DOMPurify SSR crash (use isomorphic-dompurify)
- Fix SanitizedHtml to sanitize by default
- Add auth guards to studio/catalog maintenance pages
- Add update/edit to vouchers CRUD
- Add update/edit to rare-values CRUD
- Add approve workflow to applications page
- Add edit form to guilds detail page
- Add SEO metadata to all public pages (21 pages)
- Fix mobile nav accessibility (focus trap, aria attributes)
- Fix missing labels and table accessibility
- Add dynamic imports for heavy client components (6 components)
- Fix silent error swallowing (40+ locations)
- Add content scheduling for articles (publishAt, status)
- Wire up 12 missing webhook notification triggers
- Add global search to admin panel
- Add bulk actions to admin users table
- Fix JSON formatting and a11y issues
2026-09-03 16:00:32 +02:00
openhands 67b67798b9 feat(client): polished toolbar, live online count via SSE
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m27s
- Redesign in-game client toolbar with refined glass styling and buttons
- Live online count + emulator status streamed over SSE multicast
- Who's-online tooltip throttled to reduce repeated requests
- Fix show button so it always returns the hidden toolbar
- Use theme CSS variables instead of hardcoded colors
- Add toolbar translations across all 25 locales
2026-09-02 21:14:42 +02:00
openhands 52516a368d fix: skip heavy post-import consolidation on non-final clone chunks
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 38s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m2s
The flush after every 400-item chunk was running expensive operations
(reconcileOfferIds, rebuildCatalog, verifySpriteIds, rcon updates) which
caused the import to hang after ~800 items. Now only the final chunk
triggers the full consolidation. Also raised the per-request limit from
500 to 5000 items.
2026-09-01 18:29:06 +02:00
openhands 1374bd332f Studio: add clone-all-per-hotel, per-item status detail, retry, ETA, and auto-translate
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 36s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m14s
- Add 'Clone all missing' button for clone sources with confirmation dialog
- Show per-item status badges: nitro, furnidata, catalog entry
- Add status filters: missing furnidata, missing catalog entry
- Add ETA and percentage to batch progress bar
- Add retry button for failed items after batch import
- Auto-translate all languages after clone-all completes
- Fix statusFilter 'all' bug that incorrectly filtered imported items
- Bulk-load FurnitureData + catalog references for O(1) per-item checks
2026-09-01 17:29:12 +02:00
openhands 1dc8d1d46f feat: add official furnidata sync button for importing all missing items
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 55s
- API endpoint: /api/admin/import/official/sync-all
  - Fetches all official Habbo furnidata
  - Compares with database to find missing items
  - Imports missing items via SSE batch with progress reporting
  - 500 item limit for safety
  - Proper abort signal support
- Client component: OfficialSyncClient with progress UI
- Updated StudioSyncPage to include Official Furnidata sync option
- Uses existing importSingleFurni infrastructure
2026-08-31 20:24:46 +02:00
openhands 7556b1f3fa perf: prevent import hanging with timeouts and batching
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m1s
- verifyAndFixInteractionModesCount: paginated DB queries (500/batch)
  instead of loading all items into memory at once
- withFurniDataLock: add 60s chain timeout to prevent deadlocks
  when a lock holder stalls or crashes
- withGamedataLock: same timeout protection for gamedata locks
- conversion-pool: add 60s per-job timeout, fall back to main thread
- furni/batch: abort signal + post_import progress events + skip
  post-import steps when client disconnects
- furni/batch-regen: abort signal + early exit when disconnected
- clone/sync-all: pre-fetch furnidata once per source instead of
  per item (eliminates 2000+ redundant fetches)
- sse-client: add 60s idle timeout to prevent infinite hangs
2026-08-31 18:25:32 +02:00
openhands f70d96b81c fix: prevent import hanging by adding abort signals and idle timeouts
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 59s
- Furni batch: wire request.signal to abort controller, send post_import
  progress events, skip post-import steps when aborted
- Clone sync-all: pre-fetch furnidata once per source instead of per item
  (eliminates 2000+ redundant DB reads + HTTP requests)
- SSE client: add 60s idle timeout to prevent infinite hangs when server
  stops responding
2026-08-31 18:11:54 +02:00
openhands a98b194386 feat: add scoped theme builder system with per-route, per-module, and multi-site support
- Add theme_scopes and theme_scope_values database tables for scoped themes
- Implement theme resolver engine with inheritance: global > site > module > route
- Add module detection for 20+ routes (shop, guilds, radio, news, etc.)
- Create admin UI at /admin/theme-builder with scope tree and color editor
- Add ScopedThemeVars component for injecting scoped CSS via data-attributes
- Add ThemeScopeDetector client component for runtime module/route detection
- Add site-resolver for multi-site domain detection
- Add /api/themes/export endpoint (JSON, CSS, variables formats)
- Add /api/themes/export/embed.js for external integration widget
- Add server actions for full CRUD on scopes and theme values
- Add admin nav link and EN/NL translations
2026-08-31 17:15:42 +02:00
Simo b1ddda66ff Revert "Merge pull request 'Complete Housekeeping migration and /ase cutover' (#52) from codex/housekeeping-complete into main"
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 43s
This reverts commit 488b6e57c4, reversing
changes made to b506b4499a.
2026-08-30 21:31:34 +02:00
Simo 1ec05cda39 test: make media route fixture cross-platform
CI / check (pull_request) Successful in 34s
CI / release (pull_request) Skipped
CI / deploy (pull_request) Skipped
2026-08-30 12:27:12 +02:00
Simo c524b305d7 fix(housekeeping): address task 14 review round 2 2026-08-30 11:30:17 +02:00
Simo d09eaa33d6 fix(housekeeping): address task 14 review round 1 2026-08-30 10:53:50 +02:00
openhands 164a4f4ef6 refactor: remove hotel-name fallback, fail fast when unconfigured
CI / check (push) Failing after 39s
CI / release (push) Skipped
CI / deploy (push) Skipped
Drop the hardcoded FALLBACK_HOTEL_NAME ("Atom") preset and the brand.ts
module. HOTEL_NAME is now a required env var: if it (and the CMS hotel_name
setting) is missing the site fails validation at startup/build with a clear
message instead of silently rendering a placeholder hotel name.

resolveHotelName() resolves CMS hotel_name -> required HOTEL_NAME only.
Callers that used the preset (api/home route catch branch, CMS settings form
default, mobile-nav/logo-generator prop defaults) now use the configured name
or an empty default; the real name is already passed in by server parents.
2026-08-27 16:35:00 +02:00
openhands 6dced0fb54 feat: per-import translation toggle and language picker in studio
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 53s
Furni imports can now choose whether to translate (per import) and which
languages to build, instead of always rebuilding all 13 FurnitureData_<lang>
files. The studio header also has a global switch that persists the
furnidata_translate_enabled setting, seeding the per-import default.
2026-08-24 18:16:42 +02:00
openhands c7ba04bda1 feat: relocate import tools into studio and harden catalog/furnidata integrity
CI / check (push) Failing after 26s
CI / release (push) Skipped
CI / deploy (push) Skipped
- Move /admin/import/* tools under /admin/studio/* and add studio nav, layout and tabs
- Add shared catalog maintenance panel plus a /admin/studio/maintenance tab
- Make furnidata reconciliation overwrite conflicting entries with the
  DB-authoritative items_base classname/id (surfaced via fixedConflicts)
- Add furnidata_translate_enabled setting to skip the heavy localized
  furnidata build during import (manual build-languages still forces it)
- Update staff smoke contract test for the studio hub
2026-08-24 17:13:03 +02:00
openhands c2e61dc324 fix: reduce import concurrency to prevent 100% CPU during SWF→Nitro conversion
CI / check (push) Successful in 42s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m43s
- Default batch concurrency: 3→1 (max 5→3)
- Default batch-regen concurrency: 3→1 (max 5→3)
- Default IMPORT_BATCH_CONCURRENCY: 12→3
- Added setImmediate yields between items to prevent event loop blocking

Fixes gatje and other complex furniture imports consuming 100% CPU and stalling the catalog studio.
2026-08-23 19:51:04 +02:00
openhands 5311ee1fb8 Force catalog_items.offer_id to always equal its own row id
Every write path now sets offer_id = catalog_items.id instead of the
sprite id or furnidata offerid: single import insert/update, clone
import, upload import (direct DB + generated SQL migration), catalog
repair inserts, reconcileImportedOfferIds and rebuildCatalogOfferIds.

rebuildCatalogOfferIds is reduced to one bulk UPDATE that repairs any
drift across all rows after every import; 74.838 legacy rows were
repaired on the live database with this change.
2026-08-23 13:42:47 +02:00
openhands f24426c1fa Enable FurnitureData.json writes during furniture import
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m3s
- Change skipFurniDataWrite from true to false in both import routes
- Previously: FurnitureData.json entries were deferred/skipped during import
- Now: Entries are written immediately after each furniture item import
- Result: FurnitureData.json is updated directly, translations work again, offer_id fix preserves correctly set values
2026-08-22 21:12:06 +02:00
openhands 85b5792d40 feat: RCON API transport, full furnidata translation with LibreTranslate fallback, remove organize feature, bump per-page limit to 500
CI / check (push) Failing after 7s
CI / release (push) Skipped
CI / deploy (push) Skipped
- Add EMULATOR_MODE=api option with HTTP transport mirroring RCON payload
- buildLocalizedFurniDataFiles now falls back to LibreTranslate for customs (incl. pl/ru/ar/ja)
- Remove Organiseer import button from studio and Reorganize Catalog from import page
- Delete organize API route and PUT handler; remove organizeCatalogAll from catalog-repair.ts
- Increase imported-furni list perPage from 50 to 500
2026-08-22 14:28:06 +02:00
openhands 1d8672ccc5 perf: race furniture asset download candidates instead of trying sequentially
CI / check (push) Successful in 47s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m7s
tryDownloadCandidates now fires every candidate URL concurrently and keeps
the first valid response, removing the old 15s×retry sequential waits on
slow/unreachable sources that made import speed uneven. Batch concurrency
raised 8 -> 12 to absorb the now-faster downloads.
2026-08-22 13:38:00 +02:00
openhands ac7c427c3d feat: synthesize size 32 (catalog icon) frame for all furniture .nitro bundles
CI / check (push) Successful in 35s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m18s
AddSize32ToBundle downscales the largest existing sprite (usually size 64)
to generate a 32 visualization, so every bundle — including the
source-provided gamedata furniture — carries a 32 frame without needing the
original SWF. AddSize32AllNitros rewrites every existing .nitro across all
nitro directories (incl. /var/www/Gamedata/bundled/furniture) and is
idempotent (bundles that already have 32 are skipped). Expose it via a Studio
button and the background admin endpoint POST /api/admin/import/furni/add-size32.
2026-08-22 13:31:50 +02:00
openhands 6843af235e perf: speed up batch furniture import
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 57s
- Run batch imports with bounded concurrency (IMPORT_BATCH_CONCURRENCY = 8)
  instead of fully sequentially, parallelizing network downloads and DB writes.
- Collect FurnitureData.json entries and write the whole file once per batch
  (appendFurniEntriesBulk) instead of rewriting it on every single item.

Catalog id allocation stays serialized and FurnitureData writes remain
lock-guarded, so concurrent imports are safe.
2026-08-22 12:40:43 +02:00
openhands bb7ec3db02 feat: add automatic catalog organization for all imported furniture
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 53s
Add a fully automatic "Organize all" action in the Studio that organizes
the entire database into catalog pages:

- Create a dedicated sub-page per furniture line (e.g. weebz, habbox) from
  FurnitureData.json, falling back to the auto-detected category.
- Add missing purchasable items to the catalog on their line/category page.
- Re-home and re-price existing catalog entries onto their correct page.
- Pages are created automatically when missing; no manual selection needed.

Includes the organizeCatalogAll service, a POST /api/admin/import/furni/organize
endpoint, and the Studio button.
2026-08-22 11:27:22 +02:00
openhands 0b0cf4f37f feat: Auto-fix cost_credits <= 0 to 3 on every furniture import
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 44s
- Extended fixDatabaseConsistencyAfterImport() to also set cost_credits = 3 where <= 0
- Integrated into both single and batch import routes
- API responses now include costCreditsFixed count

Ensures 100% of catalog_items have cost_credits > 0 after import
- Typecheck, lint, tests all pass
- Pushed to GitLab
2026-08-21 21:41:54 +02:00
openhands 86f3d82c5d feat: Add automatic database consistency fix to furniture imports
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 55s
- Added fixDatabaseConsistencyAfterImport() function in furni-import.ts
  * Fills empty catalog_name from items_base.public_name
  * Sets have_offer = '1' where it was '0'
  * Returns counts of fixes applied

- Integrated fix into import flows:
  * src/app/api/admin/import/furni/route.ts (single & batch POST)
  * src/app/api/admin/import/furni/batch/route.ts (SSE batch POST)

- API responses now include:
  * catalogNameFixed: number of catalog names filled
  * haveOfferFixed: number of have_offer values fixed

- Ensures 100% catalog_name coverage and have_offer=1 after every import
- Typecheck, lint, and all 827 tests pass
2026-08-21 21:31:39 +02:00
openhands 8bb339cc49 feat: auto-translate furnidata per import (nl/en/de/fr/es/tr/it)
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s
Generate localized FurnitureData_<lang>.json files from the master
FurnitureData.json + official Habbo hotel translations. Fetches per-hotel
furnidata with in-memory cache (6h TTL), maps by classname (* variant
aware), and overrides name/description where a translation exists.

Full rebuild after every batch/batch-regen/clone import and as admin
GET ?action=build-languages; single imports patch incrementally via
patchLocalizedFurniDataEntries. Failures are best-effort and never fail
the import itself. Files are written to every configured gamedata write
path (primary + mirrors) so /gamedata/config/FurnitureData_<lang>.json
is available for per-language Nitro clients.

New service: src/lib/services/furni-data-i18n.ts with
buildLocalizedFurniDataFiles, patchLocalizedFurniDataEntries,
FURNIDATA_LANGUAGES (nl/en/de/fr/es/tr/it) and applyTranslationsForTest.
2026-08-21 14:16:37 +02:00
openhands 984b5bf793 feat: auto-repair sprite_id drift after every import
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s
The emulator sends items_base.sprite_id to the client and Nitro resolves
the furniture by looking up that id in FurnitureData.json. Legacy rows
where sprite_id drifted from the id made the client render a completely
different item (e.g. a wired or custom asset instead of the purchased
furniture).

Add verifyAndFixSpriteIds() which repairs any row whose sprite_id no
longer matches its id while the local furnidata carries the item under
that id, and run it after every import path (single, batch, batch-regen,
clone) next to the offer_id rebuild.
2026-08-21 14:02:42 +02:00
openhands 4b7cb519df fix: furniture interaction detection and automatic catalog offer_id rebuild
Interaction detection:
- Trust SWF-derived sit/lay/stand flags only when the logic XML actually
  contains action data (new hasActions metadata); otherwise fall back to
  keyword detection so custom furni without <action> nodes are still
  classified correctly
- Add French/Dutch/German/Spanish/Italian keywords (chaise, banquette,
  stoel, silla, sedia, stuhl, tafel, mesa, ...) to sit/lay/stand detection
  with token-boundary matching to avoid false positives like bedside_table
- Unify interaction_modes_count priority: mechanic fixed modes, then raw
  animation state count, then sit/lay fallback, then keyword default
- Detect mechanic type even when real flags are not used

Catalog integrity:
- Skip duplicate catalog_items inserts in clone and upload imports
- Re-check live catalog rows before applying generated repair SQL
- Add rebuildCatalogOfferIds() which rebuilds every catalog_items.offer_id
  from the local FurnitureData.json (matched by entry id, then classname)
  and run it after every import path (single, batch, batch-regen, clone)
2026-08-21 13:39:21 +02:00
openhands 652d331402 Add live furnidata reload without hotel reload and notImported status filter
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 57s
- Add /api/admin/import/furni?action=live-reconcile POST endpoint that reconciles FurnitureData.json with items_base without triggering RCON hotel reload
- Add 'notImported' status filter in studio to show all non-imported furniture items
- Useful for verifying imports and seeing what's missing after furniture import
2026-08-20 16:58:26 +02:00