Home - Marvic1130/BlinkingRecognitionProject GitHub Wiki
- 
๊ฐ์ ์์ด๋์ด๋ฅผ ํ๋์ฉ ๊ฐ์ ธ์ค๊ธฐ๋ก ํด์ ์์ด๋์ด ํ์ ํ ๊ฐ์ฅ ์ธ๊ธฐ๊ฐ ์ข์๋ ์์ด๋์ด์ธ "์ธ๊ณต์ง๋ฅ์ ์ด์ฉํ ๋ ๊น๋นก์ ํ์๋ฅผ ํตํด ์ง์ค๋๋ฅผ ๊ฒ์ถํ๋ ํ๋ก์ ํธ" ์ ์  
- 
์นด๋ฉ๋ผ๋ก ์ฌ๋์ ๋ ๊น๋ฐ์ ํ์๋ ๋์ ๊ฐ๊ณ ์๋ ์๊ฐ๋ฑ์ ์ธก์ ํ์ฌ ์์ or ๊ฐ์์ ์ง์ค๋๋ฅผ ์น์ ๋ฐ์ดํฐ๋ก ํ์ํ๋ ํ๋ก์ ํธ 
๋ฐ์ดํฐ ์์ง -> ์ ์ฒ๋ฆฌ -> ๋ผ๋ฒจ๋ง -> ํ์ต ์์๋ก ์งํ ์์ 
๋จผ์  ๋ ๊น๋นก์์ ํ์ต์ํค๊ธฐ ์ํด ๋์ ๋ฌ ์ฌ์ง๊ณผ ๋์ ๊ฐ๊ณ ์๋ ์ฌ์ง์ ๊ฐ๊ฐ ํ์ต์์ผ์ผ ํ๋ค.
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๋ฅผ ์ํด Open Cv๋ฅผ ์ด์ฉํ์ฌ ์ฌ์ง or ์์์์ ์ผ๊ตด์ ์ธ์ํ์ฌ ์ผ๊ตด ๋ถ๋ถ์ ํฌ๋กญํด์ ์ ์ฅํด์ผํ๋ค.
1์ฃผ์ฐจ์ ์ฌ์ฉํ ์ฝ๋์์๋ haarcascade๋ฅผ ์ฌ์ฉํ๋๋ฐ ๋ง์คํฌ๋ฅผ ์ฐ๊ณ ์์ผ๋ฉด ์ผ๊ตด๋ก ์ธ์ํ์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ฒ ์ฃผ๋ ํ์ด์ง ๋ ์ด์์์ ๊ฐ์ด ๋์์ธํ๋ค. ์์ผ๋ก๋ ์์ง ๋ฏธ์์ฑ์ธ ํ์ด์ง ๋ ์ด์์์ ๋ค๋ฌ๊ณ ์ผ๊ตด์ธ์์ด ๋์ด ๋์จ ์ฌ์ง ํ์ผ๋ค์ ๋ผ๋ฒจ๋ง ํ์ฌ ํ๋ก๊ทธ๋จ์ ํ์ต ์ํฌ ๊ณํ์ด๋ค.
์ฒ์์๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ํ์๋ค(ํ์)๊ณผ ๊ด๋ฆฌ์(๊ต์ or ์ ์)์ผ๋ก ๊ตฌ์ํ์์ผ๋ ์์ ์ง์ค๋๋ฅผ ๋ฐ์ดํฐ๋ก ๋ณด์ฌ์ฃผ๋๋ฐ ๊ตณ์ด ๋ก๊ทธ์ธ ์์คํ ์ ๋ ๊ฐ์ง๋ก ๋๋ ํ์๊ฐ ์๋ค๊ณ ํ๋จํ์ฌ ๋ก๊ทธ์ธ์ ๊ด๋ฆฌ์๋ง ๊ฐ๋ฅํ๋๋ก ๋ณ๊ฒฝํ๊ณ ๊ด๋ฆฌ์๋ ์์ ์ ๋ฑ๋กํ๋ ๊ธฐ๋ฅ๊ณผ ์์ ์ ์์ ๋ค์ ๊ด๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ์ผ๋ก ํธ์ฑํ๋ค.
 
์ง๋์ฃผ์ ๋ง์คํฌ, ๋ชจ์ ๋ฑ์ผ๋ก ์ผ๊ตด์ด ๊ฐ๋ ค์ง๋ฉด ์ธ์์ด ์๋์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ฌ ์ด์  ๋ง์คํฌ ๋ชจ์๋ฑ์ผ๋ก ์ผ๊ตด์ด ๊ฐ๋ ค์ ธ๋ ์ผ๊ตด์ธ์์ ๋ฌธ์ ๊ฐ ์๋ค.
- ๋ฐฑ์๋ ์งํ ์ํฉ
- ์๋ฒ ๊ตฌ์ถ(node.js ์ express)
- mysql db ์ฐ๋ ๋ฐ model ๊ตฌ์กฐํ ์์
- user model
- class model
 
 
- ํ๋ก ํธ ์งํ ์ํฉ
- ๋ฉ์ธํ์ด์ง html, css ์์
- ์์ ํ๋ฉฐ ๋ ์ด์์ ์์ 
 
 

- 
ํ๋ก์ ํธ ์์ 
 ๋ ๊น๋ฐ์๊ณผ ํ๊ฒฝ๋ณ์๋ฅผ ํตํ ์ง์ค๋ ํ ์คํธ -> ๋ ๊น๋ฐ์๊ณผ ์ง์ญ๋ณ์๋ฅผ ํตํ์ฌ ๊ฐ์ ํ๊ฐ์ ์ ํ์ฑ ์ธก์  ํ ์ ์๋ ๊ฐ์ ํ๊ฐ ์ฌ์ดํธ ์ ์
- 
๋ณ๊ฒฝ ์ด์ 
 ํ๋ก์ ํธ๋ฅผ ์งํํจ์ ์์ด์ ํ์คํ ๋ชฉ์ ์ฑ์ด ์์ด ํ๋ก์ ํธ๊ฐ ์ ๋์ ์ผ๋ก ๋ณํ๊ณ ๊ทธ์ ๋ฐ๋ผ UI๊ฐ ๊ณ์์ ์ผ๋ก ๋ณํด, ํ์คํ ๋ชฉ์ ์ฑ์ด ์๋ ํ๋ก์ ํธ๋ก ๋ณ๊ฒฝ
<์ด๊ธฐ ํ์ด์ง>
<ํ์๊ฐ์
 ํ์ด์ง>
๊ต์ ํ์๊ฐ์
๊ณผ ํ์ ํ์๊ฐ์
 ๋ถ๋ฅ
<ํ์ ํ์ด์ง>
<๊ต์ ํ์ด์ง>
- ๋ฐฑ์๋ ์งํ ์ํฉ
- ํ๋ก์ ํธ ์์ ์ ๋ฐ๋ฅธ user DB๋ชจ๋ธ ์์ 
- Routers ์์ฑ ๋ฐ ๋ชจ๋ํ๋ฅผ ์ํด Controllers์ ์ฝ๋ฐฑ ํจ์ ์์ฑ
 
- ํ๋ก ํธ ์งํ ์ํฉ
- ๋ก๊ทธ์ธ ํ์ด์ง ์์
- ์์ ํ๋ฉฐ ์๋ก์ด ๋ ์ด์์ ์์  ์งํ์ค
 

- ํ๋ก ํธ ์งํ ์ฌํญ
- ํ์ ์์ ๋ฑ๋ก ํ์ด์ง ์์ ์๋ฃ (๊ต์์ ํ์ ์์ ๋ฑ๋ก ํ์ด์ง ๊ตฌ๋ถ)
 



- ํ๋ก ๋ ํต์ฌ ์ฝ๋ ๋ฆฌ๋ทฐ

-> ํ์์๋ ์จ๊ฒจ์ ธ ์๋ ์์ ๋ฑ๋ก UI๋ฅผ +๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ํ๋๊ณ ์์ ์ ์ ํํ๊ณ ๋ฑ๋ก ์๋ฃ ๋ฒํผ์ ํด๋ฆฌํ๋ฉด ์์ ๋ชฉ๋ก์ ์๋ก์ด ์๋ฆฌ๋จผํธ๋ก ๋ฒํผ์ด ์ถ๊ฐ๋๋ ๊ตฌ์กฐ์ ๋๋ค.
main branch :  ํ๋ก์ ํธ๊ฐ ์์ฑ๋์์ ๋ ์ต์ข
์ ์ผ๋ก ๋ณํฉํ๊ธฐ ์ํ ๋ธ๋์น
jaeyoun miji hyemi yeseong jungseok branch: ๊ฐ์ ์ด๋ฆ์ผ๋ก ๋ธ๋์น๋ฅผ ๊ตฌ์ฑํ์ฌ ๊ฐ์ ์์ ์ด ๋ง๋  ํํธ๋ณ ์์
์ ์งํํ๋ ๋ธ๋์น
back branch : backend ๊ธฐ๋ฅ ๊ตฌํ์ด ๋ชจ๋ ์๋ฃ ๋์์ ๋ ๋ณํฉ์ ์ํ ๋ธ๋์น
์ต๊ทผ ๋ธ๋์น ์ด๋๊ฒฝ๋ก

1. class ๋ฑ๋ก api ์์ฑ
2. ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ ์๋ฃ
3. token์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ middleware ์์ฑ
1.class ๋ฑ๋ก
const { className, professor, department, classTime, place, people } = req.body;
  
    try {
      await Class.create({
        className,
        professor,
        department,
        classTime,
        place,
        people,
      });
      return res.json({className, professor, department, classTime, place, people}).redirect("/")
    } catch (err) {
      console.log(err);};

- ๊ฒ์ ๊ธฐ๋ฅ
module.exports.find = async (req, res) => {
  const { keyword } = req.query;
  try {
    const item = await Class.findAll({
      where: {
        [Op.or]: [
          {
            className: {
              [Op.like]: `%${keyword}%`,
            },
          },
          {
            professor: {
              [Op.like]: `%${keyword}%`,
            },
          },
        ],
      },
    });
    if (item.length === 0) {
      return res.status(401).json({ message: "์ผ์นํ๋ ์์
์ด ์์ต๋๋ค!" });
    }
    return res.json({ item });
  } catch (err) {
   ; console.log(err)
  }
};
3.token์ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ middleware
if(req.headers.authorization){
        //Request์ header์ Authorization์์ ํ ํฐ์ ์ถ์ถ
        let header = req.headers["authorization"]
        
        //Authorization์์ 'Bearer'๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก split ์ฌ์ฉ!!
        let token = header && header.split("")[1]
        
        //์ ํจ์ฑ๊ฒ์ฌ
        jwt.verify(token, process.env.ACCESS_SECRET, (err,user)=>{
            if(err) {
                res.status(404).json(err)
            }else{
                req.user = user;
                next();
            }
    })
    }else{
        res.status(401).json({error: "Auth Error"})
    }   //class๋ฅผ ๋ฑ๋กํ ๋ token์ ์ ํจ์ฑ์ ๊ฒ์ฌํ ์ ์๋๋ก middleware ์ค์ ํ๊ธฐ
   classRouter.route("/register").all(authToken).post(classes.register)->accessToken์ด ๋ง๋ฃ๋์์๋ ์ฌ๋ฐํํ๋ ์ฝ๋ ํ์!

-> ๋ก์ปฌ์๋ฒ์์ ์ฌ์ฉ๊ฐ๋ฅ ํ์๊ฐ์ ์ ๋ก์ปฌ DB์ ํ์์ ๋ณด๊ฐ ์ ์ฅ๋๊ณ ์์ ๋ชฉ๋ก ํ์ด์ง๊ฐ ๋ธ

- html
    <!-- ์์
 ๋ฑ๋ก -->
    <div class="registration-container">
      <div class="classBox">
        <h1 class="title">๊ฐ์ํ๊ฐ</h1>
        <div class="formBox">
          <!-- <form method="POST"> -->
          <label for="classTitle" id="titleLabel"
            >1. ๊ฐ์์ ์ผ๋ง๋ ์ง์ค ํ๋์?</label
          ><br />
          <!-- ์ ์ฒด ์์ญ -->
          <div class="progress1">
            <!-- ํ๋ก๊ทธ๋์ค ๋ฐ -->
            <div class="state1"><span id="percentage1"></span></div>
          </div>
          
          <label for="classTime" id="timeLabel">
            2. ๊ฐ์์์ ์ป์ ์ ์๋ ์ ์ด ์์๋์?</label
          ><br />
          <!-- ์ ์ฒด ์์ญ -->
          <div class="progress2">
            <!-- ํ๋ก๊ทธ๋์ค ๋ฐ -->
            <div class="state2"><span id="percentage2"></span></div>
          </div>
          <label for="department" id="departmentLabel">
            3. ๊ฐ์๊ฐ ๋ง์กฑ์ค๋ฌ์ ๋์?</label
          ><br />
          <!-- ์ ์ฒด ์์ญ -->
          <div class="progress3">
            <!-- ํ๋ก๊ทธ๋์ค ๋ฐ -->
            <div class="state3"><span id="percentage3"></span></div>
          </div>
          <button id="registrationBtn">์ ์ถํ๊ธฐ</button>
          <!-- </form> -->
        </div>
      </div>
    </div>- css
/* ํ๋ก๊ทธ๋์ค ๋ฐ */
.progress1, .progress2, .progress3 {
  width: 75%;
  height: 50px;
  position: relative;
  top: 0;
  left: 0;
  overflow-x: hidden;
  cursor: pointer;
  border: 1px solid black;
  margin: 0 auto;
  border-radius: 2px;
}
.state1, .state2, .state3 {
  width: 0;
  height: 50px;
  position: absolute;
  top: 0;
  left: 0;
  background-color: #448593;
}
#percentage1, #percentage2, #percentage3 {
  line-height: 50px;
  vertical-align: middle;
}- javascript
$(document).ready(function () {
  //ํ๋ก๊ทธ๋์ค ๋ฐ๋ฅผ ํด๋ฆญ
  $(".progress1").click(function (e) {
    // ๋ณ์ x๋ .progress์ left๊ฐ์์ ํด๋ฆญํ ์์น์ X๊ฐ์ ๋บ๋ค.
    // e.pageX๋ ํ๋ฉด์์ ํด๋ฆญํ X์ ์์น๋ฅผ ๊ฐ์ ธ์จ๋ค.
    var x = e.pageX - $(".progress1").offset().left;
    //๋ณ์ clickPercentage๋ ๋ณ์ x / .progress.๋๋น
    clickPercentage = x / $(".progress1").width();
    //.state์ ๋๋น๋ (.progress์ ๋๋น์์ ๋ณ์ clickPercentage๋ฅผ ๊ณฑํ ๊ฐ);
    $(".state1").width($(".progress1").width() * clickPercentage);
    var percentage = clickPercentage * 100;
    //Math.floor() ์์์  ๋ฒ๋ฆผ, ์ ์๋ฅผ ๋ฐํํ๋ ํจ์
    $("#percentage1").text(Math.floor(percentage));
  });
});
ํ์ต์ ์งํํ ๋ ๋๋ฌด ๋ง์ epoch๋ overfitting์ ์ผ์ผํค๊ณ ๋๋ฌด ์ ์ epoch๋ underfitting์ ์ผ์ผํค๋๋ฐ, ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Early Stopping์ ์ฌ์ฉํ๋ค.

early_stopping_calback = EarlyStopping(monitor='loss', patience=10)
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='loss', verbose=0, save_best_only=True)
hist = model.fit(X_train, Y_train, batch_size=64, epochs=200, callbacks=[early_stopping_calback, checkpointer])patience=10
 

patience=5
 

patience=3
 

patience=1
 

ํ์ต๋ ๋ชจ๋ธ์ ํ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋ค.
 
- ์ ํ๋(Accuracy)
์ ์ฒด ๋ฐ์ดํฐ ์ค์ ์ ํํ๊ฒ ์์ธกํ ๋ฐ์ดํฐ์ ์
ACC = TP + TN / TP + TN + FP + FN
- Log Loss
์ค์  ๋ต์์ ํด๋นํ๋ ํ๋ฅ ๊ฐ์ ์์ ๋ก๊ทธ๋ฅผ ์ทจํ ํ ๋ชจ๋ ๋ํ ๊ฐ์ ํ๊ท
100%์ ํ๋ฅ (ํ์ )๋ก ๋ต์ ๊ตฌํ ๊ฒฝ์ฐ log loss๋ -log(1.0) = 0, 80% ํ๋ฅ ์ ๊ฒฝ์ฐ์๋ -log(0.8) = 0.22314, 60% ํ๋ฅ ์ ๊ฒฝ์ฐ์๋ -log(0.6) = 0.51082 ์ด ๊ฐ๋ค์ ํ๊ท
- ์ ๋ฐ๋(Precison)
์์ฑ์ผ๋ก ํ๋จํ ๊ฒ ์ค ์ง์ง ์์ฑ ๋น์จ
PREC = TP / TP + FP
- ์ฌํ์จ(ReCall)
์ง์ง ์์ฑ์ธ ๊ฒ๋ค ์ค์์ ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑ์ผ๋ก ํ๋จํ ๋น์จ
ReCall = TP / TP + FN
- F1 Score
F1 Score๋ ์ ๋ฐ๋์ ์ฌํ์จ์ ๊ฒฐํฉํ์ฌ ๋ง๋ ์งํ์ด๋ค. ์ ๋ฐ๋์ ์ฌํ์จ์ ์กฐํํ๊ท
F1 Score = 2 * Prec * Recall/(Price + Recall)
print('Test accuracy:', accuracy_score(Y_test, Y_pred))
print('Test loss:', log_loss(Y_test, y_predicted))
print("F1-score: {:.2%}".format(f1_score(Y_test, Y_pred, average='macro')))๊ฒฐ๊ณผ ํ๋ฉด


-> ์ค์  ์์ ์ ์ง์ค๋์ ํ์์ด ๊ฐ์ํ๊ฐ์์ ํ๊ฐํ ์ง์ค๋ ๋ฐ์ดํฐ๋ฅผ ์์นํํด ๊ทธ๋ํ๋ก ํํ
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="canvas" style="display: inline-block; width: 450px; height: 350px; position: relative; right: 45px;"></canvas
          ><br />
          <div class="labelBoxStick">
            <label for="realDataStick" id="realDataStick">์ค์  ์ง์ค๋</label>
            <br />
            <label for="lectureDataStick" id="lectureDataStick"
              >๊ฐ์ํ๊ฐ ์ง์ค๋</label
            ><br />
          </div>
          <div class="progress-bar-real">
            <div class="progressReal"></div>
          </div>
          <div class="progress-bar-lecture">
            <div class="progressLecture"></div>
          </div>// chart
new Chart(document.getElementById("canvas"), {
  type: "line",
  data: {
    labels: ["1", "2", "3", "4", "5", "6", "7"],
    datasets: [
      {
        label: "์์
 ์ง์ค๋",
        data: [10, 3, 30, 23, 10, 5, 50],
        borderColor: "rgba(255, 201, 14, 1)",
        fill: true,
        lineTension: 0, // ์ง์ ์ ๊ทธ๋ฆฌ๋ ค๋ฉด 0
      },
      {
        label: "๊ฐ์ํ๊ฐ ์ง์ค๋",
        data: [1, 3, 15, 10, 25, 30, 5],
        borderColor: "skyblue",
        fill: true,
        lineTension: 0,
      },
    ],
  },
  options: {
    responsive: false, // false๋ฉด ์ฐจํธ ํฌ๊ธฐ ์กฐ์  ๊ฐ๋ฅ
    title: {
      display: true,
      text: "์์
 + ๊ฐ์ํ๊ฐ ์ง์ค๋",
    },
    tooltips: {
      // ๊ทธ๋ํ์ ๋ง์ฐ์ค ๋๋ฉด ๋ฐ์ดํฐ ํ
์คํธ๋ก ๋ณด์ฌ์ฃผ๋ ํดํ
      mode: "index", // ๋์ผํ ์ธ๋ฐ์ค์ธ ํญ๋ชฉ์ ์ฐพ์ต๋๋ค.
      intersect: false, // ํดํ ๋ชจ๋๋ ๋ง์ฐ์ค ์์น๊ฐ ์์๋ฅผ ๊ต์ฐจํ  ๋๋ง ์ ์ฉ
    },
    hover: {
      mode: "nearest", // ์ ๊ณผ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฑฐ๋ฆฌ์ ์๋ ํญ๋ชฉ๋ค์ ๊ฐ์ ธ์ต๋๋ค.
      intersect: true,
    },
    scales: {
      xAxes: [
        {
          // x์ถ
          display: true,
          scaleLabel: {
            display: true,
            labelString: "hour",
          },
        },
      ],
      yAxes: [
        {
          // y์ถ
          display: true,
          ticks: {
            suggestedMin: 0,
          },
          scaleLabel: {
            display: true,
            labelString: "concentration",
          },
        },
      ],
    },
  },
});
// ๋ง๋ ๊ทธ๋ํ
const progressReal = document.querySelector(".progressReal");
const progressLecture = document.querySelector(".progressLecture");
let realData = 80;
let lectureData = 20;
progressReal.style.width = realData;
progressReal.innerHTML = `<span>${realData}%</span>`;
progressLecture.style.width = realData;
progressLecture.innerHTML = `<span>${lectureData}%</span>`;-> ๋ฐฑ์๋์ ์ฐ๊ณํ๋ ์์ ์ ์ฃผ๋ก ํ ์์ ์ด๊ณ ์นํ์ด์ง๊ฐ ์์ฑ๋๋ฉด ์์งํ ๋ฐ์ดํฐ๋ก ํ ์คํธ ์ํํด ๋ณผ ์์ 
1.passport ๋ก๊ทธ์ธ ๊ตฌํ 2. ๊ฐ์ ํ๊ฐ DBํ ์ด๋ธ ๊ตฌ์ถ
const passport = require("passport");
const { Strategy: LocalStrategy } = require("passport-local");
const bcrypt = require("bcrypt");
const Student = require("../models/Student");
const passportConfig = { usernameField: "id", passwordField: "pw" };
const passportVerify = async (id, pw, done) => {
  try {
    const user = await Student.findOne({ where: { id } });
    if (!user) {
      done(null, false, { message: "์กด์ฌํ์ง ์๋ ์ฌ์ฉ์ ์
๋๋ค." });
      return;
    }
    const compareResult = await bcrypt.compare(pw, user.pw);
    if (compareResult) {
      done(null, user);
      return;
    }
    done(null, false, { reason: "์ฌ๋ฐ๋ฅด์ง ์์ ๋น๋ฐ๋ฒํธ ์
๋๋ค." });
  } catch (error) {
    console.error(error);
    done(error);
  }
};
module.exports = () => {
  passport.use("local", new LocalStrategy(passportConfig, passportVerify));
};module.exports.login = async (req, res) => {
  try {
    // ์๊น local๋ก ๋ฑ๋กํ ์ธ์ฆ๊ณผ์  ์คํ
    passport.authenticate("local", (passportError, user, info) => {
      // ์ธ์ฆ์ด ์คํจํ๊ฑฐ๋ ์ ์  ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ์๋ฌ ๋ฐ์
      if (passportError || !user) {
        res.status(400).json({ message: info });
        return;
      }
      // user๋ฐ์ดํฐ๋ฅผ ํตํด ๋ก๊ทธ์ธ ์งํ
      req.login(user, { session: false }, (loginError) => {
        if (loginError) {
          res.send(loginError);
          return;
        }
        // ํด๋ผ์ด์ธํธ์๊ฒ JWT์์ฑ ํ ๋ฐํ
        const token = jwt.sign(
          { id: user.id, name: user.name, auth: user.auth },
          process.env.ACCESS_SECRET,
          { expiresIn: "1m", issuer: "jungseok" }
        );
        const refresh = jwt.sign(
          {
            id: user.id,
            name: user.name,
            auth: user.auth,
          },
          process.env.REFRESH_SECRET,
          { expiresIn: "10m", issuer: "jungseok" }
        );
        console.log("token: ", token);
        console.log("refresh:", refresh);
        res.redirect("/main");
      });
    })(req, res);
  } catch (error) {
    console.error(error);
    next(error);
  }
};2.๊ฐ์ํ๊ฐ DB๊ตฌ์ถ
const Sequelize = require("sequelize");
//
module.exports = class User extends Sequelize.Model {
  static init(sequelize) {
    return super.init(
      {
        q1: {
          type: Sequelize.INTEGER(20),
          allowNull: false,
        },
        q2: {
          type: Sequelize.INTEGER(20),
          allowNull: false,
        },
        q3: {
          type: Sequelize.INTEGER(20),
          allowNull: false,
        },
        q4: {
          type: Sequelize.INTEGER(20),
          allowNull: false,
        },
        q5: {
          type: Sequelize.INTEGER(20),
          allowNull: false,
        },
        q6: {
          type: Sequelize.STRING(255),
          allowNull: false,
        },
      },
      {
        sequelize,
        timestamps: false,
        underscored: false,
        modelName: "Evaluation", // ๋ชจ๋ธ ์ด๋ฆ์ ์ค์ , ๋
ธ๋ ํ๋ก์ ํธ์์ ์ฌ์ฉ
        tableName: "Evaluation",
        paranoid: false,
        charset: "utf8", //ํ๊ธ์ ์
๋ ฅํ๊ธฐ ์ํ ์ค์ 
        collate: "utf8_general_ci", //ํ๊ธ์ ์
๋ ฅํ๊ธฐ ์ํ ์ค์ 
      }
    );
  }
  static associate(db) {
    db.Evaluation.belongsTo(db.Class, {
      foreignKey: "CevaluationId",
      sourceKey: "id",
    });
  }
};์ ๋ฒ์ฃผ์๋ ์ฝ 3000๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ํ์ตํ์ฌ ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์๋ค.

์ด๋ฒ์ฃผ์๋ ์ฝ 4000๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ์ฌ ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค.
 
