-
Notifications
You must be signed in to change notification settings - Fork 7
Formatting fixes #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Formatting fixes #11
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,15 @@ | ||
| { | ||
| "name": "COC API", | ||
| "version": "1.0.0", | ||
| "name": "COC API", | ||
| "version": "1.0.0", | ||
| "description": "REST API for Coding Club backend", | ||
| "title": "Coding Club API Docs", | ||
| "title": "Coding Club API Docs", | ||
| "url": "http://localhost:3000/api/v1", | ||
| "sampleUrl": false, | ||
| "sampleUrl": false, | ||
| "template": { | ||
| "withCompare": true, | ||
| "sort": true | ||
| }, | ||
| "output": "docs/apidoc", | ||
| "input": "src/routes", | ||
| "includeFilters": ["\\.ts$"] | ||
| "output": "docs/apidoc", | ||
| "input": "src/routes", | ||
| "includeFilters": ["\\.ts$"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| console.log("Hello via Bun!"); | ||
| console.log("Hello via Bun!"); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
|
|
||
| export default { | ||
| preset: 'ts-jest', | ||
| testEnvironment: 'node', | ||
| moduleFileExtensions: ['ts', 'js', 'json'], | ||
| testMatch: ['**/tests/**/*.test.ts'], | ||
| } | ||
| preset: "ts-jest", | ||
| testEnvironment: "node", | ||
| moduleFileExtensions: ["ts", "js", "json"], | ||
| testMatch: ["**/tests/**/*.test.ts"], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,20 @@ | ||
| import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended' | ||
| import { PrismaClient } from '@prisma/client' | ||
| import { mockDeep, mockReset, DeepMockProxy } from "jest-mock-extended"; | ||
| import { PrismaClient } from "@prisma/client"; | ||
|
|
||
| let mock: DeepMockProxy<PrismaClient> | ||
| let mock: DeepMockProxy<PrismaClient>; | ||
|
|
||
| jest.mock('./src/db/client', () => { | ||
| mock = mockDeep<PrismaClient>() | ||
| jest.mock("./src/db/client", () => { | ||
| mock = mockDeep<PrismaClient>(); | ||
| return { | ||
| __esModule: true, | ||
| prisma: mock, | ||
| } | ||
| }) | ||
| }; | ||
| }); | ||
|
|
||
| import { prisma } from "./src/db/client"; | ||
|
|
||
| import { prisma } from './src/db/client' | ||
|
|
||
| export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient> | ||
| export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>; | ||
|
|
||
| beforeEach(() => { | ||
| mockReset(prismaMock) | ||
| }) | ||
| mockReset(prismaMock); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,52 +1,53 @@ | ||
| // src/app.ts | ||
| import express from 'express' | ||
| import cors from 'cors' | ||
| import multer from 'multer' | ||
| import { json, urlencoded } from 'body-parser' | ||
| import routes from './routes' | ||
| import { errorHandler } from './utils/apiError' | ||
| import { createClient } from '@supabase/supabase-js' | ||
| import config from './config' | ||
| import path from 'path' | ||
|
|
||
| import express from "express"; | ||
| import cors from "cors"; | ||
| import multer from "multer"; | ||
| import { json, urlencoded } from "body-parser"; | ||
| import routes from "./routes"; | ||
| import { errorHandler } from "./utils/apiError"; | ||
| import { createClient } from "@supabase/supabase-js"; | ||
| import config from "./config"; | ||
| import path from "path"; | ||
|
|
||
| // Initialize Supabase client for storage operations | ||
| export const supabase = createClient( | ||
| config.SUPABASE_URL, | ||
| config.SUPABASE_SERVICE_ROLE_KEY | ||
| ) | ||
| config.SUPABASE_SERVICE_ROLE_KEY, | ||
| ); | ||
|
|
||
| const app = express() | ||
| const app = express(); | ||
|
|
||
| // 1) Enable CORS for your domains | ||
| app.use(cors({ | ||
| origin: config.ALLOWED_ORIGINS.split(','), // e.g. 'https://club.example.com' | ||
| methods: ['GET','POST','PATCH','DELETE','OPTIONS'], | ||
| credentials: true, | ||
| })) | ||
| app.use( | ||
| cors({ | ||
| origin: config.ALLOWED_ORIGINS.split(","), // e.g. 'https://club.example.com' | ||
| methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"], | ||
| credentials: true, | ||
| }), | ||
| ); | ||
|
|
||
| // 2) Parse JSON and form data | ||
| app.use(json()) | ||
| app.use(urlencoded({ extended: true })) | ||
| app.use(json()); | ||
| app.use(urlencoded({ extended: true })); | ||
|
|
||
| // 3) Handle file uploads (in-memory) | ||
| const upload = multer({ storage: multer.memoryStorage() }) | ||
| const upload = multer({ storage: multer.memoryStorage() }); | ||
|
|
||
| // 4) Mount your routes, injecting `upload` middleware where needed | ||
| // For endpoints that accept file uploads, you can do e.g.: | ||
| // router.post('/members/:memberId/photo', upload.single('photo'), ...) | ||
|
|
||
| app.use('/api/v1', routes(upload, supabase)) | ||
| app.use("/api/v1", routes(upload, supabase)); | ||
|
|
||
| // 5) 404 handler | ||
| app.use((req, res) => { | ||
| res.status(404).json({ message: 'Not Found' }) | ||
| }) | ||
| res.status(404).json({ message: "Not Found" }); | ||
| }); | ||
|
|
||
| // 6) Global error handler | ||
| app.use(errorHandler) | ||
| app.use(errorHandler); | ||
|
|
||
| // 7) do 'npm run apidoc to generate the documentation, I have added it in the scripts | ||
| // then you can go to localhost:3000/docs to see the docs | ||
| app.use('/docs', express.static(path.join(__dirname, '..', 'docs/apidoc'))) | ||
| export default app | ||
| app.use("/docs", express.static(path.join(__dirname, "..", "docs/apidoc"))); | ||
| export default app; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,31 +1,30 @@ | ||||||||||||||||||||||
| import { Request, Response } from "express"; | ||||||||||||||||||||||
| import { ApiError } from "../utils/apiError"; | ||||||||||||||||||||||
| import * as progressServices from "../services/progress.service" | ||||||||||||||||||||||
| import * as progressServices from "../services/progress.service"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const getCompletedQuestion = async(req:Request,res:Response)=>{ | ||||||||||||||||||||||
| const memberId = req.params.memberId; | ||||||||||||||||||||||
| if(!memberId){ | ||||||||||||||||||||||
| throw new ApiError("required field is missing",400); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| export const getCompletedQuestion = async (req: Request, res: Response) => { | ||||||||||||||||||||||
| const memberId = req.params.memberId; | ||||||||||||||||||||||
| if (!memberId) { | ||||||||||||||||||||||
| throw new ApiError("required field is missing", 400); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const completedQuestion = await progressServices.getCompletedQuestion(memberId); | ||||||||||||||||||||||
| res.status(200).json({ | ||||||||||||||||||||||
| status:"SUCCESS", | ||||||||||||||||||||||
| completedQuestion | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| const completedQuestion = | ||||||||||||||||||||||
| await progressServices.getCompletedQuestion(memberId); | ||||||||||||||||||||||
| res.status(200).json({ | ||||||||||||||||||||||
| status: "SUCCESS", | ||||||||||||||||||||||
| completedQuestion, | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| export const toggleQuestions = async (req: Request, res: Response) => { | ||||||||||||||||||||||
| const memberId = req.params.memberId; | ||||||||||||||||||||||
| const questionId = parseInt(req.params.questionId); | ||||||||||||||||||||||
| if (!memberId || !questionId) { | ||||||||||||||||||||||
| throw new ApiError("required field is missing", 400); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+20
to
+24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validation treats
-const questionId = parseInt(req.params.questionId);
-if (!memberId || !questionId) {
+const questionId = Number(req.params.questionId);
+if (!memberId || Number.isNaN(questionId)) {
throw new ApiError("required field is missing", 400);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const toggleQuestions = async(req:Request,res:Response) =>{ | ||||||||||||||||||||||
| const memberId = req.params.memberId; | ||||||||||||||||||||||
| const questionId = parseInt(req.params.questionId); | ||||||||||||||||||||||
| if(!memberId || !questionId){ | ||||||||||||||||||||||
| throw new ApiError("required field is missing",400); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| await progressServices.markQuestion(questionId,memberId); | ||||||||||||||||||||||
| res.status(200).json({ | ||||||||||||||||||||||
| status:"SUCCESS", | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| await progressServices.markQuestion(questionId, memberId); | ||||||||||||||||||||||
| res.status(200).json({ | ||||||||||||||||||||||
| status: "SUCCESS", | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Wildcard CORS fallback may be too permissive
ALLOWED_ORIGINSdefaults to"*", allowing any origin when the env-var is absent. This is fine for local dev but risky in production. Consider failing fast or providing an explicit allow-list instead.🤖 Prompt for AI Agents