Commit Graph
1062 Commits
Author SHA1 Message Date
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
openhands 7257a7b0f4 Fix duplicate catalog pages from import race condition
CI / check (push) Failing after 49s
CI / release (push) Skipped
CI / deploy (push) Skipped
A concurrent import could create the same catalog sub-page twice
(getOrCreateCategoryPage / getOrCreateImportedParentPage do a
SELECT-then-INSERT with no unique constraint). Deduplicate right after
insert by keeping the lowest-id page and removing the duplicate, while
never deleting a page that already received catalog items.
2026-08-18 19:30:28 +02:00
openhands 8a6c596727 Polish Studio visuals
CI / check (push) Successful in 48s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m27s
- Card-shaped loading skeletons with shimmer text lines
- Hover lift and accent shadow on furni cards
- Subtle dotted floor pattern behind previews and detail image
- Sticky action footer in the detail drawer
- Theme-aware slim scrollbars inside the admin panel
- Nicer empty state with icon tile
2026-08-18 19:22:32 +02:00
openhands f18735cf3e Make Studio catalog rail collapsible
CI / check (push) Successful in 46s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m29s
The catalog tree was decorative and always consumed sidebar width.
Add a toolbar toggle so admins can hide or show the catalog rail.
2026-08-18 19:13:34 +02:00
openhands 7c9602c5cd Add search, sorting, filters and list view to Studio
CI / check (push) Successful in 32s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m19s
- Add debounced live search with keyboard shortcuts (/ focus,
  Ctrl/Cmd+A select all, Esc clear selection)
- Add category filter and sort controls (name, classname, category,
  imported-first)
- Add grid/list view toggle with a compact list table
- Add regenerate .nitro action for missing-nitro items
- Show result count in the header and a missing-nitro shortcut chip
2026-08-18 19:05:54 +02:00
openhands 3b8bf74e35 Fix Studio card markup and improve furni browsing UX
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m16s
- Fix invalid nested button elements in furni grid cards that broke
  card borders, hover styles and selection rendering
- Fix stale-closure bug where switching furni source fetched from the
  previously selected source
- Add progress bar plus Cancel/Dismiss controls to batch imports
- Make the detail drawer an overlay on small screens
- Add clear-search and clear-selection actions in the toolbar
- Use pixelated image rendering and keyboard focus rings on cards
2026-08-18 18:49:53 +02:00
openhands f285a7cd98 Add performance optimizations and component refactors
CI / check (push) Successful in 34s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m23s
- Cache read-heavy public API routes via redisCache (leaderboard, values,
  shop, articles, photos, guilds, teams, staff, users, home, radio, badges)
- Add single-flight and bounded-memory cache layer with unit tests
- Parallelize independent DB queries on search, rares, shop, staff, polls
  and profile pages
- Push radio points leaderboard aggregation to SQL with a LIMIT
- Split studio-client and import-furni-client into focused modules
- Clean up next.config.ts
2026-08-17 22:02:21 +02:00
openhands 54f2bc5e0c Add clone source selection to Studio furni browser
CI / check (push) Successful in 32s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m16s
Allow the admin Studio to browse and import furniture from custom retro
hotel sources, not just official Habbo furnidata.

- GET /api/admin/import/furni?source=<id> lists a clone source's
  furnidata (via getCloneList) and returns a per-item iconUrl from the
  source's iconBaseUrl so previews render correctly
- Studio client gets a source selector dropdown (official Habbo plus all
  configured clone_sources) that resets the selection and reloads the
  list when switched
- Single and batch imports now send sourceId so SWF/nitro/icon assets
  are fetched from the selected hotel's CDN
- Preview images prefer the source iconUrl with the existing fallback
  chain; header shows the active source name
2026-08-15 15:43:51 +02:00
openhands 5b09179404 Add all-in-one Studio merging furni import and catalog management
CI / check (push) Successful in 33s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m1s
Add a full-viewport /admin/studio workspace that unifies the import and
catalog systems into a single automated flow:

- Furni library browser against official Habbo furnidata with search,
  type/status filters, live previews and pagination
- Catalog structure rail showing where imported furniture lands
- Detail drawer with automatic placement preview (category + price via
  classifyFurni/autoPriceFurni) and one-click import that downloads
  assets, converts SWF to nitro, writes items_base, updates
  FurnitureData.json and creates an auto-priced catalog entry
- Batch auto-import with SSE progress and RCON cache refresh
- Nitro editor integration and imported-item deletion

Extract pure auto-catalog helpers (CATEGORY_PAGE, CLASSNAME_RULES,
classifyFurni, autoPriceFurni) into a client-safe module shared by the
server pipeline and the Studio UI so the preview always matches what the
emulator import applies.
2026-08-15 15:34:07 +02:00
openhands e31f6d985c Add rollback/undo functionality for furniture imports
CI / check (push) Successful in 52s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m8s
- Added LogsFurniImports table to track import history with rollback support
- Implemented rollbackFurniImport() service function to revert imports:
  - Removes items from items_base, catalog_items, FurnitureData.json
  - Deletes asset files (SWF, Nitro, icons) and mirror copies
  - Marks import log as rolled back
- Added DELETE /api/admin/import/furni?importId=X endpoint
- Added dry-run support for import validation (?dryrun=1)
- Added updateExisting option to update existing catalog entries
- All TypeScript/Biome checks pass, tests pass (806 passed, 1 pre-existing skip)
2026-08-14 19:42:01 +02:00
openhands 7ef5038a9e Add updateExisting option to furniture import
CI / check (push) Successful in 1m14s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m15s
- Added updateExisting parameter to importSingleFurni and API routes
- When updateExisting=true, existing items are updated (catalog price/page) instead of failing
- Added catalogUpdated flag to ImportSingleResult
- Updates existing catalog entries (price, page) instead of skipping duplicates
2026-08-14 18:35:00 +02:00
openhands f89b8a6adf Fix FurnitureData.json spriteId conflict auto-repair
CI / check (push) Successful in 1m21s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m17s
- Added spriteId conflict resolution to repairFurniData(): keeps first classname per id, removes conflicting entries
- Returns new removedIdConflicts count in repair result
- Updated audit event type and client UI to display removedIdConflicts
- Updated catalog-audit.ts event type and client state type
- When 'Repair FurnitureData.json' is checked, it now fixes id conflicts automatically
2026-08-14 18:23:00 +02:00
openhands 3b6ebe7bdc Fix audit client: send checkFurniDataIds in request body
CI / check (push) Successful in 1m8s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m13s
- Added checkFurniDataIds to POST body so the 'Check FurnitureData.json for spriteId conflicts' checkbox actually works
- Added checkFurniDataIds to useCallback dependency array for correct React hook behavior
2026-08-14 18:06:24 +02:00
openhands a810fba0ae Increase vitest testTimeout to 10s for full-suite reliability
CI / check (push) Successful in 56s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m23s
- Prevents deploy-workflow-contract.test.ts timeout in full-suite runs
- Test runs in ~2s individually but hits 5s default under 30s+ import time
- 10s provides sufficient headroom under resource contention
2026-08-14 17:56:43 +02:00
openhands 27a3652a79 Improve terms checkbox accessibility and clarity
CI / check (push) Successful in 55s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m13s
- Added onKeyDown handler for keyboard accessibility (a11y)
- Added 'Required for account creation' note below checkbox
- Maintains existing onClick handler for mouse users
- All TypeScript and Biome checks pass
2026-08-14 17:21:35 +02:00
openhands 3d89e108f3 Fix terms acceptance enforcement in register
CI / check (push) Failing after 1m13s
CI / release (push) Skipped
CI / deploy (push) Skipped
- Add termsAccepted to raw form data object
- Check if terms were accepted before DB insert
- Return error if terms not accepted
- All TypeScript and Biome checks pass
2026-08-14 17:10:40 +02:00
openhands 0f35bc8529 Add hCaptcha support alongside Turnstile and reCAPTCHA
CI / check (push) Successful in 1m9s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m6s
- Add hcaptcha_site_key and hcaptcha to captcha_provider options in admin settings
- Update captcha.ts server-side verification for hCaptcha (new endpoint + secret key)
- Add hCaptcha widget rendering in register-form.tsx
- All TypeScript and Biome checks pass
2026-08-14 17:04:34 +02:00
openhands 1bca9657fa Remove age verification checkboxes, keep Turnstile CAPTCHA
CI / check (push) Successful in 54s
CI / release (push) Skipped
CI / deploy (push) Successful in 2m16s
- Remove age verification (18+) checkboxes from register form
- Terms checkbox remains
- Turnstile CAPTCHA stays further down in form
- All TypeScript and biome checks pass
2026-08-14 16:57:17 +02:00
openhands 361ff56d65 Fix register form: checkboxes side by side with a11y support, improved text visibility
CI / check (push) Successful in 41s
CI / release (push) Skipped
CI / deploy (push) Failing after 1m50s
- Terms and age verification checkboxes now side by side
- Added onKeyDown handlers for keyboard navigation (a11y)
- Improved text clarity with explicit var(--color-text-readable) usage
- All TypeScript and biome checks pass
2026-08-14 16:44:22 +02:00
openhands e76c530e4f Fix TypeScript errors and implement furniture import ID integrity with 18+ age verification
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m2s
- Add termsAccepted and ageVerified columns to User table
- Update register schema with new boolean fields
- Fix register form age verification checkbox (th -> t)
- Fix furni-import spriteId declaration order
- Fix batch route variable naming (id -> spriteId)
- Fix catalog-audit import path and ensure correct types
- Hardened import with per-item id conflict checks
- Added audit option for FurnitureData.json spriteId conflicts
- Updated tagline to include Leeftijdsvereiste: 18+
2026-08-14 16:37:00 +02:00