Skip to content

Releases: kobotoolbox/kpi

2.026.07h

13 Apr 15:26
948f998

Choose a tag to compare

What's changed

Bug Fixes (1)
  • subsequences: allow accepting nlp actions even if limit exceeded (#6927)

    Ensure users can save/delete automatic NLP results even if they are over
    their usage limits.


Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07g..2.026.07h

2.026.07g

09 Apr 08:53
0ce5f9d

Choose a tag to compare

What's changed

Performance (1)
  • beat: throttle Beat schedule reloads to fix dispatch starvation (#6926)

Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07f..2.026.07g

2.026.07f

07 Apr 16:40
492f127

Choose a tag to compare

What's changed

Bug Fixes (1)
  • massEmails: do not disable emails before they are sent (#6915)

    Fixes a bug that was disabling one-time email sends before they could be
    sent.

    When users created one-off emails after the daily send lists had been
    generated, they were automatically getting turned off (having Live set
    to False) before they could actually be sent.


Full Changelog: 2.026.07e...2.026.07f

2.026.07e

09 Apr 08:50
bada421

Choose a tag to compare

What's changed

Performance (1)
  • longRunningMigrations: optimize 0020 batch strategy (#6913)

    Internal migration improvement — no user-visible change.

Testing (1)
  • hooks: fix SSRF IP mock in hook log tests (#6890)

Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07d..2.026.07e

2.026.07d

26 Mar 21:10
f130c78

Choose a tag to compare

What's changed

Bug Fixes (4)
  • longRunningMigrations: make 0020 batch size small to avoid OOM (#6875)

  • map: OpenStreetMap 403r error (#6869)

    Adds missing piece of configuration to fix 403r Access blocked error
    when rendering OpenStreetMap map.

    👷 Description for instance maintainers

    The new global default Referrer-Policy response header (introduced for
    OpenStreetMap tiles) can be overridden per environment via the
    SECURE_REFERRER_POLICY.

  • userReport: fix mfa_is_active not reflecting correct MFA status in user-reports (#6861)

    Fixes an issue where the /api/v2/user-reports API was not correctly
    reflecting MFA status for users who had MFA enabled.

    Users who recently enabled MFA were still showing mfa_is_active: false
    in the /api/v2/user-reports API response and within their underlying
    UserProfile record.

  • userReports: prevent infinite loop in MV background job (#6876, #6878)


Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07c..2.026.07d

2.026.07c

24 Mar 20:11
1b74d92

Choose a tag to compare

What's changed

Bug Fixes (1)
  • longRunningMigrations: retry on transient DB errors, fix 0011 extra_details (#6858)

Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07b..2.026.07c

2.026.07b

23 Mar 14:21
bd951c8

Choose a tag to compare

What's changed

Features (1)
  • accounts: extend activation link window to 24 hours and update related email/UI copy (#6832)

    Extends the django-allauth email confirmation expiration to 24 hours and
    updates the corresponding email templates, UI pages, and unit tests to
    reflect the new timeframe and provide better user guidance.

    This PR extends the validity of all activation links to exactly 24 hours
    and updates the associated UI and email copy to be more user-friendly
    and clear.

Bug Fixes (1)
  • pairedData: empty field intersection exposes no data (#6848)e

    When a connected project's dynamic data field restrictions did not
    overlap between source and destination, the external XML file was not
    generated correctly.

Performance (2)
  • asset: store version content hash in DB to avoid loading its content (#6843)

    Opening a project with many deployed versions and many questions could
    return a 502 error.

    👷 Description for instance maintainers

    In the API response of the asset detail endpoint
    (/api/v2/assets/{asset_uid}/), the hash of the content of each version
    was computed on the fly, loading all their JSON into memory (could be
    many MB, even GB of objects in memory at once).

    A new database field now stores the hash directly on each version
    record, computed once when the version is saved. A long-running
    migration backfills the hash for all existing records in small batches
    to avoid memory spikes.

  • openrosa: reduce SQL queries on formList and manifest endpoints (#6844)

Continous Integration (1)
  • zulip: update channel name as per zulip channel renames (#6851)

Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.07a..2.026.07b

2.026.07a

18 Mar 13:55
b41ac8f

Choose a tag to compare

What's changed

Bug Fixes (3)
  • admin: prevent manual username changes for existing users in Django admin (#6839)

    This PR locks down the username field in the Django admin panel for
    existing users, preventing superusers from manually changing it and
    breaking the _userform_id mapping in MongoDB.

    Manually changing a username via the Django admin updates the relational
    database but leaves MongoDB documents out of sync. Because the
    _userform_id key in MongoDB relies on the original username, altering
    it breaks submission retrieval and detaches submissions from their
    correct projects.

  • permissions: org admins can see and manage all asset permissions (#6836)

    Organization admins were unable to see other users' permission
    assignments on projects belonging to their organization.

    Organization admins receive manage_asset implicitly through their org
    role — no ObjectPermission record is created in the database. The
    permission visibility logic for both the asset detail endpoint and the
    organization assets list relied solely on explicit DB records to
    determine whether the requesting user could see all assignments. As a
    result, org admins were silently treated as regular users and could only
    see the owner's and their own permissions, making it impossible to
    manage sharing from the project detail page.

  • scripts: display detailed error output on unexpected migration failures (#6830)

    Fixes a logging issue in scripts/migrate.sh where unexpected migration
    tracebacks were hidden from the console, restoring standard error
    visibility for developers.

    In a recent update (see
    kpi#6796), we automated
    the resolution of materialized view schema locks during deployments. To
    achieve this, we updated scripts/migrate.sh to capture the output of
    the Django migrate command into a bash variable ($MIGRATE_OUT) so we
    could scan it for specific locking errors.

    However, this had an unintended side effect: it swallowed the Python
    traceback for all other types of migration crashes. If a migration
    failed for an unrelated reason (like a broken model or bad arguments),
    the developer only saw a generic "failed for an unknown reason" message,
    making debugging incredibly difficult.

    This PR fixes that oversight by ensuring the $MIGRATE_OUT variable is
    explicitly echoed to the console before the script exits, restoring full
    Django error visibility when unexpected migration failures occur.


Full Changelog: 2.026.07...2.026.07a

2.026.07

17 Mar 18:00
1ade945

Choose a tag to compare

What's changed

Features (24)
  • massEmails: exclude trashed users from email lists (#6615)

    Ensure users who cannot log in do not receive emails.

    Filter out any user who is already in the trash bin or who has been
    explicitly set to not active (as distinguished from users who we
    determine to be inactive by a lack of activity).

  • massEmails: exclude users who have submitted from inactive emails (#6618)

    Exclude users who have recently made submissions to any project from
    receiving inactive user emails.

    Previously we only counted users as active if they submitted to their
    own projects, but not projects owned by others.

  • processing: handle new subsequences API on frontend (#6657)

  • processing: handle non-blocking UI for NLP answers (#6671)

    Allow users to enter QA answers very fast while they are saved in
    background.

  • processing: handle "in_progress" status (#6677)

  • processing: toast on saving transcripts and translations (#6681)

  • processing: handle failure errors (#6678)

  • qa: rename qual to manual_qual (#6555)

    Rename the "qual" action to "manual_qual."

  • qual: show most recently created qual answers instead of most recently accepted (#6575)

    Display the most recent QA answers in the data table and exports rather
    than the most recently accepted.

  • qual: add new automatic QA action (#6567)

    Update advanced features API to allow requesting LLM answers to QA
    questions.

    Add a new "automated_chained_qual" action to the advanced features API
    endpoints. It is currently only a stub and will return canned answers
    rather than actually hitting an LLM.

  • submissions: support rootUuid as {id} parameter for data detail endpoints (#6660)

    Allow data detail endpoints to be accessed using rootUuid as the primary
    identifier.

    Description

    This feature adds support for using rootUuid as the `{id} parameter
    when accessing data detail endpoints. This makes it possible to retrieve
    a submission directly by its root UUID. The change improves flexibility
    and consistency when working with submission identifiers, without
    altering existing behavior for clients that continue to use the original
    primary key format.

  • subsequences: add model and new endpoints for advanced actions (#6492)

  • subsequences: show supplemental columns in data table (#6523)

    Add supplemental NLP columns to data table.

    This is just for adding the columns to the data table. They may not be
    populated correctly. If an NLP action is enabled, there will be a column
    for it, even if there are presently no responses.

  • subsequences: stop using _advanced_features field (#6503)

  • subsequences: implement get_output_fields and transform_data_for_output for QualAction (#6504)

    Add implementation of get_output_fields() and
    transform_data_for_output() in QualAction.

    This update enables qualitative analysis results to appear correctly in
    exports or the table view.
    The new logic:

    • Defines the output fields for each qualitative question (including
      labels, types, and choices).
    • Converts stored qualitative results into export-ready values,
      including expanding choice UUIDs into readable label objects.
  • subsequences: migrate old advanced_features (#6545)

  • subsequences: migrate old SubmissionExtras to SubmissionSupplemental (#6422)

  • subsequences: allow hiding of QA questions (#6550)

  • subsequences: add OpenAPI schema for advanded features (#6547)

    Add OpenAPI schema for the /api/v2/assets/{uid_asset}/advanced-features/ endpoint.

    The API schema output files and the generated Orval types have been
    updated with the schema details for the action parameters in the
    QuestionAdvancedFeature model.

  • subsequences: show again in formpack exports (#6561)

  • subsequences: do not allow users to un-accept automatic NLP responses (#6628)

    Do not allow users to un-accept an automatic NLP response.

  • subsequences: add locale field to NLP actions documentation (#6620)

    Updated the API documentation to explicitly include the locale
    parameter for NLP actions.

  • subsequences: do not allow translation of deleted transcripts (#6649)

    This PR implements a new validation rule within the subsequence
    processing flow. It ensures that a translation action cannot proceed if
    its source transcription (Manual or Automatic) has been explicitly
    deleted, regardless of whether a previously accepted version exists in
    the history.

  • viewer: improve user-agent parsing for Enketo and Collect (#6780)

    The user-agent string displayed in submission metadata is now more
    human-readable for ODK Collect, Kobo Collect, and Enketo submissions.

    Previously, submissions from ODK Collect, Kobo Collect, or Enketo would
    show a generic browser/OS string instead of a meaningful identifier.
    This change adds dedicated parsing logic.

Bug Fixes (72)
  • ci: pin pip<25.3 to restore compatibility with pip-tools 7.x (#6435)

    Fixes a CI installation issue caused by an incompatibility between pip 25.3 and pip-tools 7.x.

  • datacollectors: remove links on group delete (#6650)

  • dev: fix formpack version in dependencies files (#6616)

    Ran pip-compile script to update the formpack version to the latest
    commit

  • drawer: icon size (#6654)

  • formbuilder: update tooltips under some formbuilder buttons (#6582)

    Formbuilder header buttons had some incorrect tooltip, this PR updates
    them to at least be relevant to the button they're associated with

  • frontend: ensure useOrganizationAssumed assumption holds (#6608)

    Don't sometimes crash the website at the data table route.

  • hub: [breaking] fix hub merge conflict (#6687)

    Fixes a migration conflict in the hub app

  • languages: unauthorize languages endpoint (#6699)

    Allow anonymous users to access the languages endpoint

  • logging: prevent duplicate logs by disabling propagation to root logger (#6808)

    Celery workers were emitting every log record twice, polluting logs and
    making debugging harder.

    When a logger is configured with propagate: True (the default), log
    records are passed up the logger hierarchy all the way to the root
    logger. Because Django's logging setup attaches a handler both on the
    named logger and on the root logger, each record was processed twice —
    once by the named handler and once by the root handler — resulting in
    every log line appearing duplicated.

    Setting propagate: False on console_logger stops records from
    bubbling up, so each log record is handled exactly once.

  • openAPI: improve schema for assets list response (#6622)

  • openApi: use proper query param name (#6664)

  • openapi: fix advancedfeaturesresponse schema (#6624)

  • openapi: advanced feature response action pr...

Read more

2.026.03f

10 Mar 16:13
e590485

Choose a tag to compare

What's Changed

Full Changelog: 2.026.03e...2.026.03f