-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #639 from desci-labs/doi-oa-bookmarks
Bookmarks Update
- Loading branch information
Showing
12 changed files
with
531 additions
and
252 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
desci-server/prisma/migrations/20241118075235_/migration.sql
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
Warnings: | ||
- A unique constraint covering the columns `[userId,type,nodeUuid,doi,oaWorkId]` on the table `BookmarkedNode` will be added. If there are existing duplicate values, this will fail. | ||
*/ | ||
-- CreateEnum | ||
CREATE TYPE "BookmarkType" AS ENUM ('NODE', 'DOI', 'OA'); | ||
|
||
-- DropForeignKey | ||
ALTER TABLE "BookmarkedNode" DROP CONSTRAINT "BookmarkedNode_nodeUuid_fkey"; | ||
|
||
-- DropIndex | ||
DROP INDEX "BookmarkedNode_userId_nodeUuid_key"; | ||
|
||
-- AlterTable | ||
ALTER TABLE "BookmarkedNode" ADD COLUMN "doi" TEXT, | ||
ADD COLUMN "oaWorkId" TEXT, | ||
ADD COLUMN "type" "BookmarkType" NOT NULL DEFAULT 'NODE', | ||
ALTER COLUMN "nodeUuid" DROP NOT NULL; | ||
|
||
-- CreateIndex | ||
CREATE UNIQUE INDEX "BookmarkedNode_userId_type_nodeUuid_doi_oaWorkId_key" ON "BookmarkedNode"("userId", "type", "nodeUuid", "doi", "oaWorkId"); | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "BookmarkedNode" ADD CONSTRAINT "BookmarkedNode_nodeUuid_fkey" FOREIGN KEY ("nodeUuid") REFERENCES "Node"("uuid") ON DELETE SET NULL ON UPDATE CASCADE; |
2 changes: 2 additions & 0 deletions
2
desci-server/prisma/migrations/20241119084420_bookmark_titles/migration.sql
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-- AlterTable | ||
ALTER TABLE "BookmarkedNode" ADD COLUMN "title" TEXT; |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,71 @@ | ||
import { User } from '@prisma/client'; | ||
import { User, BookmarkType } from '@prisma/client'; | ||
import { Request, Response } from 'express'; | ||
import { z } from 'zod'; | ||
|
||
import { prisma } from '../../../client.js'; | ||
import { logger as parentLogger } from '../../../logger.js'; | ||
import { ensureUuidEndsWithDot } from '../../../utils.js'; | ||
import { BookmarkService } from '../../../services/BookmarkService.js'; | ||
export const CreateBookmarkSchema = z.discriminatedUnion('type', [ | ||
z.object({ | ||
type: z.literal(BookmarkType.NODE), | ||
nodeUuid: z.string().min(1), | ||
shareKey: z.string().optional(), | ||
}), | ||
z.object({ | ||
type: z.literal(BookmarkType.DOI), | ||
doi: z.string().min(1), | ||
}), | ||
z.object({ | ||
type: z.literal(BookmarkType.OA), | ||
oaWorkId: z.string().min(1), | ||
}), | ||
]); | ||
|
||
export type CreateNodeBookmarkReqBody = { | ||
nodeUuid: string; | ||
shareKey?: string; | ||
}; | ||
type CreateBookmarkReqBody = z.infer<typeof CreateBookmarkSchema>; | ||
|
||
export type CreateNodeBookmarkRequest = Request<never, never, CreateNodeBookmarkReqBody> & { | ||
export type CreateBookmarkRequest = Request<never, never, CreateBookmarkReqBody> & { | ||
user: User; // added by auth middleware | ||
}; | ||
|
||
export type CreateNodeBookmarkResBody = | ||
export type CreateBookmarkResBody = | ||
| { | ||
ok: true; | ||
message: string; | ||
} | ||
| { | ||
ok: false; | ||
error: string; | ||
details?: z.ZodIssue[] | string; | ||
}; | ||
|
||
export const createNodeBookmark = async (req: CreateNodeBookmarkRequest, res: Response<CreateNodeBookmarkResBody>) => { | ||
export const createNodeBookmark = async (req: CreateBookmarkRequest, res: Response<CreateBookmarkResBody>) => { | ||
const user = req.user; | ||
|
||
if (!user) throw Error('Middleware not properly setup for CreateNodeBookmark controller, requires req.user'); | ||
|
||
const { nodeUuid, shareKey } = req.body; | ||
if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required' }); | ||
|
||
const logger = parentLogger.child({ | ||
module: 'PrivateShare::CreateNodeBookmarkController', | ||
body: req.body, | ||
module: 'Bookmarks::CreateNodeBookmarkController', | ||
userId: user.id, | ||
nodeUuid: nodeUuid, | ||
shareId: shareKey, | ||
body: req.body, | ||
}); | ||
|
||
try { | ||
logger.trace({}, 'Bookmarking node'); | ||
const createdBookmark = await prisma.bookmarkedNode.create({ | ||
data: { | ||
userId: user.id, | ||
nodeUuid: ensureUuidEndsWithDot(nodeUuid), | ||
shareId: shareKey || null, | ||
}, | ||
const bookmarkData = CreateBookmarkSchema.parse(req.body); | ||
|
||
logger.trace({ type: bookmarkData.type }, 'Creating bookmark'); | ||
|
||
await BookmarkService.createBookmark({ | ||
userId: user.id, | ||
...bookmarkData, | ||
}); | ||
|
||
logger.trace({ createdBookmark }, 'Bookmark created successfully'); | ||
return res.status(200).json({ ok: true, message: 'Bookmark created successfully' }); | ||
return res.status(201).json({ ok: true, message: 'Bookmark created successfully' }); | ||
} catch (e) { | ||
logger.error({ e, message: e?.message }, 'Failed to create bookmark'); | ||
return res.status(500).json({ ok: false, error: 'Failed to create bookmark for node' }); | ||
if (e instanceof z.ZodError) { | ||
logger.warn({ error: e.errors }, 'Invalid request parameters'); | ||
return res.status(400).json({ ok: false, error: 'Invalid request parameters', details: e.errors }); | ||
} | ||
|
||
logger.error({ e }, 'Error creating bookmark'); | ||
return res.status(500).json({ ok: false, error: 'Internal server error' }); | ||
} | ||
}; |
This file contains 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
Oops, something went wrong.