From 1ff3ac50587547938024a8f037e6efad2ebf13f3 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Wed, 11 Mar 2026 20:06:05 -0400 Subject: [PATCH] Add scheduled job to delete old analytics properties from all user profiles. --- finnow-api/source/profile/data_impl_sqlite.d | 18 ++++++++++ finnow-api/source/scheduled_jobs.d | 35 ++++++++++++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/finnow-api/source/profile/data_impl_sqlite.d b/finnow-api/source/profile/data_impl_sqlite.d index 03a367a..07220de 100644 --- a/finnow-api/source/profile/data_impl_sqlite.d +++ b/finnow-api/source/profile/data_impl_sqlite.d @@ -106,6 +106,24 @@ class FileSystemProfileRepository : ProfileRepository { private string getProfilePath(string name) { return buildPath(this.usersDir, username, "profiles", name ~ ".sqlite"); } + + /** + * Helper function that applies a given function to ALL profiles of ALL + * users. + * Params: + * fn = The function to execute against all profiles of all users. + */ + static void doForAllUserProfiles(void function(Profile, ProfileRepository) fn) { + import auth.data; + import auth.data_impl_fs; + UserRepository userRepo = new FileSystemUserRepository(); + foreach (user; userRepo.findAll()) { + ProfileRepository profileRepo = new FileSystemProfileRepository(user.username); + foreach (profile; profileRepo.findAll()) { + fn(profile, profileRepo); + } + } + } } class SqlitePropertiesRepository : PropertiesRepository { diff --git a/finnow-api/source/scheduled_jobs.d b/finnow-api/source/scheduled_jobs.d index fe7e04d..adb5c40 100644 --- a/finnow-api/source/scheduled_jobs.d +++ b/finnow-api/source/scheduled_jobs.d @@ -6,14 +6,37 @@ import slf4d; void startScheduledJobs() { JobSchedule analyticsSchedule = new FixedIntervalSchedule( - hours(1), + days(1), Clock.currTime(UTC()) + seconds(5) ); JobScheduler jobScheduler = new TaskPoolScheduler(); - // jobScheduler.addJob(() { - // info("Computing account balance time series analytics for all users..."); - // info("Done computing analytics!"); - // }, analyticsSchedule); - // jobScheduler.start(); + jobScheduler.addJob(() { + // Clear old analytics data from profiles. + import profile.data; + import profile.data_impl_sqlite; + import profile.model; + FileSystemProfileRepository.doForAllUserProfiles( + (Profile profile, ProfileRepository profileRepo) { + ProfileDataSource ds = profileRepo.getDataSource(profile); + auto props = ds.getPropertiesRepository().findAll(); + bool shouldDelete = false; + foreach (prop; props) { + import std.string : startsWith; + if (startsWith(prop.property, "analytics")) { + shouldDelete = true; + break; + } + } + if (shouldDelete) { + ds.getPropertiesRepository().deleteAllByPrefix("analytics"); + infoF!"Deleted all old \"analytics\" properties for user %s profile %s."( + profile.username, profile.name + ); + } + } + ); + + }, analyticsSchedule); + jobScheduler.start(); } \ No newline at end of file