Skip to content

Conversation

@vagisha
Copy link
Collaborator

@vagisha vagisha commented Aug 18, 2025

Rationale

Submitters often forget to make their data public even after the associated paper is published. We should send them reminders periodically.

Changes

  • Send automated reminders to submitters of private datasets.
  • Reminders can be enabled, and properties such as "delay until first reminder", "reminder frequency" and "extension duration" can be configured via the Panorama Public Admin Console,
  • The Admin Console also provides an option to send reminders manually.
  • Submitters can request an extension of the private data status or request deletion of their data from Panorama Public.
  • Links to request extension or deletion are included in the reminder message.
  • Extension and deletion requests by the submitter are posted to the data message thread for record keeping.
  • Escape tilde (~) when generating notification messages. In the LabKey Markdown flavor, text between single tildes (e.g., ~strikethrough~) as well as double tildes is rendered as strikethrough.

vagisha added 14 commits May 21, 2025 15:08
…r job can be turned on via the admin console
- Made SendPrivateDataRemindersAction a FormViewAction
- DatasetStatus columns can be accessed via the ExperimentAnnotations table
- Added constructor to pass the Journal (e.g. Panorama Public) and a list of experiments to PrivateDataReminderJob
- "Panorama Public" journal folder can be selected in a drop-down.
…cript.

- Fixed RequestExtensionAction and RequestDeletionAction.
- Bumped schema cersion in PanoramaPublicModule.
- PrivateDataReminderJob skips experiments that should be be getting reminders.
- Fixed column name in DatasetStatusTableInfo.
- Added more testing in PrivateDataReminderTest.
…tildes (e.g., ~strikethrough~) is rendered as strikethrough.
- Moved date calculations to PrivateDateReminderSettings.  Added unit tests
- Improvements to PrivateDataReminderJob
- Fixed PrivateDataReminderTest
@vagisha vagisha requested a review from labkey-jeckels August 18, 2025 07:27
Copy link
Contributor

@labkey-jeckels labkey-jeckels left a comment

Choose a reason for hiding this comment

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

This is a big PR. I reviewed the code, but let me know if there are specific areas where you want extra attention. Also, I didn't do any testing on the work. Let me know if you're wanting help on that.

}
}

public static class DatasetStatusColumn extends DataColumn
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest overriding isSortable() and isFilterable() to return false. It tends to be confusing when you're sorting/filtering on a value different from the one being rendered.

{
errors.reject(ERROR_MSG, "Please enter a value for 'Reminder frequency'.");
}
else if (form.getReminderFrequency() < 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does 0 make sense here, or should this ensure that the value >= 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Does 0 make sense here, or should this ensure that the value >= 1?

0 is allowed to support automated testing in PrivateDataReminderTest. In practice on Panorama Public, we wouldn’t set it below 1 unless we intentionally want reminders to start immediately after submission. I’ve added clarifying notes on the form to make this behavior clear.

HtmlView view = new HtmlView(DIV(
DIV(getConfirmViewMessage()),
DIV("Title: " + _exptAnnotations.getTitle()),
DIV("Submitted on: " + DateUtil.formatDateTime(_exptAnnotations.getCreated(), "MMMM d, yyyy")),
Copy link
Contributor

Choose a reason for hiding this comment

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

This date format is hard-coded in a number of places. Extract as a constant?

}
else
{
messageBody.append("We were unable to locate the source folder for this data in your project. ")
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this be clear enough to the recipient? Do we want to encourage them to check and delete if appropriate, as perhaps it was renamed or moved? Or is the assumption that they should keep it around?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will this be clear enough to the recipient? Do we want to encourage them to check and delete if appropriate, as perhaps it was renamed or moved? Or is the assumption that they should keep it around?

The message should only appear if the source folder has actually been deleted (or the corresponding row in the experimentannotations table was removed). If the folder was simply moved or renamed, we can still locate it through the container column in experimentannotations.

I haven’t encountered the deletion case yet, but if it happens, the message is probably OK. Also, if the user is requesting deletion of their data on Panorama Public, the data in the source folder is likely no longer important to them.

I am open to ideas on improving the message to make it clearer to the data submitter.

- Use table name constant and date format string constant.
- isSortable and isFilterable return false for DatasetStatusColumn.
- Added clarifying text for form input elements in privateDataRemindersSettingsForm.jsp
@vagisha
Copy link
Collaborator Author

vagisha commented Aug 25, 2025

This is a big PR. I reviewed the code, but let me know if there are specific areas where you want extra attention. Also, I didn't do any testing on the work. Let me know if you're wanting help on that.

Thanks for the review! If you could have another look at PrivateDataMessageScheduler that would be great. This is my first attempt at running a scheduled job (It should run at 8AM every morning).

I have a added an automated test - PrivateDataReminderTest which:

  • Creates a Panorama Public project.
  • Creates, submits and copies 3 datasets to Panorama Public.
  • Updates the reminder settings and runs the PrivateDataReminderJob job through the admin console.
  • Confirms reminder messages are posted (or not) depending on the configured settings and data status (public / private, extension / deletion requested).

If you are able to do additional testing, that would be very welcome.

catch(Exception e)
{
_log.error("Error queuing PrivateDataReminderJob", e);
ExceptionUtil.logExceptionToMothership(null, e);
Copy link
Contributor

Choose a reason for hiding this comment

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

You're already logging the exception to the local log file, so no need for ExceptionUtil to log it again.

Suggested change
ExceptionUtil.logExceptionToMothership(null, e);
ExceptionUtil.logExceptionToMothership(null, e, false);

@labkey-jeckels
Copy link
Contributor

I did a little manual testing, largely based on the setup done in PrivateDataReminderTest.

I wasn't able to get a manually created submission to send reminders. It got skipped because it didn't think that it was the latest version. ExperimentAnnotationsManager.isCurrentVersion() returned false because getDataVersion() was null.

I didn't have all the data needed for a ProteomeExchange submission so I skipped that. Is that why the version was null? Should the reminder code fire on submissions in that state?

- Added an option in the Private Date Reminder Setting form to enter a time for reminder jobs to run.
…of RequestDeletionAction.

- Fixed SQLException by updating DatasetStatus handling:
  - Delete row in DatasetStatus when data is resubmitted and a new Panorama Public copy is created.
  - Delete row in DatasetStatus when the Panorama Public copy is deleted.
  - Prevents SQLException from shortUrl FK constraint when deleting Panorama Public copy followed by source data folder, or vice versa.
- Cleanup user accounts in PrivateDataReminderTest.
…tationsId. DatasetStatus is associated with a particular copy of the data. If a new copy is made, the data status resets. Status associated with the previous copy is no longer relevant.
@vagisha
Copy link
Collaborator Author

vagisha commented Aug 29, 2025

I did a little manual testing, largely based on the setup done in PrivateDataReminderTest.

I wasn't able to get a manually created submission to send reminders. It got skipped because it didn't think that it was the latest version. ExperimentAnnotationsManager.isCurrentVersion() returned false because getDataVersion() was null.

I didn't have all the data needed for a ProteomeExchange submission so I skipped that. Is that why the version was null? Should the reminder code fire on submissions in that state?

Thanks for testing this! All experiments copied to a Panorama Public project using the data copy pipeline job should have a dataversion. You don't need a ProteomeXchange setup, so I am not sure what happened here. If you have time for a quick Zoom call, I would like to understand what happened.

The reminder job iterates over all private datasets (or the ones you select if running manually), and posts reminders only for those that meet the conditions in PrivateDataReminderJob.getReminderDecision(). One of those conditions is that the dataset must be the most recent version.

Could you please try this workflow for testing manually:

  • Run PrivateDataReminderTest` until folder setup and copying to Panorama Public is complete (line 83). You can stop the test here.
  • Open Admin Console > Panorama Public > Private Data Reminder Settings.
    • If you have more than one Panorama Public journal projects on your dev machine, choose the one created for the test (Panorama Public ☃~!@$&()_+{}-=[],.#äöüÅ) from the Choose Panorama Public Folder drop-down.
    • Click Send Reminders Now. You should see a table listing all private datasets.
  • To simulate submitter actions after reminder messages are posted:
    • Go to the data folder
    • In the Targeted MS Experiment webpart, open the control menu and click Support Messages.
    • The reminder message should appear at the end of the message thread with links to request extension or deletion.
      (I should make it possible to do this directly from the Targeted MS Experiment webpart)
  • If you request an extension or deletion, then re-post reminders, those datasets should be skipped in subsequent reminder job runs.

NOTE: I committed some changes:

  • Delete rows in the new DatasetStatus table when related experiments are deleted. This also prompted a schema update - replacing the ShortUrl column with an ExperimentAnnotationsId column, since status is tied to a particular copy of the data and should reset on resubmission.
  • Added option to specify a run time for automatic reminder jobs.

@labkey-jeckels
Copy link
Contributor

I did a little manual testing, largely based on the setup done in PrivateDataReminderTest.
I wasn't able to get a manually created submission to send reminders. It got skipped because it didn't think that it was the latest version. ExperimentAnnotationsManager.isCurrentVersion() returned false because getDataVersion() was null.
I didn't have all the data needed for a ProteomeExchange submission so I skipped that. Is that why the version was null? Should the reminder code fire on submissions in that state?

Thanks for testing this! All experiments copied to a Panorama Public project using the data copy pipeline job should have a dataversion. You don't need a ProteomeXchange setup, so I am not sure what happened here. If you have time for a quick Zoom call, I would like to understand what happened.

The reminder job iterates over all private datasets (or the ones you select if running manually), and posts reminders only for those that meet the conditions in PrivateDataReminderJob.getReminderDecision(). One of those conditions is that the dataset must be the most recent version.

Could you please try this workflow for testing manually:

  • Run PrivateDataReminderTest` until folder setup and copying to Panorama Public is complete (line 83). You can stop the test here.

  • Open Admin Console > Panorama Public > Private Data Reminder Settings.

    • If you have more than one Panorama Public journal projects on your dev machine, choose the one created for the test (Panorama Public ☃~!@$&()_+{}-=[],.#äöüÅ) from the Choose Panorama Public Folder drop-down.
    • Click Send Reminders Now. You should see a table listing all private datasets.
  • To simulate submitter actions after reminder messages are posted:

    • Go to the data folder
    • In the Targeted MS Experiment webpart, open the control menu and click Support Messages.
    • The reminder message should appear at the end of the message thread with links to request extension or deletion.
      (I should make it possible to do this directly from the Targeted MS Experiment webpart)
  • If you request an extension or deletion, then re-post reminders, those datasets should be skipped in subsequent reminder job runs.

NOTE: I committed some changes:

  • Delete rows in the new DatasetStatus table when related experiments are deleted. This also prompted a schema update - replacing the ShortUrl column with an ExperimentAnnotationsId column, since status is tied to a particular copy of the data and should reset on resubmission.
  • Added option to specify a run time for automatic reminder jobs.

Sorry it took me a while to respond. I followed those test steps and everything looked fine when I worked from the folders that that test set up for me.

Let me know if you still want to find a time to connect on what went wrong in my original test pass. I imagine I did something wrong in submitting the data, but I'm not sure what.

@vagisha
Copy link
Collaborator Author

vagisha commented Sep 9, 2025

Thanks of testing. It will be good to understand what went wrong in your initial tests. I will follow over email to schedule a time.

@vagisha vagisha merged commit 2a8e7d5 into release25.7-SNAPSHOT Sep 9, 2025
5 checks passed
@vagisha vagisha deleted the 25.7_fb_private_data_status_message branch September 9, 2025 21:29
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