54 Commits

Author SHA1 Message Date
nendo
edb5d15420 Fix save-sync hash drift, archival save leak, and dedupe scoping
Cleanup pass on save-sync addressing three independent failure modes
that interact in production data: content_hash drift between client
and server, null-slot archival saves leaking into sync flows, and
content-hash dedupe collapsing legitimately-distinct slots.

Bug fixes
- compute_content_hash dispatched on zipfile.is_zipfile(relative_path),
  which silently returned False whenever the process's CWD wasn't
  ASSETS_BASE_PATH. Every zip save fell through to the raw-MD5 branch,
  persisting hashes that disagreed with clients computing the intended
  per-entry zip-hash. Resolve to a full path before the dispatch.
- _build_negotiate_plan, sync_push_pull_task, and sync_watcher all
  treated null-slot saves as sync-eligible. Null-slot saves represent
  web-UI / archival uploads; including them in negotiate plans matched
  them against device pushes by filename and overwrote archival data.
  Filter null-slot saves at all three call sites.
- get_save_by_content_hash matched on (rom_id, user_id, content_hash)
  only, so identical bytes uploaded to different slots collapsed into
  one record. Scope the lookup by slot when provided so clone-save-
  to-new-slot creates a distinct row per slot.
- get_save_by_filename matched on (rom_id, user_id, file_name) only.
  When two uploads to different slots happened in the same wall-clock
  second (the datetime tag is per-second), the second upload UPDATED
  the first record's slot instead of creating a distinct row. Scope
  the filename lookup by slot too.

One-shot recovery
- New recompute_save_content_hashes manual task walks every Save row,
  recomputes via the fixed dispatch, and updates rows whose values
  differ. Idempotent; safe to re-run.
- Backend startup runs a COUNT(content_hash IS NULL) query and, if
  any rows exist, enqueues the recompute task on the low-priority
  RQ queue. The API process moves on; the worker handles the
  recompute out-of-band. Subsequent restarts find zero NULL hashes
  and skip. Admins can also trigger the task manually.

Test infrastructure
- Added tests/_zipfile_shim.reload_zipfile() mirroring the pattern
  from utils/zip_cache.py for the same zipfile-inflate64 + CPython
  3.13.5 incompatibility. Test fixtures that build ZIPs call it
  immediately before opening the archive.
2026-05-29 17:00:01 +09:00
copilot-swe-agent[bot]
af870e0278 fix: replace deprecated job.get_id() with job.id for rq >= 2.7.0 compatibility
Agent-Logs-Url: https://github.com/rommapp/romm/sessions/4326c200-57f5-4a27-96e8-570df82968e5

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-04-29 19:31:13 +00:00
Georges-Antoine Assi
f2e8e337b2 Merge branch 'master' into save-sync 2026-04-05 21:47:53 -04:00
Georges-Antoine Assi
6cd213fc2b changes from bot review 2026-04-03 14:26:00 -04:00
copilot-swe-agent[bot]
789f8d4e31 fix: handle NoSuchJobError in get_tasks_status when job TTL expires
Agent-Logs-Url: https://github.com/rommapp/romm/sessions/bc0915c3-2d5f-4ac1-ab89-24942eeac825

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-04-03 17:22:58 +00:00
Georges-Antoine Assi
f107dc2752 changes from bot rview 2026-03-22 17:17:14 -04:00
Georges-Antoine Assi
997e2c44aa start pre-4.8 cleanup 2026-03-12 23:02:12 -04:00
Georges-Antoine Assi
2dd3c18562 fix tunk check 2026-03-10 16:21:40 -04:00
Georges-Antoine Assi
8f8ef1f700 some changes from review 2026-03-10 16:13:21 -04:00
copilot-swe-agent[bot]
f938e627b4 Move cleanup-all missing ROMs to background task to prevent browser hang
Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
2026-03-10 02:25:58 +00:00
Georges-Antoine Assi
b2dea510c4 [ROMM-2628] Fix desirialize job func_name 2025-11-10 17:57:28 -05:00
Georges-Antoine Assi
8c06d5de08 mark created_at as nulalble 2025-10-27 14:41:08 -04:00
Georges-Antoine Assi
9b636a9d0c don't fail on old tasks 2025-10-27 11:07:19 -04:00
Georges-Antoine Assi
87cf48e7ef return generic for old task types 2025-10-27 10:49:46 -04:00
Georges-Antoine Assi
170b3d04b7 self cleanup from review 2025-10-16 15:17:14 -04:00
Georges-Antoine Assi
c43c1041a3 fix tests 2025-10-16 14:20:38 -04:00
Georges-Antoine Assi
949466e642 restyle progress bar scan 2025-10-16 08:54:44 -04:00
Georges-Antoine Assi
4e9ab9096b more ui work on scan resutsl 2025-10-15 21:25:50 -04:00
Georges-Antoine Assi
4cfd622a89 finally finish backend state 2025-10-15 16:31:25 -04:00
Georges-Antoine Assi
6785be06a9 cleanup code massively 2025-10-15 16:21:17 -04:00
Georges-Antoine Assi
e336fc3c5e restyle by bo 2025-10-15 10:59:02 -04:00
Georges-Antoine Assi
ff15cfcee6 support states for more types of tasks 2025-10-09 19:20:19 -04:00
Georges-Antoine Assi
d37547fc56 show scan progress on page 2025-10-02 10:50:33 -04:00
Georges-Antoine Assi
4885316714 also fetch completed tasks 2025-10-01 10:59:49 -04:00
Georges-Antoine Assi
8fca3fbbfe get from running workers 2025-10-01 10:50:17 -04:00
Georges-Antoine Assi
4983f0be73 add ui for running tasks 2025-09-30 23:12:45 -04:00
Michael Manganiello
e4e3928d1b misc: Apply import sorting 2025-09-04 11:17:00 -03:00
Georges-Antoine Assi
bf42faf578 fix loading and converting images 2025-08-27 23:31:29 -04:00
Georges-Antoine Assi
586ce0ef30 Craete image to webp task 2025-08-27 22:12:12 -04:00
Georges-Antoine Assi
585ad63349 use correct key for job timeout 2025-08-26 22:22:36 -04:00
Georges-Antoine Assi
9bb586b288 set timeouts 2025-08-26 21:09:13 -04:00
Georges-Antoine Assi
8061db40b2 fix tests and cleanup 2025-08-02 17:55:43 -04:00
Georges-Antoine Assi
0acc9de6e6 add endpoint to fetch task result 2025-08-02 15:25:44 -04:00
Georges-Antoine Assi
70fe56296b Replace MessageResponse with spcific responses 2025-08-02 13:42:35 -04:00
Georges-Antoine Assi
d8af2f8956 fix review comments 2025-08-02 12:56:50 -04:00
Georges-Antoine Assi
19c5b5e428 refactor tasks endpoint 2025-08-02 10:11:00 -04:00
zurdi
fb07df6576 Refactor task execution to use low priority queue and improve loading state in Home.vue 2025-07-31 09:58:12 +00:00
zurdi
7aeccb5468 feat: Added clean resources task + revamped the whole task system 2025-07-22 16:31:36 +00:00
Georges-Antoine Assi
7d572ac0bf Merge branch 'master' into romm-403 2025-05-15 21:48:41 -04:00
Michael Manganiello
70825830c4 misc: Set prefix and tags to API routers
Improve OpenAPI documentation by setting tags to each API router. Also,
set a prefix to each router to group the endpoints by their
functionality.
2025-02-09 11:31:13 -03:00
Georges-Antoine Assi
0c95eff2e1 fetch and parse launchbox metadata.zip 2025-01-18 10:51:30 -05:00
Michael Manganiello
865370ec13 misc: Move auth constants to separate file
This simplifies avoiding circular imports when trying to use auth
handlers.
2025-01-08 22:16:31 -03:00
Michael Manganiello
beeb9f0c31 misc: Create enum for authorization scopes
Instead of using just strings, this change converts the scopes to a
`StrEnum`, to be compatible with places where a string is expected. This
avoids typos when using these scopes, simplifies searching for usages,
and improves type hints.

An extra change was the fix to the Firmware download endpoint, which
wasn't respecting the `DISABLE_DOWNLOAD_ENDPOINT_AUTH` flag.
2024-10-18 23:57:42 -03:00
Michael Manganiello
8abbae4c02 misc: Make backend handle URLs with trailing slash
According to multiple FastAPI discussions [1], FastAPI only includes a
built-in mechanism to redirect requests including a trailing slash, to
its variation without slash, using a `307` status code.

This can be an issue when certain clients do not send the same headers
on the redirected request.

This change adds a custom FastAPI `APIRouter`, that registers both route
path variations (with and without trailing slash), while only marking
the path without slash for being included in the OpenAPI schema.

[1] https://github.com/fastapi/fastapi/discussions/7298
2024-08-07 00:22:21 -03:00
Georges-Antoine Assi
880345f20c ruff-only pre-commit 2024-05-18 12:05:57 -04:00
Georges-Antoine Assi
c47167d98c remove mame task for tasks endpoint 2024-05-08 13:45:11 -04:00
Georges-Antoine Assi
4174b9753e remove mame from scheduled tasks and embed fixture 2024-03-26 16:49:02 -04:00
Georges-Antoine Assi
af56074b72 fix endpoint running tests manually 2024-03-12 10:06:55 -04:00
Zurdi
42065aec7c backend refactor as RESTful 2024-01-15 13:34:18 +01:00
Zurdi
1d2c9e7d05 standarized GET endpoints for roms and platforms 2024-01-14 02:34:37 +01:00