Skip to content

Commit

Permalink
feat: required logged in to add question (#447)
Browse files Browse the repository at this point in the history
* chore(api): update CONTRIBUTING.md

* feat: required logged in to add question

* feat(api): save user id in question

* feat(api): add onDelete Cascade

* refactor(api): restore migrations

* refactor(api): change column names

* refactor(api): typo

* feat(api): add prisma migration

* refactor(api): set createdById optional
  • Loading branch information
AdiPol1359 authored Dec 20, 2022
1 parent 305fa6e commit 09bd468
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 4 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

## Introduction

DevFAQ is organised into a monorepo with Turborepo. You'll find frontend ([www](./apps/www)) and backend ([api](./apps/api)) in the [apps](./apps) directory.
DevFAQ is organised into a monorepo with Turborepo. You'll find frontend ([app](./apps/app)) and backend ([api](./apps/api)) in the [apps](./apps) directory.

- Frontend is written in **Next.js (React) with TypeScript**.
- Backend is a REST API, and uses **HapiJS, PostgreSQL, and TypeScript**.
- Backend is a REST API, and uses **Fastify, PostgreSQL, and TypeScript**.

## Project setup

Expand Down
10 changes: 9 additions & 1 deletion apps/api/modules/questions/questions.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ const questionsPlugin: FastifyPluginAsync = async (fastify) => {
method: "POST",
schema: generatePostQuestionsSchema(args),
async handler(request, reply) {
const { question, level, category } = request.body;
const {
body: { question, level, category },
session: { data: sessionData },
} = request;

if (!sessionData) {
throw fastify.httpErrors.unauthorized();
}

try {
const newQuestion = await fastify.db.question.create({
Expand All @@ -88,6 +95,7 @@ const questionsPlugin: FastifyPluginAsync = async (fastify) => {
levelId: level,
categoryId: category,
statusId: "pending",
createdById: sessionData._user.id,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Question" ADD COLUMN "_createdById" INTEGER;

-- AddForeignKey
ALTER TABLE "Question" ADD CONSTRAINT "Question__createdById_fkey" FOREIGN KEY ("_createdById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
3 changes: 3 additions & 0 deletions apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ model Question {
categoryId String @map("_categoryId")
levelId String @map("_levelId")
statusId String @default("pending") @map("_statusId")
createdById Int? @map("_createdById")
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt() @db.Timestamptz(6)
QuestionCategory QuestionCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade)
QuestionLevel QuestionLevel @relation(fields: [levelId], references: [id], onDelete: Cascade)
QuestionStatus QuestionStatus @relation(fields: [statusId], references: [id], onDelete: Cascade)
CreatedBy User? @relation(fields: [createdById], references: [id], onDelete: Cascade)
QuestionVote QuestionVote[]
}

Expand Down Expand Up @@ -79,6 +81,7 @@ model User {
UserRole UserRole @relation(fields: [roleId], references: [id], onDelete: Cascade)
QuestionVote QuestionVote[]
Session Session[]
Question Question[]
}

model UserRole {
Expand Down
6 changes: 5 additions & 1 deletion apps/app/src/components/CtaHeader/AddQuestionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
"use client";

import { useDevFAQRouter } from "../../hooks/useDevFAQRouter";
import { useUIContext } from "../../providers/UIProvider";
import { Button } from "../Button/Button";

export const AddQuestionButton = () => {
const { openModal } = useUIContext();
const { requireLoggedIn } = useDevFAQRouter();

const handleButtonClick = () => openModal("AddQuestionModal");

return (
<>
<Button
variant="brandingInverse"
className="hidden sm:inline-block"
onClick={() => openModal("AddQuestionModal")}
onClick={requireLoggedIn(handleButtonClick)}
>
Dodaj pytanie
</Button>
Expand Down

0 comments on commit 09bd468

Please # to comment.