Skip to content

Conversation

@otchet-broad
Copy link
Contributor

@otchet-broad otchet-broad commented Apr 21, 2025

Addresses

https://broadworkbench.atlassian.net/browse/DT-1520

Summary

Consent had two state machines for determining if a Data Access Request was in draft form or submitted for a Data Access Committee to consider for approval. This PR aligns the code so that only one state machine exists. It is now centered on submission_date.

When submission_date is non-null, the DAR has been submitted by a RESEARCHER to a DATA ACCESS COMMITTEE for consideration. When the submission_date is null, it is considered a draft. This was the behavior in the existing code paths except for some tests that leveraged methods to short circuit that requirement.

The DataAccessRequest class now computes the fields draft, expired, and expiredAt fields when the submissionDate is set. These three values are now returned to the UI for enrichment.

Of critical importance is the update to DataAccessRequestDAO.findApprovedDARsByDatasetId that now requires DARs to be submitted within the last year in order to be considered "approved." <- This was already completed in #2487

Also added in DataAccessRequestDAO is findSubmittedDarsByTimeRange. This method is intended to be used by a to-be-built notification component that can alert users to expiring DARs. It allows the caller to specify the date range of approved DARs so that notifications can be sent. For example, give me the list of DARs that will expire 30 days from today. Those DARs would have a submission_date during the time of 1745193600.000 to 1745279999.999

To simplify our codebase, other test only methods that were impacting draft state were removed.


Have you read CONTRIBUTING.md lately? If not, do that first.

  • Label PR with a Jira ticket number and include a link to the ticket
  • Label PR with a security risk modifier [no, low, medium, high]
  • PR describes scope of changes
  • Get a minimum of one thumbs worth of review, preferably two if enough team members are available
  • Get PO sign-off for all non-trivial UI or workflow changes
  • Verify all tests go green
  • Test this change deployed correctly and works on dev environment after deployment

dd.dataset_id
FROM data_access_request dar
LEFT JOIN dar_dataset dd ON dd.reference_id = dar.reference_id
WHERE dar.submission_date BETWEEN SYMMETRIC to_timestamp(:begin) AND to_timestamp(:end)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now we can support time range queries for submitted DARs.

@otchet-broad otchet-broad marked this pull request as ready for review April 21, 2025 23:40
@otchet-broad otchet-broad requested a review from a team as a code owner April 21, 2025 23:40
@otchet-broad otchet-broad requested review from rushtong and s-rubenstein and removed request for a team April 21, 2025 23:40
Copy link
Contributor

@rushtong rushtong left a comment

Choose a reason for hiding this comment

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

Love the removal of draft. It would be interesting (not for this PR) to see if we could do something similar for the status field in data.

Copy link
Contributor

@s-rubenstein s-rubenstein left a comment

Choose a reason for hiding this comment

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

Where possible, could you drop comments where the SQL text blocks are logically the same? It looks like a bunch of this is solely formatting changes but I am not sure which is functional and which is format

SELECT dd.dataset_id, dar.id, dar.reference_id, dar.collection_id, dar.parent_id, dar.user_id, dar.create_date, dar.sort_date, dar.submission_date, dar.update_date,
(regexp_replace(dar.data #>> '{}', '\\\\u0000', '', 'g'))::jsonb AS data FROM data_access_request dar
LEFT JOIN dar_dataset dd on dd.reference_id = dar.reference_id
WHERE dar.submission_date is not null
Copy link
Contributor Author

Choose a reason for hiding this comment

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

switching from draft to submission date

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for these comments, they were very helpful!

AND dar.submission_date > now() - interval '1 year'
""")
@SqlQuery(
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove dar.draft + formatting

+ " WHERE dar.draft = true "
+ " AND (LOWER(dar.data->>'status') != 'archived' OR dar.data->>'status' IS NULL) "
+ " ORDER BY dar.update_date DESC")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove dar.draft + formatting

+ " AND (LOWER(dar.data->>'status') != 'archived' OR dar.data->>'status' IS NULL) "
+ " AND dar.user_id = :userId "
+ " ORDER BY dar.sort_date DESC")
"""
Copy link
Contributor Author

@otchet-broad otchet-broad Apr 23, 2025

Choose a reason for hiding this comment

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

remove dar.draft + Formatting.

+ " AND dar.user_id = :userId "
+ " AND (LOWER(dar.data->>'status') != 'archived' OR dar.data->>'status' IS NULL) "
+ " ORDER BY dar.sort_date DESC")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove dar.draft + formatting

+ "SET data = to_jsonb(regexp_replace(:data, '\\\\u0000', '', 'g')), user_id = :userId, sort_date = :sortDate, "
+ "submission_date = :submissionDate, update_date = :updateDate "
+ "WHERE reference_id = :referenceId")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

formatting.

* @param referenceId String
*/
@SqlUpdate("DELETE FROM data_access_request WHERE reference_id = :referenceId")
@SqlUpdate(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting

"UPDATE data_access_request dar "
+ "SET data=jsonb_set((regexp_replace(dar.data #>> '{}', '\\\\u0000', '', 'g'))::jsonb, '{status}', '\"Canceled\"') "
+ "WHERE reference_id IN (<referenceIds>)")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting.

* @param collectionId Integer
*/
@SqlUpdate("DELETE FROM data_access_request WHERE collection_id = :collectionId")
@SqlUpdate(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting.

+ "VALUES (:referenceId, :userId, :createDate, :sortDate, "
+ ":submissionDate, :updateDate, to_jsonb(:data), true)")
"""
INSERT INTO data_access_request
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove draft.

+ "(collection_id, reference_id, user_id, create_date, sort_date, submission_date, update_date, data) "
+ "VALUES (:collectionId, :referenceId, :userId, :createDate, :sortDate, " +
":submissionDate, :updateDate, to_jsonb(:data))")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting.

void updateDraftForCollection(@Bind("collectionId") Integer collectionId,
"""
UPDATE data_access_request
SET submission_date = now(), collection_id = :collectionId
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove the use of draft

LEFT JOIN dar_dataset dd ON dd.reference_id = dar.reference_id
WHERE dar.submission_date BETWEEN SYMMETRIC :begin AND :end
""")
List<DataAccessRequest> findSubmittedDarsByTimeRange(@Bind("begin") Timestamp begin,
Copy link
Member

Choose a reason for hiding this comment

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

Why is this API being added? I don't see it used anywhere in this PR other than tests.

Before when I asked about SYMMETRIC, my question was really about how do we know that this needs to support out-of-order queries? Without an example of how it will be used in code, it's hard to tell.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ticket includes an AC of "Mechanism to find expired DARs"
This is an example of a "Mechanism to find expired DARs"

Copy link
Member

@pshapiro4broad pshapiro4broad Apr 23, 2025

Choose a reason for hiding this comment

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

If the only need is to find expired, could it be done with a query that has a single bound? Adding the service method that uses this API (e.g. DataAccessRequestService.findExpiredDars()) would help me understand how this API works to meet the AC.

Is the idea that, instead of keeping track of which DARs we've notified users of, we instead find only those that expired in a specific time range? That could work but we'd need to be very precise about when the check is done, to avoid missing some DARs or notifying twice for others.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly. As discussed at standup this morning, we have a ticket to notify DAR submitters when their DAR will expire in 30 days (from today). We'll know the starting time and ending time of the query range. That's the use case I was specifically thinking about.
Do others exist? Sure.
Are they in other tickets? Yes.
Do I expect this to change? Maybe. It's just an example.

+ "FROM data_access_request "
+ "WHERE (LOWER(data->>'status') != 'archived' "
+ "OR data->>'status' IS NULL)")
"""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

formatting

+ " SET data = jsonb_set ((data #>> '{}')::jsonb, '{status}', '\"Archived\"', true) "
+ " WHERE reference_id IN (<referenceIds>)")
"""
UPDATE data_access_request
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting

+ "VALUES (:referenceId, :datasetId) "
+ "ON CONFLICT DO NOTHING")
"""
INSERT INTO dar_dataset (reference_id, dataset_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.

Formatting.

+ "VALUES (:referenceId, :datasetId) "
+ "ON CONFLICT DO NOTHING")
"""
INSERT INTO dar_dataset (reference_id, dataset_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.

Formatting

@SqlUpdate("DELETE FROM dar_dataset WHERE reference_id = :referenceId")
@SqlUpdate(
"""
DELETE FROM dar_dataset WHERE reference_id = :referenceId
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting.

"dar.id AS dar_id, dar.reference_id AS dar_reference_id, dar.collection_id AS dar_collection_id, "
+
"dar.parent_id AS dar_parent_id, dar.draft AS dar_draft, dar.user_id AS dar_userId, " +
"dar.parent_id AS dar_parent_id, dar.user_id AS dar_userId, " +
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove draft

return datasets;
}

public void setDatasets(Set<Dataset> datasets) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting.

Copy link
Member

@pshapiro4broad pshapiro4broad left a comment

Choose a reason for hiding this comment

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

Some possible changes; also I would like to avoid storing computed values if that's possible here. But looks OK overall.

@otchet-broad otchet-broad merged commit beb8e10 into develop Apr 23, 2025
14 checks passed
@otchet-broad otchet-broad deleted the otchet-dt-1520-add-dar-expired-status branch April 23, 2025 19:05
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.

5 participants