๐Ÿค“ ์ด ๊ธ€์˜ ๋ชฉ์ 

์ž…์‚ฌํ•˜๊ธฐ ์ „ ํ•œ๋‹ฌ ์กฐ๊ธˆ ๋„˜๋Š” ๊ธฐ๊ฐ„ ๋™์•ˆ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ์ฐ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋กœ ๊ธฐํš, ๋””์ž์ธ, ๊ฐœ๋ฐœ, ํ™๋ณด, ์œ ์ง€๋ณด์ˆ˜๊นŒ์ง€ ๋‹ค ์ง์ ‘ ์ง„ํ–‰ํ•˜์—ฌ ํ˜„์žฌ ์„œ๋น„์Šคํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๊ธ€์„ ํ†ตํ•ด ์ด ํ”„๋กœ์ ํŠธ์˜ ๊ณผ์ •๊ณผ ๊ฒฝํ—˜์„ ๋‚˜๋ˆ ๋ณด๊ณ ์ž ํ•œ๋‹ค.

๐Ÿงฉ ๋Œ€ํ•™์‹œ๊ฐ„์€..!

๋Œ€ํ•™์‹œ๊ฐ„์€ ์ˆ˜๊ฐ•์‹ ์ฒญ์„ ๋„์™€์ฃผ๋Š” ์›น์‚ฌ์ดํŠธ๋กœ, 1์›” ์ค‘์ˆœ์— ๋ฐฐํฌํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค.

college-timetable-0.png

๊ฐ์‚ฌํ•˜๊ฒŒ๋„ ํ•œํ•™๊ธฐ ํ•™์ƒ ์ˆ˜์˜ ์ ˆ๋ฐ˜์ด ๋„˜๋Š” 1600๋ช…์ด ๋Œ€ํ•™์‹œ๊ฐ„์„ ์ด์šฉํ–ˆ๋‹ค!๐ŸŒ

๋จผ์ €, ๊ฐœ๋ฐœ์— ์‚ฌ์šฉํ•œ ๊ธฐ์ˆ ์Šคํƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

college-timetable-1.png

๐ŸŽจ ์ง์ ‘ ๊ธฐํšํ•˜๊ณ  ๋””์ž์ธํ•˜๊ธฐ

์ž‘๋…„ ์šฐ์•„ํ•œํ…Œํฌ์บ ํ”„์—์„œ ๋งŒ๋‚ฌ๋˜ ํ•ด๋ฏผ์ด์™€์˜ ํ”„๋กœ์ ํŠธ ์ดํ›„์— ๋””์ž์ธ์— ๋Œ€ํ•œ ์š•์‹ฌ์ด ์ƒ๊ฒผ๊ณ  ๋‹น์‹œ ํ•ด๋ฏผ์ด๊ฐ€ ์ถ”์ฒœํ•ด์คฌ๋˜ ๋””์ž์ธ ๋ ˆํผ๋Ÿฐ์Šค ์‚ฌ์ดํŠธ์ธ Dribbble์„ ํ™œ์šฉํ•ด์„œ ์›น ๋””์ž์ธ์— ๋„์ „ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๐Ÿ’… ๋””์ž์ธ ๋„์ „๊ธฐ

์ผ๋‹จ ๋‚ด ๋ˆˆ์„ ๋†’์—ฌ ๋†“์ž๋Š” ๋งˆ์Œ์œผ๋กœ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐํšํ•˜๋Š” ์ผ์ฃผ์ผ ๋™์•ˆ Dribbble์„ ์ฐธ๊ณ ํ•ด์„œ ๋ˆˆ์„ ๋†’์ด๋Š”๋ฐ ์ง‘์ค‘ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฐธ๊ณ ํ•  ๋งŒํ•œ ๋””์ž์ธ์„ ์ฐพ์•„ ์Šคํฌ๋žฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

college-timetable-2.png

์ฒ˜์Œ์—๋Š” Dribbble์— ์žˆ๋Š” ๋””์ž์ธ์„ ๊ณ ๋Œ€๋กœ ๋”ฐ๋ผํ•˜๋ ค ํ–ˆ์ง€๋งŒ ์™„์ „ ๋„์ผํ•œ ์„œ๋น„์Šค๊ฐ€ ์•„๋‹ˆ๋‹ค๋ณด๋‹ˆ ์ ์šฉ์ด ์‰ฝ์ง€ ์•Š์•˜๋‹คโ€ฆใ…Žใ…Ž ๊ฒฐ๊ตญ ๊ณ„์† ๋ถ€๋ถ„๋ถ€๋ถ„์„ ์ฐธ๊ณ ํ•˜๋ฉฐ ์ง์ ‘ ๋””์ž์ธ์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๊ณ  ์ด๊ฒƒ์ €๊ฒƒ์„ ์ถ”๊ฐ€ํ•ด๋ณด๋ฉด์„œ ๊ดœ์ฐฎ๋‹ค ์‹ถ์€ ๋””์ž์ธ์„ ์ฐพ๊ฒŒ ๋˜์—ˆ๋‹ค. (๋”ฑ๋ณด๋ฉด ์ด์œ ๊ฑด ์žˆ๋Š”๋ฐ ๋ง‰์ƒ ๋งŒ๋“ค๊ณ  ๋ณด๋ฉด ๋ญ”๊ฐ€ ์•„์‰ฝ๋‹ค..ใ…‹ใ…‹)

ํŠนํžˆ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ชจ๋ฐ”์ผ ๊ฒฝํ—˜์— ์ง‘์ค‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ ์ด์œ ๋กœ ์ˆ˜๊ฐ•์‹ ์ฒญ ์ค€๋น„๋Š” ์‚ฌ์‹ค ๊ฒ€์ƒ‰๊ณผ ์‹œ๊ฐ„ํ‘œ๋ฅผ ํ•œ๋ฒˆ์— ๋ณด๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์—ฐํžˆ ์ปดํ“จํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ ์ง„ํ–‰ํ•  ๊ฒƒ์ด๋ผ๋Š” ์˜ˆ์ƒ๊ณผ๋Š” ๋‹ฌ๋ฆฌ ์‚ฌ๋žŒ๋“ค์€ ๋ชจ๋ฐ”์ผ์— ์ง‘์ค‘ํ–ˆ๋‹ค. ์‹ค์ œ๋กœ๋„ Mobile Web ์‚ฌ์šฉ์ž๊ฐ€ ํ›จ์”ฌ ๋งŽ์•˜๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋ฐ”์ผ์—์„œ ์‚ฌ์šฉ๊ฐ์„ ์ข‹์€ ๋””์ž์ธ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ–ˆ๋‹ค.

college-timetable-3.png

๐Ÿฅ ์ฒซ ๋””์ž์ธ

๋””์ž์ธ์„ ์ง„ํ–‰ํ•  ๋•Œ๋Š” Figma๋‚˜ Sketch์™€ ๊ฐ™์€ ํˆด์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ CSS ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์•„๋ฌด๋ž˜๋„ ๋””์ž์ธ ํˆด๋“ค์€ ์•„์ง ์ž˜ ๋ชป ๋‹ค๋ฃจ๋‹ค ๋ณด๋‹ˆ ์˜คํžˆ๋ ค CSS๋ฅผ ๋ฐ”๋กœ ์ž‘์—…ํ•˜๋ฉด์„œ ๋ณ€ํ™”๋ฅผ ์ง์ ‘ ๊ด€์ฐฐํ•˜๋Š” ํŽธ์ด ํŽธํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๊ณ„์†ํ•ด์„œ ์กฐ๊ธˆ์”ฉ ๋””์ž์ธ์„ ๋ฐ”๊พธ๋‹ค ๋ณด๋‹ˆ ๋””์ž์ธ์ด ์กฐ๊ธˆ์”ฉ ๋‚˜์•„์ง€๊ธฐ(?) ์‹œ์ž‘ํ–ˆ๋‹ค..! ์•„๋ž˜๋Š” CSS๋กœ ์™„์„ฑ๋œ ์ฒซ ๋””์ž์ธ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.

college-timetable-4.png

๐Ÿ“ ํ˜„์žฌ ๋””์ž์ธ

๊ณ ๋ฏผํ•˜๊ณ  ์ด๊ฒƒ์ €๊ฒƒ์„ ์ ์šฉํ•˜๋ฉฐ ๋งŒ๋“ค์–ด์ง„ ์ตœ์ข… ๋””์ž์ธ์˜ ๋ชจ์Šต์ด๋‹ค.

๋ฐ์Šคํฌํƒ‘ ๋ทฐ

college-timetable-5.png


๋ชจ๋ฐ”์ผ ๋ทฐ

college-timetable-6.png


๐Ÿ“ฑ๊ธฐ์ˆ  ์Šคํƒ ์ •ํ•˜๊ธฐ

college-timetable-7.png

ํ”„๋ก ํŠธ์—”๋“œ

๋‚˜๋Š” ์›น ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์ฑ„์šฉ์ด ๋˜์—ˆ์ง€๋งŒ ์‚ฌ์‹ค ๋‚˜๋Š” express์™€ ๋ชจ๋ฐ”์ผ ์•ฑ ํ”„๋ ˆ์ž„์›Œํฌ์ธ Flutter๊ฐ€ ๋” ์นœ์ˆ™ํ•˜๋‹ค. ๊ทธ๋‚˜๋งˆ ์šฐ์•„ํ•œํ…Œํฌ์บ ํ”„๋ฅผ ํ†ตํ•ด ๋ฐ”๋‹๋ผjs์™€๋Š” ์ข€ ๋” ์นœํ•ด์ง„ ๊ฒƒ ๊ฐ™์€๋ฐ ์•„์ง React์™€๋Š” ์–ด์ƒ‰ํ•˜๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ํ”„๋ก ํŠธ์—”๋“œ๋Š” React๋กœ ์ง„ํ–‰ํ•˜๋ฉฐ ์กฐ๊ธˆ ์นœํ•ด์ ธ๋ณด๊ณ ์ž ํ–ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ์ „ ํšŒ์‚ฌ์˜ Web ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ์ฐธ๊ณ ํ–ˆ๋‹ค(์ž˜ ์งœ๋†“์œผ์…”์„œ ๋งŽ์ด ๋ฐฐ์› ๋‹ค!). ํšŒ์‚ฌ ์ฝ”๋“œ๋Š” Material-UI์—์„œ ์ œ๊ณตํ•˜๋Š” ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŽ์ด ํ™œ์šฉํ–ˆ๋Š”๋ฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ์–ด๋ ต์ง€ ์•Š์€๋“ฏ ํ•ด์„œ ์ด๋ฒˆ ๊ธฐํšŒ์— ํ•œ๋ฒˆ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

๋ฐฑ์—”๋“œ

๋ฐฑ์—”๋“œ๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์— ์ง€์†์ ์œผ๋กœ ์‚ฌ์šฉํ•ด ์˜จ express๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ตฌ์„ฑํ–ˆ๊ณ , node์˜ ORM์ด์ž ๋‚˜์™€ ์นœํ•œ sequelize๋ฅผ ์ด์šฉํ•ด์„œ DB์™€ ํ†ต์‹ ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚˜๋Š” ๊ณ„์†ํ•ด์„œ ํ•™๊ต์˜ ์ตœ์‹  ๊ฐœ์„ค ๊ณผ๋ชฉ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์•ผ ํ–ˆ๊ธฐ์— Linux์˜ ์Šค์ผ€์ฅด๋Ÿฌ์ธ Crontab์„ ํ™œ์šฉํ•˜์—ฌ ์ฃผ๊ธฐ์ ์œผ๋กœ DB๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋„๋ก ํ•˜์˜€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ€๋™ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜์—ฌ ์ด์‚ญ์„ ๋ฐœ๊ฒฌํ•˜๊ณ  Nodemailer๋ฅผ ํ†ตํ•ด ์ด๋ฉ”์ผ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ฒŒ ๋˜์—ˆ๋‹ค.

์›น์„œ๋ฒ„์™€ ํฌ๋กค๋Ÿฌ๋Š” ์›” 20๋‹ฌ๋Ÿฌ์งœ๋ฆฌ Lightsail instance๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค!(์ด๊ฑฐ ์ถฉ๋ถ„ํžˆ ํˆฌ์žํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค ใ…Žใ…Ž)


๐Ÿค” ํ”„๋ก ํŠธ์—”๋“œ ๊ตฌ์กฐ ์žก๊ธฐ

models

์—ฌ๋Ÿฌ ๋ชจ๋ธ์˜ ๋‚ด์šฉ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ด€๋ จ๋œ API ํ•จ์ˆ˜๋“ค๋„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์•„๋ž˜๋Š” User ๋ชจ๋ธ์˜ ์˜ˆ์‹œ์ด๋‹ค.

import { Axios } from '../lib/axios';
import { Timetable, BookmarkedLecture, SpikeLecture } from '.';

export default class User {
  constructor(raw) {
    this.id = raw.id;
    this.email = raw.email;
    this.timetables = raw.timetables.map(
      (timetable) => new Timetable(timetable, raw.bookmarks, raw.spikes),
    );
    this.bookmarks = raw.bookmarks.map((lecture) => new BookmarkedLecture(lecture));
    this.spikes = raw.spikes.map((lecture) => new SpikeLecture(lecture));
  }

  static getUser = async () => await Axios().get(`/user`);
  static getAuth = async () => await Axios().get('/auth');
  ...
}

components

์ปดํฌ๋„ŒํŠธ๋Š” ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋ Œ๋”๋ง๋งŒ ๋‹ด๋‹นํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๊ณ  props๋ฅผ ์ „๋‹ฌ ๋ฐ›๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ๋‹ค.

์šฐ์•„ํ•œํ…Œํฌ์บ ํ”„ ๋งˆ์ง€๋ง‰ ํ”„๋กœ์ ํŠธ์ธ bmart๋ฅผ React๋กœ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ ์ด๋•Œ ์‚ฌ์šฉํ–ˆ๋˜ atomic design pattern์€ ๊ฐœ๋…์€ ๊ฐ„๋‹จํ•œ ๋“ฏ ํ•˜๋‚˜ ์‹ค์ œ ๊ตฌํ˜„์„ ํ•˜๋‹ค๋ณด๋‹ˆ ์ปดํฌ๋„ŒํŠธ์˜ depth๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ ์กฐ๊ธˆ์€ ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ทธ ๋‚ด๋ถ€์— ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•˜๋„๋ก ํ–ˆ๋‹ค.

college-timetable-8.png

pages

์ด๊ณณ์€ ๊ฐ ํŽ˜์ด์ง€์˜ ๋ Œ๋”๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์ด์‚ฌ๋ น๊ด€(Controller)๋“ค์ด ๋ชจ์—ฌ์žˆ๋‹ค.

์ด๊ณณ์— ์ •์˜ ๋˜์–ด์žˆ๋Š” ํŽ˜์ด์ง€๋Š” ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐ๋ฆฝํ•˜๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋ธ์˜ ํ•จ์ˆ˜์„ ํ†ตํ•ด ๋ฐ›์•„ ์œ ์ €์—๊ฒŒ ๋ณด์—ฌ์ค€๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์œ ์ €์˜ ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ์— ํ•„์š”ํ•œ ํ•ธ๋“ค๋ง์€ ์ด๊ณณ์— ์ •์˜ ๋˜์–ด ์žˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ์˜ ํ•ต์‹ฌ์€ TimetablePage์ธ๋ฐ ์—ฌ๋Ÿฌ ์œ ์ €์™€ ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋“ค์ด ๋ชจ์—ฌ์žˆ๋‹ค๋ณด๋‹ˆ handler๊ฐ€ ์ƒ๋‹นํžˆ ๋งŽ์ง€๋งŒ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ณด๋ฉด ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๊ณ  ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

Pages/TimetablePage.js


๐Ÿ‘จโ€๐Ÿ’ป ๋น ๋ฅธ ์ฒซ ๋ฐฐํฌ์™€ ์œ ์ € ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ํ•˜๊ธฐ

๊ทธ๋ ‡๊ฒŒ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ฒŒ ํ–ˆ๊ณ , 1์›” ์ค‘์ˆœ์— v1.0.0์„ ๋ฐฐํฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ฒซ ๋ฐฐํฌ์— ์‰ฝ๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋„ฃ์—ˆ๋‹ค.

User-Driven Development

college-timetable-9.png

์ด ๋ถ€๋ถ„์€ ์ด์ „์— Picky๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ์„ฑ์žฅํ•˜๋Š” ๊ณผ์ •์—์„œ ๋งŽ์ด ๋ฐฐ์šด ์ ์„ ์ฐธ๊ณ ํ•œ ๊ฒƒ์ด๋‹ค. ๋‹น์‹œ ์•ฑ์„ ๋ฐฐํฌํ•˜๊ณ  ๋‚˜์„œ ๋Œ€ํ‘œ๋‹˜์€ ๋งŒ๋“œ๋Š” ์‚ฌ๋žŒ์ด ์›ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž๋“ค์ด ์›ํ•˜๋Š” ๊ฒƒ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๊ฐ•์กฐํ•˜์…จ๋‹ค. ๊ทธ๋ž˜์„œ ๋ณธ์ธ์˜ ๊ฐ๋ณด๋‹ค๋Š” ์œ ์ €์˜ ํ–‰๋™์ด๋‚˜ ํ”ผ๋“œ๋ฐฑ์— ๊ท€๋ฅผ ๊ธฐ์šธ์ด์…จ๊ณ  ๊ฑฐ๊ธฐ์— ๋งž์ถฐ์„œ ๋ฐฉํ–ฅ์„ ์žก์œผ์…จ๋‹ค. ์œ ์ €์˜ ํ”ผ๋“œ๋ฐฑ์„ ์ตœ๋Œ€ํ•œ ๋งŽ์ด ๋“ฃ๊ธฐ ์œ„ํ•ด ํ”ผ๋“œ๋ฐฑ ๊ธฐ๋Šฅ์„ ์ฒซ ๋ฐฐํฌ์— ์ถ”๊ฐ€ํ–ˆ๊ณ  ์œ ์ €์˜ ํ”ผ๋“œ๋ฐฑ๊ณผ ์ถ”๊ฐ€์ ์œผ๋กœ ์ง€์ธ๋“ค์˜ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜๋ ดํ•ด์„œ ์„œ๋น„์Šค๋ฅผ ๋ฐœ์ „์‹œ์ผœ ๋‚˜๊ฐ”๋‹ค.

college-timetable-10.png

ํ”„๋กœ์ ํŠธ ํ•˜๋Š” ๋‚ด๋‚ด ์ ๊ทน์ ์œผ๋กœ ๋„์›€์„ ์คฌ๋˜ ํ˜„์„ญ์ด์™€ ์ˆ˜ํ˜„์ด์—๊ฒŒ ๊ณ ๋ง™๋‹คใ…‹ใ…‹ใ…‹

college-timetable-11.png

์ด๋ฅผ ํ†ตํ•ด ๋ฒ„๊ทธ ๋ฆฌํฌํŠธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ธฐ๋Šฅ์ ์ธ ๊ฐœ์„ ์ ๋„ ๋งŽ์ด ๋ฐœ๊ฒฌํ–ˆ๊ณ , ์ด๋ฅผ ๋ฐ˜์˜ํ•ด์„œ ์ง€์†์ ์œผ๋กœ ๋ฐฐํฌํ–ˆ๋‹ค.

๐ŸŒฑ ์ด์‚ญ ์ค๊ธฐ ์•Œ๋ฆผ ๊ฐœ๋ฐœ

๐Ÿ’ก ์•„์ด๋””์–ด์™€ ๊ฐœ๋ฐœ

์–ด์ฐจํ”ผ ๋‚˜๋Š” ๊ณ„์†ํ•ด์„œ ๊ฐœ์„ค ์‹œ๊ฐ„ํ‘œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ƒํ™ฉ์ด์—ˆ๊ณ  ์ด๋ฅผ ์œ„ํ•œ Cronjob์„ ๊ตฌํ˜„ํ•˜๋ ค๋˜ ์ฐธ์— ์žˆ์—ˆ๋‹ค. ๋งŒ์ผ ์ด ๋•Œ ์ˆ˜๊ฐ• ๊ณต์„์ด ๋ฐœ๊ฒฌ๋˜๋ฉด ์•Œ๋ ค์ฃผ๋Š” ๊ฑด ์–ด๋–จ๊นŒ ๋ผ๋Š” ์ƒ๊ฐ์— ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฉ”์ผ๋กœ ์•Œ๋ ค์ฃผ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ดค๋Š”๋ฐ Nodemailer๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ๋ฌด๊ณผ๊ธˆ์œผ๋กœ ์ด๋ฉ”์ผ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด Nodemailer๋ฅผ importํ•˜๊ณ  ์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ธ์ž๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋ฉด ์†์‰ฝ๊ฒŒ ์ด๋ฉ”์ผ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

const sendEmail = ({ user, pass, from, bcc, subject, text, html, onError, onSuccess }) => {
  const nodemailer = require('nodemailer');

  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: { user, pass },
  });

  const mailOptions = { from, bcc, subject, html, text };

  transporter.sendMail(mailOptions, function (error, info) {
    if (error) onError(error);
    else onSuccess();
  });
};

๐ŸŽ™ ํ™๋ณด ๋ฐ ์•Œ๋ฆผ ๋ชจ๋‹ฌ

๊ธฐ๋Šฅ์ด ์ž˜ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์„ ์–ด๋Š์ •๋„ ํ™•์ธํ•œ ํ›„์— ์ œ๋Œ€๋กœ ์„œ๋น„์Šค ํ•ด๋ณด์ž๋Š” ๋งˆ์Œ์œผ๋กœ ๊ธฐ๋Šฅ ์†Œ๊ฐœ์šฉ ๋ชจ๋‹ฌ๋„ ๊ตฌํ˜„ํ•˜๊ณ  ํ™๋ณด๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

college-timetable-12.png

๐Ÿ‘ ๋ฐ˜์‘

์ƒ๊ฐ๋ณด๋‹ค ์ด์‚ญ์ค๊ธฐ ์•Œ๋ฆผ์— ๋Œ€ํ•œ ๋ฐ˜์‘์ด ์ข‹์•˜๋‹ค. ํ˜„์žฌ๊นŒ์ง€ ์•ฝ 400๊ฐœ์˜ ์•Œ๋ฆผ ๋ฉ”์ผ์„ ๋ฐœ์†กํ–ˆ๊ณ , ์•Œ๋ฆผ ๋•์— ์ˆ˜๊ฐ•์‹ ์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์—ฐ๋ฝ์„ ์—ฌ๋Ÿฟ์œผ๋กœ ๋ถ€ํ„ฐ ๋ฐ›์•˜๋‹ค..! ๊ธฐ์œ ๊ฒƒ๋„ ๊ธฐ๋ปค์ง€๋งŒ ์„œ๋น„์Šค๋ฅผ ๋ฏฟ๊ณ  ์ด์šฉํ•ด์ฃผ์‹  ์—ฌ๋Ÿฌ ๋ถ„๋“ค์—๊ฒŒ ๊ฐ์‚ฌํ–ˆ๋‹ค.

college-timetable-13.png

college-timetable-14.png


๐Ÿš€ ๋ผ์ด๋ธŒ ์„œ๋น„์Šคํ•˜๊ธฐ (#๊ธฐ๋กํ•˜๊ธฐ #๋ชจ๋‹ˆํ„ฐ๋ง)

๋ผ์ด๋ธŒ ์„œ๋น„์Šค๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์šด์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜ ๋‚˜๋ฆ„์˜ ๋Œ€๋น„์ฑ…์„ ๊ฐ„๊ตฌํ–ˆ๋‹ค. ์ด์ „ ๊ฐœ์ธํ”„๋กœ์ ํŠธ์™€ ์Šคํƒ€ํŠธ์—…์—์„œ ์ผํ•˜๋ฉฐ ์—ฌ๋Ÿฌ ์•„์ฐ”ํ•œ ์ƒํ™ฉ๋“ค์„ ๊ฒฝํ—˜ํ•ด๋ดค๋‹ค. ๋ฌผ๋ก  ๋‹ค ๋‚ด๊ฐ€ ๋„ˆ๋ฌด ๋‹น์—ฐํ•œ ๊ฒƒ์„ ๊ฐ„๊ณผํ•ด์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๋“ค์ด์—ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋‚ด๊ฐ€ ๋ชจ๋ฅด๋Š” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๋“ค์ด ๋งŽ์„ ๊ฒƒ์ด๋ฏ€๋กœ, ๊ธด์žฅ๊ฐ ์†์—์„œ ์„œ๋น„์Šค๋ฅผ ๊ณ„์†ํ•ด์„œ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๋งŒ์ผ์˜ ์ƒํ™ฉ์— ๋Œ€๋น„ํ–ˆ๋‹ค.

โœ๏ธ ๊ธฐ๋กํ•˜๊ธฐ(์œ ์ € ์ •๋ณด๋Š” ์†Œ์ค‘ํ•˜๋‹ˆ๊นŒ)

์œ ์ €์˜ Authentication ์—ฌ๋ถ€์— ๋”ฐ๋ผ์„œ API ์‚ฌ์šฉ์„ ์ œํ•œ๋˜์ง€๋งŒ ๋‚ด๊ฐ€ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์•”ํ‘์˜ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ ๋ฆด ์ˆ˜ ์žˆ๊ธฐ์— ๋‘๊ฐ€์ง€ ๋Œ€๋น„๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ํ•˜๋‚˜๋Š” sequl pro์˜ export ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•ด์„œ ๊ทธ๋ƒฅ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋‚ด์šฉ์„ sql๋ฌธ์œผ๋กœ ์ €์žฅํ•ด๋†“์•˜๋‹ค.

college-timetable-15.png

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Lightsail์—์„œ ์ง€์›ํ•˜๋Š” Automatic snapshot์„ ํ™œ์šฉํ•˜๋ฉด ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐฑ์—… ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค!

college-timetable-16.png

์•„์ง ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ ์•„๊ฐ„ ์ ์€ ์—†์ง€๋งŒ ํ˜น์‹œ ๋‚ ์•„๊ฐ„๋‹ค๋ฉด ์ด๋Ÿฐ ์ค€๋น„๋ฅผ ์•ˆํ•ด๋†“์€ ๊ฒƒ์„ ์—„์ฒญ๋‚˜๊ฒŒ ํ›„ํšŒํ•  ๊ฒƒ์ด๋‹คโ€ฆ๐Ÿ˜ญ

๐Ÿ‘€ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ธฐ(#GA #Telegram)

์œ ์ €์˜ ์‚ฌ์šฉ๋Ÿ‰๊ณผ ์„œ๋น„์Šค์˜ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•˜๊ธฐ ์œ„ํ•ด ๋‘๊ฐ€์ง€๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ๋จผ์ € Google Analytics(GA)๋ฅผ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ง„ํ–‰ํ–ˆ๋‹ค. ์‚ฌ์‹ค ์ด๊ฑธ๋กœ ํฐ ๋„์›€์€ ์•ˆ๋˜์ง€๋งŒ ์œ ์ € ์ˆ˜๊ฐ€ ์ง€๊ธˆ ์–ด๋– ํ•œ์ง€ ๋ณด๋Š” ๋ง›์ด ์ ์ ํ–ˆ๋‹ค.

college-timetable-17.png

๊ทธ๋ฆฌ๊ณ  ์ฃผ๊ธฐ์ ์œผ๋กœ ๊ฐœ์„ค ๊ณผ๋ชฉ์˜ ์ •๋ณด๋ฅผ ํฌ๋กค๋งํ•ด์„œ DB์— ๋„ฃ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ๋‹ค. ๋‚˜๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ **ํ…”๋ ˆ๊ทธ๋žจ์˜ ๋ด‡**์„ ํ™œ์šฉํ•ด์„œ ํ•ด์„œ ํฌ๋กค๋Ÿฌ์˜ ๋™์ž‘ ์ƒํ™ฉ์„ ์ „๋‹ฌํ•˜๊ฒŒ ํ–ˆ๋‹ค.(๋ฌด๋ฃŒ์ด๋ฉฐ ๊ตฌํ˜„์ด ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ํ™œ์šฉํ–ˆ๋‹ค!)

try {
  ...
} catch (err) {
  sendTelegramMessage("[๐Ÿšจ ์ˆ˜๊ฐ•ํ˜„ํ™ฉ ์—…๋ฐ์ดํŠธ ์‹คํŒจ]\n\n" + err);
	...
}

์ด ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง€์†์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ์™€ ์ด์‚ญ์ค๊ธฐ ์•Œ๋ฆผ ์ „์†ก ์ƒํ™ฉ์„ ํ™•์ธํ•˜๋ฉฐ ํฌ๋กค๋Ÿฌ๊ฐ€ ์—ด์ผํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

college-timetable-18.png

๋ฌผ๋ก  ์„œ๋น„์Šค๊ฐ€ ์ž˜ ๋Œ๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋Š” ๋ชฉ์ ๋„ ์žˆ์ง€๋งŒ ๊ทธ๋ƒฅ ์‹ฌ์‹ฌํ•  ๋•Œ ๋“ค์–ด๊ฐ€์„œ ์‚ฌ๋žŒ๋“ค์ด ์ž˜ ์“ฐ๊ณ  ์žˆ๋Š”์ง€ ๋ณด๋Š” ๋ง›์ด ์žˆ์—ˆ๋‹ค..ใ…Žใ…Ž

๐ŸŒ ํ›„๊ธฐ

๐Ÿ‘ ์˜๋ฏธ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ์˜๋ฏธ๊ฐ€ ์žˆ์–ด์„œ ์ข‹์•˜๋‹ค. ํ•™๊ต์—์„œ ๋ฐฐ์›Œ์„œ ๋‚จ์ฃผ์ž๋ฅผ ๊ฐ•์กฐํ•˜๋ฉฐ ์ปดํ“จํ„ฐ ๊ณตํ•™์„ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ ์‚ฌ์‹ค ํ•˜๋ฉด์„œ๋Š” ์ ์  ๋‚˜์—๊ฒŒ ๋„์›€์ด ๋˜๋Š” ์ผ, ๋ณด์ƒ์ด ํ™•์‹คํ•œ ์ผ์„ ์ฐพ๊ธฐ์— ๊ด€์‹ฌ์„ ๊ฐ€์ง€๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ์•„๋ฌด๋Ÿฐ ๋ณด์ƒ์ด ์—†์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์ด ๋‚ด ์„œ๋น„์Šค์— ๊ฐ์‚ฌํ•จ์„ ํ‘œํ•˜๊ณ  ์‘์›ํ•ด์ฃผ๋Š” ๊ฑธ ๋ณด๋ฉด์„œ ๋Š๋ผ๋Š” ๋ณด๋žŒ์ด ๋งค์šฐ ์ปธ๋‹ค. ๋‹ค์Œ์—๋„ ์ด๋Ÿฐ ์˜๋ฏธ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ”์พŒํžˆ ์ฐธ์—ฌํ•  ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿ‘จโ€๐ŸŽค ์žฌ๋ฐŒ์—ˆ๋˜ 1์ธ๊ทน

๋ฟ๋งŒ ๋‚˜๋””์ž์ธ๋ถ€ํ„ฐ ๊ฐœ๋ฐœ, ํ™๋ณด๊นŒ์ง€ ์ „ ๊ณผ์ •์„ ํ˜ผ์ž ์ง„ํ–‰ํ•ด๋ณธ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด์—ˆ๋‹ค. ์‚ฌ์‹ค ํ˜ผ์ž ํ•˜๋‹ค๋ณด๋‹ˆ ๋งŽ์ด ์„œํˆฌ๋ฅธ ๋ถ€๋ถ„๋„ ์žˆ์—ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋„์›€๋„ ๋˜๊ณ  ๊ฐœ๋ฐœ ์ด์™ธ์˜ ๋ถ„์•ผ๋„ ์ƒˆ๋กœ์ด ๊ฒฝํ—˜ํ•ด ๋ดค๊ธฐ์— ์ข‹์€ ๊ธฐ์–ต์œผ๋กœ ๋‚จ์„ ๊ฒƒ ๊ฐ™๋‹ค. ๊ณ„์†ํ•ด์„œ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๊ณ  ์‘์›ํ•ด ์ค€ ๋ถ„๋“ค ๋ชจ๋‘ ๊ฐ์‚ฌํ–ˆ๋‹ค. (ํŠนํžˆ ๋ฐ”์œ ์™€์ค‘์—๋„ ์—ด์‹ฌํžˆ ๋„์™€์ค€ ์œ ์ง„์ด์—๊ฒŒ ํŠนํžˆ ๊ณ ๋ง™๋‹ค๐Ÿ™)