Conversation
…iliationIdAndUserRole and updated search functions in the User model
…to findByAffiliationId
added a research output question to the local default template
…d added debugging to troublehsoot request feedback failure
…n-users-page Updated resolvers and models for Admin Users page
Added debugging to troubleshoot request feedback failure
fix bug in data migration to add research output question to default …
…ng and checks for when feedback is not enabled or there are no feedback emails. Also, fixed the updateAffiliation resolver so that it checks for input.ssoEmailDomains and input.subheaderLinks because that was breaking the resolver
…d is false, since the frontend will do the check and disable the request link
Fixed bugs in removeProjectFunding to get it to work
Added override for brace-expansion to v5.0.8
… into feature/update-delete-api-support
Support for Adding/Updating/Deleting an entire Plan at once
…-token-logic Add password reset token logic
…-os-populate.ts' to run
Added back the missing 'fast-xml-parser'
… tags for questions. Updated question resolvers to manage tags, and remove tags from section resolver. Updated guidanceService to use questionTags if there are any, and fall back to sectionTags. Also made sure to copy over questionTags in generateSectionVersion and generateQuestionVersion
Updates for moving best practice tags from Section to Question
… into feature/update-delete-api-support
Minor tweaks to entirePlanX resolvers to support updated REST API
Update dependencies
Merging development into stage
jupiter007
approved these changes
Aug 4, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR merges stage into main and brings in several new backend capabilities for the DMPTool Apollo Server, including password reset support, contact-us email handling, EZID registration plumbing, and a shift of “best practice” tag associations from Sections to Questions (including versioning support).
Changes:
- Add password reset token storage + GraphQL schema/resolvers + email template support.
- Add Question tag associations (questionTags/versionedQuestionTags) and update cloning/versioning flows to carry tags forward.
- Add EZID REST datasource + DataCite XML builder + transaction support in the MySQL datasource/context plumbing.
Reviewed changes
Copilot reviewed 141 out of 154 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Adds skipLibCheck to TS build configuration. |
| src/utils/helpers.ts | Adds token hashing and future-date helper utilities. |
| src/services/userService.ts | Archives anonymized users. |
| src/services/sectionService.ts | Ensures question tags are loaded before question versioning. |
| src/services/questionService.ts | Versions question tags into versionedQuestionTags. |
| src/services/planService.ts | Adds DataCite XML builder for EZID publish workflow. |
| src/services/emailService.ts | Adds Contact Us + Reset Password email functionality and reply-to support. |
| src/services/affiliationService.ts | Adds shared resolveAffiliation helper for “Other affiliation” handling. |
| src/services/tests/sectionService.spec.ts | Updates mocks/tests for section versioning + question tag propagation. |
| src/services/tests/questionService.spec.ts | Adds tests for versioning question tags. |
| src/services/tests/projectService.spec.ts | Adjusts context mocking for sqlDataSource usage. |
| src/services/tests/integrationVersioning.spec.ts | Extends integration test to include question tags in versioning. |
| src/services/tests/emailService.spec.ts | Adds tests for contact-us and reset-password emails. |
| src/services/tests/collaboratorService.spec.ts | Formatting-only adjustment. |
| src/services/tests/affiliationService.spec.ts | Adds tests for resolveAffiliation behavior. |
| src/scripts/sql/research-output-json-fix-commonStandardId.sql | Adds maintenance SQL to backfill commonStandardId in RO table JSON columns. |
| src/scripts/sql/README.md | Documents the purpose of scripts/sql helper scripts. |
| src/scripts/sql/QuestionJSON-helpers.sql | Adds helper SQL to delete RO questions/answers. |
| src/scripts/sql/plan-fix-missing-planOwners.sql | Adds helper SQL to repair missing primary project owners. |
| src/schemas/versionedTemplate.ts | Adds versionedTemplate(id: Int!) query. |
| src/schemas/versionedGuidance.ts | Makes tagId nullable in schema. |
| src/schemas/user.ts | Expands user queries/mutations and adds new User fields. |
| src/schemas/section.ts | Removes tags fields from section inputs. |
| src/schemas/question.ts | Adds tags field to Question and tag inputs to add/update question inputs. |
| src/schemas/project.ts | Adds userProjects query and plans field to ProjectSearchResult. |
| src/schemas/plan.ts | Adds paginated plans query and multiple “entire plan” mutations/inputs. |
| src/schemas/passwordReset.ts | Introduces password reset schema (validate + send email + reset). |
| src/schemas/member.ts | Makes projectId optional on AddProjectMemberInput and adds affiliationName to update input. |
| src/schemas/funding.ts | Makes projectId optional on AddProjectFundingInput. |
| src/schemas/contactUs.ts | Adds Contact Us mutation schema. |
| src/schemas/answer.ts | Adds answer add/update input types. |
| src/schema.ts | Wires in new schema modules (contactUs, passwordReset). |
| src/resolvers/versionedTemplate.ts | Adds resolver for versionedTemplate query with auth/error handling. |
| src/resolvers/template.ts | Copies question tags when cloning templates/questions. |
| src/resolvers/section.ts | Removes section tag association handling; copies tags at the question level when cloning. |
| src/resolvers/question.ts | Adds tag association handling and chained Question.tags resolver. |
| src/resolvers/project.ts | Adds userProjects query and ProjectSearchResult.plans resolver. |
| src/resolvers/passwordReset.ts | Implements password reset flows using reset tokens and email. |
| src/resolvers/member.ts | Uses resolveAffiliation for affiliation selection/creation logic. |
| src/resolvers/funding.ts | Fixes project funding deletion ordering vs planFundings FK constraints. |
| src/resolvers/feedback.ts | Refactors feedback request flow and adds logging. |
| src/resolvers/contactUs.ts | Implements submitContactForm mutation. |
| src/resolvers/affiliation.ts | Adds null guards for optional subHeaderLinks/ssoEmailDomains during update. |
| src/resolvers/adminNotifications.ts | Formatting-only adjustment. |
| src/resolvers/tests/feedback.spec.ts | Updates affiliation mock to include feedbackEnabled. |
| src/resolver.ts | Wires in new resolver modules (contactUs, passwordReset). |
| src/models/VersionedQuestionCustomization.ts | Documentation/formatting adjustments. |
| src/models/VersionedQuestionCondition.ts | Formatting adjustment. |
| src/models/VersionedGuidanceGroup.ts | Formatting adjustment. |
| src/models/VersionedGuidance.ts | Makes tagId optional and removes required validation for it. |
| src/models/VersionedCustomQuestion.ts | Formatting adjustment. |
| src/models/User.ts | Adds isArchived/passwordChangedAt, password setting, and expanded user filtering/sorting. |
| src/models/TemplateCustomization.ts | Improves docstring for findByIdWithTemplateName. |
| src/models/Tag.ts | Shifts tag associations to questions + adds versionedQuestionTags association helpers. |
| src/models/ResearchOutputType.ts | Formatting adjustment. |
| src/models/ResearchDomain.ts | Formatting adjustment. |
| src/models/Repository.ts | Formatting adjustment. |
| src/models/Question.ts | Adds tags property and ensures tags are excluded from DB persistence fields. |
| src/models/Project.ts | Formatting adjustment. |
| src/models/PlanFeedbackComment.ts | Formatting adjustment. |
| src/models/PlanFeedback.ts | Formatting adjustment. |
| src/models/PasswordResetToken.ts | Adds password reset token model and persistence helpers. |
| src/models/MySqlModel.ts | Adds errorsToString and transaction-aware query support. |
| src/models/MemberRole.ts | Formatting adjustment. |
| src/models/Member.ts | Adds ProjectMember.areEqual helper and formatting fixes. |
| src/models/Guidance.ts | Makes tagId optional. |
| src/models/Funding.ts | Renames finder, adds new finders, and updates PlanFunding create logic. |
| src/models/CustomSection.ts | Adjusts insert call signature. |
| src/models/CustomQuestion.ts | Doc/formatting adjustments. |
| src/models/AnswerComment.ts | Formatting adjustment. |
| src/models/Answer.ts | Uses DefaultResearchOutputTypeAnswer constant and improves SQL formatting. |
| src/models/AlternateIdentifier.ts | Adds findByAlternateIdentifiers helper. |
| src/models/AffiliationDepartments.ts | Formatting and update call adjustments. |
| src/models/Affiliation.ts | Minor signature/formatting adjustments. |
| src/models/AdminNotifications.ts | Insert signature update and minor formatting fixes. |
| src/models/tests/VersionedTemplateCustomization.spec.ts | Fixes argument formatting in tests. |
| src/models/tests/VersionedTemplate.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/VersionedSection.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/VersionedQuestionCondition.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/VersionedQuestion.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/VersionedGuidanceGroup.spec.ts | Formatting fix in expected SQL. |
| src/models/tests/VersionedGuidance.spec.ts | Updates test expectation for nullable tagId. |
| src/models/tests/UserEmail.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/TemplateCustomization.spec.ts | Fixes trailing comma/formatting in tests. |
| src/models/tests/Template.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Section.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/ResearchDomain.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Repository.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/RelatedWork.spec.ts | Minor formatting fix. |
| src/models/tests/QuestionCondition.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Question.spec.ts | Adds tags to test fixture and updates expectations. |
| src/models/tests/Project.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/PlanFeedbackComment.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/PlanFeedback.spec.ts | Adds query expectation and formatting fixes. |
| src/models/tests/MetadataStandard.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/MemberRole.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Member.spec.ts | Adds tests for ProjectMember.areEqual and adjusts expectations. |
| src/models/tests/License.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Guidance.spec.ts | Minor whitespace fix. |
| src/models/tests/Funder.spec.ts | Updates tests for renamed PlanFunding finder. |
| src/models/tests/CustomSection.spec.ts | Adjusts insert call signature in tests. |
| src/models/tests/CustomQuestion.spec.ts | Formatting fix in expected SQL. |
| src/models/tests/AnswerComment.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Answer.spec.ts | Updates expected default RO type answer behavior. |
| src/models/tests/AlternateIdentifier.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/Affiliation.spec.ts | Semicolon/formatting fixes in tests. |
| src/models/tests/AdminNotification.spec.ts | Formatting-only adjustment. |
| src/models/mocks/Plan.ts | Adds createdById and templateOwnerAffiliationName to mock search results. |
| src/middleware/express.ts | Adds EZID datasource to context and validates MySQL connection at startup. |
| src/index.ts | Instantiates EZID datasource and validates MySQL connection before start. |
| src/datasources/mysql.ts | Adds transaction support and improves DatabaseError shape. |
| src/datasources/EZIDAPI.ts | Adds EZID REST datasource with ANVL formatting and Basic Auth. |
| src/datasources/tests/mysql.spec.ts | Adds transaction tests and updates validateConnection usage. |
| src/controllers/tests/signupController.spec.ts | Updates mocked User interface for new methods. |
| src/controllers/tests/signinController.spec.ts | Updates mocked User interface for new methods. |
| src/controllers/tests/integrationTokens.spec.ts | Formatting + mocked User method additions. |
| src/context.ts | Adds ezidAPIDataSource + activeTransaction to context type and builder. |
| src/config/generalConfig.ts | Adds password reset token expiry config. |
| src/config/ezidConfig.ts | Adds EZID config with env var validation. |
| src/tests/context.spec.ts | Updates context mocks to new getMockDataSources helper. |
| src/mocks/context.ts | Adds EZID datasource mock + refactors datasource mocking patterns. |
| package.json | Updates dependencies and adjusts npm overrides. |
| data-migrations/local-only/2026-07-30-0223-insert-new-tags.sql | Seeds new tag records for local use. |
| data-migrations/local-only/2025-12-01-1512-add-recommended-licenses.sql | Uses NOW() timestamps for license seeding. |
| data-migrations/2027-07-29-0848-create-questionTags.sql | Adds questionTags/versionedQuestionTags tables (dated 2027). |
| data-migrations/2026-07-24-0231-create-userToken-table.sql | Adds passwordResetTokens table (filename mismatch). |
| data-migrations/2026-07-23-1339-alter-users-add-passwordChangedAt.sql | Adds passwordChangedAt to users table. |
| data-migrations/2026-06-25-0919-add-isArchived-field-to-users.sql | Adds isArchived to users table. |
| CHANGELOG.md | Documents new features, updates, fixes, and chores. |
| .env-example | Adds EZID and password reset env examples. |
Suppressed comments (2)
src/resolvers/question.ts:203
- In updateQuestion, the tag reconciliation calls
removeFromQuestionandaddToQuestionwithout awaiting the async methods. This will make the error handling ineffective (a Promise is always truthy) and may leave unhandled rejections when the DB write fails.
src/resolvers/funding.ts:313 - In updatePlanFunding,
funding.delete(context)returns a Promise but is not awaited. That makes the subsequentif (!wasRemoved)check ineffective (a Promise is always truthy) and can hide delete failures/unhandled rejections.
Comment on lines
+287
to
294
| let resp: unknown; | ||
| if (activeTransaction) { | ||
| resp = await activeTransaction.connection.query(sql, vals); | ||
| } else { | ||
| resp = await dataSources.sqlDataSource.query(apolloContext, sql, vals); | ||
| } | ||
|
|
||
| return Array.isArray(resp) ? resp : [resp]; |
Comment on lines
+103
to
+113
| for (const item of tags) { | ||
| const tag = await Tag.findById(reference, context, item.id); | ||
|
|
||
| if (!tag) { | ||
| addTagErrors.push(`Tag ${item.id} not found`); | ||
| } | ||
|
|
||
| const wasAdded = tag.addToQuestion(context, questionId) | ||
| if (!wasAdded) { | ||
| addTagErrors.push(tag.name); | ||
| } |
Comment on lines
+341
to
+357
| const attribution = `Sent by ${name} <${email}>` | ||
|
|
||
| const body = emailMessages.contactUs | ||
| .replace('%{message}', message) | ||
| .replace('%{attribution}', attribution); | ||
|
|
||
| return await sendEmail( | ||
| context, | ||
| 'ContactUs', | ||
| [emailConfig.helpDeskAddress], // to | ||
| [],// cc | ||
| [],// bcc | ||
| `${emailSubjects.contactUs}: ${subject}`, | ||
| body, | ||
| true, // asHTML | ||
| email, // replyTo | ||
| ); |
Comment on lines
+17
to
+23
| constructor(options) { | ||
| super(options.id, options.createdAt, options.createdById, options.modified, options.modifiedById, options.errors); | ||
| this.userId = options.userId; | ||
| this.resetPasswordToken = options.resetPasswordToken; | ||
| this.resetPasswordExpiresAt = options.resetPasswordExpiresAt; | ||
| this.usedAt = options.usedAt; | ||
| } |
Comment on lines
+46
to
+51
| if (await this.isValid()) { | ||
| const newId = await PasswordResetToken.insert(context, this.tableName, this, reference); | ||
| const created = await PasswordResetToken.findById(reference, context, newId); | ||
| context.logger.debug(prepareObjectForLogs({ id: created?.id, userId: this.userId }), reference); | ||
| return created; | ||
| } |
Comment on lines
191
to
193
| const removed = await funding.delete(context); | ||
| console.log("***Removed funding", removed); | ||
| if (removed && !removed.hasErrors()) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
merging stage into main