Skip to content

Commit

Permalink
Merge pull request #110 from serafuku/yunochi/develop
Browse files Browse the repository at this point in the history
🚑  singleAnswer컴포넌트/백앤드 수정
  • Loading branch information
yunochi authored Dec 16, 2024
2 parents 99c6536 + 828a6a8 commit 790bb8b
Show file tree
Hide file tree
Showing 23 changed files with 88 additions and 41 deletions.
14 changes: 14 additions & 0 deletions prisma/migrations/20241216085248_is_anonymous/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Migration
*/
-- AlterTable
ALTER TABLE "question" ADD COLUMN "isAnonymous" BOOLEAN;

UPDATE "question"
SET
"isAnonymous" = CASE
WHEN "questioner" IS NULL THEN TRUE
ELSE FALSE
END;

ALTER TABLE "question" ALTER COLUMN "isAnonymous" SET NOT NULL;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ model question {
questionee profile @relation(fields: [questioneeHandle], references: [handle], onDelete: Cascade)
questioneeHandle String
questionedAt DateTime @default(now())
isAnonymous Boolean /// is Anonymous question?
@@index([questioneeHandle])
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/_components/answer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Link from 'next/link';
import { Dispatch, RefObject, SetStateAction, useEffect, useState } from 'react';
import NameComponents from './NameComponents';
import { AnswerWithProfileDto } from '../_dto/Answers.dto';
import { AnswerWithProfileDto } from '../_dto/answers/Answers.dto';
import { userProfileDto } from '../_dto/fetch-profile/Profile.dto';
import { useParams } from 'next/navigation';

Expand Down
4 changes: 2 additions & 2 deletions src/app/_components/question.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import Link from 'next/link';
import { SubmitHandler, useForm } from 'react-hook-form';
import { RefObject, useEffect, useLayoutEffect, useRef } from 'react';
import { CreateAnswerDto } from '@/app/_dto/create-answer/create-answer.dto';
import { questionDto } from '@/app/_dto/question/question.dto';
import { CreateAnswerDto } from '@/app/_dto/answers/create-answer.dto';
import { questionDto } from '@/app/_dto/questions/question.dto';

interface formValue {
answer: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { userProfileDto } from './fetch-profile/Profile.dto';
import { userProfileDto } from '../fetch-profile/Profile.dto';

export interface AnswerDto {
id: string;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions src/app/_dto/websocket-event/websocket-event.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { questionDto } from '@/app/_dto/question/question.dto';
import { AnswerWithProfileDto } from '../Answers.dto';
import { questionDto } from '@/app/_dto/questions/question.dto';
import { AnswerWithProfileDto } from '../answers/Answers.dto';

export const event_name_enum_arr = [
'question-created-event',
Expand Down Expand Up @@ -43,4 +43,4 @@ export type AnswerDeletedEvPayload = {
};
export class WebsocketAnswerDeletedEvent extends WebsocketEventPayload<AnswerDeletedEvPayload> {
ev_name: 'answer-deleted-event';
}
}
40 changes: 36 additions & 4 deletions src/app/api/_service/answer/answer-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import { Auth, JwtPayload } from '@/api/_utils/jwt/decorator';
import { RateLimit } from '@/_service/ratelimiter/decorator';
import { userProfileDto } from '@/app/_dto/fetch-profile/Profile.dto';
import { $Enums, blocking, profile, user, server, PrismaClient } from '@prisma/client';
import { AnswerListWithProfileDto, AnswerWithProfileDto } from '@/app/_dto/Answers.dto';
import { FetchAllAnswersReqDto } from '@/app/_dto/fetch-all-answers/fetch-all-answers.dto';
import { FetchUserAnswersDto } from '@/app/_dto/fetch-user-answers/fetch-user-answers.dto';
import { AnswerListWithProfileDto, AnswerWithProfileDto } from '@/app/_dto/answers/Answers.dto';
import { FetchAllAnswersReqDto } from '@/app/_dto/answers/fetch-all-answers.dto';
import { FetchUserAnswersDto } from '@/app/_dto/answers/fetch-user-answers.dto';
import { RedisKvCacheService } from '@/app/api/_service/kvCache/redisKvCacheService';
import { RedisPubSubService } from '@/_service/redis-pubsub/redis-event.service';
import { AnswerDeletedEvPayload, QuestionDeletedPayload } from '@/app/_dto/websocket-event/websocket-event.dto';
import { CreateAnswerDto } from '@/app/_dto/create-answer/create-answer.dto';
import { CreateAnswerDto } from '@/app/_dto/answers/create-answer.dto';
import { profileToDto } from '@/api/_utils/profileToDto';
import { mastodonTootAnswers, MkNoteAnswers } from '@/app';
import { createHash } from 'crypto';
Expand Down Expand Up @@ -331,6 +331,38 @@ export class AnswerService {
}
}

@RateLimit({ bucket_time: 300, req_limit: 600 }, 'ip')
public async GetSingleAnswerApi(_req: NextRequest, answerId: string) {
const answer = await this.prisma.answer.findUnique({
include: { answeredPerson: { include: { user: { include: { server: { select: { instanceType: true } } } } } } },
where: {
id: answerId,
},
});
if (!answer) {
return sendApiError(404, 'Not found');
}
const profileDto = profileToDto(
answer.answeredPerson,
answer.answeredPerson.user.hostName,
answer.answeredPerson.user.server.instanceType,
);
const dto: AnswerWithProfileDto = {
id: answer.id,
question: answer.question,
questioner: answer.questioner,
answer: answer.answer,
answeredAt: answer.answeredAt,
answeredPerson: profileDto,
answeredPersonHandle: answer.answeredPersonHandle,
nsfwedAnswer: answer.nsfwedAnswer,
};
return NextResponse.json(dto, {
status: 200,
headers: { 'Content-type': 'application/json', 'Cache-Control': 'public, max-age=60' },
});
}

private profileToDto(profile: profile, hostName: string, instanceType: $Enums.InstanceType): userProfileDto {
const data: userProfileDto = {
handle: profile.handle,
Expand Down
3 changes: 2 additions & 1 deletion src/app/api/_service/question/question-service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreateQuestionDto } from '@/app/_dto/create_question/create-question.dto';
import { CreateQuestionDto } from '@/app/_dto/questions/create-question.dto';
import type { PrismaClient, user } from '@prisma/client';
import { NextRequest, NextResponse } from 'next/server';
import { validateStrict } from '@/utils/validator/strictValidator';
Expand Down Expand Up @@ -128,6 +128,7 @@ export class QuestionService {
question: data.question,
questioner: data.questioner,
questioneeHandle: data.questionee,
isAnonymous: data.questioner ? false : true, //임시
},
});

Expand Down
2 changes: 1 addition & 1 deletion src/app/api/_service/websocket/websocket-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
WebsocketEventPayload,
WebsocketKeepAliveEvent,
} from '@/app/_dto/websocket-event/websocket-event.dto';
import { AnswerWithProfileDto } from '@/app/_dto/Answers.dto';
import { AnswerWithProfileDto } from '@/app/_dto/answers/Answers.dto';
import { GetPrismaClient } from '../../_utils/getPrismaClient/get-prisma-client';
import { RedisKvCacheService } from '../kvCache/redisKvCacheService';
import { blocking, PrismaClient } from '@prisma/client';
Expand Down
6 changes: 6 additions & 0 deletions src/app/api/db/answers/[userHandle]/[answerId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ export async function DELETE(req: NextRequest, { params }: { params: Promise<{ a
const answerId = (await params).answerId;
return await service.deleteAnswer(req, answerId, null as unknown as jwtPayloadType);
}

export async function GET(req: NextRequest, { params }: { params: Promise<{ answerId: string }> }) {
const service = AnswerService.getInstance();
const { answerId } = await params;
return await service.GetSingleAnswerApi(req, answerId);
}
4 changes: 2 additions & 2 deletions src/app/main/_events.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Logger } from '@/utils/logger/Logger';
import { questionDto } from '../_dto/question/question.dto';
import { questionDto } from '../_dto/questions/question.dto';
import { QuestionDeletedPayload } from '../_dto/websocket-event/websocket-event.dto';
import { AnswerWithProfileDto } from '../_dto/Answers.dto';
import { AnswerWithProfileDto } from '../_dto/answers/Answers.dto';

const QuestionCreateEvent = 'QuestionCreateEvent';
const QuestionDeleteEvent = 'QuestionDeleteEvent';
Expand Down
4 changes: 2 additions & 2 deletions src/app/main/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { userProfileMeDto } from '@/app/_dto/fetch-profile/Profile.dto';
import MainHeader from '@/app/main/_header';
import { createContext, useEffect, useState } from 'react';
import { MyProfileContext } from '@/app/main/_profileContext';
import { FetchAllAnswersReqDto } from '../_dto/fetch-all-answers/fetch-all-answers.dto';
import { AnswerListWithProfileDto, AnswerWithProfileDto } from '../_dto/Answers.dto';
import { FetchAllAnswersReqDto } from '../_dto/answers/fetch-all-answers.dto';
import { AnswerListWithProfileDto, AnswerWithProfileDto } from '../_dto/answers/Answers.dto';
import { AnswerEv } from './_events';

type MainPageContextType = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/questions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useContext, useEffect, useRef, useState } from 'react';
import DialogModalTwoButton from '@/app/_components/modalTwoButton';
import DialogModalLoadingOneButton from '@/app/_components/modalLoadingOneButton';
import { MyProfileContext } from '@/app/main/_profileContext';
import { questionDto } from '@/app/_dto/question/question.dto';
import { questionDto } from '@/app/_dto/questions/question.dto';
import { MyQuestionEv } from '../_events';
import { Logger } from '@/utils/logger/Logger';
import { QuestionDeletedPayload } from '@/app/_dto/websocket-event/websocket-event.dto';
Expand Down
17 changes: 0 additions & 17 deletions src/app/main/user/[handle]/[answer]/action.ts

This file was deleted.

16 changes: 13 additions & 3 deletions src/app/main/user/[handle]/[answer]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
import Answer from '@/app/_components/answer';
import { useParams } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
import { fetchAnswer } from './action';
import { AnswerDto } from '@/app/_dto/Answers.dto';
import { AnswerDto } from '@/app/_dto/answers/Answers.dto';
import DialogModalTwoButton from '@/app/_components/modalTwoButton';

export default function SingleAnswer() {
const [answerBody, setAnswerBody] = useState<AnswerDto>();
const singleQuestionDeleteModalRef = useRef<HTMLDialogElement>(null);
const { answer } = useParams() as { answer: string };
const { userHandle } = useParams() as { userHandle: string };

async function fetchAnswer(id: string) {
const res = await fetch(`/api/db/answers/${userHandle}/${id}`, {
method: 'GET',
});
if (!res.ok) {
throw new Error(`Fail to fetch answer! ${await res.text()}`);
}
return await res.json();
}

const handleDeleteAnswer = async (id: string) => {
const res = await fetch(`/api/db/answers/${id}`, {
const res = await fetch(`/api/db/answers/${userHandle}/${id}`, {
method: 'DELETE',
});
try {
Expand Down
4 changes: 2 additions & 2 deletions src/app/main/user/[handle]/_answers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useParams } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
import Answer from '@/app/_components/answer';
import { userProfileDto } from '@/app/_dto/fetch-profile/Profile.dto';
import { AnswerDto } from '@/app/_dto/Answers.dto';
import { FetchUserAnswersDto } from '@/app/_dto/fetch-user-answers/fetch-user-answers.dto';
import { AnswerDto } from '@/app/_dto/answers/Answers.dto';
import { FetchUserAnswersDto } from '@/app/_dto/answers/fetch-user-answers.dto';
import DialogModalTwoButton from '@/app/_components/modalTwoButton';

type ResponseType = {
Expand Down
2 changes: 1 addition & 1 deletion src/app/main/user/[handle]/_profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import DialogModalLoadingOneButton from '@/app/_components/modalLoadingOneButton
import DialogModalTwoButton from '@/app/_components/modalTwoButton';
import NameComponents from '@/app/_components/NameComponents';
import { SearchBlockListResDto } from '@/app/_dto/blocking/blocking.dto';
import { CreateQuestionDto } from '@/app/_dto/create_question/create-question.dto';
import { CreateQuestionDto } from '@/app/_dto/questions/create-question.dto';
import { userProfileDto } from '@/app/_dto/fetch-profile/Profile.dto';
import josa from '@/app/api/_utils/josa';
import Link from 'next/link';
Expand Down

0 comments on commit 790bb8b

Please sign in to comment.