Skip to content

Commit

Permalink
feat: view questions
Browse files Browse the repository at this point in the history
feat: rate-limit
  • Loading branch information
Danielzxccc committed Nov 16, 2023
1 parent d826a04 commit 407eede
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
.env
dist
uploads
uploads
test.yml
2 changes: 1 addition & 1 deletion src/middleware/RateLimitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function rateLimiter(rule: RateLimitterRule) {
if (requests > rate_limit.limit) {
return res.status(429).json({
error: true,
message: 'too much requests',
message: 'too many requests',
})
}
next()
Expand Down
2 changes: 1 addition & 1 deletion src/modules/AWS-Bucket/UploadService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dotenv.config()

const bucketName = process.env.AWS_BUCKET_NAME

const s3Client = new S3Client()
const s3Client = new S3Client({ region: process.env.AWS_REGION })

export function uploadFile(
filePath: fs.ReadStream,
Expand Down
6 changes: 1 addition & 5 deletions src/modules/Auth/AuthInteractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import { createUserTags } from '../Tags/TagsService'
import { deleteFile, readFileAsStream } from '../../utils/file'
import dbErrorHandler from '../../utils/dbErrorHandler'
import { getVerificationLevel } from '../../utils/utils'
import {
getObjectSignedUrl,
getObjectUrl,
uploadFile,
} from '../AWS-Bucket/UploadService'
import { getObjectUrl, uploadFile } from '../AWS-Bucket/UploadService'
import fs from 'fs'

export async function authenticateUser(credentials: string, password: string) {
Expand Down
8 changes: 7 additions & 1 deletion src/modules/Forums/ForumsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import { SessionRequest } from '../../types/AuthType'

export async function viewQuestion(req: SessionRequest, res: Response) {
try {
const question = await Interactor.viewQuestion(req.params.id)
const { query, params } = await zParse(Schema.ViewQuestion, req)

const pageNumber = Number(query.page) || 1
const perPage = 10
const offset = (pageNumber - 1) * perPage

const question = await Interactor.viewQuestion(params.id, offset, perPage)

res.status(200).json(question)
} catch (error) {
Expand Down
16 changes: 14 additions & 2 deletions src/modules/Forums/ForumsInteractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@ import { ForumsContent } from './../../schema/ForumsSchema'
import { getObjectUrl, uploadFiles } from '../AWS-Bucket/UploadService'
import { deleteFile } from '../../utils/file'

export async function viewQuestion(id: string) {
const question = await Service.viewQuestion(id, 0)
export async function viewQuestion(
id: string,
offset: number,
perPage: number
) {
let questionId = Number(id)

if (isNaN(questionId)) throw new HttpError('Not a valid ID', 400)

const question = await Service.viewQuestion(id, offset, perPage)

if (!question) throw new HttpError('Question Not Found', 404)

question.user.avatar = getObjectUrl(question.user.avatar)

return question
}
Expand Down
23 changes: 23 additions & 0 deletions src/modules/Forums/ForumsRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ export const ForumsRouter = express.Router()
*/
ForumsRouter.get('/', ForumsController.listQuestions)

/**
* @openapi
* /api/forums/{id}:
* get:
* tags:
* - "Forums"
* summary: Get Question Details
* parameters:
* - name: id
* in: path
* required: true
* schema:
* type: string
* description: Question ID
* responses:
* "200":
* description: Successful response
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/QuestionViewSchema"
*/

ForumsRouter.get('/:id', ForumsController.viewQuestion)

ForumsRouter.post(
Expand Down
8 changes: 6 additions & 2 deletions src/modules/Forums/ForumsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ export async function findQuestions(
return await query.limit(perpage).offset(offset).execute()
}

export async function viewQuestion(id: string, offset: number) {
export async function viewQuestion(
id: string,
offset: number,
perPage: number
) {
return await db
.selectFrom('forums')
.leftJoin('forums_answers', 'forums_answers.forumid', 'forums.id')
Expand Down Expand Up @@ -97,7 +101,7 @@ export async function viewQuestion(id: string, offset: number) {
])
.whereRef('forums.id', '=', 'forums_answers.forumid')
.orderBy('forums_answers.createdat', 'desc')
.limit(10)
.limit(perPage)
.offset(offset)
).as('answers'),
'forums.title',
Expand Down
106 changes: 106 additions & 0 deletions src/schema/ForumsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,103 @@ import { z } from 'zod'
* description: The timestamp when the question was last updated
*/

/**
*
* @openapi
* components:
* schemas:
* QuestionViewSchema:
* type: object
* properties:
* id:
* type: string
* user:
* type: object
* properties:
* avatar:
* type: string
* id:
* type: integer
* username:
* type: string
* required:
* - avatar
* - id
* - username
* tags:
* type: array
* items:
* type: object
* properties:
* tag:
* type: string
* required:
* - tag
* answers:
* type: array
* items:
* type: object
* properties:
* answer:
* type: string
* id:
* type: integer
* isaccepted:
* type: boolean
* user:
* type: object
* properties:
* avatar:
* type: string
* id:
* type: integer
* username:
* type: string
* required:
* - avatar
* - id
* - username
* required:
* - answer
* - id
* - isaccepted
* - user
* title:
* type: string
* question:
* type: string
* imagesrc:
* type: array
* items:
* type: string
* createdat:
* type: string
* format: date-time
* updatedat:
* type: string
* format: date-time
* answer_count:
* type: string
* vote_count:
* type: string
* latest_answer_createdat:
* type: string
* format: date-time
* required:
* - id
* - user
* - tags
* - answers
* - title
* - question
* - imagesrc
* - createdat
* - updatedat
* - answer_count
* - vote_count
* - latest_answer_createdat
*/

export const SearchForums = z.object({
query: z.object({
search: z.string().optional().default(''),
Expand All @@ -128,6 +225,15 @@ export const SearchForums = z.object({
}),
})

export const ViewQuestion = z.object({
query: z.object({
page: z.string().optional().default('1'),
}),
params: z.object({
id: z.string({ required_error: 'id is required' }),
}),
})

export const ForumsSchema = z.object({
body: z.object({
title: z
Expand Down

0 comments on commit 407eede

Please sign in to comment.