Commit Graph

3891 Commits

Author SHA1 Message Date
Zurdi
dd3f9d0496 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-20 18:33:54 +02:00
copilot-swe-agent[bot]
bd0bc65e92 fix: allow ROM deletion when file is missing
Co-authored-by: zurdi15 <34356590+zurdi15@users.noreply.github.com>
2026-06-20 16:23:24 +00:00
Zurdi
cce2587024 Merge pull request #3557 from rommapp/feat/logs-view
feat: real-time backend logs view
2026-06-20 17:54:23 +02:00
zurdi
78cac11913 feat: add DISABLE_LOGS_VIEWER configuration and implement checks in logs endpoints and frontend 2026-06-20 15:48:58 +00:00
zurdi
78eef900b9 feat: update logs endpoint to require 'logs.read' scope and adjust related authorization checks 2026-06-20 09:55:10 +00:00
Georges-Antoine Assi
b8450add5f Validate test database name before CREATE DATABASE
Addresses review feedback: `db_name` is interpolated into CREATE DATABASE
statements via f-strings (identifiers can't be bind parameters), so validate
it up-front against a plain-identifier allowlist ([A-Za-z0-9_]+) and refuse
anything containing quoting/other characters, rather than rely on quoting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 21:38:50 -04:00
Georges-Antoine Assi
26cf4b36f8 Scope test-user grant to the romm_test namespace
Addresses review feedback: granting ALL PRIVILEGES on *.* is overly broad,
especially against a shared DB instance. A database-level grant on the
`romm\_test%` wildcard pattern still lets the user CREATE the per-worker
databases (romm_test_gw0, ...) needed by pytest-xdist, while confining it to
that namespace — verified that out-of-namespace CREATE DATABASE is denied.

PostgreSQL needs no equivalent change: its CI service user (POSTGRES_USER)
is the container superuser.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 21:34:46 -04:00
Georges-Antoine Assi
02815ec403 Run backend tests in parallel with pytest-xdist
Add pytest-xdist and run the backend test suite across multiple workers
(`-n 4` in CI). Each worker gets its own database so the autouse
`clear_database` fixture can't wipe rows another worker is mid-test with:

- Rootdir `backend/conftest.py` sets a per-worker `DB_NAME`
  (`romm_test_gw0`, ...) before any app module is imported, so each
  worker's engine binds to its own database.
- `tests/conftest.py` creates the per-worker database on demand (mariadb/
  mysql and postgresql paths) just before migrations run.
- The test user's grant is widened to `*.*` (setup.sql + CI) so it can
  `CREATE DATABASE` for the workers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 21:02:47 -04:00
zurdi
8b70e31828 refactor: address Copilot review on logs feature
- main.py: await the cancelled log-forwarder task (suppressing
  CancelledError) so its pubsub/lock cleanup finishes before shutdown.
- forwarder: only heartbeat the Redis lock while we still own it; if a
  stall let another worker take it, relinquish forwarding to avoid
  duplicate lines (the outer loop re-contends).
- endpoints/logs.py: derive MAX_LOG_LIMIT from LOG_BUFFER_SIZE so the
  REST backfill never drifts from the producer's ring buffer.
- Logs.vue: append the download <a> to the DOM before click() (matches
  the Patcher pattern) for cross-browser reliability.
- Add tests/endpoints/test_logs.py: non-admin 403, limit clamping to
  [1, MAX_LOG_LIMIT], oldest-first ordering, and malformed-entry skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 20:53:58 +00:00
zurdi
02c6fc8d3f fix: suppress bandit B110/B112 on intentional log-stream swallows
The log-stream handler and forwarder deliberately swallow exceptions: the
handler is a best-effort mirror that must never raise into the app, and the
forwarder can't log its own failures without feeding back into the stream.
Annotate these with `# nosec` (with justification) so Trunk's bandit check
passes, keeping lines within black's width.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 16:17:45 +00:00
zurdi
ad543d93ee feat: add logs feature with internationalization support
- Introduced a new logs view for admin users, allowing real-time monitoring of backend logs.
- Implemented a log entry streaming mechanism using Socket.IO.
- Added filtering and searching capabilities for log entries.
- Created localized log messages in Spanish, French, Hungarian, Italian, Japanese, Korean, Polish, Portuguese, Romanian, Russian, Simplified Chinese, and Traditional Chinese.
- Updated router and sidebar components to include the new logs route.
- Enhanced user interface with tooltips and buttons for copying and downloading logs.
2026-06-19 16:06:50 +00:00
zurdi
54b403a38e Merge remote-tracking branch 'origin/master' into feat/add-user-avatar-to-notes 2026-06-19 07:48:36 +00:00
zurdi
e974e3b451 fix: correct down_revision reference in migration script 2026-06-19 07:39:00 +00:00
zurdi
d5c985f634 Merge remote-tracking branch 'origin/master' into feat/screenshot-CRUD-endpoints 2026-06-19 07:35:07 +00:00
zurdi
5714ba3cec refactor: move screenshot file validation logic to utils and clean up endpoints 2026-06-19 07:30:07 +00:00
Georges-Antoine Assi
e657948bba fix trunk 2026-06-18 21:17:47 -04:00
Georges-Antoine Assi
13007b36df cleanup tests 2026-06-18 21:12:13 -04:00
Georges-Antoine Assi
1e78a2ed59 Merge branch 'master' into claude/exciting-heisenberg-61PF9 2026-06-18 19:59:00 -04:00
Georges-Antoine Assi
8922c2dd12 changes forom bot review 2026-06-18 13:27:41 -04:00
Georges-Antoine Assi
892f870d0d fix migration 2026-06-18 11:51:11 -04:00
Georges-Antoine Assi
c98fd39adb Merge branch 'master' into copilot/support-sortname-tag-es-de 2026-06-18 11:49:43 -04:00
Georges-Antoine Assi
8bf7d18afe cleanup 2026-06-18 11:48:51 -04:00
Georges-Antoine Assi
a38ebe29b5 Preserve custom name_sort_key; gate derivation on "still derived"
Drop the name_sort_key_custom flag/migration in favour of a flagless rule: a
key is "custom" when it no longer equals compute(name). Apply that consistently
across all three write paths so a manual sort key survives renames while a
derived key keeps following the name:

- @validates re-derives on name assignment only when the stored key still
  matches the derived value; direct name_sort_key assignment stores a
  normalized custom key (or reverts to derived when cleared). Handles both
  kwarg orders at construction.
- update_rom mirrors the same check for the bulk update() path it bypasses.
- The edit endpoint only writes the key when the user actually changed the
  field, delegating the untouched case to update_rom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:30:40 -04:00
Georges-Antoine Assi
cd19d723fa Merge sort_name into name_sort_key with custom-override flag
Collapse the separate `sort_name` column into `name_sort_key`, which is now
the single user-settable sort field: always normalized and indexed for fast
ordering, derived from `name` by default, and overridable. A new
`name_sort_key_custom` boolean marks user/metadata overrides so they survive
renames and rescans.

- Drop the `roms.sort_name` column; repurpose migration 0085 to add
  `name_sort_key_custom`.
- Derive the key via `@validates("name")` unless pinned custom; the edit
  dialog, unmatch flow, and ES-DE gamelist <sortname> set custom keys.
- update_rom / scan_rom keep the columns in sync explicitly (bulk update and
  construction bypass / reorder the validator).
- Frontend: edit field drives name_sort_key (empty when auto), api sends the
  override only when custom, regenerated types updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:34:21 -04:00
zurdi
d4a6d97acb feat: add user avatar and updated timestamp to community screenshots 2026-06-18 14:20:54 +00:00
zurdi
c0b44cd2ef Merge branch 'feat/screenshot-CRUD-endpoints' into feat/add-user-avatar-to-notes 2026-06-18 14:17:32 +00:00
zurdi
7ef3cba02a fix(migrations): shorten 0084 revision id to fit alembic_version column
The revision id '0084_add_roms_search_and_sort_indexes' (37 chars)
exceeded alembic_version.version_num VARCHAR(32), so every migration
run and test setup failed with 'Data too long for column version_num'
when stamping the revision. Rename it to '0084_roms_search_sort_indexes'
(29 chars) and update the 0085 down_revision link to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:06:32 +00:00
zurdi
6b63a677ec feat: add screenshot category enum and visibility flags 2026-06-18 13:51:07 +00:00
zurdi
b309938a78 Merge branch 'master' into feat/screenshot-CRUD-endpoints 2026-06-18 13:47:18 +00:00
zurdi
c84e91d185 hotfix: 0084 version alias 2026-06-18 13:47:00 +00:00
Georges-Antoine Assi
e7d46ee8c4 fix types 2026-06-18 09:32:38 -04:00
Georges-Antoine Assi
ee7a581067 fix migration names 2026-06-18 09:28:56 -04:00
Georges-Antoine Assi
222f767b2a run fmt 2026-06-18 09:05:55 -04:00
Georges-Antoine Assi
0d8a0a2ab2 Merge branch 'master' into copilot/support-sortname-tag-es-de 2026-06-18 09:04:17 -04:00
zurdi
2772ecb239 Merge remote-tracking branch 'origin/master' into feat/screenshot-CRUD-endpoints 2026-06-18 12:58:31 +00:00
Georges-Antoine Assi
aea09911ad cleanup 2026-06-18 07:57:09 -04:00
zurdi
a8d2fcb605 feat: implement RDropzone component for file uploads with drag-and-drop support
- Added RDropzone component for handling file uploads with a customizable interface.
- Integrated RDropzone into Patcher and Upload views, replacing previous drop zone implementations.
- Enhanced ScreenshotsTab with additional functionality for community screenshots, including visibility toggles and owner display.
- Updated styles for improved user experience and responsiveness.
- Created Storybook stories for RDropzone to demonstrate its usage and interaction.
2026-06-18 11:05:52 +00:00
Georges-Antoine Assi
cef5ed0699 set cache_key 2026-06-18 06:56:38 -04:00
zurdi
cc9691196c feat: add screenshot upload functionality and UI enhancements
- Implemented screenshot upload feature in the ROM management section.
- Added new API methods for uploading and removing screenshots.
- Enhanced UI to support drag-and-drop for screenshots and display uploaded images.
- Updated localization files for Russian, Simplified Chinese, and Traditional Chinese to include new screenshot-related strings.
- Improved the FilesTab and MediaTab components to manage screenshots effectively.
- Added delete functionality for user-uploaded screenshots with confirmation prompts.
- Updated styling for screenshot elements to improve user experience.
2026-06-18 07:45:16 +00:00
Georges-Antoine Assi
fc688f5c16 fix(search): address Copilot review on relevance ordering & char-index cache
- Include order_by / order_dir / group_by_meta_id in the char-index cache
  key. The computed AlphaStrip positions depend on ordering and grouping,
  so keying only by user reused a stale index when those changed.
- Gate the relevance-ranking test assertions to MySQL/MariaDB. Relevance
  ordering uses MATCH ... AGAINST; PostgreSQL (also in the CI matrix) falls
  back to name ordering, where those assertions don't hold.
- Clarify the order_by API docstring: relevance ordering applies on
  MySQL/MariaDB; other databases fall back to name.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:21:53 -04:00
Georges-Antoine Assi
987e351113 refactor: derive file-name columns via @validates
Centralize the *_no_tags / *_no_ext / *_extension columns (derived from a
file name) behind @validates hooks instead of computing them by hand at
every write site:

- Add pure helpers (compute_file_name_parts and friends) to models.base;
  the filesystem base handler now delegates to them.
- Add @validates on Rom (fs_name), BaseAsset (file_name, inherited by all
  asset subclasses), and Firmware (file_name).
- update_rom keeps the fs_name-derived columns in sync on bulk update(),
  which also fixes the rename path never updating fs_extension.
- Drop the now-redundant computations at the scan/rename call sites.

Also fix the migration backfill loop and a pre-existing list[str | None]
type mismatch surfaced in scan_handler. Add tests for the helpers, the
validators, and the update_rom bulk-sync path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:14:16 -04:00
Georges-Antoine Assi
1d63c9c89d refactor: derive name_sort_key via @validates instead of ORM event
Replace the before_insert/before_update event listener with a
@validates("name") method on Rom. The sort key is now recomputed exactly
when name is assigned (ORM construction or mutation) rather than on every
flush of any field. Bulk update() still sets it explicitly in update_rom.

Also linearize the merged 0084 migration onto 0083_rom_category_soundtrack
so there is a single alembic head.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:06:45 -04:00
Georges-Antoine Assi
3ccae1d560 chore: merge roms search/sort migrations into single 0084
Combine 0083_add_roms_search_indexes, 0084_add_roms_name_index, and
0085_add_roms_name_sort_key into one migration (revision 0084) off
0082_save_origin_device.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:01:49 -04:00
Georges-Antoine Assi
fd4964909f fix lint issues 2026-06-17 17:44:43 -04:00
Georges-Antoine Assi
4bacdc5f09 Merge branch 'master' into fix/search-performance-improvements 2026-06-17 17:39:47 -04:00
Georges-Antoine Assi
fa97fd76de set atari st to gen4 2026-06-17 15:51:44 -04:00
Zurdi
b52c5f1ae7 Merge branch 'master' into chore/frontend-v2 2026-06-17 15:43:08 +02:00
zurdi
2a53669459 fix: prevent crash on startup by bootstrapping library structure A when none is detected 2026-06-17 14:20:58 +02:00
zurdi
17e37c4262 feat: add user avatar and updated timestamp to notes schema and frontend components 2026-06-17 13:41:07 +02:00
Daniel Bonofiglio
d5ffeeeddb fix(search): full-text indexes+caching
Adds a few new indexes to handle full-text searches instead of doing
`ILIKE` matching, improving performance substantially.
Alongside that, a few other things were done in order to improve search
performance, such as caching filter values so they're not computed on
each request to /api/roms. Overall, this should have a very noticeable
impact on large collections when using the search feature.
2026-06-16 20:39:15 -03:00