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

fix: Adds activity_id filter to answers dates query to fix problem with dataviz calendar (M2-8215) #1680

Draft
wants to merge 13 commits into
base: develop
Choose a base branch
from

Conversation

ramirlm
Copy link
Contributor

@ramirlm ramirlm commented Dec 10, 2024

📝 Description

🔗 Jira Ticket M2-8215

This change introduces a new (optional) field to the answers dates endpoint, which includes an additional filter to the query and removes incorrectly retrieved answers.

🪤 Peer Testing

  • Access Dataviz for Limited users, and search for activities with answers from limited users on different dates.
  • Only the answers for the user within that activity should be seen in the correct days.

✏️ Notes

  • As an optional field, this change shall not cause any incompatibility issues.

Copy link

➡️ Preview environment created: Click Me!

Copy link

❌ E2E tests failed

@ramirlm ramirlm changed the title fix: Adds activity_id filter to answers dates query to fix problem with dataviz calendar (M2-8215) fix: Adds activity_id filter to answers dates query to fix problem with dataviz calendar (M2-8216) Dec 10, 2024
@ramirlm ramirlm changed the title fix: Adds activity_id filter to answers dates query to fix problem with dataviz calendar (M2-8216) fix: Adds activity_id filter to answers dates query to fix problem with dataviz calendar (M2-8215) Dec 10, 2024
@farmerpaul farmerpaul self-requested a review December 10, 2024 15:56
@@ -34,6 +34,7 @@ class AppletSubmissionsFilter(BaseQueryParams):
class AppletSubmitDateFilter(BaseQueryParams):
respondent_id: uuid.UUID | None
target_subject_id: uuid.UUID | None
activity_id: str | None
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 just checking in with @ChaconC about task definition. I think this endpoint should also accept an optional activity_flow_id. Stay tuned!

Copy link
Contributor

Choose a reason for hiding this comment

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

Or maybe use a field named activity_or_flow_id and in query use same code we are using in other endpoints

                case(
                    (
                        AnswerSchema.flow_history_id.isnot(None),
                        AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == str(activity_or_flow_id),
                    ),
                    else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) == str(activity_or_flow_id),
                )

src/apps/answers/crud/answers.py Show resolved Hide resolved
Copy link
Contributor

@rcmerlo rcmerlo left a comment

Choose a reason for hiding this comment

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

You should add automated tests

@@ -34,6 +34,7 @@ class AppletSubmissionsFilter(BaseQueryParams):
class AppletSubmitDateFilter(BaseQueryParams):
respondent_id: uuid.UUID | None
target_subject_id: uuid.UUID | None
activity_or_flow_id: str | None
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this remain uuid.UUID to maintain validation rules? I don't see anywhere else in the codebase where we type activity_or_flow_id as str.

Were you running into a typing issue that prompted you to switch to str?

Copy link
Contributor

Choose a reason for hiding this comment

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

pleas see comment bellow

Comment on lines +241 to +244
AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == str(filters.activity_or_flow_id), # noqa: E501
),
else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) # noqa: E501
== str(filters.activity_or_flow_id),
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 clear why we need to convert the UUID to string. The id_from_history_id functions return a UUID | none type, so it should be fine to do quality comparison against another UUID | none type, no? Maybe I'm missing something…

Suggested change
AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == str(filters.activity_or_flow_id), # noqa: E501
),
else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) # noqa: E501
== str(filters.activity_or_flow_id),
AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == filters.activity_or_flow_id,
),
else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) == filters.activity_or_flow_id,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@farmerpaul If you see this field in the database, the uuid is saved with a version in the end, causing an error parsing as uuid, that's why I had to use string instead

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, but filters.activity_or_flow_id should be UUID, because we should validate it by pydantic, we can not accept a free format string, so original code should work, calling str(filters.activity_or_flow_id) will have same behavior

Copy link
Contributor

Choose a reason for hiding this comment

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

please, do not use # noqa: E501 you can break the line, use make cqf to automatically fix this, ignoring a lint or mypy error should be always the last solution

Copy link
Contributor

Choose a reason for hiding this comment

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

causing an error parsing as uuid, that's why I had to use string instead

@ramirlm I am not seeing any errors related to the types in my VS Code when using UUID. I'm also not seeing any errors that suggest that # noqa: E501 is needed anywhere. With the code I suggested above, everything works fine, no issues. The reason make cqf isn't making any formatting changes is because there's no issue with the formatting, at least on my end.

I'm curious where you're seeing errors @ramirlm – is it in VS Code? Perhaps there's a configuration issue? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CleanShot 2024-12-13 at 09 39 04@2x

@farmerpaul this is the error

Copy link
Contributor

@farmerpaul farmerpaul Dec 16, 2024

Choose a reason for hiding this comment

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

Oh, you're talking about a runtime error. I was only talking about pylance/linting errors till now, but I've reproduced your runtime error.

The error you showed is actually the result of the str() coercion above, which is what I was trying to point out is not correct. The str() is coercing None (when the parameter is omitted) to a zero-length string '', which is not a well-formed UUID string.

When I updated the code to what I suggested above – without the str() coercion:

                (
                    AnswerSchema.flow_history_id.isnot(None),
                    AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == filters.activity_or_flow_id,
                ),
                else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) == filters.activity_or_flow_id,

the error went away.

Are you seeing something different?

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, now I understood the problem here,

  • without str() in filters.activity_or_flow_id, we have a comparison between str resulted from AnswerSchema.id_from_history_id() and UUID, this will not work, we should keep str()
  • We should include this where clause only when filters.activity_or_flow_id is not None, it make more sense to me, because it is a optional filter

Copy link
Contributor

Choose a reason for hiding this comment

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

@rcmerlo I don't quite follow your first bullet. According to my VS Code, AnswerSchema.id_from_history_id returns a UUID or None, not a string:

CleanShot 2024-12-16 at 11 27 23@2x

So I don't see the reason for keeping str().

However, I agree we should omit this clause altogether if activity_or_flow_id is None.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, you are right, I was confused because of hybrid_method decorator from SQLAlchemy used in this method

@@ -34,6 +34,7 @@ class AppletSubmissionsFilter(BaseQueryParams):
class AppletSubmitDateFilter(BaseQueryParams):
respondent_id: uuid.UUID | None
target_subject_id: uuid.UUID | None
activity_or_flow_id: str | None
Copy link
Contributor

Choose a reason for hiding this comment

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

pleas see comment bellow

@@ -295,6 +297,7 @@ async def test_list_submit_dates(
respondentId=tom.id,
fromDate=datetime.date.today() - datetime.timedelta(days=10),
toDate=datetime.date.today() + datetime.timedelta(days=10),
activityOrFlowId=applet.activities[0].id,
),
Copy link
Contributor

Choose a reason for hiding this comment

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

all tests are using only activites, please add one with a activity flow

Comment on lines +241 to +244
AnswerSchema.id_from_history_id(AnswerSchema.flow_history_id) == str(filters.activity_or_flow_id), # noqa: E501
),
else_=AnswerSchema.id_from_history_id(AnswerSchema.activity_history_id) # noqa: E501
== str(filters.activity_or_flow_id),
Copy link
Contributor

Choose a reason for hiding this comment

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

please, do not use # noqa: E501 you can break the line, use make cqf to automatically fix this, ignoring a lint or mypy error should be always the last solution

@ramirlm
Copy link
Contributor Author

ramirlm commented Dec 12, 2024

@rcmerlo make cfq did not fix this issue, that's why I added the noqa command. Any suggestions? Thanks!

@ramirlm ramirlm marked this pull request as draft December 16, 2024 12:41
@ramirlm
Copy link
Contributor Author

ramirlm commented Dec 16, 2024

It will be necessary to change the reviews and flows endpoints as well. This is back to draft
CC @ChaconC @rcmerlo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants