나의 발자취

미니 프로젝트(2) - 습관 관리 웹앱 (Struggle 노트🥵) 본문

Backend

미니 프로젝트(2) - 습관 관리 웹앱 (Struggle 노트🥵)

달모드 2024. 9. 30. 10:20

레포지토리 https://github.com/est22/habit_web 에 더욱 상세한 내용을 작성해놓았다. (README)

참고로, 개발 및 모든 작성 언어는 영어로 작성했다.

 

요구사항

- 회원가입 및 로그인 기능

- 회원 별로 습관을 관리 해야 한다.

- 습관 목록을 조회할 수 있어야 하고, 습관을 추가할 수 있어야 한다

- 습관 별로 기록을 관리할 수 있어야 한다.- 습관 기록에는 메모를 할 수 있는 기능이 필요하다.

 

ER 엔티티 설계

(이메일이 추가되었다.. ㅎ)

 

파일 구성

아직 디렉토리를 정리하지 않았지만, 아래와 같이 파일들이 구성되어있다. 

 

작업 순서

1. Html 목업 

2. DB 및 테이블 생성

3. 프로그래밍: 회원가입 및 로그인

4. 프로그래밍: 습관 목록 및 습관 추가

5. 프로그래밍: 습관 기록 목록 및 습관 기록 추가

6. 프로그래밍: 습관 기록 삭제 및 습관 삭제

 

 

위 작업 순서를 챕터로 하여, 각 챕터마다 발생한 궁금증들을 아래에 정리를 해볼 것이다.

 

 

1. Html 목업 

(1) ejs 파일도 style.css 파일이 적용이 되는지가 궁금했다.

안되면 안돼....ㅠ

-> 생각해보니, 당연히 되고말고다. 왜냐면 직전에 백엔드를 연습하면서 게시판을 만들어볼 때 simple CSS 를 적용했었던 것을 떠올려보면 된다. <head>태그 내에 <link> 태그로 하니까 됐었기 때문에, CSS 파일이 위치한 경로만 동일하게 <link> 태그로 잘 해주면 되는 문제였다.

+ 그러나 app.js에서 위쪽에 app에 대한 메서드를 정의할 때 아래와 같이 꼭 경로를 지정해주어야 한다. (나는 public 이라는 폴더 이름 안에 css 파일이 있어서 아래처럼 작성함.)

app.use(express.static("public"));

 

 

2. DB 및 테이블 생성

(1) dummy data 생성 시 궁금했던 점

일단 각 테이블에 더미 데이터를 집어넣으려고 하는데, users 테이블을 제일 최초로 생성했었다.

 

* users DB

// 테이블 구조

create table users (
    id integer primary key AUTOINCREMENT,
    name varchar(100),
    email varchar(255) UNIQUE,
    password varchar(255),
    createdAt datetime default CURRENT_TIMESTAMP
);

 

insert into users(name, email, password)  values('홍길동', 'hong1@gmail.com', 'admin1234'); -- 1
insert into users(name, email, password)  values('이영록', 'rok@gmail.com', 'admin1234'); -- 2

 

다른 테이블의 더미 데이터를 생성할 때, habits 테이블의 user_id는 users 테이블의 id를 참조하는 외래키로 되어있는데 더미 데이터를 생성하는 정확한 쿼리가 궁금했다.

 

* habits DB

// 테이블 구조

create table habits (
    id integer primary key AUTOINCREMENT,
    habit_name varchar(255),
    start_date datetime,
    end_date datetime
    createdAt datetime default CURRENT_TIMESTAMP,
    user_id integer not null,
    FOREIGN KEY(user_id) REFERENCES user(id)
);

 

-> 직접 해당하는 user_id를 지정해서 넣어줘야 한다.

홍길동에게만 습관 데이터를 주려면

지금 홍길동은 id가 자동으로 1로 부여되었기 때문에, user_id = 1로 넣어준다.

DB별로 다르긴 하지만 sqlite의 경우 날짜 데이터를 문자열로 주어도 자기가 알아서 날짜 형식으로 변환하더라.. :)

insert into habits(habit_name, start_date, end_date, user_id) values ('Morning Exercise', '2024-10-01', '2024-10-30', 1);
insert into habits(habit_name, start_date, end_date, user_id) values ('Lunch Exercise', '2024-10-01', '2024-10-30', 1);
insert into habits(habit_name, start_date, end_date, user_id) values ('Dinner Exercise', '2024-10-01', '2024-10-30', 1);

 

 

 

* records DB

create table records (
    id integer PRIMARY key AUTOINCREMENT,
    memo varchar(255),
    createdAt datetime default CURRENT_TIMESTAMP,
    habit_id integer not null,
    FOREIGN KEY(habit_id) REFERENCES habits(id)
);

 

-> 마찬가지로 records DB의 habit_id는 외래키이지만 습관마다 고유한 번호를 가지고 있는 것이기 때문에 habits DB를 봐야한다.

 

여기에서, Morning Exercise는 habit_id가 1이기 때문에 habit_id = 1로 넣어준다.

-- Morning Exercise
insert into records(memo, habit_id) values('Day 1 Morning Exercise Complete', 1);
insert into records(memo, habit_id) values('Day 2 Morning Exercise Complete', 1);
insert into records(memo, habit_id) values('Day 3 Morning Exercise Complete', 1);
insert into records(memo, habit_id) values('Day 4 Morning Exercise Complete', 1);

 

 

그럼 Dinner Exercise는? habit_id가 3이기 때문에 =3으로 넣어준다.

-- Dinner Exercise
insert into records(memo, habit_id) values('Day 1 Dinner Exercise Complete', 3);
insert into records(memo, habit_id) values('Day 2 Dinner Exercise Complete', 3);
insert into records(memo, habit_id) values('Day 3 Dinner Exercise Complete', 3);

 

 

3. 프로그래밍: 회원가입 및 로그인

이 부분은 무난하게 했는데, 엣지 케이스가 발견되었다. 바로 아래 습관 추가 페이지에서, 네비게이션 바에 있는 Habit List를 누르면 최초 클릭 시에는 로그아웃이 되어버려 로그인 창으로 돌아가는 것이다. (정상적인 결과라면 우측 화면이 보여야 한다.)

 

-> 엣지케이스가 발생되는 패턴을 분석해보니, 뭔가 새로운 기능을 구현하고 나면 그럴 때마다 이러는 것이다.

-> 새로운 기능 구현 후 반영 및 확인을 위해 내가 Cmd+S로 저장을 하기 때문에, 그럴 때마다 노드몬이 서버를 내렸다가 올려서 발생되는 문제였다. ^^ 

 

 

4. 프로그래밍: 습관 목록 및 습관 추가

웹주소로 들어가는 라우터 경로를 바꾸는 것은 모두 app.get(), app.post() 에 들어간다.

그러나 여기서! .ejs 파일에 있는 버튼에 연결된 링크도 동일하게 일치시켜주어야 한다.

// app.js

// Add Habit
app.get("/habit/add", (req, res) => {
  res.render("habit_add");
});

app.post("/habit/add", (req, res) => {
  const { habit_name, start_date, end_date } = req.body;
  const user = req.session.user;
  ...
  }

 

 

 

// habit_list.ejs

<a class="button" href="/habit/add">Add Habit</a>

 

 

 

5. 프로그래밍: 습관 기록 목록 및 습관 기록 추가

 

그리고 여기서, Habit Record: 뒤에는 습관명을 DB에서 가져와서 적고싶은데 forEach문에서 items로 접근하는 방법만 알다 보니, 밖에서 바로 접근하는 방법을 몰라서 못가져오고 있었다. ㅠㅠ

6. 프로그래밍: 습관 기록 삭제 및 습관 삭제

위에서 보이는 것처럼, DB 생성 순서에 따라 ID값의 공백이 있는 것은 (현재 id값이 외래키 등 DB 테이블끼리 참조가 되어있어 이것을 변경하려면 품이 많이 들긴 하지만) 아래와 같은 SQL 쿼리문으로 해결할 수 있다. 

여기에서 row_number() 이라는 내장함수를 사용해주면 된다.

 

 

728x90
반응형
Comments