node -v 16.19.0
Game page
![game_page_gif](.github/game_page.gif)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ฌด์์๋ก ๊ฒน์น์ง ์๋ ๋ฌด์์ ์นด๋๋ฅผ 5์ฅ์ ๋ฝ๋๋ค
- ์ด 10์ฅ์ ์นด๋๋ก 2๊ฐ์ฉ ์ง์ ๋ง์ถ๋ ๋ผ์ด๋๊ฐ ์์(์นด๋ ๋ก๋ฉ์ค์๋ ์๊ฐ์ด ๋ฉ์ถค)
- ์๊ฐ์ ํ์ด ์๊ณ ๋ผ์ดํ๊ฐ 3๊ฐ๊ฐ ์ฃผ์ด์ง๋ฉฐ ์๋ชจ์ ๊ฒ์์ด ์ข ๋ฃ
- ์นด๋๋ 5์ด๊ฐ ํ์ธ๊ฐ๋ฅํ๊ณ ์ดํ ์๋์ผ๋ก ๋ค์ง์ด์ง
- ๊ฒ์์ค ์ด 3๋ฒ์ pause๊ฐ ๊ฐ๋ฅ
- ๊ฒ์์ค๋ฒ์ ์ค์ฝ์ด๋ฅผ ๊ธฐ๋ก๊ฐ๋ฅ (ํ์๊ฐ์ ํ์)
Showcase page
Score page
Upload page
Timeout page
- idToken์ด ๋ง๋ฃ ๋๋ ์ ํจํ์ง ์์๊ฒฝ์ฐ ์๋ฒ๋ก๋ถํฐ ๋ฆฌ๋ค์ด๋ ์ ๋๋ ํ์ด์ง
- ์ ๊ทผ์ ๊ฐ์ ๋ก ๋ก๊ทธ์์
"next": "13.2.3",
"typescript": "4.9.5"
"sass": "^1.58.3",
"recoil": "^0.7.7",
"axios": "^1.3.4",
"firebase": "^9.17.2",
"firebase-admin": "^11.5.0",
"@aws-sdk/client-s3": "^3.289.0",
"formidable": "^2.1.1",
"react-cropper": "^2.3.1",
"gravatar": "^1.8.2",
Member
ํ์๊ฐ์
/ํ์์ ๋ณด๊ฐฑ์
POST /api/member.add
headers: { authoriztion: "Bearer $idToken"; }
body: {
uid: string;
email?: string | null;
emailId?: string | null;
displayName?: string | null;
photoURL?: string | null;
}
response: {
result: boolean;
message: string;
}
์ด๋ฏธ ๋ฑ๋ก๋ ์ฌ์ฉ์์ผ ๊ฒฝ์ฐ body data๋ฅผ ํตํด ํ์์ ๋ณด ๊ฐฑ์
Image
์ด๋ฏธ์ง ์
๋ก๋
POST /api/image.add
headers: { authoriztion: "Bearer $idToken"; }
body/formData {
image: File;
imageName: string;
imageType: "image/png" | "image/jpeg";
uid: "string";
}
response: {
result: boolean;
imageName: string;
message: string;
}
์ด๋ฏธ์ง๊ฒ์(์ต์ ์)
GET /api/image.get
query: {
idx?: string;
}
response: {
imageData: ImageInfo[];
lastIdx: number;
}
idx๊ฐ ์์์ ํด๋น idx์ดํ ์ด๋ฏธ์ง๋ฅผ ์ต์ ์์ผ๋ก ๊ฐ์ ธ์ด(ํ์ด์ง๋ค์ด์
)
๋๋ค ์ด๋ฏธ์ง๊ฒ์
GET /api/image.random
response: {
imageData: ImageInfo[];
}
๊ฒน์น์ง ์๋ ์ด๋ฏธ์ง 5์ฅ์ ๊ฐ์ ธ์จ๋ค.
*์ด DB ์ด๋ฏธ์ง๊ฐ 5์ฅ์ดํ์ผ ๊ฒฝ์ฐ์๋ ์๋ฒ์๋ฌ๋ฐ์
์ด๋ฏธ์ง๊ฒ์(ํ์ดํ/imageName)
GET /api/image.find
query)
name: string;
next?: "true" | "false"
response)
{
imageData: ImageInfo[];
lastName: string | null;
lastIdx: number;
}
imageName์ผ๋ก ์
๋ก๋ํ ์ด๋ฏธ์ง ๊ฒ์, imageName์์ผ๋ก ์ ๋ ฌ
next๊ฐ "true"์ผ์ name์ ๋ค์ ์ด๋ฏธ์ง 5์ฅ์ ๊ฐ์ง๊ณ ์ด(ํ์ด์ง๋ค์ด์
)
์ด๋ฏธ์ง ํ์ดํ(imageName) ์ค๋ณต์ฒดํฌ
GET /api/image.check
query: {
name: string;
}
response: {
result: boolean;
}
DB์ ์ ๊ทผํ์ฌ ํด๋น name์ ์ด๋ฏธ์ง๊ฐ ์๋ ์ง ํ์ธ, ์ค๋ณต์ผ์ false์ ๋ฐํ
Score
์ค์ฝ์ด ์ ์ ๊ธฐ๋ก
POST /api/score.add
headers: { authoriztion: "Bearer $idToken"; }
body: {
uid: string;
score: number;
displayName: string;
}
response: {
result: boolean;
}
์ค์ฝ์ด ๋ญํน ๊ฒ์
GET /api/score.get
query: {
idx?: string;
}
response: {
scoreData: PasedScoreInfo[];
lastIdx: number;
}
score id์์ผ๋ก ๋ด๋ฆผ์ฐจ์ 10๊ฐ ์กฐํ
idx๊ฐ ์์์ ํด๋น idx์ดํ ์ค์ฝ์ด๋ฅผ ์ต์ ์์ผ๋ก ๊ฐ์ ธ์ด(ํ์ด์ง๋ค์ด์
)
PROTOCOL=
HOST=
PORT=
LOCAL_TIME=32400000
/* S3 Bucket */
AWS_S3_ACCESSKEY_Id=
AWS_S3_SECRET_ACCESS_KEY=
AWS_S3_REGION=
AWS_S3_BUCKET=
/* Firebase Client */
FIREBASE_PROJECT_ID=
FIREBASE_AUTH_API_KEY=
FIREBASE_AUTH_AUTH_DOMAIN=
/* Firebase Admin */
FIREBASE_ADMIN_PROJECT_ID=
FIREBASE_ADMIN_CLIENT_EMAIL=
FIREBASE_ADMIN_PRIVATE_KEY=
/* Vercel temp Path */
IMAGE_STORAGE_PATH=/tmp