Function bodies 25 total
cn function · typescript · L4-L6 (3 LOC)app/lib/utils.ts
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}main function · typescript · L9-L91 (83 LOC)prisma/seed.ts
async function main() {
console.log('Seeding database...')
// Seed UserProfile
await prisma.userProfile.upsert({
where: { id: 1 },
update: {},
create: { id: 1, weightKg: 82.3, heightCm: 178, waistCm: 97.2, targetWaistRatio: 0.5 },
})
console.log(' ✓ UserProfile')
// Seed UserStats
await prisma.userStats.upsert({
where: { id: 1 },
update: {},
create: { id: 1 },
})
console.log(' ✓ UserStats')
// Seed exercises
const exerciseMap = new Map<string, number>()
for (const ex of EXERCISES) {
const created = await prisma.exercise.upsert({
where: { name: ex.name },
update: { muscleGroup: ex.muscleGroup, equipment: ex.equipment, description: ex.description },
create: { name: ex.name, muscleGroup: ex.muscleGroup, equipment: ex.equipment, description: ex.description },
})
exerciseMap.set(ex.name, created.id)
}
console.log(` ✓ ${EXERCISES.length} exercises`)
// Seed workout templates
for (const tmpl of WORKOUcheckAchievements function · typescript · L5-L101 (97 LOC)server/utils/achievements.ts
export async function checkAchievements(): Promise<string[]> {
const [
achievements,
mealLogCount,
mealTemplateCount,
sessionCount,
exerciseLogs,
bodyMeasurementCount,
journalCount,
streaks,
userStats,
bodyMeasurements,
profile,
healthImportCount,
] = await Promise.all([
prisma.achievement.findMany(),
prisma.mealLog.count(),
prisma.mealTemplate.count({ where: { isActive: true } }),
prisma.workoutSession.count({ where: { isComplete: true } }),
prisma.exerciseLog.findMany({ select: { comfortRating: true, sessionId: true } }),
prisma.bodyMeasurement.count(),
prisma.journalEntry.count(),
calculateStreaks(),
prisma.userStats.findFirst({ where: { id: 1 } }),
prisma.bodyMeasurement.findMany({ where: { waistCm: { not: null } }, orderBy: { date: 'asc' }, select: { waistCm: true } }),
prisma.userProfile.findFirst({ where: { id: 1 } }),
prisma.healthImport.count(),
])
const heightCm = profile?parseHealthData function · typescript · L23-L33 (11 LOC)server/utils/health-parser.ts
export function parseHealthData(content: string, filename: string): ParseResult {
const ext = filename.split('.').pop()?.toLowerCase()
if (ext === 'json') return parseJSON(content)
if (ext === 'csv') return parseCSV(content)
// Try to auto-detect
const trimmed = content.trim()
if (trimmed.startsWith('[') || trimmed.startsWith('{')) return parseJSON(content)
return parseCSV(content)
}parseCSV function · typescript · L35-L66 (32 LOC)server/utils/health-parser.ts
function parseCSV(content: string): ParseResult {
const lines = content.trim().split('\n')
if (lines.length < 2) return { metrics: [], errors: ['CSV has no data rows'], dataType: 'MIXED' }
const headers = lines[0].split(',').map((h) => h.trim().toLowerCase().replace(/['"]/g, ''))
const metrics: HealthMetricInput[] = []
const errors: string[] = []
const types = new Set<string>()
for (let i = 1; i < lines.length; i++) {
const values = parseCSVLine(lines[i])
if (values.length !== headers.length) {
errors.push(`Row ${i + 1}: column count mismatch (expected ${headers.length}, got ${values.length})`)
continue
}
const row: Record<string, string> = {}
headers.forEach((h, idx) => { row[h] = values[idx] })
try {
const metric = normaliseRow(row, i + 1)
if (metric) {
metrics.push(metric)
types.add(metric.metricType)
}
} catch (e: any) {
errors.push(`Row ${i + 1}: ${e.message}`)
}
}
return { mparseJSON function · typescript · L68-L105 (38 LOC)server/utils/health-parser.ts
function parseJSON(content: string): ParseResult {
let data: any
try {
data = JSON.parse(content)
} catch {
return { metrics: [], errors: ['Invalid JSON'], dataType: 'MIXED' }
}
// Detect Health Auto Export format: { data: { metrics: [...], workouts: [...] } }
if (data?.data?.metrics && Array.isArray(data.data.metrics) && data.data.metrics[0]?.name && data.data.metrics[0]?.data) {
return parseHealthAutoExport(data)
}
const records = Array.isArray(data) ? data : data.data ?? data.metrics ?? data.records ?? []
if (!Array.isArray(records)) return { metrics: [], errors: ['JSON must contain an array of records'], dataType: 'MIXED' }
const metrics: HealthMetricInput[] = []
const errors: string[] = []
const types = new Set<string>()
for (let i = 0; i < records.length; i++) {
try {
const row: Record<string, string> = {}
for (const [k, v] of Object.entries(records[i])) {
row[k.toLowerCase().replace(/[_\s]/g, '')] = String(v)
parseHealthAutoExport function · typescript · L119-L211 (93 LOC)server/utils/health-parser.ts
function parseHealthAutoExport(json: any): ParseResult {
const metrics: HealthMetricInput[] = []
const errors: string[] = []
const types = new Set<string>()
const metricGroups: any[] = json.data.metrics || []
const workouts: any[] = json.data.workouts || []
for (const group of metricGroups) {
const metricType = HAE_METRIC_MAP[group.name]
if (!metricType || !VALID_METRIC_TYPES.includes(metricType)) continue
const samples: any[] = group.data || []
for (let i = 0; i < samples.length; i++) {
try {
const sample = samples[i]
const date = parseHAEDate(sample.date)
if (!date) {
errors.push(`${group.name}[${i}]: invalid date "${sample.date}"`)
continue
}
let value = sample.qty
if (typeof value !== 'number' || isNaN(value)) continue
if (group.name === 'walking_running_distance' && group.units === 'm') {
value = value / 1000
}
metrics.push({ date, metricTypProvenance: Repobility (https://repobility.com) — every score reproducible from /scan/
parseHAEDate function · typescript · L213-L217 (5 LOC)server/utils/health-parser.ts
function parseHAEDate(dateStr: string | undefined): Date | null {
if (!dateStr) return null
const date = new Date(dateStr)
return isNaN(date.getTime()) ? null : date
}normaliseRow function · typescript · L219-L280 (62 LOC)server/utils/health-parser.ts
function normaliseRow(row: Record<string, string>, rowNum: number): HealthMetricInput | null {
const dateStr = row.date || row.startdate || row.start_date || row.timestamp || row.datetime
if (!dateStr) throw new Error('Missing date field')
const date = new Date(dateStr)
if (isNaN(date.getTime())) throw new Error(`Invalid date: ${dateStr}`)
let metricType = (row.type || row.metrictype || row.metric_type || row.metric || '').toUpperCase()
if (!metricType) {
if (row.steps) metricType = 'STEPS'
else if (row.distance && (row.pace || row.duration)) metricType = 'RUN'
else if (row.weight || row.bodymass) metricType = 'WEIGHT'
else if (row.vo2max) metricType = 'VO2MAX'
else if (row.heartrate || row.heartrateavg) metricType = 'HEART_RATE'
else throw new Error('Cannot determine metric type')
}
if (metricType === 'RUNNING' || metricType === 'RUN_DISTANCE') metricType = 'RUN'
if (metricType === 'WALKING' || metricType === 'WALK_DISTANCE') metricType = parseOptionalFloat function · typescript · L282-L286 (5 LOC)server/utils/health-parser.ts
function parseOptionalFloat(val: string | undefined): number | undefined {
if (!val || val === 'undefined' || val === 'null' || val === '') return undefined
const n = parseFloat(val)
return isNaN(n) ? undefined : n
}parseOptionalInt function · typescript · L288-L292 (5 LOC)server/utils/health-parser.ts
function parseOptionalInt(val: string | undefined): number | undefined {
if (!val || val === 'undefined' || val === 'null' || val === '') return undefined
const n = parseInt(val, 10)
return isNaN(n) ? undefined : n
}detectDataType function · typescript · L294-L304 (11 LOC)server/utils/health-parser.ts
function detectDataType(types: Set<string>): string {
if (types.size === 0) return 'MIXED'
if (types.size === 1) {
const type = [...types][0]
if (type === 'STEPS') return 'STEPS'
if (type === 'RUN' || type === 'WALK') return 'RUNS'
if (type === 'WEIGHT') return 'WEIGHT'
if (type === 'VO2MAX') return 'VO2MAX'
}
return 'MIXED'
}parseCSVLine function · typescript · L306-L329 (24 LOC)server/utils/health-parser.ts
function parseCSVLine(line: string): string[] {
const result: string[] = []
let current = ''
let inQuotes = false
for (let i = 0; i < line.length; i++) {
const char = line[i]
if (char === '"') {
if (inQuotes && line[i + 1] === '"') {
current += '"'
i++
} else {
inQuotes = !inQuotes
}
} else if (char === ',' && !inQuotes) {
result.push(current.trim())
current = ''
} else {
current += char
}
}
result.push(current.trim())
return result
}recalculateRPG function · typescript · L4-L198 (195 LOC)server/utils/recalculate.ts
export async function recalculateRPG() {
const [
profile,
completedSessions,
allExerciseLogs,
mealLogs,
mealTemplateCount,
bodyMeasurements,
journalEntries,
achievementsUnlocked,
healthImportCount,
] = await Promise.all([
prisma.userProfile.findFirst({ where: { id: 1 } }),
prisma.workoutSession.findMany({ where: { isComplete: true }, include: { exercises: true } }),
prisma.exerciseLog.findMany({ include: { session: { select: { date: true } } } }),
prisma.mealLog.findMany({ select: { date: true, calories: true, proteinG: true, fiberG: true, mealSlot: true } }),
prisma.mealTemplate.count({ where: { isActive: true } }),
prisma.bodyMeasurement.count(),
prisma.journalEntry.findMany({ select: { energyLevel: true, sleepQuality: true } }),
prisma.achievement.count({ where: { unlockedAt: { not: null } } }),
prisma.healthImport.count(),
])
const weightLbs = (profile?.weightKg ?? 82.3) * 2.20462
const calorieTargetcalculateStats function · typescript · L87-L95 (9 LOC)server/utils/rpg.ts
export function calculateStats(inputs: StatInputs) {
return {
discipline: calcDiscipline(inputs),
nutrition: calcNutrition(inputs),
strength: calcStrength(inputs),
recovery: calcRecovery(inputs),
consistency: calcConsistency(inputs),
}
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
calcDiscipline function · typescript · L98-L104 (7 LOC)server/utils/rpg.ts
function calcDiscipline(i: StatInputs): number {
const currentStreakScore = Math.min(25, (i.currentStreak / 30) * 25)
const longestStreakScore = Math.min(25, (i.longestStreak / 60) * 25)
const activityScore = (i.activeDaysPercent / 100) * 25
const journalScore = Math.min(25, (i.journalEntryCount / 50) * 25)
return clamp(Math.round(currentStreakScore + longestStreakScore + activityScore + journalScore))
}calcNutrition function · typescript · L107-L114 (8 LOC)server/utils/rpg.ts
function calcNutrition(i: StatInputs): number {
const calorieScore = Math.min(30, (i.calorieComplianceDays / 30) * 30)
const proteinScore = Math.min(30, (i.proteinTargetDays / 30) * 30)
const fiberScore = Math.min(20, (i.fiberTargetDays / 20) * 20)
const templateScore = Math.min(10, (i.mealTemplateCount / 10) * 10)
const loggingScore = Math.min(10, (i.daysWithMealsLogged / 60) * 10)
return clamp(Math.round(calorieScore + proteinScore + fiberScore + templateScore + loggingScore))
}calcStrength function · typescript · L117-L123 (7 LOC)server/utils/rpg.ts
function calcStrength(i: StatInputs): number {
const sessionScore = Math.min(30, (i.completedSessions / 50) * 30)
const overloadScore = Math.min(30, (i.exercisesProgressed / 10) * 30)
const comfortScore = Math.min(20, (i.avgComfortRating / 5) * 20)
const volumeScore = Math.min(20, (i.totalSetsLogged / 500) * 20)
return clamp(Math.round(sessionScore + overloadScore + comfortScore + volumeScore))
}calcRecovery function · typescript · L126-L132 (7 LOC)server/utils/rpg.ts
function calcRecovery(i: StatInputs): number {
const kneeScore = Math.min(30, (i.kneeExerciseAvgComfort / 5) * 30)
const sleepScore = Math.min(25, (i.avgSleepQuality / 5) * 25)
const energyScore = Math.min(25, (i.avgEnergyLevel / 5) * 25)
const comebackScore = Math.min(20, (i.comebackSessions / 10) * 20)
return clamp(Math.round(kneeScore + sleepScore + energyScore + comebackScore))
}calcConsistency function · typescript · L135-L141 (7 LOC)server/utils/rpg.ts
function calcConsistency(i: StatInputs): number {
const workoutScore = Math.min(30, (i.workoutsPerWeekAvg / 3) * 30)
const mealScore = Math.min(25, (i.mealLoggingDaysPerWeekAvg / 7) * 25)
const measurementScore = Math.min(25, (i.weeksWithMeasurement / 12) * 25)
const scheduleScore = Math.min(20, (i.activeDaysPercent / 100) * 20)
return clamp(Math.round(workoutScore + mealScore + measurementScore + scheduleScore))
}clamp function · typescript · L143-L145 (3 LOC)server/utils/rpg.ts
function clamp(value: number): number {
return Math.max(0, Math.min(100, value))
}calculateXP function · typescript · L148-L174 (27 LOC)server/utils/rpg.ts
export function calculateXP(inputs: {
completedSessions: number
daysWithAllMeals: number // days with breakfast+lunch+dinner logged
proteinTargetDays: number
bodyMeasurements: number
journalEntries: number
achievementsUnlocked: number
longestStreak: number
progressiveOverloads: number
}): number {
let xp = 0
xp += inputs.completedSessions * 100
xp += inputs.daysWithAllMeals * 50
xp += inputs.proteinTargetDays * 25
xp += inputs.bodyMeasurements * 75
xp += inputs.journalEntries * 25
xp += inputs.progressiveOverloads * 150
if (inputs.longestStreak >= 7) xp += 300
if (inputs.longestStreak >= 14) xp += 500
if (inputs.longestStreak >= 30) xp += 1000
xp += inputs.achievementsUnlocked * 200
return xp
}toDateString function · typescript · L60-L62 (3 LOC)server/utils/streak.ts
function toDateString(date: Date): string {
return date.toISOString().slice(0, 10)
}Same scanner, your repo: https://repobility.com — Repobility
daysBetween function · typescript · L64-L67 (4 LOC)server/utils/streak.ts
function daysBetween(a: Date, b: Date): number {
const msPerDay = 86400000
return Math.round((new Date(toDateString(b)).getTime() - new Date(toDateString(a)).getTime()) / msPerDay)
}addDays function · typescript · L69-L73 (5 LOC)server/utils/streak.ts
function addDays(date: Date, days: number): Date {
const result = new Date(date)
result.setDate(result.getDate() + days)
return result
}