Skip to content

Commit 2c2aae2

Browse files
committed
add db schema and routers
1 parent d9a541c commit 2c2aae2

File tree

14 files changed

+401
-14
lines changed

14 files changed

+401
-14
lines changed

.vscode/extensions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"nrwl.angular-console",
44
"esbenp.prettier-vscode",
55
"dbaeumer.vscode-eslint",
6-
"ms-playwright.playwright"
6+
"ms-playwright.playwright",
7+
"prisma.prisma"
78
]
89
}

.vscode/settings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
{
22
"editor.codeActionsOnSave": {
33
"source.fixAll": "always"
4+
},
5+
"files.exclude": {
6+
"**/dist": true,
7+
"**/.nx/cache": true,
8+
"**/node_modules": true
9+
},
10+
"search.exclude": {
11+
"**/dist": true,
12+
"**/.nx": true,
13+
"**/node_modules": true
414
}
515
}

.vscode/tasks.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Dev Stack",
6+
"dependsOrder": "parallel",
7+
"dependsOn": ["web:serve", "api:serve", "api:prisma:watch", "api:prisma:studio"],
8+
"group": {
9+
"kind": "build",
10+
"isDefault": true
11+
}
12+
},
13+
{
14+
"label": "web:serve",
15+
"type": "shell",
16+
"command": "nx run web:serve",
17+
"isBackground": true,
18+
"problemMatcher": []
19+
},
20+
{
21+
"label": "api:serve",
22+
"type": "shell",
23+
"command": "nx run api:serve",
24+
"isBackground": true,
25+
"problemMatcher": []
26+
},
27+
{
28+
"label": "api:prisma:watch",
29+
"type": "shell",
30+
"command": "nx run api:prisma:watch",
31+
"isBackground": true,
32+
"problemMatcher": []
33+
},
34+
{
35+
"label": "api:prisma:studio",
36+
"type": "shell",
37+
"command": "nx run api:prisma:studio",
38+
"isBackground": true,
39+
"problemMatcher": []
40+
}
41+
]
42+
}

apps/api/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
"@types/cors": "^2.8.17"
1212
},
1313
"scripts": {
14-
"prisma:watch": "prisma generate --schema=prisma/schema.prisma --watch"
14+
"prisma:watch": "prisma generate --watch",
15+
"prisma:studio": "prisma studio",
16+
"prisma:push": "prisma db push"
1517
}
1618
}

apps/api/prisma/schema.prisma

Lines changed: 157 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,166 @@
1+
generator client {
2+
provider = "prisma-client-js"
3+
}
4+
15
datasource db {
26
provider = "postgresql"
37
url = env("DATABASE_URL")
48
}
59

6-
generator client {
7-
provider = "prisma-client-js"
10+
enum ProcessingStatus {
11+
PENDING
12+
PROCESSING
13+
COMPLETED
14+
ERROR
15+
}
16+
17+
enum MediaVariant {
18+
THUMBNAIL
19+
SMALL
20+
MEDIUM
21+
LARGE
22+
ORIGINAL
823
}
924

10-
model Example {
11-
id String @id @default(cuid())
12-
createdAt DateTime @default(now())
13-
updatedAt DateTime @updatedAt
25+
model User {
26+
id String @id @default(cuid())
27+
email String @unique
1428
name String
15-
description String
29+
createdAt DateTime @default(now())
30+
updatedAt DateTime @updatedAt
31+
mediaItems MediaItem[]
32+
collections Collection[]
33+
tags Tag[]
34+
35+
@@map("users")
36+
}
37+
38+
model MediaItem {
39+
id String @id @default(cuid())
40+
checksum String @unique
41+
originalPath String
42+
originalFileName String
43+
mimeType String
44+
fileSize Int
45+
metadata Json
46+
createdAt DateTime @default(now())
47+
createdById String
48+
createdBy User @relation(fields: [createdById], references: [id])
49+
mediaVersions MediaVersion[]
50+
51+
@@index([checksum])
52+
@@index([createdById])
53+
@@map("media_items")
54+
}
55+
56+
model MediaVersion {
57+
id String @id @default(cuid())
58+
mediaItemId String
59+
status ProcessingStatus
60+
processingError String?
61+
createdAt DateTime @default(now())
62+
createdById String
63+
mediaItem MediaItem @relation(fields: [mediaItemId], references: [id])
64+
processedMedia ProcessedMedia[]
65+
mediaTags MediaTag[]
66+
collectionItems CollectionItem[]
67+
68+
@@index([mediaItemId])
69+
@@index([status])
70+
@@index([createdById])
71+
@@map("media_versions")
72+
}
73+
74+
model ProcessedMedia {
75+
id String @id @default(cuid())
76+
mediaVersionId String
77+
variant MediaVariant
78+
path String
79+
width Int
80+
height Int
81+
fileSize Int
82+
createdAt DateTime @default(now())
83+
mediaVersion MediaVersion @relation(fields: [mediaVersionId], references: [id])
84+
85+
@@unique([mediaVersionId, variant])
86+
@@index([mediaVersionId])
87+
@@map("processed_media")
88+
}
89+
90+
model Collection {
91+
id String @id @default(cuid())
92+
name String
93+
description String?
94+
isPublic Boolean @default(false)
95+
createdAt DateTime @default(now())
96+
createdById String
97+
createdBy User @relation(fields: [createdById], references: [id])
98+
collectionVersions CollectionVersion[]
99+
100+
@@index([createdById])
101+
@@map("collections")
102+
}
103+
104+
model CollectionVersion {
105+
id String @id @default(cuid())
106+
collectionId String
107+
name String
108+
description String?
109+
isPublic Boolean
110+
createdAt DateTime @default(now())
111+
createdById String
112+
collection Collection @relation(fields: [collectionId], references: [id])
113+
collectionItems CollectionItem[]
114+
115+
@@index([collectionId])
116+
@@index([createdById])
117+
@@map("collection_versions")
118+
}
119+
120+
model CollectionItem {
121+
id String @id @default(cuid())
122+
collectionVersionId String
123+
mediaVersionId String
124+
sortOrder Int
125+
createdAt DateTime @default(now())
126+
createdById String
127+
collectionVersion CollectionVersion @relation(fields: [collectionVersionId], references: [id])
128+
mediaVersion MediaVersion @relation(fields: [mediaVersionId], references: [id])
129+
130+
@@index([collectionVersionId])
131+
@@index([mediaVersionId])
132+
@@index([createdById])
133+
@@map("collection_items")
134+
}
135+
136+
model Tag {
137+
id String @id @default(cuid())
138+
namespace String?
139+
value String
140+
createdAt DateTime @default(now())
141+
createdById String
142+
createdBy User @relation(fields: [createdById], references: [id])
143+
mediaTags MediaTag[]
144+
145+
@@unique([namespace, value])
146+
@@index([namespace])
147+
@@index([value])
148+
@@index([createdById])
149+
@@map("tags")
150+
}
151+
152+
model MediaTag {
153+
id String @id @default(cuid())
154+
mediaVersionId String
155+
tagId String
156+
createdAt DateTime @default(now())
157+
createdById String
158+
mediaVersion MediaVersion @relation(fields: [mediaVersionId], references: [id])
159+
tag Tag @relation(fields: [tagId], references: [id])
160+
161+
@@unique([mediaVersionId, tagId])
162+
@@index([mediaVersionId])
163+
@@index([tagId])
164+
@@index([createdById])
165+
@@map("media_tags")
16166
}

apps/api/src/trpc/root.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import { router } from './router';
2+
import { mediaRouter } from './routers/media';
3+
import { collectionsRouter } from './routers/collections';
4+
import { tagsRouter } from './routers/tags';
5+
import { usersRouter } from './routers/users';
6+
import { mediaVersionsRouter } from './routers/mediaVersions';
7+
import { processedMediaRouter } from './routers/processedMedia';
28

39
export const appRouter = router({
4-
// Add sub-routers here
10+
media: mediaRouter,
11+
collections: collectionsRouter,
12+
tags: tagsRouter,
13+
users: usersRouter,
14+
mediaVersions: mediaVersionsRouter,
15+
processedMedia: processedMediaRouter
516
});
6-
717
export type AppRouter = typeof appRouter;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { z } from 'zod';
2+
import { publicProcedure, router } from '../router';
3+
4+
export const collectionsRouter = router({
5+
getCollection: publicProcedure
6+
.input(z.object({ id: z.string() }))
7+
.query(async ({ ctx, input }) => {
8+
return ctx.db.collection.findUnique({
9+
where: { id: input.id },
10+
include: {
11+
collectionVersions: {
12+
include: {
13+
collectionItems: {
14+
include: {
15+
mediaVersion: true
16+
}
17+
}
18+
}
19+
}
20+
}
21+
});
22+
}),
23+
24+
listCollections: publicProcedure
25+
.query(async ({ ctx }) => {
26+
return ctx.db.collection.findMany({
27+
include: {
28+
collectionVersions: true
29+
}
30+
});
31+
})
32+
});

apps/api/src/trpc/routers/media.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { z } from 'zod';
2+
import { publicProcedure, router } from '../router';
3+
4+
export const mediaRouter = router({
5+
getMediaItem: publicProcedure
6+
.input(z.object({ id: z.string() }))
7+
.query(async ({ ctx, input }) => {
8+
return ctx.db.mediaItem.findUnique({
9+
where: { id: input.id },
10+
include: {
11+
mediaVersions: {
12+
include: {
13+
processedMedia: true,
14+
mediaTags: {
15+
include: { tag: true }
16+
}
17+
}
18+
}
19+
}
20+
});
21+
}),
22+
23+
listMediaItems: publicProcedure
24+
.query(async ({ ctx }) => {
25+
return ctx.db.mediaItem.findMany({
26+
include: {
27+
mediaVersions: {
28+
include: {
29+
processedMedia: true
30+
}
31+
}
32+
}
33+
});
34+
})
35+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { z } from 'zod';
2+
import { publicProcedure, router } from '../router';
3+
4+
export const mediaVersionsRouter = router({
5+
getMediaVersion: publicProcedure
6+
.input(z.object({ id: z.string() }))
7+
.query(async ({ ctx, input }) => {
8+
return ctx.db.mediaVersion.findUnique({
9+
where: { id: input.id },
10+
include: {
11+
processedMedia: true,
12+
mediaTags: {
13+
include: { tag: true }
14+
},
15+
collectionItems: true
16+
}
17+
});
18+
}),
19+
20+
listMediaVersions: publicProcedure
21+
.query(async ({ ctx }) => {
22+
return ctx.db.mediaVersion.findMany({
23+
include: {
24+
processedMedia: true,
25+
mediaTags: true
26+
}
27+
});
28+
})
29+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { z } from 'zod';
2+
import { publicProcedure, router } from '../router';
3+
4+
export const processedMediaRouter = router({
5+
getProcessedMedia: publicProcedure
6+
.input(z.object({ id: z.string() }))
7+
.query(async ({ ctx, input }) => {
8+
return ctx.db.processedMedia.findUnique({
9+
where: { id: input.id },
10+
include: {
11+
mediaVersion: true
12+
}
13+
});
14+
}),
15+
16+
listProcessedMedia: publicProcedure
17+
.query(async ({ ctx }) => {
18+
return ctx.db.processedMedia.findMany({
19+
include: {
20+
mediaVersion: true
21+
}
22+
});
23+
})
24+
});

0 commit comments

Comments
 (0)