Skip to content

Commit

Permalink
asset add/rm 2 collection (probably works)
Browse files Browse the repository at this point in the history
  • Loading branch information
dromzeh committed May 6, 2024
1 parent 03ce162 commit 651cbc5
Show file tree
Hide file tree
Showing 3 changed files with 379 additions and 0 deletions.
190 changes: 190 additions & 0 deletions src/v2/routes/collection/add-asset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { AppHandler } from "../handler"
import { getConnection } from "@/v2/db/turso"
import {
userCollection,
userCollectionCollaborators,
asset,
userCollectionAsset,
} from "@/v2/db/schema"
import { and, desc, eq, not } from "drizzle-orm"
import { createRoute } from "@hono/zod-openapi"
import { GenericResponses } from "@/v2/lib/response-schemas"
import { z } from "@hono/zod-openapi"
import { AuthSessionManager } from "@/v2/lib/managers/auth/user-session-manager"

const paramsSchema = z.object({
id: z.string().openapi({
param: {
name: "id",
in: "path",
description: "The ID of the collection to add asset to",
required: true,
},
}),
assetId: z.string().openapi({
param: {
name: "assetId",
in: "path",
description: "The ID of the asset to add.",
required: true,
},
}),
})

const responseSchema = z.object({
success: z.literal(true),
})

const openRoute = createRoute({
path: "/{id}/add/{assetId}",
method: "post",
summary: "Add asset to collection",
description:
"Add an asset to a collection, you must be the collection owner or a collaborator to add an asset.",
tags: ["Collection"],
request: {
params: paramsSchema,
},
responses: {
200: {
description:
"Returns true if the asset was added to the collection.",
content: {
"application/json": {
schema: responseSchema,
},
},
},
...GenericResponses,
},
})

export const AddAssetToCollectionRoute = (handler: AppHandler) => {
handler.openapi(openRoute, async (ctx) => {
const { id, assetId } = ctx.req.valid("param")
const { drizzle } = await getConnection(ctx.env)

const authSessionManager = new AuthSessionManager(ctx)
const { user } = await authSessionManager.validateSession()

if (!user) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

const [existingCollection] = await drizzle
.select({
id: userCollection.id,
userId: userCollection.userId,
})
.from(userCollection)
.where(eq(userCollection.id, id))
.limit(1)

if (!existingCollection) {
return ctx.json(
{
success: false,
message: "Collection ID provided does not exist",
},
404
)
}

const [existingAsset] = await drizzle
.select({
id: asset.id,
})
.from(asset)
.where(eq(asset.id, assetId))
.limit(1)

if (!existingAsset) {
return ctx.json(
{
success: false,
message: "Asset ID provided does not exist",
},
404
)
}

const [existingCollaborator] = await drizzle
.select({
role: userCollectionCollaborators.role,
collaboratorId: userCollectionCollaborators.collaboratorId,
})
.from(userCollectionCollaborators)
.where(
and(
eq(userCollectionCollaborators.collectionId, id),
eq(userCollectionCollaborators.collaboratorId, user.id),
not(eq(userCollectionCollaborators.role, "viewer"))
)
)
.limit(1)

if (!existingCollaborator && existingCollection.userId !== user.id) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

// check if asset is already in collection

const [existingAssetInCollection] = await drizzle
.select({
collectionId: userCollectionAsset.collectionId,
assetId: userCollectionAsset.assetId,
})
.from(userCollectionAsset)
.where(
and(
eq(userCollectionAsset.collectionId, id),
eq(userCollectionAsset.assetId, assetId)
)
)
.limit(1)

if (existingAssetInCollection) {
return ctx.json(
{
success: false,
message: "Asset already in collection",
},
400
)
}

const [lastOrder] = await drizzle
.select({
order: userCollectionAsset.order,
})
.from(userCollectionAsset)
.where(eq(userCollectionAsset.collectionId, id))
.orderBy(desc(userCollectionAsset.order))
.limit(1)

await drizzle.insert(userCollectionAsset).values({
collectionId: id,
order: lastOrder ? lastOrder.order + 1 : 0,
assetId: assetId,
})

return ctx.json(
{
success: true,
},
200
)
})
}
5 changes: 5 additions & 0 deletions src/v2/routes/collection/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { ModifyCollectionRoute } from "./modify-collection"
import { GetCollectionAssetsByIdRoute } from "./get-collection-assets"
import { UnlikeCollectionByIDRoute } from "./unlike-collection"
import { LikeCollectionByIdRoute } from "./like-collection"
import { AddAssetToCollectionRoute } from "./add-asset"
import { RemoveAssetFromCollectionRoute } from "./remove-asset"

const handler = new OpenAPIHono<{ Bindings: Bindings; Variables: Variables }>()

Expand All @@ -16,6 +18,9 @@ ModifyCollectionRoute(handler)
CreateCollectionRoute(handler)
DeleteCollectionRoute(handler)

AddAssetToCollectionRoute(handler)
RemoveAssetFromCollectionRoute(handler)

LikeCollectionByIdRoute(handler)
UnlikeCollectionByIDRoute(handler)

Expand Down
184 changes: 184 additions & 0 deletions src/v2/routes/collection/remove-asset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import { AppHandler } from "../handler"
import { getConnection } from "@/v2/db/turso"
import {
userCollection,
userCollectionCollaborators,
asset,
userCollectionAsset,
} from "@/v2/db/schema"
import { and, eq, not } from "drizzle-orm"
import { createRoute } from "@hono/zod-openapi"
import { GenericResponses } from "@/v2/lib/response-schemas"
import { z } from "@hono/zod-openapi"
import { AuthSessionManager } from "@/v2/lib/managers/auth/user-session-manager"

const paramsSchema = z.object({
id: z.string().openapi({
param: {
name: "id",
in: "path",
description: "The ID of the collection to remove asset from",
required: true,
},
}),
assetId: z.string().openapi({
param: {
name: "assetId",
in: "path",
description: "The ID of the asset to remove",
required: true,
},
}),
})

const responseSchema = z.object({
success: z.literal(true),
})

const openRoute = createRoute({
path: "/{id}/remove/{assetId}",
method: "post",
summary: "Remove collection asset",
description:
"Remove an asset from a collection, you must be the collection owner or a collaborator to remove an asset.",
tags: ["Collection"],
request: {
params: paramsSchema,
},
responses: {
200: {
description:
"Returns true if the asset was removed to the collection.",
content: {
"application/json": {
schema: responseSchema,
},
},
},
...GenericResponses,
},
})

export const RemoveAssetFromCollectionRoute = (handler: AppHandler) => {
handler.openapi(openRoute, async (ctx) => {
const { id, assetId } = ctx.req.valid("param")
const { drizzle } = await getConnection(ctx.env)

const authSessionManager = new AuthSessionManager(ctx)
const { user } = await authSessionManager.validateSession()

if (!user) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

const [existingCollection] = await drizzle
.select({
id: userCollection.id,
userId: userCollection.userId,
})
.from(userCollection)
.where(eq(userCollection.id, id))
.limit(1)

if (!existingCollection) {
return ctx.json(
{
success: false,
message: "Collection ID provided does not exist",
},
404
)
}

const [existingAsset] = await drizzle
.select({
id: asset.id,
})
.from(asset)
.where(eq(asset.id, assetId))
.limit(1)

if (!existingAsset) {
return ctx.json(
{
success: false,
message: "Asset ID provided does not exist",
},
404
)
}

const [existingCollaborator] = await drizzle
.select({
role: userCollectionCollaborators.role,
collaboratorId: userCollectionCollaborators.collaboratorId,
})
.from(userCollectionCollaborators)
.where(
and(
eq(userCollectionCollaborators.collectionId, id),
eq(userCollectionCollaborators.collaboratorId, user.id),
not(eq(userCollectionCollaborators.role, "viewer"))
)
)
.limit(1)

if (!existingCollaborator && existingCollection.userId !== user.id) {
return ctx.json(
{
success: false,
message: "Unauthorized",
},
401
)
}

// check if asset is already in collection

const [existingAssetInCollection] = await drizzle
.select({
collectionId: userCollectionAsset.collectionId,
assetId: userCollectionAsset.assetId,
})
.from(userCollectionAsset)
.where(
and(
eq(userCollectionAsset.collectionId, id),
eq(userCollectionAsset.assetId, assetId)
)
)
.limit(1)

if (!existingAssetInCollection) {
return ctx.json(
{
success: false,
message: "Asset is not in collection",
},
400
)
}

await drizzle
.delete(userCollectionAsset)
.where(
and(
eq(userCollectionAsset.collectionId, id),
eq(userCollectionAsset.assetId, assetId)
)
)

return ctx.json(
{
success: true,
},
200
)
})
}

0 comments on commit 651cbc5

Please sign in to comment.