Skip to content

Commit

Permalink
Merge pull request #616 from desci-labs/doi/retry
Browse files Browse the repository at this point in the history
Admin api to Replay DOI minting for pending Submission
  • Loading branch information
shadrach-tayo authored Dec 11, 2024
2 parents 15b31d1 + d66ab3d commit 2bf647b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 15 deletions.
24 changes: 24 additions & 0 deletions desci-server/src/controllers/doi/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,37 @@ import { Request, Response, NextFunction } from 'express';
import _ from 'lodash';

import { prisma } from '../../client.js';
import { BadRequestError } from '../../core/ApiError.js';
import { SuccessMessageResponse, SuccessResponse } from '../../core/ApiResponse.js';
import { MintError } from '../../core/doi/error.js';
import { logger as parentLogger } from '../../logger.js';
import { EmailTypes, sendEmail } from '../../services/email.js';
import { getTargetDpidUrl } from '../../services/fixDpid.js';
import { crossRefClient, doiService } from '../../services/index.js';
import { DiscordChannel, discordNotify, DiscordNotifyType } from '../../utils/discordUtils.js';

export const retryDoiMint = async (req: Request, res: Response, _next: NextFunction) => {
const { submissionId } = req.params;
if (!submissionId) throw new BadRequestError();

const submission = await doiService.getSubmissionById(parseInt(submissionId));
if (!submission) {
throw new MintError('No pending submission found');
}

await doiService.retryDoiMint(submission);

const targetDpidUrl = getTargetDpidUrl();
discordNotify({
channel: DiscordChannel.DoiMinting,
type: DiscordNotifyType.INFO,
title: 'Retry DOI Minting',
message: `${targetDpidUrl}/${submission.dpid} sent a request to mint: ${submission.uniqueDoi}`,
});

new SuccessMessageResponse().send(res);
};

export interface RequestWithCrossRefPayload extends Request {
payload: {
notifyEndpoint: string;
Expand Down
15 changes: 0 additions & 15 deletions desci-server/src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
import { Router } from 'express';

import { handleCrossrefNotificationCallback } from '../controllers/doi/mint.js';
import { resolve } from '../controllers/raw/resolve.js';
import { asyncHandler } from '../utils/asyncHandler.js';

import page404 from './pages/404.js';
import pageRoot from './pages/root.js';
import { ensureCrossrefNotifier, identifyEndpoint } from './v1/crossref.js';
import v1 from './v1/index.js';

const router = Router();

router.use(`/v1`, v1);

// potential notification fallback catch
router.post(
'/crossref/callback',
[identifyEndpoint('/crossref/callback'), ensureCrossrefNotifier],
asyncHandler(handleCrossrefNotificationCallback),
);
router.post(
'/crossref/callback/v1/crossref/callback',
[identifyEndpoint('/crossref/callback/v1/crossref/callback'), ensureCrossrefNotifier],
asyncHandler(handleCrossrefNotificationCallback),
);

router.get('/:query*', resolve);

router.use(pageRoot);
Expand Down
11 changes: 11 additions & 0 deletions desci-server/src/routes/v1/admin/doi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Router } from 'express';

import { retryDoiMint } from '../../../controllers/doi/mint.js';
import { ensureAdmin } from '../../../middleware/ensureAdmin.js';
import { ensureUser } from '../../../middleware/permissions.js';
import { asyncHandler } from '../../../utils/asyncHandler.js';

const router = Router();
router.post('/retry-mint/:submissionId', [ensureUser, ensureAdmin], asyncHandler(retryDoiMint));

export default router;
3 changes: 3 additions & 0 deletions desci-server/src/routes/v1/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ensureUser } from '../../../middleware/permissions.js';
import { asyncHandler } from '../../../utils/asyncHandler.js';

import communities from './communities/index.js';
import doiRouter from './doi.js';
import usersRouter from './users/index.js';

const router = Router();
Expand All @@ -26,4 +27,6 @@ router.use('/communities', [ensureUser, ensureAdmin], communities);
router.get('/attestations', [ensureUser, ensureAdmin], asyncHandler(listAttestations));
// router.use('/users', [ensureUser, ensureAdmin], usersRouter);

router.use('/doi', doiRouter);

export default router;
47 changes: 47 additions & 0 deletions desci-server/src/services/Doi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,47 @@ export class DoiService {
return submission;
}

async retryDoiMint(submission: DoiSubmissionQueue) {
const { dpid, uuid, manifest, researchObject } = await this.checkMintability(submission.uuid);
// mint new doi

const latestVersionTimestamp = researchObject.versions[researchObject.versions.length - 1]?.time;
const publicationDate = latestVersionTimestamp
? new Date(parseInt(latestVersionTimestamp) * 1000).toLocaleDateString().replaceAll('/', '-')
: (await this.getLastPublishedDate(uuid)).toLocaleDateString().replaceAll('/', '-');
logger.trace(
{
latestVersionTimestamp: new Date(parseInt(latestVersionTimestamp) * 1000)
.toLocaleDateString()
.replaceAll('/', '-'),
publicationDate,
},
'latestVersionTimestamp',
);

const [month, day, year] = publicationDate.split('-');

const metadataResponse = await crossRefClient.registerDoi({
manifest,
doi: submission.uniqueDoi,
dpid,
publicationDate: { day, month, year },
});

logger.info({ doi: submission.uniqueDoi, uuid, metadataResponse }, 'DOI SUBMITTED');
if (!metadataResponse.ok) {
throw new MintError("We couldn't register a DOI for this research object");
}

await this.dbClient.doiSubmissionQueue.update({
where: { id: submission.id },
data: { status: DoiStatus.PENDING },
});

// return submission queue data
return submission;
}

async autoMintTrigger(uuid: string) {
const sanitizedUuid = ensureUuidEndsWithDot(uuid);
const isPending = await this.hasPendingSubmission(sanitizedUuid);
Expand Down Expand Up @@ -254,6 +295,12 @@ export class DoiService {
});
}

async getSubmissionById(id: number) {
return await this.dbClient.doiSubmissionQueue.findFirst({
where: { id },
});
}

async getPendingSubmissions() {
return await this.dbClient.doiSubmissionQueue.findMany({
where: { status: DoiStatus.PENDING },
Expand Down

0 comments on commit 2bf647b

Please sign in to comment.