Skip to content

Engagement heatmap API for unit-scoped task activity#88

Merged
BrianDangDev merged 1 commit intothoth-tech:Feature/Peers-Progressfrom
davidngash98:Feature/Peers-Progress
May 4, 2026
Merged

Engagement heatmap API for unit-scoped task activity#88
BrianDangDev merged 1 commit intothoth-tech:Feature/Peers-Progressfrom
davidngash98:Feature/Peers-Progress

Conversation

@davidngash98
Copy link
Copy Markdown

Summary
This adds a new backend API endpoint to support the Heatmap module for OnTrack. The endpoint provides an 84-day view of student task engagement activity, scoped strictly to a single project (enrolment). This will power the frontend heatmap visualisation without leaking data across units or projects.

Key Changes

New Service: app/services/engagement_heatmap_service.rb

  • Calculates activity for the last 84 days (server timezone).
  • Groups TaskEngagement records by day with proper date normalization.
  • Computes tasks_completed, active_days, and current_streak.
  • Strictly scoped to the requested project’s tasks only.

New API Endpoint: GET /api/projects/:id/engagement_heatmap

  • Added to projects_api.rb.
  • Uses standard authentication + authorise?(current_user, project, :get).
  • Returns consistent JSON contract: project_id, unit_id, range, days[], and summary.

Tests: Added comprehensive tests in test/api/projects_api_test.rb covering:

  • Happy path and full response contract
  • Authorisation (403 for unauthorised users)
  • Scoping (no cross-project leakage)
  • Edge cases (no activity, sparse activity, streak logic)
  • 404 for non-existent project

Test Environment Fix

  • Updated test.rb to allow Rack::Test host (example.org)
  • Prevents HostAuthorization from blocking test requests

How to Test

  • Run: bundle exec rails test test/api/projects_api_test.rb -n /engagement_heatmap/

  • Then call: GET /api/projects/:id/engagement_heatmap and verify the response includes:

  • project_id

  • unit_id

  • range

  • days (84 entries)

  • summary

Notes / Limitations

  • Fixed 84-day window (no query params yet).
  • Uses server timezone for daily bucketing.
  • tasks_completed counts distinct tasks with at least one "Complete" engagement.
  • Streak ends today (or yesterday if today has no activity), bounded by the 84-day window.

Copy link
Copy Markdown

@millyamolo millyamolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds a well structured backend endpoint for the engagement heatmap, with clear logic in the service layer for computing the 84 day activity window and related metrics. The feature is easy to verify using the provided test command (bundle exec rails test test/api/projects_api_test.rb -n /engagement_heatmap/) and by calling GET /api/projects/:id/engagement_heatmap, which returns a consistent response including project_id, unit_id, range, days (84 entries), and summary. Test coverage is solid and the endpoint behaves as expected. The CI file reorganisation looks fine, though the change to run plagiarism checks daily is worth confirming. it looks good I am happy to approve.

@AjayPAnand
Copy link
Copy Markdown

Tested the new GET /api/projects/:id/engagement_heatmap endpoint end-to-end using Swagger and verified that the response structure matches the expected contract. Confirmed that the payload includes project_id, unit_id, range, a full 84-day days array with correctly normalised dates, and an accurate summary section (including tasks_completed, active_days, and current_streak).

Validated that the endpoint is correctly scoped to the specified project, with no cross-project data leakage. Also checked edge cases such as no activity and sparse activity, and confirmed streak calculations behave as expected.

In addition to manual testing, ran the relevant automated tests in the doubtfire-api project using:
bundle exec rails test test/api/projects_api_test.rb -n /engagement_heatmap/

All tests passed successfully, including authorisation checks (403), non-existent project handling (404), and data integrity scenarios.
image

Swagger screenshots:
image
image

@BrianDangDev
Copy link
Copy Markdown

@davidngash98 could you have a look at the unit tests

@davidngash98
Copy link
Copy Markdown
Author

@davidngash98 could you have a look at the unit tests

Hey @BrianDangDev, I dug into the logs from all three runs the failure isn't actually in my tests, it's the Docker image build crashing before the test step ever runs. tlmgr (TeX Live's package manager) is failing while pulling LaTeX packages from the CTAN mirror inside the Dockerfile (tlmgr install catchfile csvsimple ... enumitem exits 1). My PR only touches the heatmap service, projects_api.rb, the test file, and config/environments/test.rb nothing in the Dockerfile or CI workflow so the same build would fail on any PR right now. The heatmap tests pass locally for me and for @millyamolo and @AjayPAnand . Since it's a separate infra issue, I'd rather not bundle a Dockerfile fix into this feature PR. I was suggesting if we can merge on the passing Ruby checks + manual verification let me know your thoughts.

@BrianDangDev BrianDangDev merged commit 2c34163 into thoth-tech:Feature/Peers-Progress May 4, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants