Skip to content

Commit

Permalink
Merge pull request #195 from innovationacademy-kr/develop
Browse files Browse the repository at this point in the history
⚰️ BETA 버전 배포
  • Loading branch information
yongjulejule authored Feb 11, 2022
2 parents 7b25e23 + 70fb1fd commit 6ab989b
Show file tree
Hide file tree
Showing 162 changed files with 17,565 additions and 28 deletions.
28 changes: 28 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FORTYTWO_APP_ID=
FORTYTWO_APP_SECRET=
RETURN_URL=

FORTYTWO_APP_ID_EVENT=
FORTYTWO_APP_SECRET_EVENT=

DB_HOST=
DB_PORT=
DB_USER=
DB_PASSWORD=
DB_NAME=

REDIS_HOST=
REDIS_PORT=
REDIS_PASSWORD=

JWT_SECRET_KEY=
OPEN_API_SERVICE_KEY=

VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=

COOKIE_SECRET=

SENTRY_DSN=

NODE_ENV=
24 changes: 24 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": ["eslint:recommended", "airbnb", "prettier"],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"guard-for-in": 0,
"import/extensions": 0,
"import/no-import-module-exports": 0,
"no-console": 0,
"no-restricted-syntax": 0,
"no-shadow": 0,
"no-underscore-dangle": 0,
"no-unused-vars": 0,
"no-use-before-define": 0
}
}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,12 @@ dist

# TernJS port file
.tern-port

# os x
.DS_Store

#vscode
.vscode

#redis
dump.rdb
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 100,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "avoid"
}
45 changes: 19 additions & 26 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,32 @@
우리42벤트 프로젝트는 아래의 코딩 스타일 가이드를 따릅니다.

- HTML & CSS

[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)

[google_style_guide_ko.pdf](CONTRIBUTION%20md%20d74ea19b520c4640bcedd80bbde6f317/google_style_guide_ko.pdf)

[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)
[google_style_guide_ko.pdf](CONTRIBUTION%20md%20d74ea19b520c4640bcedd80bbde6f317/google_style_guide_ko.pdf)
- JavaScript

[Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)

[Airbnb JavaScript Style Guide (한글)](https://github.com/tipjs/javascript-style-guide)

[Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
[Airbnb JavaScript Style Guide (한글)](https://github.com/tipjs/javascript-style-guide)
- 주석은 한글로 작성합니다.

# Git Branch Convention

- git flow 사용
- 브랜치 설명
- `main` : 서비스 출시 브랜치
- `develop` : 다음 출시 버전 개발 브랜치
- `feature` : 기능 개발 브랜치, `feature/(기능)` 형식으로 브랜치명 작성 (e.g. login 기능 개발 목적이면 `feature/login`)
- `release` : 출시 버전 준비 브랜치
- `hotfix` : 출시 버전 버그 수정 브랜치
- `main` : 서비스 출시 브랜치
- `develop` : 다음 출시 버전 개발 브랜치
- `feature` : 기능 개발 브랜치, `feature/(기능)` 형식으로 브랜치명 작성 (e.g. login 기능 개발 목적이면 `feature/login`)
- `release` : 출시 버전 준비 브랜치
- `hotfix` : 출시 버전 버그 수정 브랜치
- Reference

[우린 Git-flow를 사용하고 있어요 | 우아한형제들 기술블로그](https://techblog.woowahan.com/2553/)

[우린 Git-flow를 사용하고 있어요 | 우아한형제들 기술블로그](https://techblog.woowahan.com/2553/)

# Commit Convention

- 한글로 작성

### Commit Template

```java
```shell
# (gitmoji) <타입> : <제목><이슈번호>

##### 제목은 이슈 번호와 함께 최대 50 글자까지 한 줄로 입력 ############## -> |
Expand All @@ -46,13 +38,13 @@

# --- COMMIT END ---
# <타입> 리스트
# ✨ feat : 기능 (새로운 기능)
# 🐛 fix : 버그 (버그 수정)
# ♻ refactor : 리팩토링
# 💄 style : 스타일 (코드 형식, 세미콜론 추가: 비즈니스 로직에 변경 없음)
# 📝 docs : 문서 (문서 추가, 수정, 삭제)
# ✅ test : 테스트 (테스트 코드 추가, 수정, 삭제: 비즈니스 로직에 변경 없음)
# 🔨 chore : 기타 변경사항 (빌드 스크립트 수정 등)
#(:sparkles:) feat : 기능 (새로운 기능)
# 🐛(:bug:) fix : 버그 (버그 수정)
#(:recycle:) refactor : 리팩토링
# 💄(:lipstick:) style : UI 스타일 변경
# 📝(:memo:) docs : 문서 (문서 추가, 수정, 삭제)
#(:white_check_mark:) test : 테스트 (테스트 코드 추가, 수정, 삭제: 비즈니스 로직에 변경 없음)
# 🔨(:hammer:) chore : 기타 변경사항 (빌드 스크립트 수정 등)
# ------------------
# 제목은 명령문으로
# 제목 끝에 마침표(.) 금지
Expand All @@ -61,6 +53,7 @@
# 본문은 한 줄을 작성하고 . 마침표를 찍어서 분리한다.
# ------------------
```

- Reference

[커밋 템플릿 · innovationacademy-kr/slabs-saver Wiki](https://github.com/innovationacademy-kr/slabs-saver/wiki/%EC%BB%A4%EB%B0%8B-%ED%85%9C%ED%94%8C%EB%A6%BF)
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,69 @@
# our42vent
슬랙에 마구잡이로 올라오는 42 이벤트들을 한 눈에 볼 수 있는 캘린더 웹사이트
# 우리42벤트

<br>

<p align='center'>
<img src='https://raw.githubusercontent.com/innovationacademy-kr/our42vent/31b47343ee2021cfc653ba9d7adaf4919b072416/public/assets/images/our42vent_logo_white.svg' alt='our42vent_logo_white' width='200' height='' style='background:#13171d'/>
</p>

<br>
<p align='center'>
<b><em>
슬랙에 마구잡이로 올라오는 42 이벤트들을 한 눈에 볼 수 있는 캘린더 웹사이트
</em>
</b>
</p>

<p align='center'>

<img src='https://img.shields.io/badge/node.js-000000.svg?&style=for-the-badge&logo=node.js' alt='node_logo' >
<img src='https://img.shields.io/badge/express-000000.svg?&style=for-the-badge&logo=express' alt='express_logo' >
<img src='https://img.shields.io/badge/mariadb-000000.svg?&style=for-the-badge&logo=mariadb' alt='mariadb_logo' >
<img src='https://img.shields.io/badge/redis-000000.svg?&style=for-the-badge&logo=redis' alt='redis_logo' >
<img src='https://img.shields.io/badge/npm-000000.svg?&style=for-the-badge&logo=npm' alt='npm_logo' >
<br>
<img src='https://img.shields.io/badge/webpack-000000.svg?&style=for-the-badge&logo=webpack' alt='webpack_logo' >
<img src='https://img.shields.io/badge/ejs-000000.svg?&style=for-the-badge&logo=ejs' alt='ejs_logo' >
<img src='https://img.shields.io/badge/javascript-000000.svg?&style=for-the-badge&logo=javascript' alt='javascript_logo' >
<img src='https://img.shields.io/badge/css3-000000.svg?&style=for-the-badge&logo=css3' alt='css3_logo' >
<img src='https://img.shields.io/badge/html5-000000.svg?&style=for-the-badge&logo=html5' alt='html5_logo' >

</p>

## Introduction

### ✅ 이벤트 일정 확인

- 캘린더 뷰에서 다양한 42 이벤트들의 일정을 확인할 수 있습니다.

### ✨ 이벤트 생성

- 특강, 외부 컨퍼런스, 개인 카뎃들이 여는 이벤트등을 캘린더 이벤트로 생성해서 42 서울 커뮤니티에 공유할 수 있습니다.

### 🔔 이벤트 구독

- 이벤트를 구독하여 나만의 캘린더로 관리할 수 있습니다.
- 알림설정을 통하여 브라우저 알림을 받을 수 있습니다.

### 📣 이벤트 홍보

- 이벤트 생성 후 자동으로 홍보글이 만들어져서 손쉽게 홍보할 수 있습니다.

### 🧭 사용 가이드
- <a href="https://teal-grill-819.notion.site/42-e71f7d1e8fc24f90b3ca079b3affc837" target="_blank">우리42벤트 가이드</a>에서 서비스 사용 가이드를 확인하세요.

## Contributing

- 우리42벤트는 오픈 소스 프로젝트입니다. 프로젝트에 기여하기 원하신다면 <a href="/CONTRIBUTION.md" target="_blank">CONTRIBUTION.md</a> 따라서 PR 해주세요!

## DevLog

- 프로젝트 <a href="https://teal-grill-819.notion.site/42-DevLog-88791cfa191b42c9a4bc46103bfede46" target="_blank">DevLog</a> & <a href="https://teal-grill-819.notion.site/42-cd34716bc09d4670857cceb5f040a87a" target="_blank">기획 문서</a>에서 개발 과정을 확인할 수 있습니다.

## Contact

- 운영팀 이메일 : [[email protected]](mailto:[email protected])

<br>

![MIT](https://img.shields.io/badge/MIT_LICENSE-000000.svg?&style=for-the-badge&logo=MIT)
87 changes: 87 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';
import express from 'express';
import expressLayouts from 'express-ejs-layouts';
import helmet from 'helmet';
import createError from 'http-errors';
import morgan from 'morgan';
import schedule from 'node-schedule';
import passport from 'passport';
import { dirname, join } from 'path';
import Sentry from '@sentry/node';
import Tracing from '@sentry/tracing';
import { fileURLToPath } from 'url';
import helmetConfig from './config/helmet.js';
import { httpErrorStream } from './config/winston.js';
import initializePassport from './controllers/initializePassport.js';
import triggerPush from './lib/push/triggerPush.js';
import errorHandler from './middlewares/errorHandler.js';
import { verifyUser } from './middlewares/verifyUser.js';
import calendarRoute from './routes/calendar.js';
import errorRoute from './routes/error.js';
import eventRoute from './routes/event.js';
import indexRoute from './routes/index.js';
import loginRoute from './routes/login.js';
import logoutRoute from './routes/logout.js';
import pushRoute from './routes/push.js';

// dotenv 로드
dotenv.config();

// 앱 전역 변수 설정
const __dirname = dirname(fileURLToPath(import.meta.url)); // 현재 디렉토리 주소 __dirname 에 저장

// passport-42 초기 설정
initializePassport(passport);

// express 세팅
const app = express();

Sentry.init({
dsn: process.env.SENTRY_DSM,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Tracing.Integrations.Express({ app }),
],
tracesSampleRate: 1.0,
});

// 알림 trigger 스케줄러
schedule.scheduleJob('event^notifier', '*/1 * * * *', triggerPush);

app.use(helmet(helmetConfig));

app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());

// TODO : 400 미만의 모든 요청에 대한 로그가 필요한지 고민해봐야함
app.use(morgan('dev', { skip: (req, res) => res.statusCode >= 400 }));
app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400, stream: httpErrorStream }));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(express.static(join(__dirname, 'public')));
app.use(passport.initialize());
app.use(/^\/(?!login|logout|error).*$/, verifyUser);

// ejs 로 view engine 설정
app.set('views', join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(expressLayouts);
app.set('layout', 'layouts/layout');

// router 연결
app.use('/', indexRoute(express));
app.use('/login', loginRoute(express, passport));
app.use('/logout', logoutRoute(express));
app.use('/event', eventRoute(express));
app.use('/calendar', calendarRoute(express));
app.use('/push', pushRoute(express));
app.use('/error', errorRoute(express));

// 에러 핸들러
app.use(Sentry.Handlers.errorHandler());
app.use((req, res, next) => next(createError(404)));
app.use(errorHandler());

export default app;
72 changes: 72 additions & 0 deletions bin/www.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env node

// SECTION: 모듈 import

import http from 'http';
import debug from 'debug';
import app from '../app.js';

const debugServer = debug('our42vent:server');

// SECTION: 포트 연결 및 서버 세팅

// 환경변수에서 port 받아서 express 에 저장
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

// HTTP 서버 생성
const server = http.createServer(app);

// 포트 listen
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

// SECTION: 함수 정의

// 포트 인자 number || string || false 로 분류
function normalizePort(val) {
const port = parseInt(val, 10);

if (Number.isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// 포트 번호
return port;
}

return false;
}

// HTTP 서버 listener
function onListening() {
const addr = server.address();
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
debugServer(`Listening on ${bind}`);
}

// HTTP 서버 에러 발생 시 listener
function onError(err) {
if (err.syscall !== 'listen') {
throw err;
}

const bind = `Pipe ${port}`;

// 에러 메시지
switch (err.code) {
case 'EACCES':
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(`${bind} is already in use`);
process.exit(1);
break;
default:
throw err;
}
}
Loading

0 comments on commit 6ab989b

Please sign in to comment.