Skip to content

Phase 3 fixes (time-range filter, audit logging) + Phase 4 Wave 1: recommendations endpoint - #31

Merged
Dynamic-ctrl merged 9 commits into
LifeAtlas:stagingfrom
Adilislam0:staging
Jun 21, 2026
Merged

Phase 3 fixes (time-range filter, audit logging) + Phase 4 Wave 1: recommendations endpoint#31
Dynamic-ctrl merged 9 commits into
LifeAtlas:stagingfrom
Adilislam0:staging

Conversation

@Adilislam0

Copy link
Copy Markdown
Collaborator

Summary

Closes the remaining Phase 3 gate gap and ships Phase 4 Wave 1 — a real,
auth-protected GET /recommendations/{user_id} endpoint backed by mock
data, so Jahanvi can build frontend cards against a stable contract
before Jaivardhan's reasoning core lands.

What's in this PR

Phase 3 — closing the gate gap

  • GET /signals/ time-range filter — added start/end query params,
    wired through store.list_signals() via .gte()/.lte() on timestamp.
    This was the single largest gap between the gate sheet ("Timeline
    queryable by user and time range") and the running code.
  • Audit log bug fixedlog_user_activity() was failing silently on
    signal_ingested because the user_activity_logs CHECK constraint only
    allowed goal_created / goal_updated / goal_deleted. Migration
    20260615000000_signals_rls_and_log_action.sql adds signal_ingested to
    the constraint — run supabase db push before testing this branch.
  • logging.py: print()logger.exception() for log_user_activity
    failures, so a future constraint mismatch surfaces in real log output
    instead of silently disappearing into stdout.
  • store.get_user_activity_logs() added — queries Supabase directly so
    tests can assert the audit row actually exists in the DB, not just in
    the in-memory mirror (which appends unconditionally and would pass even
    if the real insert failed).
  • Removed the now-dead try/except around log_user_activity() in
    signals.py — that function already never raises internally.

Phase 4 Wave 1 — recommendations endpoint (mine)

  • GET /api/v1/recommendations/{user_id} now requires a valid Supabase
    JWT (previously had no auth dependency at all).
  • Returns up to limit (default 3, max 10) mock Recommendation objects,
    sorted by priority descending, on the same 0.80–7.00 priority scale
    goals use — so the frontend reuses one priority-badge component.
  • _build_mock_recommendations() is a clean swap point: Jaivardhan
    replaces this one call in Wave 2 with real goal/signal reasoning; the
    response contract (and every test in test_recommendations_endpoint.py)
    stays unchanged.
  • user_id is a path param, not derived from the JWT, by design — one
    authenticated demo session needs to pull up all 3 seeded intern profiles
    for the demo. Documented in the module docstring; flagged as the thing
    to revisit if this becomes real multi-tenant.

Tests

  • tests/test_recommendations_endpoint.py (new) — covers auth, response
    shape, sort order, and limit validation against Wave 1's mock data.
    Deliberately does not assert on which actions come back — that's
    Jaivardhan's correctness tests in test_recommendations.py.

Also included (test scaffolding, not for review depth)

  • scripts/ingest_bpi2013.py, scripts/test_endpoints.py — local-only
    ingestion/smoke scripts used to manually validate the signals endpoint
    against BPI 2013 and synthetic data. Not part of the app; happy to move
    these to a scripts/local-only/ folder or drop them from this PR if
    preferred.
  • lpi_testing_guide.md — local testing reference doc, same call as above.

How to test

git checkout this-branch
supabase db push          # REQUIRED — applies the signal_ingested CHECK constraint fix
pytest tests/ -v          # full suite should be green

Manually via Swagger (/docs):

  1. Authorize with a valid JWT
  2. GET /api/v1/signals/?start=2026-06-13T00:00:00Z&end=2026-06-20T00:00:00Z
  3. GET /api/v1/recommendations/intern-a-demo-profile → 3 mock cards, sorted by priority
  4. GET /api/v1/recommendations/intern-a-demo-profile?limit=1 → top-priority card only
  5. Hit /api/v1/recommendations/{user_id} with no Authorization header → 401

Known follow-ups (not in scope here)

  • log_transition() and log_system_event() in logging.py still use
    print() — same fix as log_user_activity(), left for a separate pass.
  • Simulated event generator for signals is still design-doc only.
  • GitHub ingestion script (ingest_github_events.py) still missing its
    Authorization header — will 401 on any auth-enforced deployment.

Reviewers

@jaivardhan — recommendations contract, swap-in point for Wave 2
@Daksh_build_mock_recommendations() as orchestration fallback
@yashikauser_activity_logs schema/migration

Type

  • Feature (new endpoint / model)
  • [ x] Fix (bug, test failure)
  • [ x] Refactor
  • [ x] Docs / reports

Checklist

  • [x ] make lint exits 0
  • [ x] make test exits 0 (no new failures)
  • Tests added or updated for changed behaviour
  • Daily report updated in reports/
  • [ x] No .env secrets committed
  • PR targets staging (never main directly)

@Dynamic-ctrl
Dynamic-ctrl merged commit b7edfd3 into LifeAtlas:staging Jun 21, 2026
1 check 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.

2 participants