This change makes the RetroAchievements progression sync endpoint to
optionally perform an incremental sync (when `incremental` is true),
by only fetching new achievements since the last sync.
This reduces the amount of data fetched and speeds up the sync
process for users who frequently sync their progression. It unblocks the
implementation of automatic periodic syncs in the future.
Frontend behavior:
- When the `Apply` button is clicked in the RetroAchievements settings,
a full sync is performed (same as before). This is because a change to
the RA username may have occurred.
- When the `Sync` button is clicked, an incremental sync is performed.
Stop using query parameters for user creation and update endpoints in
the API. Instead, use the request body to pass user data.
This change stops leaking sensitive information like passwords in the
URL.
Fixes#2010
- Implemented RA hash handling in ROM processing.
- Added functionality to refresh RetroAchievements data for users.
- Updated user model to store RA progression data.
- Created a new component for managing RetroAchievements settings in user profiles.
- Enhanced ROM metadata to include merged RA achievements and badge paths.
- Refactored API calls to accommodate new RA features and removed unused API key handling.
- Updated frontend components to reflect changes in RA metadata and user settings.
- Adjusted Docker configuration for database service naming.
When a user does not set an email address, we now set it to `NULL` in
the database. That bypasses the unique constraint on the `email` column,
allowing multiple users to have no email address set.
Fixes#1445.
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.
The `add_user` endpoint was querying the database at import time, to
decide whether to enforce the `users.write` scope or not. This is
problematic because the database might not be ready at import time.
Also, the decided `scopes` was being maintained for the entire
application lifetime, which is not ideal, as users can be created
without having the `users.write` scope, until the application is
restarted.
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
Pytest v8.2 introduced the `PYTEST_VERSION` environment variable [1],
that can be used to check if code is running from within a pytest run.
This way, we can avoid checking the loaded `sys` modules.
[1] https://docs.pytest.org/en/stable/changelog.html#id57
`ASYNC` rules [1] tries to find issues regarding asynchronous code. This
change enables `ruff` to start reporting these issues, and fixes
existing warnings.
[1] https://docs.astral.sh/ruff/rules/#flake8-async-async