Skip to content

fix(backend): competitions join deadline, seasons rollover scoring, achievements monotonicity, and analytics bucket alignment - #2072

Merged
Olowodarey merged 1 commit into
Arena1X:mainfrom
GF-Hunter:fix/1949-1950-1951-1952-backend-fixes
Oct 20, 2026
Merged

Olowodarey merged 1 commit into
Arena1X:mainfrom
GF-Hunter:fix/1949-1950-1951-1952-backend-fixes

Conversation

@GF-Hunter

Copy link
Copy Markdown
Contributor

Summary

This pull request addresses and fixes four backend issues assigned to @GF-Hunter:


Detailed Implementation

1. Competitions Join Deadline Rejection (#1949)

  • File: backend/src/competitions/competitions.service.ts, backend/src/competitions/entities/competition.entity.ts, backend/src/competitions/dto/create-competition.dto.ts
  • Behavior:
    • Added optional join_deadline to competition entity and create competition DTO.
    • Enforced join deadline validation in joinCompetition: requests strictly after the deadline (now > deadline) are rejected with BadRequestException containing the ISO deadline.
    • Enforced documented boundary rule: joins up to and including the exact deadline timestamp (now <= deadline) are allowed.
  • Tests:
    • a join after deadline is rejected with a clear error containing the deadline
    • a join before deadline succeeds
    • a join exactly at the boundary follows the documented rule (inclusive boundary succeeds)

2. Seasons Rollover Boundary Scoring (#1950)

  • File: backend/src/seasons/seasons.service.ts
  • Behavior:
    • Added attributePredictionToSeason / attributePrediction and scorePredictionForSeason to deterministically attribute predictions to seasons by the documented half-open interval rule [starts_at, ends_at).
    • Guarantees predictions submitted before rollover score in the prior season even if resolved after rollover.
    • Boundary-exact timestamps (t === season.ends_at === next_season.starts_at) follow the documented policy (exclusive of prior season end, inclusive of next season start).
  • Tests:
    • a prediction made before rollover scores in the prior season
    • a prediction resolved after rollover is attributed per the rule
    • boundary-exact timestamps follow the documented inclusive/exclusive policy

3. Achievements Progress Monotonicity (#1951)

  • File: backend/src/achievements/achievements.service.ts
  • Behavior:
    • Added recordProgress and updateProgress with monotonic progress guarantees: newProgress = Math.max(existing.current_value, value).
    • Out-of-order events with lower progress values never regress progress.
    • Enforced award-once semantics: crossing threshold awards and triggers notifications/broadcasts exactly once.
    • Replayed events do not double-award.
  • Tests:
    • replayed events do not double-award an achievement
    • out-of-order events never decrease progress
    • crossing a threshold awards exactly once

4. Analytics Event Aggregation Bucket Alignment (#1952)

  • File: backend/src/analytics/analytics.service.ts
  • Behavior:
    • Added aggregateEventsByTimeBucket implementing the documented half-open interval [bucket_start, bucket_end).
    • Guarantees each event is assigned to exactly one bucket.
    • Boundary-timestamp events land in the bucket where timestamp === bucket_start and never double-count.
    • Totals are guaranteed conserved (sum of buckets equals the ungrouped total).
    • Empty buckets are represented as zero (count: 0, total_value: 0), ensuring continuity.
  • Tests:
    • an edge-timestamp event lands in exactly one bucket
    • sum of buckets equals the ungrouped total
    • empty buckets are represented as zero, not omitted where continuity is required

…chievements monotonicity, and analytics bucket alignment

- competitions: enforce join deadline rejection with clear error message, supporting inclusive boundary joins (Arena1X#1949)
- seasons: deterministic prediction season attribution and rollover boundary scoring using half-open interval (Arena1X#1950)
- achievements: enforce monotonic progress tracking and single-fire award semantics against replayed/out-of-order events (Arena1X#1951)
- analytics: enforce half-open time-bucket event aggregation with exact single-bucket assignment, continuous zeroes, and total conservation (Arena1X#1952)

Closes Arena1X#1949, Arena1X#1950, Arena1X#1951, Arena1X#1952
@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@GF-Hunter Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
insight-arena-4rll Error Error Oct 20, 2026 10:21am UTC

@Olowodarey
Olowodarey merged commit bb7642e into Arena1X:main Oct 20, 2026
1 of 5 checks passed

This branch had an error being deployed

1 failed deployment
Preview — 119cb109 Deployed Oct 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants