Redesign analytics as internal plugin-based architecture #30
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: McPringle/fitpub#30
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
We have made several changes to
ActivitySummaryServiceon a separate branch to fix issues in the current analytics implementation. Those changes solved specific problems, but the resulting design became too complex.Instead of continuing to patch the existing approach, we want to redesign analytics from the ground up with a simpler and more maintainable architecture that incorporates the lessons learned.
Goal
Replace the current analytics implementations with a new internal plugin-based architecture.
This does not mean loading external code or JARs. "Plugin" here refers only to the internal project structure: analytics features should be implemented as isolated, clearly defined modules within the codebase.
The redesign should cover at least:
Proposed architecture
Core plugin contract
Use a single base interface for all analytics plugins:
AnalyticsPluginAnalyticsPluginType getPluginType()String getPluginKey()Each plugin must have:
pluginTypepluginKeypluginTypeis defined centrally by FitPub through an enum.pluginKeyis defined by the concrete plugin implementation.Suggested enum values:
ACHIEVEMENTPERSONAL_INFOPERSONAL_RECORDSUMMARYTRAININGWhy a single interface
We initially discussed a hierarchy such as
AchievementsPlugin,SummaryPlugin, etc., but the current direction is to keep the contract simpler:getPluginType()getPluginKey()This keeps the system easier to reason about and avoids marker-interface complexity unless category-specific contracts are actually needed later.
Execution model
Analytics recalculation should be handled by a central orchestration service.
FitPub should trigger analytics recalculation when activities are:
The orchestration service should then:
Transaction strategy
Each plugin recalculation should run in a separate transaction so that:
Consequence: analytics become eventually consistent, which is acceptable as long as it is a deliberate design decision.
Storage model discussion
Rejected option: one table per plugin
We do not want a separate database table for each individual plugin.
That would create too much schema growth and too much storage boilerplate.
Considered option: one global analytics table
We discussed a fully generic single-table design, but this has risks:
Preferred direction: one table per plugin type
The current preferred direction is:
This is a good middle ground because plugin types are:
This keeps the schema explicit without exploding the number of tables.
Why one table per plugin type
Different plugin types have different semantics and lifecycles:
ACHIEVEMENT: earned states or achievement eventsPERSONAL_RECORD: best values with source/reference activitySUMMARY: current and/or period-based aggregationsPERSONAL_INFO: user-specific status/info metricsTRAINING: training-related evaluations, recommendations, or load metricsA separate table per plugin type allows:
Open design direction for storage
Within each plugin-type table, entries should still be identified by:
user_idplugin_keyDepending on the type, additional fields may be needed, for example:
activity_idcalculated_at,earned_at,recorded_atA
payloadfield (for examplejsonb) may still be useful, but only as part of a structured per-type model, not as the only storage concept.Architectural principles
The redesign should enforce these boundaries:
Expected benefits
ActivitySummaryServicedesignOpen questions
AnalyticsPluginexpose beyondgetPluginType()andgetPluginKey()?Next step
Define a minimal target model for:
AnalyticsPluginpluginTypeSUMMARYfor "current week"That should be enough to validate the architecture before migrating all analytics features.