feat: goal-based savings tracking & milestones (fixes #133)#643
Open
DrGalio wants to merge 2 commits intorohitdash08:mainfrom
Open
feat: goal-based savings tracking & milestones (fixes #133)#643DrGalio wants to merge 2 commits intorohitdash08:mainfrom
DrGalio wants to merge 2 commits intorohitdash08:mainfrom
Conversation
) Implements a production-grade background job execution system with: Core Engine (services/jobs.py): - Exponential backoff retries (30s → 2min → 8min) - Dead-letter queue for permanently failed jobs - @register_handler decorator for pluggable job types - process_due_jobs() batch processor with configurable limits - retry_dead_letter_job() for manual reprocessing - get_job_stats() for monitoring aggregation Job Model (models.py): - BackgroundJob model with full lifecycle tracking - JobStatus enum: PENDING, RUNNING, SUCCESS, FAILED, DEAD_LETTER - Tracks: attempt count, max_retries, next_run_at, last_error, result Reminders Integration (routes/reminders.py): - run_due endpoint now enqueues jobs instead of fire-and-forget - send_reminder raises on failure for proper retry handling - Handler registered via @register_handler decorator Admin Monitoring API (routes/jobs.py): - GET /admin/jobs/stats — aggregated stats by status/type - GET /admin/jobs — paginated list with status/type filters - GET /admin/jobs/:id — full job details - POST /admin/jobs/:id/retry — manual dead-letter retry - POST /admin/jobs/process — manual batch processing trigger - DELETE /admin/jobs/:id — remove job record - All endpoints require admin role Observability (observability.py): - finmind_job_events_total Prometheus counter (event/job_type/status) - track_job_event() helper function Database: - background_jobs table with indexes (schema.sql) - Migration file for existing deployments (001_background_jobs.sql) - Auto-migration via _ensure_schema_compatibility() OpenAPI (openapi.yaml): - Full documentation for all 6 admin endpoints - BackgroundJob schema definition - Jobs tag added Tests (tests/test_jobs.py): - 20 tests covering service layer and admin API - Backoff calculation, enqueue, execute, retry, dead-letter - Admin auth enforcement (403 for non-admin, 401 for unauth)
Implements a full savings goal system with contribution tracking and milestone detection: Models (models.py): - SavingsGoal: name, target_amount, current_amount, currency, deadline, category, status - SavingsContribution: goal_id, amount, note, contributed_at - SavingsGoalStatus enum: ACTIVE, COMPLETED, PAUSED - Relationship: goal.contributions (dynamic, cascade delete) Routes (routes/savings.py): - GET /savings/goals — list goals with ?status= filter, progress_pct, milestones_reached - POST /savings/goals — create goal with name, target_amount, currency, deadline, category - GET /savings/goals/:id — goal detail with all contributions - PATCH /savings/goals/:id — update name, target, deadline, category, status - DELETE /savings/goals/:id — delete goal + cascade contributions - POST /savings/goals/:id/contribute — add contribution, auto-update current_amount - GET /savings/goals/:id/milestones — milestone status at 25/50/75/100% Features: - Auto-complete: goal status flips to COMPLETED when current_amount >= target_amount - Milestone tracking: reports which thresholds reached + next milestone + amount needed - Progress analytics: progress_pct, remaining amount, milestones_reached list - User isolation: all endpoints scoped to authenticated user - Over-saving allowed: contributions can exceed target (progress_pct > 100) Database: - savings_goals + savings_contributions tables (schema.sql) - Migration file (002_savings_goals.sql) - Auto-migration via _ensure_schema_compatibility() Tests (tests/test_savings.py) — 20 tests: - Goal CRUD (create, list, get, update, delete) - Validation (missing name, zero/negative target) - Contributions (single, multiple accumulate, exceed target) - Auto-completion at 100% - Milestones endpoint (partial, all reached) - Auth enforcement (401 unauthenticated) - User isolation (other user cannot see/contribute) OpenAPI: - Full docs for all 7 endpoints - SavingsGoal, SavingsGoalDetail, NewSavingsGoal, UpdateSavingsGoal, NewContribution schemas - Savings tag 8 files changed, 607 insertions
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.
Summary
Implements a full goal-based savings tracking system with contribution logging and milestone detection — addressing Issue #133 ($250 bounty).
What's Built
Models (
models.py)SavingsGoal: name, target_amount, current_amount, currency, deadline, category, status (ACTIVE/COMPLETED/PAUSED)SavingsContribution: individual contributions with amount, note, date — linked to goal with cascade deleteSavingsGoalStatusenum for type-safe status valuesAPI Endpoints (
routes/savings.py)GET /savings/goals?status=POST /savings/goalsGET /savings/goals/:idPATCH /savings/goals/:idDELETE /savings/goals/:idPOST /savings/goals/:id/contributeGET /savings/goals/:id/milestonesKey Features
COMPLETEDwhencurrent_amount >= target_amountprogress_pct,remaining, andmilestones_reachedDatabase
savings_goalsandsavings_contributionstables with proper indexesmigrations/002_savings_goals.sql_ensure_schema_compatibility()— zero-downtime deployTests (
tests/test_savings.py)20 tests covering:
OpenAPI
SavingstagAcceptance Criteria
Example Flow
Files Changed
8 files changed, 967 insertions