๋ชจ๋ ํ๊ต๋ฅผ ์ํ ๋์์ ์ธ ํ๊ต ์ ๋ณด ์์คํ
- ๐ ์๋ ํ์ธ์!
- ๐ป ์ค์นํด ๋ด ์๋ค!
- โจ๏ธ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์?
- ๐ก ๊ฐ๋ฐ์ ์ํ ์ ๋ณด!
- ๐ ์ง์ ์ค์นํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ
- ๐ ๋ฌธ์๋ค์ ์ด๋์?
- โค๏ธ ๊ธฐ์ฌํ๋ ๋ฐฉ๋ฒ
Important
์๋ ํ์ธ์! Altsis(Alternative School Infomation System)๋ ๋ชจ๋ ํ๊ต๋ฅผ ์ํ ๋์์ ์ธ ํ๊ต ์ ๋ณด ์์คํ ์ ๋๋ค!
Tip
- Alt : ๋์์ ์ด๊ณ ์์ค๋์ ๊ต์ก์ ์งํฅํ๋ ๊ต์ก์ ์ธ ์์คํ
- Function Key : ๋ค์ํ ๊ธฐ๋ฅ์ผ๋ก ์ปค์คํ ํ ์ ์๋ ๋ง์ถคํ ์์คํ
- Keyboard : ์ ๋ณด๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋ค๋ฃฐ ์ ์๋ ์ ๋ฌธ์ ์ธ ์์คํ
Important
2016๋ ๋ณ๋ฌด๋ฆฌํ๊ต ์๊ฐ ์ ์ฒญ ์์คํ ์ ์ํด ๊ฐ๋ฐ๋ BLMS๋ฅผ ๋ณด์ํ๊ณ ๋ฐ์ ์ํค์ํด 2022๋ ๋ณ๋ฌด๋ฆฌํ๊ต ๊ต์ฌ์ ์กธ์ ์์ด ํ์ ๋ชจ์ ๊ฐ๋ฐํ Altsis์ ๋๋ค. ์ง๊ธ์ AEG๋ฅผ ์ด์ํ์ฌ ๋์์ ์ธ ํ๊ต ๊ด๋ฆฌ ์์คํ ์ด ํ์ํ ๋ง์ ํ๊ต๋ค์๊ฒ ๋ณด๊ธํ๊ธฐ ์ํด ํ์ฐ๊ณ ์์ต๋๋ค!
Note
- 2016 ๋ณ๋ฌด๋ฆฌํ๊ต ์๊ฐ ์ ์ฒญ์ ์ํ ๋ง์ถคํ ํ์ต ๊ด๋ฆฌ ์์คํ BLMS ๊ฐ๋ฐ @devgoodway
- 2022 BLMS๋ฅผ ๋ฐ์ ์ํจ ALTSIS ๊ฐ๋ฐ @devgoodway @jessie129j @seedlessapple and @O-ye
- 2023 ALTSIS ์คํ ์์ค ํ๋ก์ ํธ ์์ @devgoodway
- 2024 AEG Altsis Educator Group ์์ @devgoodway
Important
- ๋์ํ๊ต์์ ๋ง๋ ๋์๊ต์ก์ ์ํ ๋์์ ์ธ ํ๊ต ์ ๋ณด ์์คํ
- ๋ค์ํ ํ๊ต์ ๊ต์ก๊ณผ์ ์ ์ ์ฉ ํ ์ ์๋ ์ ์ฐํ๊ณ ๋ ์ฐฝ์ ์ธ ์์คํ
- ๋ฏธ๋ ์งํฅ์ ์ธ ๊ต์ก์ฒ ํ์ ์คํํ๋ ๊ต์ก์ ์ธ ์์คํ
Note
- ๐ซ ์์นด๋ฐ๋ฏธ ์์คํ : ๋จ ํ๋์ ์์นด๋ฐ๋ฏธ์์ ๋ณต์์ ํ๊ต ๋จ์ ๊ต์ก ๊ณผ์ ์ด์ ๊ฐ๋ฅ
- ๐ป ๋ง์ถคํ ์์คํ : ์์คํ ์ค์ ๊ณผ ์๋ํฐ๋ฅผ ์ด์ฉํด ํ์์ ๋ง๋ ๋ง์ถคํ ์์คํ ๊ตฌ์ฑ ๊ฐ๋ฅ
- ๐งโ๐ ํ์ ์ค์ฌ ์์คํ : ํ์์ด ์์ ๊ฐ์ค ๋ฐ ํ๊ฐ ๋ฑ์๋ ์ฐธ์ฌ ํ ์ ์๋ ํ์ ์ค์ฌ ์์คํ
- ๐ฃ๏ธ ํตํฉ ์์คํ : ํ์์ ์์ , ํ๊ฐ, ๊ธฐ๋ก, ์ถ๋ ฅ์ ํ๋์ ์์คํ ์์ ๊ด๋ฆฌ
Important
๋ฐฐํฌ ํ๊ฒฝ
- ๐พ Server : MongoDB, Redis, AWS Ec2, AWS S3๋ฅผ ์ด์ฉํด ์๋ฒ ๊ตฌ์ฑ
โ๏ธ Backend : express๋ฅผ ์ด์ฉํ REST-ful APIโถ๏ธ Frontend : React๋ฅผ ์ด์ฉํ Node.js ์์คํ
git clone https://github.com/bmrdevteam/Altsis.git
ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ > backend
๋ก ์ด๋ํฉ๋๋ค.
cd Altsis\backend
- ์์กด์ฑ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
yarn
Tip
OS ํ๊ฒฝ์ ๋ง๊ฒ yarn์ ์ค์นํด ๋ก์๋ค!
- cross-env, nodemon์ ์ ์ญ์ผ๋ก ์ค์นํฉ๋๋ค.
yarn global add cross-env
yarn global add nodemon
.env
ํ์ผ์ ์์ฑํ๊ณ , ํ์ํ ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํฉ๋๋ค.
Altsis>backend>.env
# CORS ์ค์ ์ ์ํ Frontend URL : ์์
URL='http://localhost:3030'
# Backend ์๋ฒ๋ฅผ ์คํํ PORT : ์์
SERVER_PORT=8080
# MongoDB ํด๋ฌ์คํฐ ์ฐ๊ฒฐ URI
DB_URL='mongodb+srv://*********:****************@******.*******.mongodb.net'
# Redis ์ฐ๊ฒฐ URI
REDIS_URL='redis://default:********************************@redis-*****.****.****************.ec2.cloud.redislabs.com:*****'
# Session ์ ์ฅ์ ์ฌ์ฉํ ์ํธํค (mongoose-encryption)
session_key='********************************************'
# Google Login์ ์ฌ์ฉ๋๋ client ID (Google Cloud)
GOOGLE_CLIENT_ID='*********************************************.apps.googleusercontent.com'
# AWS S3 ์ง์ญ ์ ๋ณด : ์์
s3_region='ap-northeast-2'
# S3์ ํ๋กํ ์ฌ์ง์ ์ ์ฅํ๊ธฐ ์ํ ํ๊ฒฝ ๋ณ์
# AWS S3 ๋ฒํท๋ช
: ์์
s3_bucket='altsis-profile'
# AWS S3 ์
๋ก๋ ๊ถํ์ ๊ฐ์ง IAM์ keyId
s3_accessKeyId='********************'
# AWS S3 ์
๋ก๋ ๊ถํ์ ๊ฐ์ง IAM์ secretAccessKey
s3_secretAccessKey='****************************************'
# S3์ ํ์ผ์ ์ ์ฅํ๊ธฐ ์ํ ํ๊ฒฝ ๋ณ์
# AWS S3 ์
๋ก๋ ๊ถํ์ ๊ฐ์ง IAM์ keyId : ์์
s3_bucket2='altsis-files'
# AWS S3 ์
๋ก๋ ๊ถํ์ ๊ฐ์ง IAM์ keyId
s3_accessKeyId2='********************'
# AWS S3 ์
๋ก๋ ๊ถํ์ ๊ฐ์ง IAM์ secretAccessKey
s3_secretAccessKey2='****************************************'
# ์๊ฐ ์ ๋ณด์ ํ๊ฐ ์ ๋ณด๋ฅผ ์ํธํํ๊ธฐ ์ํ ํ๊ฒฝ ๋ณ์ (mongoose-encryption)
# ๊ณต๊ฐํค(32๋นํธ)
ENCKEY_E=********************************************
# ์ํธํค(64๋นํธ)
SIGKEY_E=****************************************************************************************
# ํ์ ๊ธฐ๋ก ์ ๋ณด๋ฅผ ์ํธํํ๊ธฐ ์ํ ํ๊ฒฝ ๋ณ์ (mongoose-encryption)
# ๊ณต๊ฐํค(32๋นํธ)
ENCKEY_A=********************************************
# ์ํธํค(64๋นํธ)
SIGKEY_A=****************************************************************************************
# ๋น๋ฐ๋ฒํธ ํด์ฑ์ ์ํ ์ค์ ๊ฐ (passport) : ์์
saltRounds=10
Tip
- URL์ REST-API๋ฅผ ํธ์ถํ๋ Frontend ์๋ฒ์ URL์ ๋๋ค.
- ํ๊ฒฝ ๋ณ์๋ฅผ ์ ์ฅํ๊ธฐ ์ํด MongoDB, Redis, Google Cloud, AWS S3์ ํ๊ฒฝ ์ค์ ๋ฐ ํด๋น ๊ฐ์ ํธ์ถ ํ ์ค๋น๋ฅผ ํฉ๋๋ค!
- mongoose-encryption๋ฅผ ์ด์ฉํด ์ธ์ ๋ฐ ์ํธํค๋ฅผ ์์ฑํ๋๋ก ํฉ๋๋ค.
- ์๋ฒ๋ฅผ ์คํํฉ๋๋ค.
yarn dev
- ์์กด์ฑ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
yarn
.env
ํ์ผ์ ์์ฑํ๊ณ , ํ์ํ ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํฉ๋๋ค.
altsis>frontend>.env
# Google Login์ ์ฌ์ฉ๋๋ client ID (Google Cloud)
REACT_APP_GOOGLE_CLIENT_ID='*********************************************.apps.googleusercontent.com'
# Frontend ์๋ฒ URL : Backend PORT - ์์
REACT_APP_SERVER_URL='http://localhost:8080'
# Frontend ์๋ฒ PORT - ์์
PORT=3030
Tip
- Google Cloud Client ID๋ Backend ์ค์ ๊ณผ ๋์ผํฉ๋๋ค.
- ์๋ฒ๋ฅผ ์คํํฉ๋๋ค.
yarn start
- ์ค์นํ MongoDB Database์ ์ ์ํฉ๋๋ค.
root>academies
์ Academy Document๋ฅผ ์์ฑํฉ๋๋ค.
{
"_id": {
"$oid": [์๋ ์์ฑ]
},
"academyId": "root",
"academyName": "root",
"dbName": "root",
"isActivated": true
}
- ์์นด๋ฐ๋ฏธ๊ฐ ์์ฑ๋์๋์ง ํ์ธํ๊ธฐ ์ํด ํด๋ผ์ด์ธํธ๋ฅผ ์คํํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์์นด๋ฐ๋ฏธ ์
์ฅ ํ๋ฉด์ด ๋์ค๋ฉด ์์นด๋ฐ๋ฏธ ID์
root
๋ฅผ ์ ๋ ฅํ๊ณ ์ ์ฅ์ด ์ ์์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋์ง ํ์ธํฉ๋๋ค.
root
๋ฐ์ดํฐ๋ฒ ์ด์ค์users
์ปฌ๋ ์ ์ ์ถ๊ฐํฉ๋๋ค.
users
์ ์์ ์ Document๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
{
"_id": {
"$oid": [์๋ ์์ฑ]
},
"academyId": "root",
"academyName": "root",
"auth":"owner",
"userId": "admin",
"userName": "๊ด๋ฆฌ์",
"password": "",
}
- ์ฌ์ฉ์ ๊ณ์ ์ด ์์ฑ๋์๋์ง ํ์ธํ๊ธฐ ์ํด ๋ก๊ทธ์ธ ํ๋ฉด์์ ์์ด๋์ ์์์ ์ค์ ํ userId๋ฅผ ์ ๋ ฅํ๊ณ ๋น๋ฐ๋ฒํธ๋ฅผ ์์๋ก ์ ๋ ฅํ ํ '๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ์ต๋๋ค'๋ผ๋ ๋ฉ์์ง๊ฐ ๋์ค๋์ง ํ์ธํฉ๋๋ค.
backend>src>_passport>localStrategy2.js
ํ์ผ์์ ๋ก๊ทธ์ธ ์ ์ ๋ ฅํ ๋น๋ฐ๋ฒํธ์ ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋น๊ตํ๋ ์ฝ๋(29~35 Line)๋ฅผ ์ฃผ์์ฒ๋ฆฌํ๊ณ ์๋ฒ๋ฅผ ์ฌ์คํํฉ๋๋ค.
Warning
๋ก๊ทธ์ธ ํ์๋ ๋ฐ๋์ ์ฃผ์์ ํ์ด์ฃผ์ ์ผ ํฉ๋๋ค.
backend>src>_passport>localStrategy2.js
import passport from "passport";
import { Strategy as CustomStrategy } from "passport-custom";
import { Academy, User } from "../models/index.js";
import {
ACADEMY_INACTIVATED,
PASSWORD_INCORRECT,
__NOT_FOUND,
} from "../messages/index.js";
const local2 = () => {
passport.use(
"local2",
new CustomStrategy(async function (req, done) {
const { academyId, userId, password } = req.body;
const academy = await Academy.findOne({
academyId,
});
if (!academy) {
const err = new Error(__NOT_FOUND("academy"));
return done(err, null, null);
}
if (!academy.isActivated) {
const err = new Error(ACADEMY_INACTIVATED);
return done(err, null, null);
}
const user = await User(academyId)
.findOne({ userId })
.select("+password");
if (!user) {
const err = new Error(__NOT_FOUND("user"));
return done(err, null, null);
}
// ์ฃผ์ ์์
const isMatch = await user.comparePassword(password);
if (!isMatch) {
const err = new Error(PASSWORD_INCORRECT);
return done(err, null, null);
}
// ์ฃผ์ ๋
user.password = undefined;
return done(null, user, academyId);
})
);
};
export { local2 };
- ์๋ฒ๋ฅผ ์ฌ์คํํ ํ ๋ก๊ทธ์ธํฉ๋๋ค.
- ์ฌ์ฉ์ ์ค์ ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. 7๋ฒ์์ ์ค์ ํ ์ฃผ์์ ํด์ ํ ํ ์๋ฒ๋ฅผ ์ฌ์คํํฉ๋๋ค. ๋ก๊ทธ์์ ํ ์ค์ ํ ๋น๋ฐ๋ฒํธ๋ก ๋ก๊ทธ์ธ์ด ๋๋์ง ํ์ธํฉ๋๋ค.
Important
์์คํ ์ ์ด์ํ๊ธฐ ์ํ ๊ด๋ฆฌ์ ๊ธฐ๋ฅ๊ณผ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ๋ ์ฌ์ฉ์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
Important
โ๏ธ ๊ด๋ฆฌ์ : โซ ์์คํ ๊ด๋ฆฌ์(owner), ๐ด ์์นด๋ฐ๋ฏธ ๊ด๋ฆฌ์(admin), ๐ต ํ๊ต ๊ด๋ฆฌ์(manager)
Tip
์ฌ์ง/์์
BackupAndRestore.mp4
Note
- ์์ ๊ฐ์ค ๊ถํ
- ์๊ฐ์ ์ฒญ ๊ถํ
- ํ๊ฐ ๊ถํ
Important
๐ ์ฌ์ฉ์ : ํ์(student), ๊ต์ฌ(teacher)
Tip
Important
โ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ต๊ณผ๋ชฉ์ด ๊ฐ์ ์์ ์ ํ ํ๊ธฐ ๋ด์์ ํ๊ฐ ์ ๋ณด๊ฐ ๋๊ธฐํ๋๊ณ , ํ๊ฐ ๋จ์๊ฐ 'ํ๋ ๋'์ธ ํ๊ฐ ํญ๋ชฉ์ ํ ํ๋ ๋ ๋ด์์ ํ๊ฐ ์ ๋ณด๊ฐ ๋๊ธฐํ๋๋ค.
Tip
์ฌ์ง/์์
UCalendar.mp4
Node.js
Important
ํ๋ก์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
- ๋ผ์ฐํธ(Route): HTTP ์์ฒญ์ ๋ผ์ฐํ ํฉ๋๋ค.
- ์ปจํธ๋กค๋ฌ (Controller): ๋ผ์ฐํ ๋ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ฉฐ ํ์ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํํฉ๋๋ค.
- ๋ชจ๋ธ (Model): ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ ์คํค๋ง๋ฅผ ์ค์ ํฉ๋
Note
- MongoDB Cloud: ๋ฉ์ธ DB์
๋๋ค.
- ํ๊ต ๋ฐ์ดํฐ๋ ๊ด๊ณ๊ฐ ๋ง์์ sql์ด ์ ํฉํ ์ ์์ง๋ง ์๋น์ค์ ๊ฐ์ฅ ํฐ ํน์ง์ธ ์ปค์คํฐ๋ง์ด์ง ๊ธฐ๋ฅ์ ์ด๋ฆฌ๊ธฐ ์ํด์๋ ๊ฐ์ฒด ํํ๋ก ์ ์ฅํ ์ ์๋ MongoDB๊ฐ ์ ํฉํ๋ค๊ณ ํ๋จํ์ต๋๋ค.
- Redis Cloud: ์ผ์์ ์ด๊ณ ๋น ๋ฅด๊ฒ ๊ฐ์ ธ์์ผ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ๋ก๊ทธ์ธ ์ธ์ ์ ์ฅ
- ์๋ฆผ ์์ ์ ์ค์๊ฐ ์๋ฆผ์ ์ํ ์์ผ ์ ๋ณด ์ ์ฅ
- ์๊ฐ์ ์ฒญ ์ ์ค์๊ฐ ๋๊ธฐ๋ฒํธ ์ ์ก์ ์ํ ์์ผ ์ ๋ณด ์ ์ฅ
Important
- MongoDB ํด๋ฌ์คํฐ ๋ด์ ๋ ์ข
๋ฅ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์์ต๋๋ค.
- ๋ฃจํธ DB(
root
): ์์นด๋ฐ๋ฏธ ๋ํ๋จผํธ์ ์์ ์ ๊ถํ์ ๊ฐ์ง ์ฌ์ฉ์ ๋ํ๋จผํธ๊ฐ ์ ์ฅ๋๋ค. - ์์นด๋ฐ๋ฏธ DB(
{academyId}-db
): ๊ฐ์ ๋ ์์นด๋ฐ๋ฏธ๋ณ๋ก ๋ํ๋จผํธ๊ฐ ์ ์ฅ๋๋ค. ex)knu-db
- ๋ฃจํธ DB(
- ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ๋์ผํ ๊ตฌ์กฐ์ ์ปฌ๋ ์ ์ด ์์ฑ๋ฉ๋๋ค.
Note
๋ฃจํธ DB
- academies: ๊ฐ์ ๋ ์์นด๋ฐ๋ฏธ
- users: ์์นด๋ฐ๋ฏธ๋ฅผ ์์ฑ/๊ด๋ฆฌํ ์ ์๋ ์์ ์ ๊ณ์
Note
์์นด๋ฐ๋ฏธ DB
- users: ๊ด๋ฆฌ์ ๊ณ์ ์ ํฌํจํ ์์นด๋ฐ๋ฏธ ์ฌ์ฉ์ ๊ณ์
- schools: ํ๊ต ์ ๋ณด
- ํ๊ต ๋ณ๋ก ๊ธฐ๋ก ์์์ ์ค์ ํ ์ ์์ต๋๋ค.
- seasons: ํ๊ต์ ์์ฑ๋ ํ๊ธฐ ์ ๋ณด
- ํ๊ธฐ ๋ณ๋ก ๊ถํ๊ณผ ์์์ ์ค์ ํ ์ ์์ต๋๋ค.
- ๊ถํ: ์์ ๊ฐ์ค/์๊ฐ์ ์ฒญ/ํ๊ฐ ๊ถํ
- ์์: ๊ฐ์์ค, ๊ต๊ณผ๋ชฉ, ๊ฐ์๊ณํ์ ์์, ํ๊ฐ ์์
- registrations: ํ๊ธฐ ๋ฑ๋ก ์ ๋ณด
- user A, school B, season C๊ฐ ์์ ๋ user A๋ฅผ school B์ ๋ฑ๋กํ ํ์ season C์ ํ์ ๋๋ ์ ์์ผ๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค.
- syllabus: ๊ฐ์๊ณํ์
- enrollment: ์๊ฐ ์ ๋ณด
- user A, syllabus B๊ฐ ์์ ๋ user A๊ฐ B ์์ ์ ์๊ฐ์ ์ฒญ์ ํ๋ฉด enrollment C๊ฐ ์์ฑ๋ฉ๋๋ค.
- ์๊ฐ ์ ๋ณด์๋ ํ๊ฐ ์ ๋ณด(evaluation)๊ฐ ํฌํจ๋๊ณ , ํ๊ฐ ์ ๋ณด๋ ์ํธํ๋์ด ์ ์ฅ๋ฉ๋๋ค.
- archive: ๊ธฐ๋ก ์ ๋ณด
- ํ๊ต ์ฌ์ฉ์์ ๋ํ ๊ธฐ๋ก ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค
- ์ํธํ๋์ด ์ ์ฅ๋ฉ๋๋ค
- forms: ์์
- ํ๊ต ๋ณ๋ก ๊ฐ์๊ณํ์, ์๊ฐํ, ๋ฌธ์ ๋ฑ์ ์์์ ์์ฑํ๊ณ ์ ์ํฉ๋๋ค
- notification: ์๋ฆผ
- ์์ ์ ๋ฉํ ์ธ ์ ์๋์ ์๊ฐ์๋ค์๊ฒ ์๋ฆผ์ ์ ์กํ ์ ์์ต๋๋ค
Note
There are two types of DB; Root DB and academy DB
- Root DB(
root-db
)- ์์นด๋ฐ๋ฏธ ๋ํ๋จผํธ์ ์ฌ์ฉ์(์์ ์) ๋ํ๋จผํธ๊ฐ ์ ์ฅ๋๋ค.
- Academy DB(
{academyId}-db
)- ์์นด๋ฐ๋ฏธ ๊ด๋ จ ๋ํ๋จผํธ๊ฐ ์ ์ฅ๋๋ค.
- ํ๊ต, ์ฌ์ฉ์(๊ด๋ฆฌ์, ๋งค๋์ , ๋ฉค๋ฒ), ํ๊ธฐ, โฆ
- ์์นด๋ฐ๋ฏธ ๊ด๋ จ ๋ํ๋จผํธ๊ฐ ์ ์ฅ๋๋ค.
Note
- https://bmrdevteam.github.io/altsis-docs/api/Models.html
backend>models
ํด๋ ๋ด์ ๊ฐ ๋ชจ๋ธ ํ์ผ์์ jsdoc์ผ๋ก ๋ฌธ์๋ฅผ ์ ์ํ๋คnpm run jsdoc
์คํ ์backend>docs
์ html ํ์ผ์ด ์์ฑ๋จ -> ์ด๋ฅผ ๊ฐ๋ฐ ๋ฌธ์ ์ ๋ก๋ ๋ ํฌ์ ์ ๋ก๋ํ๋ค
Note
- ๋ก๊ทธ์ธ ์ธ์ ์ ์ฅ
- ์๋ฆผ ์์ ์ ์ค์๊ฐ ์๋ฆผ์ ์ํ ์์ผ ์ ๋ณด ์ ์ฅ
- ์๊ฐ์ ์ฒญ ์ ์ค์๊ฐ ๋๊ธฐ๋ฒํธ ์ ์ก์ ์ํ ์์ผ ์ ๋ณด ์ ์ฅ
Note
- ํ๋กํ ์ฌ์ง
- ๊ธฐ๋ก ํ์ผ
- ์์นด๋ฐ๋ฏธ ๋ฐฑ์ ํ์ผ
- ๋ก๊ทธ
Note
- AWS S3
- ํ๋กํ ์ฌ์ง ๋ฒํท
/original/
๊ฒฝ๋ก์ ํ๋กํ ์ฌ์ง ์ ๋ก๋๋๋ฉด AWS Lambda๊ฐ ํธ๋ฆฌ๊ฑฐ๋์ด ์ฌ์ง์ ๋ฆฌ์ฌ์ด์งํ๊ณ/thumb/
๊ฒฝ๋ก์ ์ ์ฅ๋ฉ๋๋ค.
- ์์นด๋ฐ๋ฏธ ํ์ผ ๋ฒํท
- ํ์ ๊ธฐ๋ก(archive) ํ์ผ ์ ์ฅ
- ๋ฐฑ์ ํ์ผ ์ ์ฅ
- ๋ก๊น
๋ฒํท
/raw/
๊ฒฝ๋ก์ ๋ฐฐํฌ ํ๊ฒฝ ๋ก๊ทธ๊ฐ ์ค์๊ฐ์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.- ์ ๊ฐ์ด ๋๋ฉด AWS Lambda๊ฐ ํธ๋ฆฌ๊ฑฐ๋์ด ์ ๋ ์ ๋ก๊ทธ๋ฅผ
/yyyy-mm-dd/
๊ฒฝ๋ก๋ก ์ฎ๊น๋๋ค.
- ํ๋กํ ์ฌ์ง ๋ฒํท
Note
- AWS S3: ํด๋ผ์ด์ธํธ๊ฐ ๋น๋๋์ด ๋ฐฐํฌ๋ฉ๋๋ค.
- AWS CloudFront: ํด๋ผ์ด์ธํธ์ ๋๋ฉ์ธ ์ฃผ์๋ฅผ ์ ์ฉํด๊ณ https ํต์ ์ ์ ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
- ์บ์ฑ์ผ๋ก ์๋ ํฅ์์ ์ด์ ์ ์ค ์ ์์ง๋ง ํ์ฌ๋ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ๋ก ์ ์ฉํ๊ธฐ ์ํด ์ ์ฉํ์ง ์์์ต๋๋ค.
- AWS EC2, Docker: EC2 ์ธ์คํด์ค์ Docker๋ก ์๋ฒ ์ปจํ ์ด๋๊ฐ ์คํ๋ฉ๋๋ค.
- ALB: https ํต์ ์ ์ ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
- Auto Scaling๋ ๊ณ ๋ คํ์ผ๋ ์ ์ฉํ์ง ์์์ต๋๋ค.
Note
- AWS S3
- AWS CloudFront
- AWS Route53
- AWSย Certificate Manager(ACM) - https ํต์ ์ ์ํ SSL ์ธ์ฆ์ ๋ฐ๊ธ
Note
- AWS EC2
- AWS ALB(Application Load Balancer)
- https ํต์ ์ ์ํด ์ ์ฉํจ
- AWS Route53
- ์๋ธ๋๋ฉ์ธ์ผ๋ก ์๋ฒ ์ฃผ์ ํ ๋น
Note
- Personal Access Token ์์ฑ:
- GitHub ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํฉ๋๋ค.
- ์ค๋ฅธ์ชฝ ์๋จ์ ํ๋กํ ์ฌ์ง์ ํด๋ฆญํ๊ณ , "Settings"๋ก ์ด๋ํฉ๋๋ค.
- ์ผ์ชฝ ๋ฉ๋ด์์ "Developer settings" ์๋์ "Personal access tokens"์ ์ ํํฉ๋๋ค.
- "Generate token"์ ํด๋ฆญํ๊ณ ํ์ํ ๊ถํ์ ์ ํํฉ๋๋ค.
- ๋ฐฐํฌ์ ํ์ํ ๊ถํ์ ์ ํํด์ผ ํ๋ฉฐ, worlflow, write:packages, delete:packages๋ฅผ ์ ํํฉ๋๋ค.
- ํ ํฐ์ ์์ฑํ๊ณ ์์ ํ ์ฅ์์ ๋ณต์ฌํฉ๋๋ค.
- GitHub Secrets์ ๋ฑ๋ก:
- ๋ ํฌ์งํ ๋ฆฌ๋ก ์ด๋ํ์ฌ "Settings"๋ฅผ ํด๋ฆญํฉ๋๋ค.
- ์ผ์ชฝ ๋ฉ๋ด์์ "Secrets"๋ฅผ ์ ํํ๊ณ , "New repository secret"์ ํด๋ฆญํ์ฌ ์๋ก์ด ์ํฌ๋ฆฟ์ ์ถ๊ฐํฉ๋๋ค.
- ์ํฌ๋ฆฟ ์ด๋ฆ(GHCR_TOKEN_์์ด๋)์ ์ง์ ํ๊ณ , ์์ ์์ฑํ Personal Access Token ๊ฐ์ ์ ๋ ฅํฉ๋๋ค.
Note
- See
.github > workflows > frontend-pipeline.yml
- frontend ๋ธ๋์น์ push๊ฐ ์ผ์ด๋๋ฉด ๋ฐฐํฌ๊ฐ ์์๋จ
- CI/CD
- Github container registry์์ ์บ์ ๋ฐ์์ด
- Github secrets์ ์ ์ฅ๋ ๊ฐ์ผ๋ก .envํ์ผ ์์ฑ
- ๋ชจ๋ ์ค์น ํ ๋น๋
- ๋น๋ ํ์ผ s3 ํด๋ผ์ด์ธํธ ๋ฐฐํฌ์ฉ ๋ฒ์ผ์ ์ ๋ก๋
- ์ฌ๋ ์๋ฆผ
Note
- See
.github > workflows > backend-pipeline.yml
- backend ๋ธ๋์น์ push๊ฐ ์ผ์ด๋๋ฉด ๋ฐฐํฌ๊ฐ ์์๋จ
- CI
- GitHub ์ปจํ ์ด๋ ๋ ์ง์คํธ๋ฆฌ์ ๋ก๊ทธ์ธ
- Github secrets์ ์ ์ฅ๋ ๊ฐ์ผ๋ก .envํ์ผ ์์ฑ
bakcend>Dockerfile
๋ก Docker image ๋น๋ํ๊ณ Github container registry์ push- ์ฌ๋ ์๋ฆผ
- CD
- action runner๋ก ๋ฑ๋ก๋ ec2์์ ์คํ๋จ
- Github container registry์ ๋ก๊ทธ์ธ ํ Docker image pull
- Docker container ์คํ
--restart on-failure
์ต์ ์ผ๋ก ์๋ฒ๊ฐ ๋ค์ด๋์ ๋ ์๋์ผ๋ก ์ฌ์คํ๋๋๋ก ์ค์
- ์ฌ๋ ์๋ฆผ
Note
- https://bmrdevteam.github.io/altsis-docs/api/APIs.html
backend>controllers
ํด๋ ๋ด์ ๊ฐ ์ปจํธ๋กค๋ฌ ํ์ผ์์ jsdoc์ผ๋ก ๋ฌธ์๋ฅผ ์ ์ํ๋คnpm run jsdoc
์คํ ์backend>docs
์ html ํ์ผ์ด ์์ฑ๋จ -> ์ด๋ฅผ ๊ฐ๋ฐ ๋ฌธ์ ์ ๋ก๋ ๋ ํฌ์ ์ ๋ก๋ํ๋ค
Note
frontend>...>hooks>useAPIv2
ํ ์ผ๋ก API๋ฅผ ์ ์ํ๊ณ ํธ์ถํ ์ ์๋คuseAPIv2
์์ ์ฌ์ฉํ๋ API ์ด๋ฆ๊ณผ API ๋ฌธ์์์์ API ์ด๋ฆ์ ๋์ผํ๋ค
Note
- ํ๊ธฐ ์์ฑ ๊ธฐ๋ฅ์ ๋ฒ๊ทธ ๋ฐ๊ฒฌ
- ํด๋ผ์ด์ธํธ์์ ํ๊ธฐ ์์ฑ์ ์ด๋ค API๋ฅผ ์ฌ์ฉํ๋์ง ํ์ธํ๋ค ex) CSeason API
- API ๋ฌธ์์์ CSeason API๋ฅผ ์ฐพ๊ณ ์์ฒญ์ ์ ๋๋ก ๋ณด๋๋์ง ํ์ธ
- ์์ฒญ์ ์ ๋๋ก ๋ณด๋๋ค๋ฉด backend ํด๋์์ "CSeason"์ ๊ฒ์ํ์ฌ ํด๋น API ์ฝ๋ ํ์ธ
- ์๋ต์ ์๋ฌ ๋ฉ์์ง๊ฐ ์๋ค๋ฉด ํด๋น ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๋ถ๋ถ์ ์ฐพ์ ์์ธ ํ์
- ๋ฒ๊ทธ ์์ ํ ๋ฐฐํฌ
Note
winston
, winston-daily-rotate-file
, morgan
, s3-streamlogger-daily
Note
backend>logs
ํด๋์ ๋ก๊ทธ ํ์ผ ์์ฑ๋จ
Note
- AWS S3์ ๋ก๊ทธ ๋ฒํท์ ๋ก๊ทธ ํ์ผ ์์ฑ๋จ
raw
ํด๋์ ์ค์๊ฐ ๋ก๊ทธ ๊ธฐ๋ก๋จ- ์ค์๊ฐ ๋ก๊ทธ ํ์ผ ์ด๋ฆ์ ์๋ฒ๊ฐ ์คํ๋ ์๊ฐ์ผ๋ก, ์ค์ ์๋ฒ๊ฐ ๊ธฐ๋ก๋๋ ์๊ฐ๊ณผ๋ ๋ฌด๊ดํ๋ค
- ๋งค์ผ ์์ ์ AWS Lambda ์ค์ผ์ค๋ฌ๊ฐ ์คํ๋์ด ์ ๋ ๋ก๊ทธ๋ฅผ
archived
ํด๋๋ก ์ฎ๊ธด๋ค- ex) 2023๋
1์ 10์ผ์ ๊ธฐ๋ก๋ ๋ก๊ทธ๋ 2023๋
1์ 11์ผ ์์ ์
archived/2023-01-10
ํด๋๋ก ์ฎ๊ฒจ์ง๋ค
- ex) 2023๋
1์ 10์ผ์ ๊ธฐ๋ก๋ ๋ก๊ทธ๋ 2023๋
1์ 11์ผ ์์ ์
Note
์์ฒญ ์๊ฐ, http, http ๋ฒ์ , ip ์ฃผ์, user.academyId, user._id, method(POST, GET, ...), url, req.body, res.status, response time(ms), referrer, user agent
Important
Altsis๋ ์คํ ์์ค ํ๋ก์ ํธ์ด๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ์ง์ ์๋ฒ์ ์ค์นํ์ฌ ์ด์ฉ ํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ง์ ์ค์นํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ ์ด๋ฏธ ์๋ฒ๋ฅผ ์ด์ฉํ๊ณ ์๋ ๊ด๋ฆฌ์์๊ฒ ์์ฒญํ์ฌ ์์นด๋ฐ๋ฏธ๋ฅผ ๋ฐ๊ธ๋ฐ์ ์ด์ฉ ํ ์๋ ์์ต๋๋ค. ์๋๋ ์์นด๋ฐ๋ฏธ ์๋ฒ๋ฅผ ์ ๊ณตํ๋ ๋จ์ฒด์ ์๋ด์ ๋๋ค.
Tip
- AEG(Altsis Educator Group)๋ ๋ณ๋ฌด๋ฆฌํ๊ต์์ ์ด์ํ๋ Altsis ์๋ฒ(https://altsis.org) ๋ฅผ ์๋ํ์ฌ ํ๊ต(๋๋ ๋จ์ฒด)์์ ์ ๊ณตํ๋ ์ญํ ์ ํฉ๋๋ค. ์์ธํ ์ฌํญ์ AEG ๋ฌธ์๋ฅผ ํ์ํ์ธ์.
Important
Altsis์ ๊ด๋ จ๋ ๋ฌธ์๋ Github Page์์ ํ์ธ ํ ์ ์์ต๋๋ค.
Tip
๋ฌธ์๋ ์๋์ ์น์ ์ผ๋ก ๋๋ ์ ธ ์์ต๋๋ค.
๋น์ ์ ์ฐธ์ฌ๋ก Altsis์ ์์คํ ๋ฌธ์๋ฅผ ๋ฐ์ ์ํฌ ์ ์์ต๋๋ค.
Important
์ด ํ๋ก์ ํธ์ ์ฃผ์ ๋ชฉ์ ์ Altsis์ ์ฃผ์ ๊ธฐ๋ฅ์ ๋์ฑ ๋ฐ์ ์ํค๊ณ ๋ง์ ์ฌ๋๋ค์ด ๋์ฑ ์ฝ๊ฒ ์ฌ์ฉํ๋๋ก ํ๊ธฐ ์ํจ์ ๋๋ค. Altsis๋ Github๋ฅผ ํตํด์ ๊ฐ๋ฐํ๊ฒ ๋๋๋ฐ ์ด๋ ์ค๋ฅ๋ฅผ ์์ ํ๊ณ ์ฝ๋๋ฅผ ๋ฐ์ ์ํค๊ธฐ ์ํด ์ข์ ๋๊ตฌ๊ฐ ๋ฉ๋๋ค. ๋ฐ๋์ ์๋ ๋ฌธ์๋ฅผ ์์ธํ ์ฝ๊ณ ํ๋ก์ ํธ์ ๋์ฐธํด์ฃผ์ธ์.
Tip
Code of Conduct๋ ์ฐ๋ฆฌ ํ๋ก์ ํธ์ ์ฐธ์ฌํ ๋ ์ง์ผ์ผ ํ ์ฝ์๊ณผ ํ๋๋ฅผ ๊ธฐ์ ํ๊ณ ์์ต๋๋ค.
Altsis is MIT licensed.