#44 [dApp 개발] (07.06) - 프로젝트

sookyoung.k·2023년 7월 6일
0
post-thumbnail

하아아... 10년 전 이맘때 쯤엔... '나 대학 갈 수 있을까...?' 라는 생각을 하며... 수심이 깊었는데... 10년이 지난 지금은 '나 회사 갈 수 있을까...?' 라는 생각을 하고 있다. (360도 변했다)

사실 교육 과정에 대해 할 말이 참 많은데, 일단은 참는다. 그리고 너무 뭐라고만 하기엔 얻어가는 것들도 분명히 있다. 불평불만에 시간을 쏟기에 프로젝트에 주어진 시간이 너무 짧다. (정확히 13일 줬다. 장난해...?)
하지만

😓 제발 프로그래밍 교육 시간 좀 늘려주세요.

아니 늘리지 마... 솔직히 나 다음 기수부터 바로 늘어나면 개빡칠 것 같애... 우리한텐 왜그랬어요? 하면서... 후 이건 너무 이기적이죠?

교육에 참여하기 전엔 프로그래밍 교육 시간이 되게 많을 것처럼 이야기하는데 실상은 그렇지 않다는 점을... 말하고 싶다. 솔직히 조금... 뭐랄까... 손해볼 거 없는 사기당한 기분 꾸준히 나오는 불평과 불만이라고 하는듯. 그러나 개선된 사항은 보이지 않는다. 하지만 이전 기수에 참여했던 분의 말씀을 들어보니 이것이 개선된 것이라고 한다. 상당히 놀라움... 난 리액트를 공부하고 싶어서 온 건데 nodejs를 배워서 결국 프로젝트에서 맡은 부분은 백엔드다 ㅋㅋㅋㅋㅋ 리액트 안 가르쳐줌... (교육 과정에 적혀있어서 온 건데...) 그렇지만 난 백엔드를 좋아하니까! nodejs를 다룰 줄 알게 된 건 좀 좋다. 잘 하는 건 아니지만요... 그리고 프로젝트 담당 강사님이 너무 잘 가르쳐주시고 쏙쏙 이해가 잘 되게 해주셔서 정말 좋다. 그러니까... 더 아쉬운거임. 더 배우고 하고 싶었는데 내가 대체 뭘 할 수 있는건지 모르겠다... 아무리 프로젝트 하면서 배우는게 더 많다지만... 하...

그렇지만... 이번주 일요일까지 포폴도 내야 하고... 12일까지는 프로젝트도 끝내야 하고... 남들 하는 거 보고 있으면 (자세히 들여다 본 건 아니지만) '나... 인턴 할 수 있을까...? 나 취업할 수 있을까...? 나만 못하는 거아냐...?' 이런 생각들에 자괴감이 든다... 내가 할 수 있는거라곤... 최대한 기록해서 안 까먹고 나중에 써먹을 수 있게 하는거랑... 응원받기...

내가 조금씩 멘탈이 나가서... 흥엉앵엉엉 장난스럽게 말하지만 속으로 진짜 울고싶은 마음으로 카톡할 때마다 계속계속 응원해주는 환이 😗
사실 나는 남들의 응원이 그렇게 필요한 사람이 아니라고 생각했는데... '넌 할 수 있어!'같은 말이 넘넘 와닿는 날이 오는 걸 보니 지금 정말 불안함이 큰 것 같긴 하다. 그리고 내가 믿는 사람이기도 하니까 더 기분이 좋은 걸지도~ 하하~ 하... 너무너무 불안해요. 암튼... '넌 할 수 있어!' 라고 말해주세요...하는 노래가 생각남... 일단 응원해!
모두 나를 응원하시길...

같이 백엔드를 맡은 명식 오빠도 너무 든든하고, 프론트 정근이도 너무 잘 한다... 명식오빠... 힘을 숨기고 있었어... 예상은 했지만 예상보다 훨씬 더 잘하고 너무나 능력자인 것... 프론트도 화면 구현 경이롭다... 정근이는 분명 이번에 좋은 회사에 갈 것 같다. 명식오빠도... 난... 나는...? ㅠㅠ 걱정이 태산이다. 다른 조원들도 진짜 잘 하는 것 같다. 나는... 혼자 무얼 하고 있는가... 그래도 이리저리 도움 받으면서 최대한 잘 마무리를 해봐야지... 내 능력이 부족함을 느낄 때마다 너무 속상하다. 어떻게 짜야할지 머리 속이 새하얘질 때마다 누가 볼까바 무서워ㅠ 나는 이렇게 바보랍니다... 잘 하는 사람들이 많으니까 더 기죽어. 흑흑. 다른 사람들은 이걸 어떻게 이렇게 잘 하지? 그건 그 사람들이내가 놀 때 노력을 했기 때문이겠지... 그러니 나도 더 열심히 해야지... (눈물)

▶️ 07.04~05 프로젝트 - 개발 시작

기획이 오래 걸리는 통에 개발 쪽을 본격적으로 시작하게 된 건 7월 5일이 다 되어서였다. 사실 그 전까지도 기획이 다 끝난 건 아니라... 머리 속에 그려지는 그림이 없어서 대체 뭘 어떻게 시작해야 할지 몰라 혼자 CS 공부를 하고 있었다. 프로젝트에 도움이 되길 바라며. 직접적인 도움이라기보단 간접적인 도움같은데, 아무튼 다 필요한 지식이라는 것을 프로젝트를 할 때마다 느낀다. 기본적인 CS 지식을 이해하고 있어야 한다는 사실을 점점 느낀다. 이전 학원에서 CS 가르쳐 줄 때마다 엄청 졸고 재미없어하고 그렇게 중요성을 느끼지 못했는데 말임... 죄송해요 강사님~! 취업하게 되면 감사했다고 꼭 인사를 드려야지.

📃 요구사항 정의서

명식오빠가 가지고 있는 틀을 활용해서 필요한 기능과 세부 내용, 우선 순위를 정해서 작성했다.

워낙 기간이 짧은 프로젝트이다보니 많은 기능을 나중으로 미루게 되었다. 속상...

📃 프로젝트 흐름도

마찬가지로 명식오빠가 가지고 있는 틀을 활용해서 흐름도를작성했다. 라우터를 나누고, 각자 어떤 파트를 맡아서 서버를 구축할 것인지를 나눴다. 그런데 프로젝트를 진행하면서 기획이 또 살짝 바뀌게 되어서 ㅋㅋㅋㅋ 내일 교육장에 가면 수정을 해야할 것 같다.

📃 DB 설계도

마찬가지로 명식오빠 33... 테이블 및 컬럼을 구성하였고 컬럼 각각에 데이터 타입과 크기, 특성들을 정의해놓았다.

💻 23.07.04 개발 시작!

정근이가 파일 구조를 짰고, 프론트 - client / 백엔드 - server 이렇게 나누어서 작업을 진행하고 있다.

팀원들마다 각자의 브랜치가 있고, release 브랜치에서 머지하고 통합해서 작업을 진행하고있다. main은 절대 건드려선 안돼...!

4, 5일은 크게 한 것이 없었다. 깃 클론해서 받아오고... 기본적인 세팅과 라이브러리 설치를 하고... 뭘 했지? 4일은 진짜 기억이 안 나네... 그냥 초반 구성을 미리 해놓은 명식오빠에게 감탄하고 허겁지겁 따라갔던 기억이 나요! 우와!

📌 마이페이지 - 회원 정보 수정

5일(2일차)에 가장 힘들었던 부분이자 내가 실패한 첫 임무는 마이페이지의 회원 정보를 수정하는 일이었다.

가장 기본이 되는 server.js

const member = require('./Router/member.js')();
app.use('/member', member);

라우터를 만들어놓고 member.js에서 작업을 진행하였다.

member.js에서 가장 먼저 해야 하는 일은

  1. express 로드하기
  2. router 변수에 대입하기
  3. DB 연결하기

이 정도인 것 같다. 이것도 처음 할 땐 뭐부터 해야 할 지 몰라서 머리가 하얘진다... 흑흑.

회원가입과 로그인은 명식오빠가 하는 부분이고, 나는 오빠가 만들어 둔 이 두 기능을 가지고 마이페이지에서 회원 정보를 불러오고 수정하는 부분을 맡았다.

   // localhost:3000/member/myPage [get] mypage, 세션에 저장된 유저 정보 불러오기
   router.get('/myPage', function (req, res) {
      console.log(req.session.logined);
      res.render('mypage.ejs', {
         data: req.session.logined,
      });
   });

경로를 설정한 후 세션에 저장된 로그인 정보를 불러와 mypage.ejs라는 테스트용 뷰에 띄워보았다. 아직 리액트와 연결하기 전이라 테스트 뷰를 만들어서 사용하고 있었다. 데이터가 잘 들어가는지만 보기 위해서 만든거라... 나중에 리팩토링이 필요하다.

수정 페이지를 띄워준 후 수정을 완료하면

   // localhost:3000/member/edit [post] 회원정보 수정(DB 업데이트 및 세션 정보 수정)
   router.post('/edit', upload.single('_profile'), function (req, res) {
      console.log(req.body);
      const input_profile = req.file.filename;
      const input_id = req.body._id;
      const input_name = req.body._name;
      const input_birth = req.body._birth;
      const input_email = req.body._email;
      const input_pass = req.body._pass;
      console.log(input_profile, input_id, input_name, input_birth, input_email, input_pass);

      // 회원정보 업데이트 (DB에 UPDATE)
      const sql = `
       update member 
       set member_id = ?, 
       member_password = ?, 
       member_name = ?, 
       member_birth = ?, 
       member_email = ?, 
       member_profile = ? 
       where member_num = ?;
       `;
      const values = [
         input_id,
         input_pass,
         input_name,
         input_birth,
         input_email,
         input_profile,
         req.session.logined.MEMBER_NUM,
      ];

      connection.query(sql, values, function (err, result) {
         if (err) {
            console.log(err);
            res.send(err);
         } else {
            // 정보 수정(update 성공 시)한 후 DB에 업데이트 된 로그인 정보 조회(select)
            const selectSql = `
                select
                *
                from
                member
                where
                MEMBER_ID = ?
                and
                MEMBER_PASSWORD = ?
                `;

            const selectValues = [input_id, input_pass];

            connection.query(selectSql, selectValues, async function (err, selectResult) {
               if (err) {
                  console.log(err);
                  res.send(err);
               } else {
                  // 업데이트 된 DB 데이터를 세션에 새로 넣어준 후 myPage로 redirect
                  console.log('## checkLogin : ' + selectResult);
                  if (selectResult.length != 0) {
                     console.log('## result[0]: ' + selectResult[0]);
                     req.session.logined = selectResult[0];
                     res.redirect('/member/myPage');
                  } else {
                     res.redirect('../');
                  }
               }
            });
         }
      });
   });

이렇게 말도 안되게 긴 코드로 정보를 업데이트 해준다. 이렇게 한 이유는 다음과 같다...

처음엔 get, post 연결을 잘못해서 수정 자체도 안 됐는데 나중에는 수정은 되면서 마이페이지에 아에 정보가 뜨지를 않아서 문제였다. (DB에 업데이트는 되는데 마이페이지에 데이터가 로드되지 않는 상황을 최종으로 맞닥뜨렸다.)

알고보니... DB 정보는 업데이트가 되었지만, 세션 정보는 업데이트가 되지를 않아서 그랬던 것! 콘솔에 세션을 찍어보니 이전에 저장된 세션 정보로 뜨는 걸 보고 명식오빠가 알아챘던 것 같다. 그래서 일단 그래서 결국 쿼리 속 쿼리,,,

먼저 DB에 유저 정보를 업데이트 해준 후 로그인 정보를 뽑아와서 로그인 정보에 넣어주는 것... 쿼리 속 쿼리... 아직 세션을 잘 사용하질 못해서 분명히 더 줄일 수 있을 것 같은데, 이렇게까지 코드가 길고 복잡하지 않을 것 같은데 방법을 모르겠다. 일단은 ㅠ... 이렇게 고고... 나중에 리팩토링 꼭 하고 싶은 부분. 내일 세션에 대해서 강사님이나 명식오빠 붙잡고 집요하게 물고 늘어져야겠다. 이해하고 싶어!

🔔 기억에 남는 에러

✔️ get, post 너무 어려워...

보안이 필요하거나 용량이 큰 데이터는 post 방식으로, 그렇지 않은 일반적인 경우에는 get 방식을 사용해야 한다는 것은 알고 있다. 그렇지만... 에러가 나고 뭔가 페이지가 로드가 잘 안 되는 경우에는 내가 뭔갈 잘못했나...? get/post가 문제인건가...? 하고 한 번씩 말이 안 되는 걸 알면서도 바꿔보게 된다. (그러다가 말이 되기도 함...)

가장 허탈했던 잘못은 get 방식의 경우에는 req.query에, post 방식은 req.body에 데이터를 담아오는데 아주 당당하게 get에서 req.body를 써놓곤 에러를 내고 있었다. 그러니까 cannot found 이러지 ㅋㅋㅋㅋ

사실 전날 연결 문제는 결국 해결하지 못한 채로 집에 돌아갔다. 몸 상태도 너무 좋지 않고 머리도 하루 종일 아팠고... 그러면 집중 안 되는 거 아시죠? 결국 6일 오전에 해결!

💻 23.07.06 개발 3일차

📌 회원정보 업데이트 기능 구현 완료

오전에는 회원정보 업데이트를 성공적으로 끝마치고, 프로필 사진을 업데이트 할 수 있게 만들었다.

// 파일 업로드
const multer = require("multer");

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, "public/upload/");
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname);
    },
});

const upload = multer({
    storage: storage,
});

파일 업로드를 위해 필요한 라이브러리를 설치하고, 어차피 프로필 사진은 회원가입 할 때가 아니라 회원 정보를 수정할 때 넣어주는 것이기 때문에 수정이 쉬웠다.

깃 풀 해오다가 명식오빠 파트와 충돌이 일어나서 울고싶긴 했음. 그래도 요샌 충돌 수정하기 쉽더라... vscode는 원래 그랬나? 이전 프로젝트 이클립스로 하다가 vscode 쓰니까 선녀같음...

📌 핸드폰 번호 인증 문자 코드 수정

이 부분은 내가 맡은 부분은 아니고... 명식 오빠 부분인데 오후에 조퇴하면서 갑자기 잘 되던 인증이 안 되는 바람에 멘붕 온 나와 정근이가 열심히 고쳤다. 식겁했네 진짜... 각자가 만든 코드가 아니라 '이게.. 뭘까..' 열심히 고민하면서 공부가 되었던 것 같다.

// coolsms 라이브러리 로드 
const coolsms = require("coolsms-node-sdk").default;

// apiKey, apiSecret 설정
const messageService = new coolsms('ENTER_YOUR_API_KEY', 'ENTER_YOUR_API_SECRET');

sms 문자 인증을 위해서 사용한 라이브러리다! 그런데... 말입니다... default를 붙이지 않으면 인증 번호가 오질 않았다.

이유까지 찾진 못했고 해당 문서에 나와있는 사용법을 보면
CoolSMS SDK for Node.js(Server Side Only)

원래 default 키워드를 붙여서 사용해야 하는 것 같다. 나중에 시간이 되면... 읽어봐야지 ㅎㅎ 특: 안읽음

아래는 회원가입 인증 부분이다.

   // localhost:3000/member/smsAuth [post] Ajax sms인증
   router.post('/smsAuth', async function (req, res) {
	  // 핸드폰 번호를 입력 받는다. 
      console.log(req.body);
      const input_id = req.body._id;
	  
      // 난수 설정기를 통해 4개의 번호를 무작위로 만들어준다. 
      let authNum = generateRandomCode(4);
      console.log(authNum);
      // 문자를 보낼 텍스트를 써준다. (Blend는 우리 서비스 이름)
      const phonetext = '[Blend]Blend에서 인증번호를 발송해드립니다. 당신의 인증번호는 [' + authNum + '] 입니다.';
      // 여기에서 오타가 나서 전송이 안 됐음. 자나깨나 오타 조심)
      // 난수 정보를 키-밸류의 제이슨 형태로 변수 선언 하여 담아준다. 
      const resNum = { auth_Num: authNum };
      console.log('## text : ' + phonetext);

      const SQL = `
        select
        *
        from
        member
        where
        MEMBER_ID = ?
        `;

        const values = [input_id];

        connection.query(SQL, values, function (err, result) {
            if (err) {
                console.log(err);
                res.send(err);
            } else {
                console.log("## ID check : " + result);
                if (result.length == 0) {
                    // 2건 이상의 메시지를 발송할 때는 sendMany, 단일 건 메시지 발송은 sendOne을 이용해야 합니다.
                    messageService
                        .sendMany([
                            {
                                to: input_id,
                                from: "개인정보입니다",
                                text: phonetext,
                            },
                        ])
                        .then((res) => console.log(res))
                        .catch((err) => console.error(err));
                  	// resNum에 저장한 난수를 json 형태로 프론트에 넘겨준다. 
                    res.json(resNum);
                } else {
                    console.log("중복됨");
                    res.json({ auth_Num: "0" });
                }
            }
      });
   });

로직이 완벽하게 이해가 되는 것은 아니지만... 대충 어떤 흐름으로 가는 지는 알 것 같다. 내가 이해한 만큼 주석을 달아봤다. 나중에 기회가 되면 내 프로젝트에 내가 적용시켜봐야지~

📌 메인 페이지 상품 사진 업로드

시간이 짧다보니... 기획은 거창하였으나 회의 단계에서 많은 것을 제외하였다. 그 중 하나가 쇼핑몰... 이걸 어케 해요! 그래서 메인 페이지에 보여줄 상품은 그냥 더미 데이터를 보여주면서 그럴싸하게 보여주는 것으로 퉁침. 암튼 그래서 내가 해야하는 것은 우선 메인 화면에 사진 업로드인 것이다!

server.js

const main = require('./Router/main.js')();
app.use('/main', main);

서버 뚫어주기~!

Router 폴더에 main.js를 만들어 주었고

// express 로드
const express = require('express');

// Router() 변수에 대입
const router = express.Router();

// DB 연결
const mysql = require('mysql2');
const connection = mysql.createConnection({
   host: process.env.host,
   port: process.env.port,
   user: process.env.user,
   password: process.env.password,
   database: process.env.database,
});


module.exports = function () {
   // 기본 경로: localhost:4000/main

   router.get('/', function (req, res) {
     /**/
      });
   });

   return router;
};

기본 설정...

사실 여기까지만 해도 에러가 넘쳤지만... 코드를 어떻게 짜지? 걍 막막... 한 5분 정도 울고싶다가 정신차리고 해결... 나는 사진만 조회하면 되는 거니까! DB에 있는 정보 중 무얼 가져오면 되는걸까?! 이미지 파일만 가져오면 됨! → select를 쓰면 되겠군아...!

먼저 DB에서 필요한 정보를 불러올 수 있는 쿼리문을 제대로 확인한 후

 // goods 테이블에서 상품사진(GOODS_CONTENT) 데이터 불러오기
      const sql = `
        select
        GOODS_CONTENT
        from
        goods
    `;
      connection.query(sql, function (err, result) {
         if (err) {
            console.log(err);
            res.send(err);
         } else {
            console.log(result[0], result[1], result[2]);
            res.json({
               data1: result[0],
               data2: result[1],
               data3: result[2],
            });
         }
      });

코드를 작성해주었다.

🔔 에러

이 곳에서의 실수...

  1. server.js에서... const main = require('./Router/main.js')(); 이 부분 () 괄호를 뒤에 안 붙여서... 안 됐음... 내가 또 뭘 잘못했나 한참을 괴로워했는데... 이거였다. 하... 너무 자괴감. 강사님이 정말 자주 하는 실수라고 말씀해주시긴 했는데 귀에 안 들어옴. (사실 들어옴) 진짜 이런 실수 하지 말자... 이런 에러의 경험이 쌓이면 나중엔 알아서 척척 잘... 코드를 짜게 될까? (현실: 그냥 에러 잘 찾는 사람 됨. 하지만 이것도 좋아... 오히려 좋아일지도...)

  2. module.exports 부분에... return router; 안 붙이기 ㅠ... 절대 안 됨... 서버 오픈부터 쉽지가 않았다. 너무나 속상했음... 난 이런 것도 하지 못하는 걸까... 강사님께 늘 기초적이고 어이없는 실수만 질문하는 것 같아 속상했다. 바보같은 나...⭐ 그래도 어케요 ㅠ 모르면 배워야지...

📮 POSTMAN

그리고 내가 낑낑대면서 뷰를 만들고 GET, POST 연결을 잘 못해서 질문하니까... 강사님이 한참 알려주시다가 '그런데 왜 이렇게 해요?' 라고 되물으셨다. 기가 죽어선 '이렇게 하는 거 아닌가요...?' (동공지진) (속마음: 아니 저도 데이터가 잘 왔다갔다 하는지 테스트를 해봐야 할 것 아녜여...!)

이렇게 하지 않아도 된다.

바로 포스트맨을 사용해서... 뷰 없이 백엔드 서버에서 데이터가 잘 전달되는지 알 수 있게 도와주는... 심지어 콘솔에도 바로 찍히고 DB에도 업데이트가 되는... 그런 멋진...!

제대로만 코드를 작성했다면 이렇게 데이터 전송 결과를 아래에 제이슨 형태로 잘 뱉어준다. 흑흑... 이런 선녀같은 도구가? 하지만 이건 GET 방식이라 전송할 데이터가 없어서 쉬운 편이었고, POST 방식은 내가 데이터 형식에 맞게 작성을 잘 해주어야 전달이 되는 거라 조금 익숙해질 시간이 필요할 것 같다. 하지만 기왕 이렇게 된 거 잘 사용해보자!

💡 res.json()

계속 힘들고 고생스럽게 뷰를 만들어가면서 프론트에 전달되는 데이터를 확인했던 것도 확인했던 거지만... 그래서 프론트에 데이터는 어떻게 넘길건데? 하는 의문을 계속해서 갖고 있었다. 사실 당장은... 일단은 아니니까 ㅎ 하면서 마음 한 구석에서 외면하고 있었는데... 그냥 json 형태로 데이터를 넘기기만 하면 프론트에서 알아서 처리를 해주는 것 같다. 그냥 이렇게 보내면 되는 거였음... 하하... 이런 방법이!!!


내일은 마일리지 교환 부분을... 해야 한다. trade.js를 만들어는 놨는데... 시간도 애매했고 이건 또 코드를 어케 짜누... 그리고 컨트랙트 연결은 어케 하지? 이런저런 고민을 해보다 결론, "내일 명식오빠 오면! 물어봐야겠다!" 였음. 명식 의존도... 너무 높은가... 오빤 짱이다. 빽짱... 그리고 나도 잘 하고 싶어ㅠㅠ! 열심히 공부하고 배워서... 나도 짱이 될거야. 사실 물어보는 것도 미안하다 ㅠ 그래도 프로젝트는 해야 하니까... 최대한 강사님께 여쭤보고... 진짜 열심히 해야지. 암튼 오늘은 이만 자야겠다!

내일 할 일
1. main에 로그인 후 화면에 뿌려질 회원 정보는... 서버에서 세션으로 뿌려줘야 하는가? 이 과정은 어떻게 되는가? 추후 세션을 다루는 법에 대한 공부가 필요해보임

  1. 컨트랙트 연결해서 trade.js 부분 최대한 완성시키기

  2. 시간이 된다면 완성된 부분 프론트와 연결해서 데이터 전송 부분 수정하기

자랑
수업 중 잠시 연결을 해봤었는데~ 서버 열어서 핸드폰으로 잠시 확인해보기~~

짜잔~ 우리 팀 프론트 진짜 개멋져~~ 프론트도 재미있긴 하지만 난 정말로 디자인적 감각이 없기 때문에... 이렇게 만들라고 해도 만들지 못했을 거다... 확실히 프론트는 결과물이 한 번에 뿅 나오는 것이 매력적이지만... 그래도 백이 좋아~!!

profile
영차영차 😎

1개의 댓글

comment-user-thumbnail
2023년 8월 23일

그 스트레스 받는 상황에서도 블로그를 야무지게 쓰셨군요.. 당신의 부지런함... 무릎탁치고 갑니당!

답글 달기