Files
chore/.github/specs/active/feat-dynamic-points/IMPLEMENTATION_SUMMARY.md
Ryan Kegel 3dee8b80a2
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 24s
feat: Implement task and reward tracking feature
- Added tracking events for tasks, penalties, and rewards with timestamps.
- Created new TinyDB table for tracking records to maintain audit history.
- Developed backend API for querying tracking events with filters and pagination.
- Implemented logging for tracking events with per-user rotating log files.
- Added unit tests for tracking event creation, querying, and anonymization.
- Deferred frontend changes for future implementation.
- Established acceptance criteria and documentation for the tracking feature.

feat: Introduce account deletion scheduler

- Implemented a scheduler to delete accounts marked for deletion after a configurable threshold.
- Added new fields to the User model to manage deletion status and attempts.
- Created admin API endpoints for managing deletion thresholds and viewing the deletion queue.
- Integrated error handling and logging for the deletion process.
- Developed unit tests for the deletion scheduler and related API endpoints.
- Documented the deletion process and acceptance criteria.
2026-02-09 15:39:43 -05:00

4.9 KiB

Tracking Feature Implementation Summary

Implementation Complete

All acceptance criteria from feat-tracking.md have been implemented and tested.


📦 What Was Delivered

Backend

  1. Data Model (tracking_event.py)

    • TrackingEvent dataclass with full type safety
    • Factory method create_event() for server-side timestamp generation
    • Delta invariant validation (delta == points_after - points_before)
  2. Database Layer (tracking.py)

    • New TinyDB table: tracking_events.json
    • Helper functions: insert_tracking_event, get_tracking_events_by_child, get_tracking_events_by_user, anonymize_tracking_events_for_user
    • Offset-based pagination with sorting by occurred_at (desc)
  3. Audit Logging (tracking_logger.py)

    • Per-user rotating file handlers (logs/tracking_user_<user_id>.log)
    • 10MB max file size, 5 backups
    • Structured log format with all event metadata
  4. API Integration (child_api.py)

    • Tracking added to:
      • POST /child/<id>/trigger-task → action: activated
      • POST /child/<id>/request-reward → action: requested
      • POST /child/<id>/trigger-reward → action: redeemed
      • POST /child/<id>/cancel-request-reward → action: cancelled
  5. Admin API (tracking_api.py)

    • GET /admin/tracking with filters:
      • child_id (required if no user_id)
      • user_id (admin only)
      • entity_type (task|reward|penalty)
      • action (activated|requested|redeemed|cancelled)
      • limit (default 50, max 500)
      • offset (default 0)
    • Returns total count for future pagination UI
  6. SSE Events (event_types.py, tracking_event_created.py)

    • New event type: TRACKING_EVENT_CREATED
    • Payload: tracking_event_id, child_id, entity_type, action
    • Emitted on every tracking event creation

Frontend

  1. TypeScript Models (models.ts)

    • TrackingEvent interface (1:1 parity with Python)
    • Type aliases: EntityType, ActionType
    • TrackingEventCreatedPayload for SSE events
  2. API Helpers (api.ts)

    • getTrackingEventsForChild() function with all filter params
  3. SSE Registration

    • Event type registered in type union
    • Ready for future UI components

Tests

Backend Unit Tests (test_tracking.py):

  • Tracking event creation with factory method
  • Delta invariant validation
  • Insert and query tracking events
  • Filtering by entity_type and action
  • Offset-based pagination
  • User anonymization on deletion
  • Points change correctness (positive/negative/zero delta)
  • No points change for request/cancel actions

🔑 Key Design Decisions

  1. Append-only tracking table - No deletions, only anonymization on user deletion
  2. Server timestamps - occurred_at always uses server time (UTC) to avoid client clock drift
  3. Separate logging - Per-user audit logs independent of database
  4. Offset pagination - Simpler than cursors, sufficient for expected scale
  5. No UI (yet) - API/models/SSE only; UI deferred to future phase

🚀 Usage Examples

Backend: Create a tracking event

from models.tracking_event import TrackingEvent
from db.tracking import insert_tracking_event
from utils.tracking_logger import log_tracking_event

event = TrackingEvent.create_event(
    user_id='user123',
    child_id='child456',
    entity_type='task',
    entity_id='task789',
    action='activated',
    points_before=50,
    points_after=60,
    metadata={'task_name': 'Homework'}
)

insert_tracking_event(event)
log_tracking_event(event)

Frontend: Query tracking events

import { getTrackingEventsForChild } from "@/common/api";

const res = await getTrackingEventsForChild({
  childId: "child456",
  entityType: "task",
  limit: 20,
  offset: 0,
});

const data = await res.json();
// { tracking_events: [...], total: 42, count: 20, limit: 20, offset: 0 }

📋 Migration Notes

  1. New database file: backend/data/db/tracking_events.json will be created automatically on first tracking event.
  2. New log directory: backend/logs/tracking_user_<user_id>.log files will be created per user.
  3. No breaking changes to existing APIs or data models.

🔮 Future Enhancements (Not in This Phase)

  • Admin/parent UI for viewing tracking history
  • Badges and certificates based on tracking data
  • Analytics and reporting dashboards
  • Export tracking data (CSV, JSON)
  • Time-based filters (date range queries)