Skip to content
Snippets Groups Projects

Services for persisting Cycle Analytics group stages

Merged Adam Hegyi requested to merge persisting-ca-group-stages into master
All threads resolved!

What does this MR do?

This change introduces service objects for creating, updating and finding cycle analytics group stages.

The models and validations have been already merged, so this change only contains the service objects. In an upcoming MR these services will be exposed via an API to the fronted.

Specs

Cycle Analytics provides 7 default stages to everyone (FOSS feature), these 7 stages should be available on the group level as well, however reporters should be able to create additional, custom stages.

  Defined for a Group, stored in `analytics_cycle_analytics_group_stages` table.

  +---------------------+
  | Stages              |
  |   +-------------+   |
  |   |   Stage A   |   |     
  |   |             |   |     
  |   +-------------+   |     
  |   | Start Event |   |
  |   +-------------+   |     
  |   | End Event   |   |      
  |   +-------------+   |  
  |                     |
  |   +-------------+   |
  |   |   Stage B   |   |
  |   |             |   |
  |   +-------------+   |
  |   | Start Event |   |
  |   +-------------+   |
  |   | End Event   |   |
  |   +-------------+   |
  |                     |
  |   ...               |
  +---------------------+

Requirements (future):

  • Ability to change the order of stages.
  • Ability to hide a default stage.

To fulfil these requirements, we must also persist the 7 default stages in the database. To keep the record creation at minimum and avoid background migrations, the 7 default stages is going to be persisted as soon as the reporter attempts to make a change to the list of stages (until then, we provide them as in-memory objects):

  • Creating a new, customized stage (for the first time).
  • Hiding a default stage.

Queries

Note 1: this is the first time we query the stages. We have nothing in the prod DB.

Note 2: We expect that a group will have max 10-15 analytics_cycle_analytics_group_stages records (premium only).

Exists Query

SELECT  1 AS one FROM "analytics_cycle_analytics_group_stages" WHERE "analytics_cycle_analytics_group_stages"."group_id" = 15 AND "analytics_cycle_analytics_group_stages"."custom" = true AND "analytics_cycle_analytics_group_stages"."id" != 3 LIMIT 1;

Uses the index

Limit  (cost=0.14..2.17 rows=1 width=4) (actual time=0.007..0.007 rows=0 loops=1)
   ->  Index Scan using index_analytics_ca_group_stages_on_group_id_and_name on analytics_cycle_analytics_group_stages  (cost=0.14..2.17 rows=1 width=4) (actual time=0.006..0.006 rows=0 loops=1)
         Index Cond: (group_id = 15)
         Filter: (custom AND (id <> 3))
 Planning Time: 0.129 ms
 Execution Time: 0.028 ms

Find by name query

SELECT "analytics_cycle_analytics_group_stages".* FROM "analytics_cycle_analytics_group_stages" WHERE "analytics_cycle_analytics_group_stages"."group_id" = 4 AND "analytics_cycle_analytics_group_stages"."name" = 'issue' LIMIT 1;

Uses the index

Limit  (cost=0.14..2.16 rows=1 width=578) (actual time=0.016..0.016 rows=0 loops=1)
   ->  Index Scan using index_analytics_ca_group_stages_on_group_id_and_name on analytics_cycle_analytics_group_stages  (cost=0.14..2.16 rows=1 width=578) (actual time=0.014..0.015 rows=0 loops=1)
         Index Cond: ((group_id = 4) AND ((name)::text = 'issue'::text))
 Planning Time: 0.163 ms
 Execution Time: 0.042 ms
(5 rows)

Screenshots

stages

Does this MR meet the acceptance criteria?

Conformity

closes #32570 (closed)

Edited by 🤖 GitLab Bot 🤖

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Matija Čupić
  • Thank you for tackling this @ahegyi! I did a first round of review. It's mostly about test architecture and code style.

  • Adam Hegyi resolved all threads

    resolved all threads

  • Adam Hegyi added 154 commits

    added 154 commits

    Compare with previous version

  • Author Maintainer

    Thanks for the thorough review @matteeyah, really great suggestions. Pipeline is passing so :ping_pong:

  • assigned to @matteeyah

    • Resolved by Adam Hegyi

      contexts should define a "set of circumstances" or parameters for an example. Their names usually start with "when ..." (e.g. "when data is invalid") to closer describe the variables state in that context. Specs in this MR are in imperative - i.e. they group a set of examples instead of defining a specific state that is being tested.

  • Adam Hegyi added 1 commit

    added 1 commit

    Compare with previous version

  • Adam Hegyi added 1 commit

    added 1 commit

    Compare with previous version

  • assigned to @matteeyah

    • Resolved by Adam Hegyi

      Generally speaking we usually only have inline example definitions it { is_expected.to ... } or block bodied example definitions it 'example name' do ... end within a single example group (like a context or describe). I think we shouldn't mix them - if we can use the inline form everywhere in the example group great, if not they should all be blocks.

    • Resolved by Matija Čupić

      This already looks several times more clean and readable than the initial iteration. Thank you for taking the effort to make sure the code is top notch @ahegyi!

      I left a couple more, less important, stylistic spec related discussions. We're getting really close.

  • Adam Hegyi resolved all threads

    resolved all threads

  • Adam Hegyi resolved all threads

    resolved all threads

  • Adam Hegyi added 1 commit

    added 1 commit

    Compare with previous version

  • Adam Hegyi added 1 commit

    added 1 commit

    Compare with previous version

  • assigned to @matteeyah

  • removed typefeature label

  • Adam Hegyi added 226 commits

    added 226 commits

    Compare with previous version

  • Adam Hegyi resolved all threads

    resolved all threads

  • Adam Hegyi resolved all threads

    resolved all threads

  • assigned to @splattael

  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Peter Leitzen
  • Hey @ahegyi :wave:

    Starting now, I'll be OOO for 3 months (yes, months - Parental Leave).

    You might need to choose another maintainer for this MR. Sorry for the friction and I hope all goes well so this MR will be merged timely :thumbsup:

  • Adam Hegyi added 328 commits

    added 328 commits

    Compare with previous version

  • Adam Hegyi added 1 commit

    added 1 commit

    • 418ee7bf - Move stage services to Stages namespace

    Compare with previous version

  • Adam Hegyi added 1 commit

    added 1 commit

    • 68347056 - Move stage services to Stages namespace

    Compare with previous version

  • Adam Hegyi resolved all threads

    resolved all threads

    • Author Maintainer
      Resolved by Adam Hegyi

      Hi @jprovaznik,

      Could you do the maintainer review?

      The initial maintainer review was done by @splattael, however he'll be OOO for a while. I added most of the suggested changes except introducing a Base service class. Reasoning:

      • Currently we have 3 services: List, Create, Update.
      • The constructor is the same for Create and Update.
      • All 3 services have the execute method, however the implementation differs.
      • The execute method for Create and Update is similar but not the same. I find it overkill to generalize it (could use template method with calling super), it wouldn't reduce the duplication and would introduce more abstraction.
        • permission check, persisting method, returning http_status are different.
    • Resolved by Jan Provaznik

      Thanks @ahegyi, overall this looks good :thumbsup:! I left some comments inline, let me know what you think.

      (out of scope of this MR): It's little bit hard to review this w/o seeing also the code which would actually use it (API or controllers). In future, when doing this iteratively, it might be easier to split the work not by code layers (first models, then all services then controllers), but rather by functionality (first ability to list default stages, then add ability to create a new one, then update existing...) - these can be hidden behind a feature flag during development.

  • Adam Hegyi resolved all threads

    resolved all threads

  • Adam Hegyi added 300 commits

    added 300 commits

    Compare with previous version

  • Jan Provaznik
  • Thanks @ahegyi, left some replies inline, let me know what you think.

  • Adam Hegyi added 135 commits

    added 135 commits

    Compare with previous version

  • Adam Hegyi added 1 commit

    added 1 commit

    • 3014840b - Move stage services to Stages namespace

    Compare with previous version

  • Adam Hegyi added 64 commits

    added 64 commits

    Compare with previous version

  • Jan Provaznik approved this merge request

    approved this merge request

  • Jan Provaznik resolved all threads

    resolved all threads

  • Thanks @ahegyi, LGTM :thumbsup:

  • merged

  • Jan Provaznik mentioned in commit 679c13da

    mentioned in commit 679c13da

  • 🤖 GitLab Bot 🤖 changed the description

    changed the description

  • Please register or sign in to reply
    Loading