새해를 맞아서, 1월 1일 부터 미니 프로젝트 [당직]을 진행하였다.
부대 동기가 Excel을 사용하여 손으로 당직을 짜는 것이 변경사항이 생기면 당직을 바꾸기도 어렵고, 시간도 많이 든다고 하여서, 배운것을 토대로 실습을 진행할 겸 당직을 짜주는 웹 어플리케이션을 기획했다.
프론트는 React로 , 백엔드는 Nodejs로 개발을 진행하였다.
style은 @emotion/react와 @emotion/styled를 사용하여 구현했다.
Form은 react-hook-form을 사용하여 간편하게 구현했다.
추후에, zod같은 schema validation library를 사용하면 좋을 것 같다.
달력은 date-fns 라이브러리에서 현재의 달을 받아와서 구현하였다. 현재는 수동으로 당직을 추가해야 하는데, date-fns에서 가져온 날짜 데이터를 기반으로 주말과 평일을 구분하여 자동으로 당직을 생성하게 해주면 좋을 것 같다.
또한, Duty와 User들이 전역적으로 사용되고 있기 때문에, redux와 redux toolkit을 사용해서 전역 데이터들을 손쉽게 가져올 수 있게 구현하면 좋을 것 같다.
(궁금점1 : 현재는 데이터베이스에서 CRUD를 모두 진행하고 있는데, redux를 사용하면 자체적으로 프론트단에서 데이터를 가지고 있을 수 있다. 그러면 데이터베이스의 과부하를 줄이기 위해서 Read하는 경우에는 axios 요청을 통해 데이터 베이스에서 데이터들을 가져오는 것이 아니라, redux로 관리되고 있는 데이터들을 가져올 수 있을 것이다. 그러면 프로그램 성능에 더 좋을까? 다른사람들은 어떻게 하고 있는지 궁금하다)
데이터 베이스는 Mysql 을 사용하였고, ORM은 Sequelize를 사용하였다.
프로젝트를 진행하면서 관계쿼리에 많이 익숙해 진 것 같다.
nodemon 에서 포트가 충돌한다는 이슈
-> 전에 돌리고 있던 서버가 비정상적으로 종료되서 나타나는 문제로, netstat -nlp 명령어를 입력하면, 사용하고 싶은 port에서 돌아가는 ProcessId가 나올텐데, kill - 9 {ProcessId}를 입력하면 돌아가던 프로세스가 종료된다.
axios 요청을 보낼때는 서버 포트는 안적어야 한다...
axios.delete와 axios.get 요청에서 data를 파라미터로 전달했음에도 불구하고, 서버에서 req.body로 접근이 안될때!
요청 메서드의 원형은 다음과 같다.
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
post,put,patch는 기본 인자로 data가 있지만, get과 delete는 없다는 것을 확인할 수 있다.
따라서, get, delete를 사용할 때는 axios.delete("서버주소", {data})
이렇게 객체로 data를 전달해주어야 한다.
array.map안에 Promise 사용할때, 앞에 Promise.allSettled 붙여주면 된다.
-> 실행순서는 보장 안됨
실행 순서 보장하려면 for of 문 사용해야함
Sequelize 쿼리문 앞에 제발 await 붙이는거 까먹지 말자...
-> 이거때매 고생한게 한두번이 아님
Mysql에서 foreign_key때문에 데이터가 안 지워 질때
mysql> SET foreign_key_checks = 0; // 체크 해제
입력하고 삭제하고 싶은 데이터 지운다음에
mysql> SET foreign_key_checks = 1; // 다시 체크 설정
하면 된다.
Sequelize 쿼리에서 Find 할때, 원하는 값이 여러개 일때(하나의 column이 목록 중 하나의 값 에 포함되는 것 조회시)
Op.or 사용하면 된다.
Post.findAll({
where: {
authorId: {
[Op.or]: [12, 13, 14, 15]
}
}
});
const date = await Date.findOne({
order : Sequelize.literal('RAND()'),
include : [{
model : User,
where : {
id : req.body.id,
}
},{
model : Duty,
where : {
UserId : null,
off : req.body.off,
}
}]
})
위를 만족하는 date나, user, duty가 한개일 지라도 !!
date.Users -> User 인스턴스들이 포함된 객체이므로, date.Users[0].dataValues를 해야 값에 접근이 가능하다
react-hook-form Input Clear 하기
reset()함수 사용하면 된다.
ex) 요청 보낸 후 reset()사용하기
에러는 나는데 error.response가 undefined 일때
라이브러리 import 빼먹었는지 확인하자
여러가지 Form으로 데이터 추가 가능
사용자 추가, 당직 추가, 사용자 당직 점수 변경, 당직 배정 제외일 추가, 당직 강제로 배정, 당직 강제로 해지
사용자 추가된 모습은 다음과 같음.
당직이 추가됐는데, 수행할 사람이 지정되지 않으면 다음과 같이 미배정이라고 나옴
OJT 배정 버튼 누르면, month가 3이하인 사용자들이 ojtSchedule대로 당직 배정이 된다. (좋은 사관 우선)
OJT 아닌 사용자들의 당직 배정 버튼 누르면 나머지 사용자들이 우선순위대로 당직 배정이 된다.
당직이 배정되면, 앞뒤로 4일간 겹치는 당직이 발생하지 않도록 설정했다.
///근데 사용자 추가는 초기 1번만 한다고 쳐도, 당직 추가가 매달 새로 하는게 많이 귀찮아서, 이를 자동화 하는 기능도 넣을 예정이다.
프로젝트를 하면서 정말 많은 에러를 마주하고, 극복하면서 많이 배운 것 같다. 아래 이미지와 같이, 자동차를 만들려고 하면 하나씩 완벽히 구현해 나가는 것이 아니라, 대충 구현한후 점점 발전시키는 방향이 맞는 것 같다고 생각했다
프로젝트 github 주소 : https://github.com/mscwrd02/Dangjik
ToDos
1. redux 도입
2. checkbox input 고치기
우와 잘했다! 나중에 앱으로 만들면 나 UI 만들어보게 해줘~