Home [Cabinet Project] 사물함 배정 프로그램 개발일지 2 - 사물함 정보 및 신청 API 개발
Post
Cancel

[Cabinet Project] 사물함 배정 프로그램 개발일지 2 - 사물함 정보 및 신청 API 개발

Front End 설계 재구성

보안을 위해 대부분의 API는 POST방식을 선택했다.
하지만 그래도 페이지 링크를 통한 페이지 이동이 진행되면 보안 상에 문제가 있을 수 있다고 생각한다.
그래서 동일 페이지에서 body값만 변경되게 설정했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
  <head>
    <%-include('header') %>
  </head>
  <body>
    <% if(!name && !floor) { %>
        <%-include('main') %>
    <% }else if(name && !floor) { %>
        <%-include('stairs') %>
    <% }else if(cabinets != undefined) { if(floor == 1) { %>
        <%-include('first') %>
    <% }else if(floor == 2) { %>
        <%-include('second') %>
    <% } } %>
  </body>
</html>

솔직히 말하면 이렇게 하면 코드가 꼬이는 것 같다는 느낌이 슬슬 들기 시작했다.
일단은 별로 큰 규모의 웹사이트가 아니기 때문에 별 문제가 없으면 진행을 할 예정이다.

이전 글에 설계한 로그인 페이지에서 이름과 학번 8자리를 입력하면 다음과 같이 사물함 층을 선택하는 화면으로 넘어간다. session에 name이 넘겨졌다는 것은 로그인이 되었다는 의미이다.

층을 선택하면 각 층의 사물함 배치에 맞춰서 사물함 레이아웃이 나타난다.

1층 레이아웃

2층 레이아웃

각 층의 레이아웃에 존재하는 사물함은 모두 버튼으로 구현했다. 해당 사물함 버튼을 클릭하면 신청 API로 넘어가게 된다. 이미 배정된 사물함은 빨간색으로 변경되고 버튼자체가 비활성화된다.

Models 설계 재구성

user DTO

앞서 설계한 DTO model중에 user모델을 API 개발에 맞춰서 재구성을 했다.
이전에 있던 DTO의 필드에서 새로운 필드를 추가했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
const mongoose = require("mongoose");
var Schema = mongoose.Schema;

var userSchema = new Schema({
  studentID: { type: Number, unique: true, required: true },
  name: { type: String, required: true },
  isAdmin: { type: Boolean, default: false },
  isPay: { type: Boolean, required: true },
  useCabinet: { type: Number, default: 0 },
  useFloor: { type: Number, default: 0 },
});

module.exports = mongoose.model("user", userSchema);

사용하는 사물함의 번호와 층수를 기록하게 되어있다. 층수를 기록한 이유는 서로 다른 층에 있는 사물함 번호가 겹치는 경우가 있어서 데이터 관리의 편의를 위해서 기록했다.

cabinet_info DTO

사물함 정보를 저장하는 DTO model이다. 사물함 정보를 넘겨주는 역할을 하게된다.

1
2
3
4
5
6
7
8
9
10
11
const mongoose = require("mongoose");
var Schema = mongoose.Schema;

var cabinetSchema = new Schema({
  cabinetNumber: { type: Number, unique: true, required: true },
  studentID: { type: Number, default: 00000000 },
  floor: { type: String, required: true },
  isUsed: { type: Boolean, default: false },
});

module.exports = mongoose.model("cabinet", cabinetSchema);

기본적인 정보인 해당 사물함의 번호와 층수를 저장한다. 그리고 해당 사물함을 사용하는 사람이 있으면 사용자의 학번을 등록한다. 그리고 사용여부를 기록하고 기본값은 false로 모두 초기화 시켜둔다. 그 후 API를 통해서 값을 변경해주면된다.

API

Main page API

1
2
3
4
5
6
7
8
9
10
app.get("/", function (req, res) {
    var sess = req.session;

    res.render("index", {
      name: sess.name,
      studentID: sess.studentID,
      floor: sess.floor,
      cabinets: undefined,
    });
  });

메인페이지를 로드하는 API이다. 이전에 있던 메인페이지에 세션값들을 변수로 넘겨줬다.
사물함을 관리하는 cabinets는 특정한 경우 아니면 사용되지 않아서 초기는 undefined로 넘겨준다.

Login API

우선 로그인 API를 일부 수정했다. 세션상에 현재 로그인한 학생정보를 다루면서 메인 페이지를 변경시키는 원리로 설계했기 때문에 세션에 값을 넘겨주는 부분을 추가했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
app.post("/login", function (req, res) {
    const notUser =
      '<script type="text/javascript">alert("존재하지 않는 학생입니다."); window.location="/";</script>';
    var sess = req.session;
    var currID = req.body.studentID;

    User.findOne({ studentID: currID }, function (err, user) {
      if (err) {
        console.error(err);
        return;
      }

      if (!user) {
        // console.log("Not found");
        res.send(notUser);
      } else {
        sess.studentID = user.studentID;
        sess.name = user.name;

        res.redirect("/");
      }
    });
  });

우선 유저를 탐색 후 값이 존재하는 경우에 세션에 값을 추가해준다. 세션 값이 변동되면서 메인 페이지로 넘어가는 API에서 넘어가면서 조건에 맞춰서 불러오는 페이지를 변경한다.

First Floor API

사물함 층별로 사물함 데이터를 받아와서 메인페이지에 사물함 정보를 넘겨주는 API이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
app.post("/first", function (req, res) {
    var sess = req.session;
    var currFloor = "first";
    sess.floor = 1;

    Cabinet.find({ floor: currFloor }, function (err, cabinets) {
      if (err) {
        return res.status(500).send({ error: "database failure" });
      }

      res.render("index", {
        cabinets: cabinets,
        name: sess.name,
        studentID: sess.studentID,
        floor: sess.floor,
      });
    });
  });

주어진 데이터베이스를 탐색할 때 현재 층수로 검색을 진행한다. 그래서 해당 층수의 모든 사물함 정보를 가져온다.
검색을 통해 찾아낸 모든 사물함 정보를 변수로 넘겨주어서 프론트에서 자바스크립트를 통해서 해당 사물함의 사용 여부를 확인한다. 동일한 형태로 2층 API도 처리해준다.

Apply Cabinet API

사물함을 신청하는 API다. 사물함 버튼을 누르면 신청 API로 넘어오게 된다.
이 API에서 처리하는 것은 현재 사물함 데이터를 가져와서 사용상태를 업데이트하고 신청 유저의 상태도 업데이트하는 API다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
app.post("/apply", function (req, res) {
    var currCabinet = Number(req.body.cabinetNum);
    var sess = req.session;
    var f;
    if (sess.floor == 1) {
      f = "first";
    } else {
      f = "second";
    }

    Cabinet.findOne(
      { floor: f, cabinetNumber: currCabinet },
      function (err, cabinets) {
        cabinets.studentID = sess.studentID;
        cabinets.isUsed = true;

        cabinets.save(function (err) {
          if (err) {
            res.status(500).json({ result: "failed" });
          }

          console.log("success");
        });
      }
    );

    User.findOne({ studentID: sess.studentID }, function (err, user) {
      user.useCabinet = currCabinet;
      user.useFloor = sess.floor;

      user.save(function (err) {
        if (err) {
          res.status(500).json({ result: "failed" });
        }

        console.log("success");
      });
    });
  });

사물함의 번호는 Number자료형으로 입력받는데 실제로 받아오는 값이 String 값으로 받아졌었다. 그 부분때문에 계속 데이터 탐색이 이뤄지지 않았다.
혹시나해서 currCabinet의 자료형 확인을 했더니 String이어서 데이터베이스에서 탐색을 하지 못했다. 그래서 강제로 자료형을 타입캐스팅을 진행했더니 데이터베이스에서 탐색을 할 수 있었다. 그래서 해당 사물함의 이용자 학번을 현재 세션에서 갖고 있는 학번으로 설정해주고 사물함 사용 여부를 true로 변경해준다.
그 후 해당 사물함 데이터 정보를 업데이트하고 동일하게 사용자 정보도 업데이트한다.


This post is licensed under CC BY 4.0 by the author.

[Cabinet Project] 사물함 배정 프로그램 개발일지 1 - 로그인 화면, API 개발

[Review] Naver AI Rush 2021 코딩테스트 후기 및 합격

Comments powered by Disqus.