FE - Cycle analytics architecture improvements
Background
Recently we built out group level cycle analytics, this involved moving cycle analytics from a project level, to a group level and refactoring existing HAML functionality into Vue components. The initial approach was to simply port existing functionality as we were preparing to add new features.
Since then we have been building additional features:
- Customizable cycle analytics
- Group analytics over time charts
- Visualizing tasks by type
- Visualizing flow of tasks
Previously we had a single endpoint for cycle analytics data, but by completion of https://gitlab.com/gitlab-org/gitlab-ee/issues/12196 we will have multiple endpoints to fetch individual sections of data. Additionally we now have multiple "top-level" components that have different data requirements.
| Endpoint | Result |
|---|---|
GET /-/analytics/cycle_analytics/summary |
returns: Summary data |
GET|POST /-/analytics/cycle_analytics/stages |
returns: Stages, Custom stage events, post creates a custom stage |
GET /-/analytics/cycle_analytics/stages/:stage_id/records |
returns: Stage events |
GET /-/analytics/cycle_analytics/stages/:stage_id/median |
returns: Stage median value |
GET /-/analytics/cycle_analytics/stages/:stage_id/duration_chart |
returns: Duration chart data |
GET|PUT|DELETE /-/analytics/cycle_analytics/stages/:stage_id |
returns a stage, update / delete stage |
GET /groups/:group_id/-/labels |
returns: Group labels |
GET /-/analytics/type_of_work/tasks_by_type |
returns: Task by type data |
GET /-/analytics/type_of_work/tasks_by_stage - not implemented yet |
I expect this would return the Tasks by stage data |
| Section | Summary data | Stages | Group labels | Stage events | Stage medians | Tasks by type | Tasks by stage | Custom stage events | Duration chart data |
|---|---|---|---|---|---|---|---|---|---|
| A | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| B | [ ] | [x] | [x] | [x] | [x] | [ ] | [ ] | [x] | [ ] |
| C | [ ] | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [x] |
| D | [ ] | [ ] | [x] | [ ] | [ ] | [x] | [ ] | [ ] | [ ] |
| E | [ ] | [ ] | [x] | [ ] | [ ] | [ ] | [x] | [ ] | [ ] |
Challenges
After a group is selected a series of request are sent to fetch the data required to render the stage table and charts required.
- Multiple requests to different endpoints needed to fetch all the required data
- Vuex store is getting quite large with some dependent requests
- Stage medians requires Stages request first
- Stage events requires Stages request first
- Tasks by type requires group labels
Possible improvements
Split /-/analytics/cycle_analytics/stages endpoint
Currently this endpoint returns the stages for cycle analytics as well as the events needed to create a custom analytics stage, changes to the stage list (adding a stage, hiding a default stage, removing a custom stage and eventually updating the order of stages) require a refetch to the endpoint to retrieve the updated list of stages, returning the custom stage events seems a bit wasteful here.
Pros
- We only fetch the custom stage events when we need them (when we display the form)
- Clearer purpose for the endpoint
Cons
- Another endpoint
- Possibly premature optimization / yak-shaving
Split the major components into several modules
We should be able to confidently split the base.vue component into smaller modules, similar to the approach taken for productivity analytics:
- Summary data (A)
- Stage table (B)
- Charts (C, D, E)
This should provide a clearer distinction between the data and requests needed for a specific module and the data needed across all the modules.
Pros
- Seems to be an accepted Vuex pattern
- Gives us smaller more maintainable apps to work with moving forward
- Similar approach already taken with productivity analytics so we would be adding consistency to analytics
- We can better work independently on new features / enhancements with less conflicts
- Easier to progressively load parts of the page as requests for data complete
Cons
- Some refactoring required
- Probably additional testing needed
Move requests to a graphql endpoint
We have graphql available but have not explored this yet for analytics features, if part of our vision is to provide graphql as the main way to interact with our APIs, now seems like a good time to explore what this might mean for analytics.
Pros
- Single endpoint for all our current data
- Easier discoverability of cycle analytics data when building FE features
- Looser coupling between UI and API endpoints
- Good opportunity to understand potential issues we will encounter moving analytics endpoints to graphql
Cons
- Needs a bit more investigation
- Extra time needed to get up to speed + possibly more engineering burden
- Adding another layer of complexity
Continue along
Pros
- We can continue to ship features
- No additional work required
- We can continue to iterate on possible ways forward while gathering user feedback
Cons
- Potentially harder to bring new FE's up to speed since theres already a lot going on
- More moving parts that are interrelated, more chance of bugs / regressions
- Kicking the can down the road, future features will probably be more time consuming to develop than they need to be
