Running Days Docs
GitHub

Achievement Service

The achievement service tracks milestone progress and detects when users unlock new achievements.

Milestones

Running Days celebrates progress at these milestones:

DaysNameDescription
50First StepsGetting started on your journey
100CenturyTriple digits!
150HalfwayMore than half the year
200CommittedSerious dedication
250EliteAlmost there
300ChampionDefault yearly goal achieved

Functions

detectNewMilestones

Detects milestones crossed between two day counts.

typescript
import { detectNewMilestones } from '@running-days/business-logic';

const newMilestones = detectNewMilestones(previousDays, currentDays);
// Returns: [100, 150] if user went from 99 to 151 days

Parameters:

  • previousDays: Day count before update
  • currentDays: Day count after update

Returns: Array of milestone values crossed

getAchievementStatus

Get detailed status for a specific milestone.

typescript
import { getAchievementStatus } from '@running-days/business-logic';

const status = getAchievementStatus(175, 200);
// Returns:
// {
//   milestone: 200,
//   name: "Committed",
//   unlocked: false,
//   unlockedAt: null,
//   next: { milestone: 200, daysRemaining: 25 }
// }

getAllMilestones

Get status of all milestones for a user.

typescript
import { getAllMilestones } from '@running-days/business-logic';

const milestones = getAllMilestones(currentDays, unlockedDates);
// Returns array of milestone statuses with unlock dates

getNextMilestone

Get the next milestone to achieve.

typescript
import { getNextMilestone } from '@running-days/business-logic';

const next = getNextMilestone(87);
// Returns: { milestone: 100, name: "Century", daysRemaining: 13 }

isMilestoneAchieved

Check if a specific milestone is achieved.

typescript
import { isMilestoneAchieved } from '@running-days/business-logic';

isMilestoneAchieved(150, 175); // true
isMilestoneAchieved(200, 175); // false

UI Integration

Display achievements with appropriate celebration:

typescript
const newMilestones = detectNewMilestones(oldDays, newDays);

for (const milestone of newMilestones) {
  showCelebration(milestone);
  await saveUnlockDate(userId, milestone, new Date());
}

Custom Goals

While milestones are fixed, users can set custom yearly goals (e.g., 200 days instead of 300). The achievement system tracks both:

  • Fixed milestones (always the same)
  • Goal completion (based on user’s target)