Skip to content

Commit

Permalink
Merge pull request 100xdevs-cohort-2#881 from tarunclub/master
Browse files Browse the repository at this point in the history
week-11 solution
  • Loading branch information
hkirat authored Mar 11, 2024
2 parents 7d540ae + 2bbdd5d commit b0505dd
Show file tree
Hide file tree
Showing 18 changed files with 720 additions and 0 deletions.
2 changes: 2 additions & 0 deletions week-11/solution/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DATABASE_URL=""
DIRECT_URL=""
10 changes: 10 additions & 0 deletions week-11/solution/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
dist
.wrangler
.dev.vars

# Change them to your taste:
package-lock.json
yarn.lock
pnpm-lock.yaml
bun.lockb
8 changes: 8 additions & 0 deletions week-11/solution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```
npm install
npm run dev
```

```
npm run deploy
```
18 changes: 18 additions & 0 deletions week-11/solution/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"scripts": {
"dev": "wrangler dev src/index.ts",
"deploy": "wrangler deploy --minify src/index.ts"
},
"dependencies": {
"@prisma/client": "^5.9.1",
"@prisma/extension-accelerate": "^0.6.3",
"hono": "^4.0.3",
"jsonwebtoken": "^9.0.2"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240208.0",
"@types/jsonwebtoken": "^9.0.5",
"prisma": "^5.9.1",
"wrangler": "^3.25.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-- CreateTable
CREATE TABLE "User" (
"id" SERIAL NOT NULL,
"username" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,

CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Posts" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"body" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "Posts_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Tags" (
"id" SERIAL NOT NULL,
"tag" TEXT NOT NULL,

CONSTRAINT "Tags_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "_PostsToTags" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "Tags_tag_key" ON "Tags"("tag");

-- CreateIndex
CREATE UNIQUE INDEX "_PostsToTags_AB_unique" ON "_PostsToTags"("A", "B");

-- CreateIndex
CREATE INDEX "_PostsToTags_B_index" ON "_PostsToTags"("B");

-- AddForeignKey
ALTER TABLE "Posts" ADD CONSTRAINT "Posts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_PostsToTags" ADD CONSTRAINT "_PostsToTags_A_fkey" FOREIGN KEY ("A") REFERENCES "Posts"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_PostsToTags" ADD CONSTRAINT "_PostsToTags_B_fkey" FOREIGN KEY ("B") REFERENCES "Tags"("id") ON DELETE CASCADE ON UPDATE CASCADE;
3 changes: 3 additions & 0 deletions week-11/solution/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
36 changes: 36 additions & 0 deletions week-11/solution/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}

model User {
id Int @id @default(autoincrement())
username String
email String
password String
posts Posts[]
}

model Posts {
id Int @id @default(autoincrement())
title String
body String
tags Tags[]
User User @relation(fields: [userId], references: [id])
userId Int
createdAt DateTime @default(now())
}

model Tags {
id Int @id @default(autoincrement())
tag String @unique
post Posts[]
}
236 changes: 236 additions & 0 deletions week-11/solution/src/controller/postController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import { PrismaClient } from '@prisma/client/edge';
import { withAccelerate } from '@prisma/extension-accelerate';

import { Context } from 'hono';

enum StatusCode {
BADREQ = 400,
NOTFOUND = 404,
NOTPERMISSIOON = 403,
}

export async function getPosts(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const response = await prisma.posts.findMany({
include: {
tags: true,
User: true,
},
});
return c.json({
post: response.map((res) => ({
id: res.id,
username: res.User.username,
userId: res.User.id,
title: res.title,
body: res.body,
tags: res.tags,
createdAt: res.createdAt,
})),
});
} catch (error) {
return c.body(`Internal server error: ${error}`, 500);
}
}

export async function getUserPosts(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const resp = await prisma.posts.findMany({
where: {
userId: c.get('userId'),
},
});
return c.json({
post: resp,
});
} catch (error) {
return c.body(`Internal server error: ${error}`, 500);
}
}

export async function createPost(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const body: {
title: string;
body: string;
tags: string;
} = await c.req.json();

const tagNames = body.tags.split(',').map((tag) => tag.trim());

if ((body.body && body.title) == null) {
return c.body('Invalid user input', StatusCode.BADREQ);
}
const res = await prisma.posts.create({
data: {
title: body.title,
body: body.body,
userId: c.get('userId'),
tags: {
connectOrCreate: tagNames.map((tag) => ({
where: { tag },
create: { tag },
})),
},
},
include: {
tags: true,
},
});

return c.json({
message: 'Post successfully',
post: {
id: res.id,
title: res.title,
body: res.body,
tags: res.tags.map((tag) => tag.tag),
createdAt: res.createdAt,
},
});
} catch (error) {
return c.body(`Internal server error: ${error}`, 500);
}
}

export async function getPost(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const id: number = Number(c.req.param('id'));

const isPostExist = await prisma.posts.findFirst({
where: {
id: id,
userId: c.get('userId'),
},
include: {
tags: true,
},
});

if (isPostExist == null) {
return c.body('Post does not exists', StatusCode.NOTFOUND);
}
return c.json({
data: {
id: isPostExist.id,
title: isPostExist.title,
body: isPostExist.body,
tags: isPostExist.tags,
createdAt: isPostExist.createdAt,
},
});
} catch (error) {
return c.body(`Internal server error: ${error}`, 500);
}
}

// this controller update the specific post
export async function updatePost(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const id: number = Number(c.req.param('id'));

const body: {
title: string;
body: string;
tags: string;
} = await c.req.json();

const tagNames = body.tags.split(',').map((tag) => tag.trim());

const isPostExist = await prisma.posts.findFirst({
where: {
id: id,
userId: c.get('userId'),
},
});

if (isPostExist == null) {
return c.body('Post does not exists', StatusCode.NOTFOUND);
}

const res = await prisma.posts.update({
where: {
id: id,
userId: c.get('userId'),
},
data: {
title: body.title,
body: body.body,
tags: {
connectOrCreate: tagNames.map((tag) => ({
where: { tag },
create: { tag },
})),
},
},
include: {
tags: true,
},
});

return c.json({
data: {
id: res.id,
title: res.title,
body: res.body,
tags: res.tags,
createdAt: res.createdAt,
},
});
} catch (error) {
return c.body(`Internal server error: ${error}`, 500);
}
}

export async function deletePost(c: Context) {
const prisma = new PrismaClient({
datasourceUrl: c.env.DATABASE_URL,
}).$extends(withAccelerate());

try {
const id: number = Number(c.req.param('id'));

const isPostExist = await prisma.posts.findFirst({
where: {
id: id,
userId: c.get('userId'),
},
});

if (isPostExist == null) {
return c.body('Post does not exists', StatusCode.NOTFOUND);
}

const res = await prisma.posts.delete({
where: {
id: id,
userId: c.get('userId'),
},
});
return c.json({
message: 'post deleted',
});
} catch (error) {
return c.json({ msg: `Internal server error: ${error}` }, 500);
}
}
Loading

0 comments on commit b0505dd

Please sign in to comment.