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

Add API to void entries in the passed locations #677

Closed
Tracked by #1499
mahalakshme opened this issue Jan 2, 2024 · 14 comments
Closed
Tracked by #1499

Add API to void entries in the passed locations #677

mahalakshme opened this issue Jan 2, 2024 · 14 comments
Assignees

Comments

@mahalakshme
Copy link
Contributor

mahalakshme commented Jan 2, 2024

Motivation:

Frequently implementors are in need to void entries in the database using SQLs. This is prone to errors. Hence we can develop APIs that will do the task so that they need not run SQLs.

Related tickets:

https://avni.freshdesk.com/a/tickets/3343
https://avni.freshdesk.com/a/tickets/3345
https://app.zenhub.com/workspaces/avni-impl--support-5cf8e458bf08585333fd64ac/issues/gh/avniproject/apfodishanutrition/118

Reason:

In the ground, because of collaboration issues, sometimes locations get created in the wrong catchments. In this particular case, users of the right catchment with the actual location have already registered the individuals. And users(who have left the job) with the catchment with incorrect location have also registered individuals. So we need to delete the locations, remove the locations from the catchments and delete all the entries in the location. Its better to develop APIs at unit level and hence we can just do voiding all entries in the location and others can be achieved via UI.

AC:

  • Add an API called /api/voidEntries with parameter that accepts an array of location UUIDs
  • When the API is called void all the entries(subjects, encounters, enrolments, approval status etc.,) in that location
  • Add the above and this: /subjectMigration/bulk to the API documentation
  • Feel free to change the above technical implementation details without changing the overall intention.
@mahalakshme mahalakshme converted this from a draft issue Jan 2, 2024
@mahalakshme mahalakshme moved this from In Analysis to In Analysis Review in Avni Product Jan 2, 2024
@mahalakshme mahalakshme moved this from In Analysis Review to Ready in Avni Product Jan 3, 2024
@mahalakshme mahalakshme moved this from Ready to In Analysis in Avni Product Jan 4, 2024
@mahalakshme mahalakshme moved this from In Analysis to Ready in Avni Product Jan 4, 2024
@himeshr himeshr moved this from Ready to In Progress in Avni Product Jan 4, 2024
@himeshr himeshr self-assigned this Jan 4, 2024
@himeshr
Copy link
Contributor

himeshr commented Jan 5, 2024

@mahalakshme Let me know your thoughts regarding the following..

Clarification needed:

  • What privilege(s) should the user have to be able to invoke this operation.?
  • Shouldn't this be run as a background job, as this could take a long time to complete and the connection could close before that.?
  • What are the limits regarding the scale of entities that could be voided as part of single request.? In terms of addressLevels
  • Should we return summary information regarding entities that were voided as part of the response.?
  • Should the void of all entries happen as part of single transaction or separate transaction for each entity type.?

@mahalakshme
Copy link
Contributor Author

mahalakshme commented Jan 5, 2024

@himeshr

  • the user should have orgAdmin permission
  • currently for the requirement for each address level the no of individuals and encounter combined is less than 500. I think we can keep it simple for now - no need to make it bg job. So may be to avoid such problems we can have the API accept just single location
  • As mentioned above, for the requirement we ve now, currently the scale is low
  • No need summary information - just status information should suffice since the users are going to be our implementors they can check from prod read db. If its easy, may be we can just return the count of each entity type(individual/encounter, etc.,) deleted.
  • Whatever is simple - its okay if last_modified_date_time is gonna be same.

@mahalakshme
Copy link
Contributor Author

@himeshr Moved it to 7.0

@himeshr himeshr moved this from In Progress to Hold in Avni Product Jan 8, 2024
@mahalakshme
Copy link
Contributor Author

@himeshr just reminder that we need to complete this for 7.0 release. U can move it to Ready as well, if u think there is no dependency on u.

@himeshr himeshr removed their assignment Jan 15, 2024
@himeshr himeshr moved this from Hold to Ready in Avni Product Jan 15, 2024
@petmongrels petmongrels moved this from Ready to In Progress in Avni Product Jan 15, 2024
@petmongrels petmongrels moved this from In Progress to Ready in Avni Product Jan 15, 2024
@petmongrels petmongrels moved this from Ready to In Progress in Avni Product Jan 16, 2024
@petmongrels petmongrels self-assigned this Jan 16, 2024
petmongrels added a commit that referenced this issue Jan 17, 2024
…updating last modified date time to ensure that too many records do not have the same last modified datetime (required for sync).

WIP - void subjects at location.
petmongrels added a commit that referenced this issue Jan 22, 2024
…cs for bulk subject migration and bulk subject tree voiding.
@petmongrels petmongrels moved this from In Progress to Code Review Ready in Avni Product Jan 22, 2024
@1t5j0y 1t5j0y moved this from Code Review Ready to In Code Review in Avni Product Jan 24, 2024
@1t5j0y
Copy link
Contributor

1t5j0y commented Jan 24, 2024

@petmongrels https://editor.swagger.io/?url=https://raw.githubusercontent.com/avniproject/avni-server/master/avni-server-api/src/main/resources/api/external-api.yaml shows a few errors in the swagger yaml.

Semantic error at paths./api/subjectTree.delete.requestBody
DELETE operations cannot have a requestBody.
Jump to line 1161
Semantic error at components.schemas.BulkSubjectMigrationBody.properties.subjectTypeIds
Schemas with 'type: array', require a sibling 'items: ' field
Jump to line 1672
Semantic error at components.schemas.VoidSubjectCriteriaBody.properties.addressIds
Schemas with 'type: array', require a sibling 'items: ' field
Jump to line 1678

Guess we can't do much about the first error but we can probably address the others.

@1t5j0y 1t5j0y moved this from In Code Review to QA Ready in Avni Product Jan 24, 2024
@petmongrels
Copy link
Contributor

petmongrels commented Jan 25, 2024 via email

@himeshr
Copy link
Contributor

himeshr commented Jan 25, 2024

@petmongrels https://editor.swagger.io/?url=https://raw.githubusercontent.com/avniproject/avni-server/master/avni-server-api/src/main/resources/api/external-api.yaml shows a few errors in the swagger yaml.

Semantic error at paths./api/subjectTree.delete.requestBody
DELETE operations cannot have a requestBody.
Jump to line 1161
Semantic error at components.schemas.BulkSubjectMigrationBody.properties.subjectTypeIds
Schemas with 'type: array', require a sibling 'items: ' field
Jump to line 1672
Semantic error at components.schemas.VoidSubjectCriteriaBody.properties.addressIds
Schemas with 'type: array', require a sibling 'items: ' field
Jump to line 1678

Guess we can't do much about the first error but we can probably address the others.

@petmongrels would it be better to make this a POST API, with a "voidAll" keyword in the PATH.
"POST => /api/subjectTree/voidAll" instead of "DELETE => /api/subjectTree"

@AchalaBelokar AchalaBelokar moved this from QA Ready to In QA in Avni Product Feb 5, 2024
@AchalaBelokar AchalaBelokar moved this from In QA to QA Ready in Avni Product Feb 8, 2024
@mahalakshme mahalakshme moved this from QA Ready to In QA in Avni Product Feb 20, 2024
@mahalakshme
Copy link
Contributor Author

moving this back since I am not doing the QA

@mahalakshme mahalakshme moved this from In QA to QA Ready in Avni Product Feb 20, 2024
@vinayvenu vinayvenu moved this from QA Ready to In QA in Avni Product Feb 20, 2024
@vinayvenu
Copy link
Member

If this should be part of the external API, then

  1. Addresses in other APIs are in the form of a hashmap. Shouldn't we use the hashmap, or the uuid/externalId?
  2. Do we need to have the reason as part of the API?

@vinayvenu
Copy link
Member

vinayvenu commented Feb 21, 2024

Test cases

  1. Permissions
    • Should not work without permissions
    • Should not void when there are no permissions ( Failed )
    • Should not void when admin
  2. Tree
    • Should void everything (individual, individual_relationship, encounter, program_enrolment, program_encounter, checklist, checklist_item, group_subject, comment, comment_thread, subject_migration, subject_program_eligibility, entity_approval_status) ( Failed )
    • Should not fail if there are no subjects
    • Should not fail when there is one bad address line ( Failed )
  3. API
    • Should fail when API structure is incorrect
  4. API response
    • Should provide details in response
  5. Large transactions
    • Test against 1000 subjects and see what happens

Issues

Issue 1

Missing address id throws an error

Error 500
User: hasiru_ka_uat
Environment: prerelease
Request

{
    "addressIds": [2453]
}

Error: https://pastebin.com/raw/ywU5gJ31
Note: The address id exists in a different organisation. The issue seems to happen whenever the address id does not exist

Issue 2

In the above, the user did not have access to this API, but was still able to access the API. It looks like our privilege checker does not look for voided user_group entries.

Issue 3

The last_modified_date_time is not spread over time. It is the same value across all rows on the same table (see address level 11520 on staging)

Issue 4

comment_thread is not voided while its parent is

Notes

1.7 seconds on staging for 1 subject. For 145 subjects, it took 2.85 seconds. 1.45 seconds again for 1203 subjects. The response improves at log pace. Did not verify for all tables

@vinayvenu vinayvenu moved this from In QA to QA Failed in Avni Product Feb 21, 2024
@petmongrels petmongrels moved this from QA Failed to In Progress in Avni Product Feb 21, 2024
petmongrels added a commit that referenced this issue Feb 21, 2024
… queries. fixed failure in address checking.
@petmongrels petmongrels moved this from In Progress to Code Review Ready in Avni Product Feb 21, 2024
@mahalakshme mahalakshme moved this from Code Review Ready to In Code Review in Avni Product Feb 22, 2024
@mahalakshme mahalakshme moved this from In Code Review to QA Ready in Avni Product Feb 22, 2024
@mahalakshme mahalakshme moved this from QA Ready to Code Review with Comments in Avni Product Feb 23, 2024
@mahalakshme
Copy link
Contributor Author

@petmongrels I just realised now is calculated from the clients mobile time, which might not be inline with the server's time. Hence I think using random() to update last_modified_date_time may cause issues.

@petmongrels
Copy link
Contributor

petmongrels commented Feb 23, 2024 via email

@petmongrels petmongrels moved this from Code Review with Comments to QA Ready in Avni Product Feb 26, 2024
@himeshr himeshr moved this from QA Ready to In QA in Avni Product Feb 28, 2024
@himeshr
Copy link
Contributor

himeshr commented Feb 28, 2024

Standard use-case to void all entries corresponding to specified address_level is working as expected.
But we still have issue with Privilege Check.

Issue 1: Missing address id should throw a validation error
Status: Resolved
User: hasiru_ka_uat
Environment: prerelease
Request:

{
    "addressIds": [2453]
}

Response:

{
    "locations": {},
    "notFoundAddresses": [
        2453
    ]
}

Issue 2: In the above, the user did not have access to this API, but was still able to access the API. It looks like our privilege checker does not look for voided user_group entries.
Status: Unresolved

Below Sql query returns true, due to voided flags being ignored:

select bool_or(groups.has_all_privileges) from users
    left outer join user_group ug on users.id = ug.user_id
    left outer join groups on ug.group_id = groups.id
where users.id = 10260;

Its used in AccessControlService.userExistsAndHasAllPrivileges(contextUser) -> userRepository.hasAllPrivileges(contextUser.getId());

Whereas the sql query returns false, once we include voided checks:

select bool_or(groups.has_all_privileges) from users
    left outer join user_group ug on users.id = ug.user_id and not ug.is_voided
    left outer join groups on ug.group_id = groups.id and not groups.is_voided
where users.id = 10260 and not ug.is_voided;

Issue 3: The last_modified_date_time is not spread over time.
Status: Resolved


Issue 4: comment_thread is not voided while its parent is
Status: Resolved


@himeshr himeshr moved this from In QA to QA Failed in Avni Product Feb 28, 2024
@petmongrels petmongrels moved this from QA Failed to QA Ready in Avni Product Feb 28, 2024
@himeshr
Copy link
Contributor

himeshr commented Feb 28, 2024

Issue 2: In the above, the user did not have access to this API, but was still able to access the API. It looks like our privilege checker does not look for voided user_group entries.
Status: Unresolved
Request:
{
"addressIds": [412317]
}
Response:

User doesn't have privilege of type: MultiTxEntityTypeUpdate

@himeshr himeshr closed this as completed Feb 28, 2024
@github-project-automation github-project-automation bot moved this from QA Ready to Done in Avni Product Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

5 participants