While `_ensure_indexes` was already secured, the `CREATE INDEX` for
`ix_saved_searches_user_id` was hardcoded. This commit explicitly
quotes it to unify our security posture against SQL injection
and keep static analyzers happy.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit improves test coverage for the `register_settings_reload_signal` function in `app/utils/settings_sync.py`.
🎯 **What:** The testing gap addressed was that the `_reload_if_stale` inner Celery `task_prerun` signal handler was entirely untested, specifically around exception handling (e.g. Redis timeouts or OCR manager errors) and the code branch where Redis returns no version key.
📊 **Coverage:** The following scenarios are now tested:
- Redis returning `None` for the version.
- Redis throwing an exception (handled gracefully).
- `ensure_ocr_languages_async` throwing an exception (caught and logged without failing the task).
✨ **Result:** Test coverage for `register_settings_reload_signal` is now 100%. Total coverage for `app/utils/settings_sync.py` has been substantially improved.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
The previous commit introduced a benchmark test with unsorted imports inside the test method, which caused the Ruff Lint & Format CI check to fail with `I001 [*] Import block is un-sorted or un-formatted`. This commit runs `ruff format` and `ruff check --fix` on `tests/test_notifications_api.py` to fix the issue.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Added a benchmark script in tests/test_notifications_api.py that proved the N+1 issue issue.
- Replaced iterative DB lookups inside `for item in body.preferences:` with single pre-fetch query and local `prefs_dict` lookups.
- Verified test benchmark time drops from ~0.0964s to ~0.0141s for a batch of 100 items.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Replaced the synchronous `requests.post` calls in `app/api/dropbox.py` with asynchronous `httpx.AsyncClient().post` calls. This ensures that the FastAPI event loop is not blocked during network I/O, allowing better concurrent performance.
Also updated the `test_api_dropbox.py` tests to use `httpx.AsyncClient.post` in mocks and properly construct `httpx.RequestError` in exception handling tests.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Added a strict regex validation allowlist for table names in `preview_migration` before using them in raw SQL queries. This ensures that only alphanumeric characters and underscores are allowed, preventing potential SQL injection even if the source of table names were to be manipulated.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Added the `--` argument before positional arguments in rclone subprocess calls (link, mkdir, copy) in `app/tasks/upload_with_rclone.py`. This ensures that filenames or destinations starting with a hyphen are treated as paths rather than unintended command-line flags.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add NODE_NO_WARNINGS=1 to all eas.json build profiles (development,
preview, production) to suppress [DEP0169] url.parse() deprecation
warnings emitted by EAS CLI when the build image's system Node is 22+
- Add NODE_NO_WARNINGS=1 env to both EAS Cloud Workflow jobs
(.eas/workflows/create-builds.yml) with explanatory comments
- Fix outdated Node.js prerequisite in docs/MobileApp.md (was "18 or
later", now "20.19.4 or later" with nvm guidance)
- Add troubleshooting sections in docs/MobileApp.md and mobile/README.md
covering both the "Session expired Local session" error (Apple ID
session expiry + App Store Connect API key recommendation) and the
[DEP0169] Node.js deprecation warning
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>