Conversation
…pletion (#2023) Fix: before selecting best_in_progress, filter out any in-progress submissions whose end_time is older than best_completed.end_time. These are definitionally stale - they predate the most recent completion and were superseded by a restart-and-complete cycle. Adds unit tests covering: - per-submit_id collapsing - best completed selection - best in-progress selection with and without prior completions - the exact restart bug scenario (A stale, B completed, C new in-progress) - edge cases: empty input, multiple flows, boundary timestamps
…sion (#2020) When a version mismatch is detected for a flow submission, adopt the version from the existing answer group instead of rejecting with a 400. This allows in-progress flows to be completed after an applet version update. Re-validates flow progress with the corrected version's history IDs. * feat: add version-aware activity endpoint for deleted flow resume Add optional 'version' query parameter to GET /activities/{id} endpoint. When version is provided, fetches activity data from the immutable history tables instead of the live activities table. This allows the frontend to load activity items for activities that were deleted from the current applet version but are still needed for resuming an in-progress flow. - Add _get_by_language() helper for multi-language to single-language conversion - Add _get_activity_from_history() to fetch and convert history records - Modify activity_retrieve() to accept optional version param * feat: add flow_activity_ids to CompletedEntity for cross-device flow resume * fix: version-aware in-progress flow filtering and COUNT-based activity_flow_order * feat: add flow_name to CompletedEntity for cross-device resume * fix: add null check for flow_history_id before dict access * fix: exclude flowActivityIds and flowName from completed flows - Add model_serializer to conditionally exclude flowActivityIds and flowName when None - These fields should only appear for in-progress flows (is_flow_completed=False) - Maintains backwards compatibility with existing API consumers - Add null check for flow_history_id before dictionary access in CRUD * test: add tests for cross-version flow resume
🔗 [Jira Ticket M2-10475](https://mindlogger.atlassian.net/browse/M2-10475) Add index on `answers_items.answer_id` to speed up `JOIN` for the `AnswerSchema.answer_item` relationship. Related to #2022.
🔗 [Jira Ticket M2-10475](https://mindlogger.atlassian.net/browse/M2-10475) @jodybrookover reminded me to check the arbitrary database too. The arbitrary database shares the same SQLAlchemy schemas but has a separate set of Alembic migrations. Turns out that the arbitrary database already has an index for `answers_items.answer_id` but was missing other indexes. Changes include: - Configure Alembic to generate blank revision with `uv run alembic -c alembic_arbitrary.ini revision`. - Add indexes to arbitrary database for `answers.applet_id`, `answers.flow_history_id`, `answers.event_history_id`, and `answers.device_id`. Related to #2021.
…#2018) 🔗 [Jira Ticket M2-9037](https://mindlogger.atlassian.net/browse/M2-9037) This is a breaking change! Any previously available `POST /themes`, `PUT /themes/{pk}`, and `DELETE /themes/{pk}` endpoints will now fail and return `404 Not Found`. Changes include: - Removed the `POST /themes` (create theme) endpoint — any authenticated user could previously create themes visible to all MindLogger users, enabling abuse (profanity in names, inappropriate images) - Removed the `PUT /themes/{pk}` (update theme) endpoint — same concern - Removed the `DELETE /themes/{pk}` (delete theme) endpoint — any authenticated user could previously delete any and all themes including the default one - Removed associated tests for the above endpoints Only `GET /themes` remains. Themes can now only be managed directly in the database. The underlying service and CRUD code for create, update, and delete are intact — the endpoints are simply no longer registered with the router. This makes it straightforward to restore or gate behind an admin/superuser permission in a future ticket if needed.
🔗 [Jira Ticket M2-9233](https://mindlogger.atlassian.net/browse/M2-9233) Changes include: - Added order by statement - Added tests (which mostly ignore the style of the other tests that use the problematic personas) Testing: 1. Login to the admin 2. Invite a user 3. delete the user/invite 4. invite the user again 5. repeat this a few times so you have a good chance of failure 6. In the admin, copy the invite link - it should work. Previously, it was returned non-deterministically and might not work
🔗 [Jira Ticket M2-10393](https://mindlogger.atlassian.net/browse/M2-10393) 🔗 [Jira Ticket M2-10460](https://mindlogger.atlassian.net/browse/M2-10460) Changes include: `make audit` to identify dependencies with reported vulnerabilities using `uv-secure`: make audit make audit SEVERITY=low # same as `make audit` make audit SEVERITY=medium # medium or greater severity make audit SEVERITY=high # high or greater severity make audit SEVERITY=critical # critical severity only Upgrade dependencies to remove high vulnerabilities: uv add "aiohttp>=3.13.3" uv add "cryptography>=46.0.5" uv add "python-multipart==0.0.22" uv sync --upgrade-package azure-core uv sync --upgrade-package protobuf uv sync --upgrade-package pyasn1 uv sync --upgrade-package starlette uv sync --upgrade-package urllib3 Upgrade dependencies to remove remaining vulnerabilities: uv add --dev "pre-commit>=4.5.1" uv sync --upgrade-package filelock uv sync --upgrade-package h2 uv sync --upgrade-package orjson uv sync --upgrade-package virtualenv uv sync --upgrade-package Werkzeug Remove unused dependencies: uv remove bytecode uv remove more-itertools uv remove pyopenssl uv remove --dev greenlet uv remove --dev ipdb uv remove --dev pudb uv remove --dev pytest-lazy-fixtures uv remove --dev reproschema Install S3 type annotations for `boto3` in `dev` only: uv remove boto3-stubs uv add --dev "boto3-stubs[s3]>=1.40.60" Before: 215 dependencies with 24 vulnerabilities (4 low, 10 medium, 10 high) After: 184 dependencies with 0 vulnerabilities
🔗 [Jira Ticket M2-9695](https://mindlogger.atlassian.net/browse/M2-9695) 🔗 [Jira Ticket M2-10487](https://mindlogger.atlassian.net/browse/M2-10487) We’ve accumulated a number of SQLAlchemy schema changes that aren’t reflected in the Alembic migrations and vice versa, so `uv run alembic revision --autogenerate` hasn’t been working cleanly. The following changes bring SQLAlchemy schemas and Alembic migrations back in sync. The PRs when schema and migration deviated are included for reference. Add SQLAlchemy schemas missing in Alembic’s list of `migrations_apps`: - `apps.activity_assignments.db.schemas` #1511 - `apps.integrations.loris.db.schemas` #1580 Update SQLAlchemy schemas to match Alembic migrations: - `Text()` → `String()` for `answers.{applet,activity,flow}_history_id` #518 - `String(56)` → `String(100)` for `users.email` #528 - `name="token_purpose"` for `token_blacklist.type` enum #551 - `String(5)` → `String(20)` for `subjects.language` #1217 - `ForeignKey` → `UUID` for `activity_assignments.{activity_id,activity_flow_id}` #1533 - `nullable=False` for `event_histories.{version,periodicity}` #1718 - `nullable=False` for `events.{version,periodicity}` #1733 - `index=False` for `answers.{event_history_id,device_id}` #1754 - `Index(postgresql_using="gin")` for `subjects.meta` #1798 - `onupdate="CASCADE"` for `{subjects,events}.id` foreign keys #1802 - `UniqueConstraint` for `answers_ehr (submit_id, activity_id)` #1837 - `nullable=False` for `subjects.is_deleted` #1855 - `nullable=False` for `users.mfa_enabled` #1973 Add missing `token_blacklist.type` enum values: - `MFA = "mfa"` #1976 - `DOWNLOAD_RECOVERY_CODES = "download_recovery_codes"` #1983 Drop tables and columns left over from schedule migration: - `{activity,flow,user}_events` tables #1723 - `periodicity` table and `events.periodicity_id` column #1733 - `subjects.is_deleted_null` column #1855 - `applet_events_cleanup` table #1858 Drop redundant `(submit_id, activity_id)` composite index: - Already indexed by `answers_ehr_submit_activity_key` unique constraint #1837 Create missing `consents` table: - Defined for LORIS integration but never created #1580 After the changes, test autogenerate yields an empty migration: uv run alembic upgrade head uv run alembic revision --autogenerate -m "Test autogenerate migration"
sricharan-varanasi
approved these changes
Apr 7, 2026
aweiland
approved these changes
Apr 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Includes changes tested in 2026.03.1-rc1.