Commit Graph
1081 Commits
Author SHA1 Message Date
openhands e6dd22a4de Update all packages to the latest versions for Epicnextcms
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 42s
2026-08-22 14:41:01 +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 5668493485 chore: update dependencies to latest versions within version ranges
CI / check (push) Failing after 7s
CI / release (push) Skipped
CI / deploy (push) Skipped
Run pnpm update; bumped 21 packages, removed 20. App still typechecks and
passes Biome.
2026-08-22 13:42:07 +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 2996ae3ab0 feat: include size 32 (catalog icon) sprites in nitro bundles
CI / check (push) Successful in 32s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m1s
The SWF-to-Nitro converter previously dropped the size 32 visualization
and any sprite image whose name contained '_32_', so bundles lacked the
small/catalog render size. Keep them so each furniture bundle renders
correctly at every scale the client requests.

- xml-processor: stop skipping visualization size === 32
- index.ts: stop excluding '_32_' sprite assets/images from the sheet
2026-08-22 12:49:13 +02:00
openhands 53db4a858b perf: download icon and swf concurrently during furni import
CI / check (push) Successful in 33s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
Run the independent icon and swf downloads in parallel via Promise.all
instead of sequentially. The nitro fallback still runs after the swf check
since it depends on the swf result.

Combined with batch concurrency and the single FurnitureData write, this
further cuts per-item import time (roughly halves the download phase).
2026-08-22 12:44:18 +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 488f40919d fix: only reorganize items already in the Imported Furniture section
CI / check (push) Successful in 41s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m15s
organizeCatalogAll no longer pulls every items_base row into the catalog.
It now touches only items whose catalog entry lives on a page under the
Imported Furniture parent (re-homing/re-pricing onto line/category
sub-pages). Items are never newly added. Button renamed to 'Organiseer
import'.
2026-08-22 11:48:47 +02:00
openhands eb885c044f fix: truncate furniture-line slug to fit caption_save varchar(25)
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m7s
Line pages used caption_save 'imp_line_<slug>' which could exceed the
25-char column limit (e.g. imp_line_pixel_collectible = 26 chars),
causing the INSERT to fail. Cap the slug at 16 chars.
2026-08-22 11:36:09 +02:00
openhands b109ca6f32 fix: only create furniture-line pages for lines with enough items
CI / check (push) Successful in 36s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m5s
Add a LINE_PAGE_MIN_ITEMS threshold so small one-off lines collapse
onto the category page instead of creating hundreds of tiny pages.
2026-08-22 11:32:13 +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 b5c8a29956 docs: add furniture import auto-translation guide
CI / check (push) Successful in 37s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m8s
2026-08-21 20:25:52 +02:00
openhands 8174ffa6af feat: add studio translation to all 13 admin nav language files
CI / check (push) Successful in 38s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m2s
2026-08-21 20:22:16 +02:00
openhands d156ad9905 chore: add new scripts to knip config
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 59s
2026-08-21 20:10:00 +02:00
openhands 3d832cceff scripts: fix translate call for furni18n
CI / check (push) Failing after 28s
CI / release (push) Skipped
CI / deploy (push) Skipped
2026-08-21 20:06:27 +02:00
openhands f2a023efb3 scripts: fix build/translate calls for furni18n 2026-08-21 20:06:02 +02:00
openhands e66b2c1a5a scripts: add full build/translate scripts for furnidata i18n 2026-08-21 20:04:53 +02:00
openhands 2339485e9a feat(i18n): add Portuguese, Finnish, Polish, Russian, Arabic, Japanese
CI / check (push) Successful in 33s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s
Extend FURNIDATA_LANGUAGES from 8 to 13 (nl/en/de/fr/es/tr/it/pt plus
fi/pl/ru/ar/ja). Official Habbo translations for fi (habbo.fi),
pt (habbo.com.br) use hotel gamedata; pl/ru/ar/ja fall back to
LibreTranslate en->xx. Docker LibreTranslate now loads 13 language
models (en,nl,de,fr,es,tr,it,pt,fi,pl,ru,ar,ja).
2026-08-21 14:47:45 +02:00
openhands 01a3ba6e39 feat(i18n): LibreTranslate fallback for customs (free, self-hosted)
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m2s
Use official Habbo translations where available; fall back to
self-hosted LibreTranslate (http://127.0.0.1:5000, host-network, 7
languages) for custom furni with no official translation. Patch path
(single imports) translates name/description via LibreTranslate
(en -> nl/de/fr/es/tr/it) with persistent cache
(.translations_libre_cache.json) and caches 6h for official maps.
Full rebuilds stay official-only to avoid 500k+ API calls; customs are
translated incrementally per import. LibreTranslate URL configurable via
site setting libretranslate_url. Docker: host-network fix for DNS.
2026-08-21 14:32:52 +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 92b0ba3b18 fix: make notImported studio filter work independently of import status
CI / check (push) Successful in 27s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
2026-08-21 13:41:06 +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
openhands 7ad78db0ea Fix: Ensure Imported Furniture catalog page is created during import
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
The getOrCreateImportedParentPage() function was skipping database checks due to an early return cache check. This caused the 'imported_furni' catalog page to not be created when missing, preventing imported furniture from appearing in the catalog.

Removed the cache early return so the function always queries the DB and creates the page if needed.
2026-08-20 16:10:14 +02:00
openhands 01369d8943 feat: add Habboon, Leet and Hubbly furni import sources
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
Add verified retro-hotel sources to the studio furni clone list. All
endpoints (furnidata JSON, .nitro bundles, icons, SWF) were probed and
verified reachable (HTTP 200), and Leet/Hubbly nitro bundles parse with
parseNitroBundle.

Also allow source-specific SWF downloads without a revision path segment
(/hof_furni/{classname}.swf), which Leet and Habboon use.
2026-08-20 15:38:50 +02:00
openhands 56bfa164a1 feat: set interaction_type at import and track cross-section normalizations
CI / check (push) Successful in 30s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m2s
Newly imported items with a generic .nitro logicType stayed on interaction_type
'default' until the post-import verification sweep ran. Fall back to the same
auto-detected type used by the sweep (classname mechanic + keyword + real flags)
so imports carry the correct interaction immediately; updates keep their
existing emulator handler types.

Also count cross-section id alignments under a separate normalizedIds field in
reconcileFurniDataWithItemsBase so fixedIds keeps its original meaning.
2026-08-20 15:09:18 +02:00
openhands b811086de6 fix: normalize cross-section duplicate ids in furnidata reconcile
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m6s
Classnames listed in both roomitemtypes and wallitemtypes keep a canonical copy
with the correct id/offerid while the stray wall copy can carry a legacy wrong
id. reconcileFurniDataWithItemsBase now normalizes those stray copies to the
offerid whenever the offerid maps to an items_base row whose classname matches
exactly, so id === offerid === sprite id holds for every uniquely-mapped
classname. The sandbox rehearsal asserts this invariant and the live database
has been reconciled (76 ids fixed, 0 remaining).
2026-08-20 14:57:40 +02:00
openhands 3a63152ee3 fix: reorder catalog missing-entry scan after structural repair
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 55s
runCatalogAudit computed missingCatalogEntries from the pre-repair snapshot,
so generated catalog SQL could reference sprite ids deleted by the
duplicate-classname merge and create new orphaned catalog_items rows. Re-derive
entries after repairStructure and add a defensive guard in generateCatalogSql
that skips entries whose item id no longer exists in items_base.

Also fix the catalog_pages INSERT template (18 columns vs 17 values) which made
page creation always fail with 'Column count doesn't match value count'.

Add a sandbox-guarded live repair rehearsal test covering the full pipeline.
2026-08-20 13:09:50 +02:00
openhands 60b6d0856c test: add live DB integration audit for furni import ID consistency
CI / check (push) Failing after 24s
CI / deploy (push) Skipped
CI / release (push) Skipped
2026-08-20 12:35:17 +02:00
openhands 29958d0f8c fix(ci): drop invalid RENOVATE_CONFIG_FILE inline JSON
CI / check (push) Successful in 32s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
RENOVATE_CONFIG_FILE must point to a config file on disk; the inline
JSON string made Renovate abort with 'Custom config file ... must exist'.
The repo-root renovate.json (which already extends config:recommended)
is picked up automatically, so the env var is not needed.
2026-08-20 11:51:16 +02:00
openhands 6021a91ef7 fix: harden furni import pipeline for production
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 57s
- importSingleFurni: actually update an existing item instead of failing on a primary key INSERT collision; refuse to reassign a spriteId owned by a different classname
- reconcileFurniDataWithItemsBase: also sync each entry's offerid to the DB sprite id, not just the id
- Move the full-table interaction_modes_count verification out of the per-item import hot path and run it once per batch/single import
- clone-import: apply the auto-detected interaction_type (was hardcoded 'default'), set FurnitureData offerid and catalog_items.offer_id to the new local sprite id (was the source hotel's id / -1)
- clone batch route: run the same post-import reconcile/verify/ownership/RCON consolidation as the furni batch route
- upload-import: set offer_id to the allocated id in both the direct insert and the generated SQL migration (was -1)
- generateCatalogSql: use the classname as catalog_name and the item id as offer_id so rows match the app-managed import convention
- stats + missing-nitro endpoints: match catalog membership via item_ids instead of the catalog_name join, so translated display names no longer break counts
- deleteImportedItem/rollback: delete catalog rows by the canonical item_ids link only
- classifyFurni: wall items always classify as 'walls' before prefix rules (rare_/val_/xmas_) can misfile them
2026-08-20 11:48:51 +02:00
openhands 2b9a015afb feat: add manual 'verify & fix all interactions' admin tool
CI / check (push) Successful in 26s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s
New POST /api/admin/import/furni/verify re-runs the full interaction
verification over items_base at any time, plus a Tools dropdown entry
in the furni import admin. It corrects interaction_type,
interaction_modes_count and allow_sit/lay/walk against real furniture
data (furnidata flags + .nitro animation states); items without real
data are skipped and existing emulator handler types are preserved.
2026-08-19 21:11:38 +02:00
openhands 0b1d3b24c2 feat: verify fixes allow_sit/lay/walk and interaction_type too
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 55s
verifyAndFixInteractionModesCount now corrects the full interaction
profile against real furniture data, not just the modes count:
- allow_sit/allow_lay/allow_walk set from real furnidata flags
- interaction_type filled in when the DB still has the generic
  'default' (existing emulator handler types are never overwritten)
- allow_sit/lay/walk of 2 (emulator-special: tents, walk-through)
  is preserved

Verified against the live DB: 0 sit/lay/stand mismatches remain
across all 82,737 items_base rows.
2026-08-19 20:48:31 +02:00
openhands 3fa192a108 feat: auto interaction detection from real furniture data
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m17s
Replace classname/name keyword guessing with real data so sit/lay/stand
has zero false positives:
- autoDetectInteraction() now accepts real flags (cansiton/canlayon/
  canstandon), logicType, and animation-state count; real data wins and
  keywords are only a fallback when no real data exists.
- New furni-real-interaction helper reads the local FurnitureData.json
  (highest-revision entries win; a true flag in any duplicate is kept)
  and falls back to the official Habbo furnidata.
- interaction_modes_count now uses emulator conventions: dice=6,
  gate/teleport=2, roller=1, generic multistate = animation-state count,
  chairs/beds=1, plain items=0.
- verifyAndFixInteractionModesCount only touches items with real data
  and skips everything else (no keyword overwrites).
- parseNitroBundle falls back to gunzip for gzip-compressed .nitro files.
- Wired through furni-import, upload-import, clone-import, and the nitro
  editor auto-detect button.
2026-08-19 20:28:24 +02:00
openhands 121dda7249 fix: clone sources blocked by content-type check and TLS fingerprint
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m0s
- fetchSourceFurnidata now parses JSON regardless of content-type,
  so GitHub raw mirrors (Kyzegs, sphynxkitten) that serve JSON as
  text/plain work again instead of forcing a FlareSolverr round-trip.
- Add curl subprocess fallback (curl-fetch.ts) for CDNs that block
  Node's fetch by TLS fingerprint (Leet.city) — used for furnidata,
  nitro bundle and icon downloads before giving up.
- Merge verified default clone source presets with stored user sources
  so the admin always offers many working sources.
2026-08-19 19:39:32 +02:00
openhands 7911a25ced feat: verify and fix interaction_modes_count on every import
CI / check (push) Successful in 41s
CI / release (push) Skipped
CI / deploy (push) Successful in 46s
- Added verifyAndFixInteractionModesCount() to scan all items_base entries
- Auto-detects correct interaction_modes_count from classname/name
- Fixes mismatched values during furniture import
- Reports fixed/checked count in warnings
2026-08-18 22:44:15 +02:00
openhands dee843106f feat: add auto furniture interaction detection
CI / check (push) Successful in 25s
CI / release (push) Skipped
CI / deploy (push) Successful in 59s
- New auto-interaction.ts: detects canSit/canLay/canStand from classname/name keywords
- Maps keywords to interaction types (bench, chair, bed, table, etc.)
- Returns clickLimit and interactionModesCount for proper click/interaction limits
- Nitro editor: added auto-detect button with preview of detected settings
- furni-import.ts: auto-sets interaction_modes_count during import
- upload-import.ts: auto-detects for direct insert and SQL migrations
- clone-import.ts: auto-detects when cloning from other hotels
2026-08-18 22:33:40 +02:00
openhands 0b4fc4559e chore: update dependencies and lockfile to latest stable versions
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 49s
2026-08-18 21:02:57 +02:00
openhands 635abfbc9f Surface post-import verification results in the Studio
CI / check (push) Successful in 45s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m17s
After a batch import the progress panel now shows a verification
summary (offer_id fixed, furnidata ids fixed / missing / conflicts,
nitros and icons synced, folders chowned). Single imports include the
key counts in the success toast.
2026-08-18 20:54:16 +02:00
openhands b4968a9967 Reconcile FurnitureData.json with items_base after import
CI / check (push) Successful in 45s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m16s
After every single import, batch import and batch-regen, cross-check all
items_base rows against the local FurnitureData.json: entries whose
spriteId drifted are corrected to the DB id, and missing entries plus
real id conflicts are reported in the API/SSE response. Entries that are
missing entirely are counted (rebuilding them needs SWF/nitro metadata).
2026-08-18 20:43:41 +02:00
openhands b4021f6b42 Backfill icons too in the Gamedata bundle sync
CI / check (push) Successful in 38s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m28s
Extend the post-import backfill to also copy missing _icon.png files
into /var/www/Gamedata/icons (in addition to nitros into
bundled/furniture) so all imported furniture shows an icon in-game.
Report copied nitros and icons separately in the API/SSE responses.
2026-08-18 20:35:48 +02:00
openhands bcd24bfca4 Backfill missing nitros into the Gamedata bundle on import
CI / check (push) Successful in 43s
CI / release (push) Skipped
CI / deploy (push) Failing after 1m19s
After each single import, batch import and batch-regen, copy every
.nitro file that is missing from /var/www/Gamedata/bundled/furniture so
the emulator can render all imported furniture even when the mirror write
was skipped. Reports the copied files in the API/SSE response.
2026-08-18 20:29:30 +02:00
openhands 99e77d9872 Fix ownership reconcile on the batch import route
CI / check (push) Successful in 54s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m27s
The Studio's batch import uses /api/admin/import/furni/batch, which never
ran the offer_id reconciliation or the www-data ownership fix (only the
single/legacy-batch route did). Run both after the batch finishes and
report the counts in the batch_complete SSE event.
2026-08-18 20:01:18 +02:00
openhands 18825115a4 Auto-fix furni asset ownership after import
CI / check (push) Successful in 44s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m17s
After each single or batch import, chown the swf/icon/nitro asset
directories and the FurnitureData.json folders to www-data:www-data so
nginx and the emulator can read newly written files. Best-effort and
non-blocking; the API response reports which folders were fixed.
2026-08-18 19:52:32 +02:00
openhands c95ad4a37f Reconcile offer_id after every import
CI / check (push) Successful in 40s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m12s
After each single or batch import, walk all catalog items under the
Imported Furniture tree and set offer_id to the furnidata sprite id,
repairing any stale values (e.g. legacy -1 rows). Reports how many
rows were fixed in the API response.
2026-08-18 19:40:17 +02:00
openhands 305a0c42ff Derive catalog offer_id from furnidata sprite id
CI / check (push) Successful in 44s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m19s
Import used a hardcoded offer_id of -1, while the matching
FurnitureData.json entry already carries offerid = spriteId.
Set catalog_items.offer_id to the sprite id on insert and update so
purchases resolve to the correct furni offer.
2026-08-18 19:34:34 +02:00