Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
package-lock.json
node_modules/**/package.json
package.json
project/
node_modules/
node_modules/**/*.json
*.json
body-parser/
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
*/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# COLLUSIC

#### 온라인 프로듀싱 협업 프로젝트
#### 온라인 프로듀싱 협업 프로젝트!

프로듀싱하는데 협업을 하고 싶다?

Expand All @@ -10,8 +10,6 @@

"작곡가"들을 위한 온라인 프로듀싱 협업 서비스🎤🎶🎸🎹



#### 프로젝트 규칙

Collusic 프로젝트를 처음 접하시는 같이 개발하는 개발자에게 전합니다. 이 규칙은 서로의 코드를 더 잘 이해할 수 있게 정해진 규칙입니다. 때문에 언제든지 모든 개발자가 동의한다면 변경이 가능합니다. 규칙을 준수하여 서로의 발전을 도와줍시다.
Expand All @@ -28,8 +26,6 @@ Collusic 프로젝트를 처음 접하시는 같이 개발하는 개발자에게
8. 컴포넌트를 제외한 함수의 이름은 동작의 의미가 담겨 있어야 합니다.
9. 컴포넌트 코드가 들어간 파일의 확장자는 jsx를 사용합니다.



##### 코딩컨벤션

else 사용을 최대한 자제합니다.
Expand All @@ -48,8 +44,6 @@ else 사용을 최대한 자제합니다.

게터/세터 속성 사용을 금지합니다.



규칙1, 2, 3, 5, 6, 9

https://developerfarm.wordpress.com/2012/02/03/object_calisthenics_summary/
Expand Down
1 change: 1 addition & 0 deletions backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
COOKIE_SECRET=cookiesecret
72 changes: 72 additions & 0 deletions backend/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const express = require("express");
const cookieParser = require("cookie-parser");
const morgan = require("morgan");
const path = require("path");
const session = require("express-session");
const nunjucks = require("nunjucks");
const dotenv = require("dotenv");
const passport = require("passport");
dotenv.config();
const pageRouter = require("./routes/page");
const authRouter = require("./routes/auth");
const postRouter = require("./routes/post");
const { sequelize } = require("./models");
const passportConfig = require("./passport");

const app = express();
passportConfig();
app.set("port", process.env.PORT || 8001);
app.set("view engine", "html");
nunjucks.configure("views", {
express: app,
watch: true,
});
sequelize
.sync({ force: false }) //sequelize가 초기화 될 때 DB에 필요한 테이블 생성
.then(() => {
console.log("데이터베이스 연결 성공");
})
.catch((err) => {
console.error(err);
});

app.use(morgan("dev"));
app.use(express.static(path.join(__dirname, "public")));
app.use("/img", express.static(path.join(__dirname, "uploads")));

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use("/", pageRouter);
app.use("/auth", authRouter);
app.use("/post", postRouter);

app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});

app.use((err, req, res, next) => {
res.locals.message = err.message;
res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
res.status(err.status || 500);
res.render("error");
});

app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기중");
});
23 changes: 23 additions & 0 deletions backend/config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"development": {
"username": "root",
"password": "daaeda",
"database": "collusic",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
27 changes: 27 additions & 0 deletions backend/models/hashtag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const Sequelize = require('sequelize');

module.exports = class Hashtag extends Sequelize.Model {
static init(sequelize) {
return super.init({
title: {//해시태그 이름만
type: Sequelize.STRING(15),
allowNull: false,
unique: true,
},
}, {
sequelize,
timestamps: true,
underscored: false,
modelName: 'Hashtag',
tableName: 'hashtags',
paranoid: false,
charset: 'utf8mb4',
collate: 'utf8mb4_general_ci',
});
}

static associate(db) {
db.Hashtag.belongsToMany(db.Post, { through: 'PostHashtag' });
}
};

26 changes: 26 additions & 0 deletions backend/models/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development'; //config.json의 development 가져오기
const config = require('../config/config')[env]; //config.json의 development 가져오기
const User = require('./user');
const Post = require('./post');
const Hashtag = require('./hashtag');

const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config,
);

db.sequelize = sequelize;
db.User = User;
db.Post = Post;
db.Hashtag = Hashtag;
//사람과 게시글은 1:1관계, 게시글과 해시태그는 1:N 관계
User.init(sequelize);
Post.init(sequelize);
Hashtag.init(sequelize);

User.associate(db);
Post.associate(db);
Hashtag.associate(db);

module.exports = db;
30 changes: 30 additions & 0 deletions backend/models/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Sequelize = require('sequelize');

module.exports = class Post extends Sequelize.Model {
static init(sequelize) {
return super.init({
content: {//id 생략. -> sequlize에서는 id가 생략될 수 있음.
type: Sequelize.STRING(140),
allowNull: false,
},
img: {
type: Sequelize.STRING(200),
allowNull: true,
},//img 한개만 올릴 수 있음.
}, {
sequelize,
timestamps: true,
underscored: false,
modelName: 'Post',
tableName: 'posts',
paranoid: false, //deleted at false -> 게시글 삭제시 완전 삭제
charset: 'utf8mb4', //이모티콘
collate: 'utf8mb4_general_ci',
});
}

static associate(db) {
db.Post.belongsTo(db.User);//post belongs to many user , has many 만 있어도 되지만 둘다 쓰는게 좋음.
db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' });//belongs to many 는 N:N 관계
}// through: 'PostHashtag'는 중간 테이블 이름. N:N관계는 중간테이블이 생김.
};
57 changes: 57 additions & 0 deletions backend/models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const Sequelize = require('sequelize');
//db 테이블과 sequelize 연동을 위한 코드
module.exports = class User extends Sequelize.Model {
static init(sequelize) {
return super.init({
email: {
type: Sequelize.STRING(40),
allowNull: true,
unique: true,
},
nick: {
type: Sequelize.STRING(15),
allowNull: false,//sns 로그인인경우 없음.
},
password: {
type: Sequelize.STRING(100),
allowNull: true,
},
provider: {//로그인 제공자
type: Sequelize.STRING(10),
allowNull: false,
defaultValue: 'local',//local을 통해 로그인 한 상태 카카오면 kakao
},
introduce: {
type: Sequelize.TEXT,
allowNull: true,
},
imagePath: {
type: Sequelize.STRING(100),
allowNull: true
}
}, {
sequelize,
timestamps: true, //생성일 수정일 삭제일이 기록
underscored: false,
modelName: 'User',
tableName: 'users',
paranoid: true, //deleted at 삭제한척하는
charset: 'utf8',
collate: 'utf8_general_ci', //한글 지원
});
}

static associate(db) {
db.User.hasMany(db.Post);//user has many db.post
db.User.belongsToMany(db.User, {
foreignKey: 'followingId', //둘다 foreignkey가 userid이면 모르니까. 선언.
as: 'Followers',
through: 'Follow',
});//사용자와 사용자간의 관계: 팔로잉 팔로워 관계
db.User.belongsToMany(db.User, {
foreignKey: 'followerId',
as: 'Followings',
through: 'Follow',
});
}
};
Loading