Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Signup Method: Signup Flow and Shift Structure #1202

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

felixrindt
Copy link
Member

@felixrindt felixrindt commented Feb 9, 2024

  • QualificatioMixStructure
  • race condition
  • what happens when deleting a Qualification configured in the shift structures
  • check PDF export
  • update tests to work again
  • add new tests
  • update plugin dev docs
  • update user docs and make sure it's linked correctly
  • profiling and performance improvements
  • display flow/structure descriptions
  • migration
  • delete old plugin

@felixrindt felixrindt added [C] enhancement Changes to an existing feature making it better [C] refactoring refactors code without changing functionality labels Feb 9, 2024
ephios/core/services/matching.py Outdated Show resolved Hide resolved
ephios/core/services/matching.py Show resolved Hide resolved
ephios/core/signup/structure/base.py Outdated Show resolved Hide resolved
ephios/core/signup/views.py Outdated Show resolved Hide resolved
@felixrindt felixrindt force-pushed the signup-flow-refactor branch 3 times, most recently from ce6d367 to ff18ad2 Compare March 29, 2024 12:30
@coveralls
Copy link

coveralls commented Mar 29, 2024

Coverage Status

coverage: 87.342% (-0.5%) from 87.828%
when pulling bf14865 on signup-flow-refactor
into d0ae64b on main.

@felixrindt felixrindt marked this pull request as ready for review April 17, 2024 12:37
Copy link
Contributor

@jeriox jeriox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed until matching.py

logger = logging.getLogger(__name__)


class BaseSignupFlowConfigurationForm(SignupConfigurationForm):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added those to have a common base class for the Flow Config Forms, although they aren't any different from the common SignupCOnfigurationForm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see.
i generally feel that the (class) structure of the code became a lot more complicated and is harder to understand. I think this is caused by a lot of classes (with empty ones like this) and very similar names (base and basic) that are hard to tell apart. maybe we can have a chat about whether we can improve on that

from ephios.core.signup.flow.participant_validation import NoSignupSignupActionValidator


class ManualSignupActionValidator(NoSignupSignupActionValidator):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is this different from NoSignupSignupActionValidator?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual and Coupled both use that superclass but customize the message.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't that be part of the NoSignupSignupActionValidator? that already defines a message which feels kinda doubled


class InstantConfirmSignupFlow(BaseSignupFlow):
slug = "instant_confirmation"
verbose_name = _("Direct signup")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether it is clear what "direct" means here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please suggest a better name. This is hard 🙈

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i still like instant confirmation as it tells exactly what the user can expect to happen

@property
def slug(self):
"""
A unique identifier for this signup method.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

structure, same below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I got to search for mentions of signup_method and replace it in some more places...

@@ -0,0 +1,116 @@
from django import forms
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are the built-in flows in core but the structures in plugins?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's similar to what we had before, but I agree they could both be a plugin, or both in core. I think because they can be a plugin, it should be a plugin, but also because they provide a lot of the base implementation useful when building custom flows and structures, they should be in core.
I'm more leaning towards the plugin though. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer both the same way regardless of what we decide on
I experienced multiple instances where people where confused why they couldn't add events and why they needed to enable such basic functionality upfront. Also it rarely makes sense to disable the builtin flows/structures, even if there are custom ones. so i would lean towards core, but the problem probably could be fixed by better pre-activating the builtin flows/methods

def get_checkers(self):
def check_maximum_number_of_participants(shift, participant):
if (
not shift.signup_flow.uses_requested_state
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should make that configurable (happily as a followup)

^^^^^^^^^^^

Configure named teams with individual min/max counts and qualification requirement to
sort participants into. Participants can even be asked for their preferred team.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe an example to better understand what this can be used for?

ephios/core/services/matching.py Show resolved Hide resolved
)
if not position.required_skill <= participant_skill:
# the participant does not have some required skill
return -1 # avoid 0 as that causes trouble with the matching lib
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BenBals thinks that it can occur that the algorithm will prefer a matching with someone unqualified because it guarantees that the matching fulfills \lvert M \rvert = \min(\lvert U \rvert, \lvert V \rvert),

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can he provide an example where it breaks? When we thought through it we came to the conclusion it shouldn't happen, no proof obvsl...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I adjusted the scoring so the case Ben constructed should be handled correctly (added a test too).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first glance, this looks like it should work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for having a look. When thinking about the complex matching I might look into the solvers you mentioned 🙈

Copy link
Contributor

@jeriox jeriox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made it through

@@ -0,0 +1,43 @@
# Generated by Django 5.0.3 on 2024-03-25 18:45
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think that belongs here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C] enhancement Changes to an existing feature making it better [C] refactoring refactors code without changing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants