diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..812c2f62671e3f94792eb6f8b7ed11501807e1a8 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +DB_HOST=localhost +DB_USER=root +DB_PASSWORD=0000 +DB_NAME=meeting +MONGO_URI=mongodb://localhost:27017/your_mongo_db +PORT=3306 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 40b878db5b1c97fc77049537a71bb2e249abe5dc..f51c03d15e456a71dcab0ead5892f2ded16469f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -node_modules/ \ No newline at end of file +node_modules/ +.env/ +config.json/ diff --git a/app.js b/app.js index 30e4db353850f08d3fc669d8d2d7a747c4ecee45..801de0935118cb72891b27e2206157cff066a04a 100644 --- a/app.js +++ b/app.js @@ -1,11 +1,32 @@ +// app.js + +require('dotenv').config(); // 환경 변수 로드 + const express = require('express'); const app = express(); -const PORT = process.env.PORT || 3000; +const sequelize = require('./config/sequelize'); +//const mongoose = require('./config/mongoose'); +//const userRoutes = require('./routes/userRoutes'); +//const passport = require('./passport'); -app.get('/', (req, res) => { - res.send('Hello, World!'); -}); +// 미들웨어 설정 +app.use(express.json()); +//app.use(passport.initialize()); +// 라우팅 +//app.use('/users', userRoutes); + +// Sequelize 데이터베이스 연결 및 동기화 +sequelize.sync() + .then(() => { + console.log('Sequelize synchronized.'); + }) + .catch(err => { + console.error('Sequelize synchronization error:', err); + }); + +// 서버 시작 +const PORT = process.env.PORT || 3000; app.listen(PORT, () => { - console.log(`Server is running on http://localhost:${PORT}`); -}); \ No newline at end of file + console.log(`Server running on port ${PORT}`); +}); diff --git a/config/config.json b/config/config.json index 0f858c669328baf9399cc3b487ef4c0289360e32..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/config/config.json +++ b/config/config.json @@ -1,23 +0,0 @@ -{ - "development": { - "username": "root", - "password": null, - "database": "database_development", - "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" - } -} diff --git a/config/mongoose.js b/config/mongoose.js new file mode 100644 index 0000000000000000000000000000000000000000..3379779bf664ebd969317df7f7de48e7a74b34be --- /dev/null +++ b/config/mongoose.js @@ -0,0 +1,18 @@ +// config/mongoose.js + +const mongoose = require('mongoose'); + +mongoose.connect(process.env.MONGO_URI, { + useNewUrlParser: true, + useUnifiedTopology: true, +}); + +mongoose.connection.on('connected', () => { + console.log('Mongoose connected.'); +}); + +mongoose.connection.on('error', (err) => { + console.error('Mongoose connection error:', err); +}); + +module.exports = mongoose; diff --git a/config/sequelize.js b/config/sequelize.js new file mode 100644 index 0000000000000000000000000000000000000000..c814262f78d7785ff4fad276aad06be1d509ca27 --- /dev/null +++ b/config/sequelize.js @@ -0,0 +1,15 @@ +// config/sequelize.js + +const { Sequelize } = require('sequelize'); + +const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, { + host: process.env.DB_HOST, + dialect: 'mysql', // 사용하려는 DBMS에 맞게 변경 + logging: false, + define: { + //timestamps: true, // createdAt, updatedAt 자동 생성 + underscored: true, // created_at 형식의 필드명 사용 + }, +}); + +module.exports = sequelize; \ No newline at end of file diff --git a/models/Friend.js b/models/Friend.js new file mode 100644 index 0000000000000000000000000000000000000000..fc72c69ac47e8ae67810b4d32af2e2281481dc2f --- /dev/null +++ b/models/Friend.js @@ -0,0 +1,23 @@ +// models/Friend.js + +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); +const User = require('./User'); + +const Friend = sequelize.define('Friend', { + type: { + type: DataTypes.ENUM('NORMAL', 'SPECIAL'), + allowNull: false, + }, +}, { + tableName: 'Friends', + timestamps: false, +}); + +Friend.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); +Friend.belongsTo(User, { foreignKey: 'friend_id', as: 'friend' }); + +User.hasMany(Friend, { foreignKey: 'user_id', as: 'friends' }); +User.hasMany(Friend, { foreignKey: 'friend_id', as: 'friendOf' }); + +module.exports = Friend; diff --git a/models/Friends.js b/models/Friends.js deleted file mode 100644 index 77b56cf79a247c8f237543901402cd2ee5b45b2a..0000000000000000000000000000000000000000 --- a/models/Friends.js +++ /dev/null @@ -1,47 +0,0 @@ -// models/Friend.js -module.exports = (sequelize, DataTypes) => { - const Friend = sequelize.define('Friend', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - user_id: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Users', - key: 'id', - }, - onDelete: 'CASCADE', - }, - friend_id: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Users', - key: 'id', - }, - onDelete: 'CASCADE', - }, - type: { - type: DataTypes.ENUM('NORMAL', 'SPECIAL'), - allowNull: false, - }, - created_at: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, - }, - }, { - tableName: 'Friends', - timestamps: false, - indexes: [ - { - unique: true, - fields: ['user_id', 'friend_id'], - }, - ], - }); - - return Friend; -}; diff --git a/models/chatParticipant.js b/models/chatParticipant.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/models/chatRoom.js b/models/chatRoom.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/models/index.js b/models/index.js index a7921eea49db6545d9f632920e591e578009a1fb..9206ae91c1ee3ac6017edf694473c430f565b419 100644 --- a/models/index.js +++ b/models/index.js @@ -1,42 +1,18 @@ -// models/User.js -module.exports = (sequelize, DataTypes) => { - const User = sequelize.define('User', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - name: { - type: DataTypes.STRING, - allowNull: false, - }, - email: { - type: DataTypes.STRING, - allowNull: false, - unique: true, - validate: { - isEmail: true, // 이메일 형식 검증 - }, - }, - invite_code: { - type: DataTypes.UUID, - defaultValue: DataTypes.UUIDV4, // 자동으로 UUID 생성 - allowNull: false, - unique: true, - }, - created_at: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, - }, - // updated_at 추가 (필요 시) - updated_at: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, - }, - }, { - tableName: 'Users', - timestamps: false, // created_at과 updated_at을 수동으로 관리 - }); +// models/index.js - return User; +const sequelize = require('../config/sequelize'); + +const User = require('./User'); +const Schedule = require('./Schedule'); +const Meeting = require('./Meeting'); +const MeetingParticipant = require('./MeetingParticipant'); +const Friend = require('./Friend'); + +module.exports = { + sequelize, + User, + Schedule, + Meeting, + MeetingParticipant, + Friend, }; diff --git a/models/meeting.js b/models/meeting.js index 537335b2b1fca933f401e90ea59b750d50882731..7944e355fef21458c8550ce46bbb6eeb7e3cbc46 100644 --- a/models/meeting.js +++ b/models/meeting.js @@ -1,64 +1,41 @@ // models/Meeting.js -module.exports = (sequelize, DataTypes) => { - const Meeting = sequelize.define('Meeting', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - title: { - type: DataTypes.STRING, - allowNull: false, - }, - description: { - type: DataTypes.TEXT, - allowNull: true, - }, - start_time: { - type: DataTypes.DATE, - allowNull: false, - }, - end_time: { - type: DataTypes.DATE, - allowNull: false, - validate: { - isAfterStart(value) { - if (value <= this.start_time) { - throw new Error('end_time은 start_time 이후여야 합니다.'); - } - }, - }, - }, - location: { - type: DataTypes.STRING, - allowNull: true, - }, - deadline: { - type: DataTypes.DATE, - allowNull: true, - }, - type: { - type: DataTypes.ENUM('OPEN', 'CLOSE'), - allowNull: false, - }, - created_by: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Users', - key: 'id', - }, - onDelete: 'CASCADE', - }, - }, { - tableName: 'Meetings', - timestamps: false, - indexes: [ - { - fields: ['created_by'], - }, - ], - }); - return Meeting; -}; +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); +const User = require('./User'); + +const Meeting = sequelize.define('Meeting', { + title: { + type: DataTypes.STRING, + allowNull: false, + }, + description: { + type: DataTypes.TEXT, + }, + start_time: { + type: DataTypes.DATE, + allowNull: false, + }, + end_time: { + type: DataTypes.DATE, + allowNull: false, + }, + location: { + type: DataTypes.STRING, + }, + deadline: { + type: DataTypes.DATE, + }, + type: { + type: DataTypes.ENUM('OPEN', 'CLOSE'), + allowNull: false, + }, +}, { + tableName: 'Meetings', + timestamps: false, +}); + +Meeting.belongsTo(User, { foreignKey: 'created_by', as: 'creator' }); +User.hasMany(Meeting, { foreignKey: 'created_by', as: 'meetings' }); + +module.exports = Meeting; diff --git a/models/meetingParticipant.js b/models/meetingParticipant.js index a989460b727872116a939b895649b2a6361c3d52..fd456faf26ebfeff79bb4bb9f1bb9148242e2e67 100644 --- a/models/meetingParticipant.js +++ b/models/meetingParticipant.js @@ -1,39 +1,19 @@ // models/MeetingParticipant.js -module.exports = (sequelize, DataTypes) => { - const MeetingParticipant = sequelize.define('MeetingParticipant', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - meeting_id: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Meetings', - key: 'id', - }, - onDelete: 'CASCADE', - }, - user_id: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Users', - key: 'id', - }, - onDelete: 'CASCADE', - }, - }, { - tableName: 'MeetingParticipants', - timestamps: false, - indexes: [ - { - unique: true, - fields: ['meeting_id', 'user_id'], - }, - ], - }); - return MeetingParticipant; -}; +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); +const Meeting = require('./Meeting'); +const User = require('./User'); + +const MeetingParticipant = sequelize.define('MeetingParticipant', {}, { + tableName: 'MeetingParticipants', + timestamps: true, +}); + +MeetingParticipant.belongsTo(Meeting, { foreignKey: 'meeting_id', as: 'meeting' }); +Meeting.hasMany(MeetingParticipant, { foreignKey: 'meeting_id', as: 'participants' }); + +MeetingParticipant.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); +User.hasMany(MeetingParticipant, { foreignKey: 'user_id', as: 'meetingParticipations' }); + +module.exports = MeetingParticipant; diff --git a/models/message.js b/models/message.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/models/schedule.js b/models/schedule.js index e32af033a79298ccce8aa3d3444627b18c9bfd62..215e272d7d8e49bea9eaacb2d6febe4798531a1d 100644 --- a/models/schedule.js +++ b/models/schedule.js @@ -1,48 +1,28 @@ // models/Schedule.js -module.exports = (sequelize, DataTypes) => { - const Schedule = sequelize.define('Schedule', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - user_id: { - type: DataTypes.BIGINT, - allowNull: false, - references: { - model: 'Users', - key: 'id', - }, - onDelete: 'CASCADE', - }, - title: { - type: DataTypes.STRING, - allowNull: false, - }, - start_time: { - type: DataTypes.DATE, - allowNull: false, - }, - end_time: { - type: DataTypes.DATE, - allowNull: false, - validate: { - isAfterStart(value) { - if (value <= this.start_time) { - throw new Error('end_time은 start_time 이후여야 합니다.'); - } - }, - }, - }, - }, { - tableName: 'Schedules', - timestamps: false, - indexes: [ - { - fields: ['user_id'], - }, - ], - }); - return Schedule; -}; +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); +const User = require('./User'); + +const Schedule = sequelize.define('Schedule', { + title: { + type: DataTypes.STRING, + allowNull: false, + }, + start_time: { + type: DataTypes.DATE, + allowNull: false, + }, + end_time: { + type: DataTypes.DATE, + allowNull: false, + }, +}, { + tableName: 'Schedules', + timestamps: true, +}); + +Schedule.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); +User.hasMany(Schedule, { foreignKey: 'user_id', as: 'schedules' }); + +module.exports = Schedule; diff --git a/models/user.js b/models/user.js index a7921eea49db6545d9f632920e591e578009a1fb..fbf92c144d9a6de814321390a784bc4c66c5d2eb 100644 --- a/models/user.js +++ b/models/user.js @@ -1,42 +1,24 @@ // models/User.js -module.exports = (sequelize, DataTypes) => { - const User = sequelize.define('User', { - id: { - type: DataTypes.BIGINT, - primaryKey: true, - autoIncrement: true, - }, - name: { - type: DataTypes.STRING, - allowNull: false, - }, - email: { - type: DataTypes.STRING, - allowNull: false, - unique: true, - validate: { - isEmail: true, // 이메일 형식 검증 - }, - }, - invite_code: { - type: DataTypes.UUID, - defaultValue: DataTypes.UUIDV4, // 자동으로 UUID 생성 - allowNull: false, - unique: true, - }, - created_at: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, - }, - // updated_at 추가 (필요 시) - updated_at: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, + +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/sequelize'); // sequelize 인스턴스 경로에 맞게 수정하세요. + +const User = sequelize.define('User', { + name: { + type: DataTypes.STRING, // VARCHAR + allowNull: false, + }, + email: { + type: DataTypes.STRING, // VARCHAR + allowNull: false, + unique: true, + validate: { + isEmail: true, }, - }, { - tableName: 'Users', - timestamps: false, // created_at과 updated_at을 수동으로 관리 - }); + }, +}, { + tableName: 'Users', + timestamps: true, // createdAt과 updatedAt 자동 관리 +}); - return User; -}; +module.exports = User; diff --git a/package.json b/package.json index e756213aec4f3e54bc1225e7d5bdc7be05bb2eb5..fad438c8abf0716dac3d1df3736c19b9e4fe1e39 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "webback", "version": "1.0.0", - "main": "index.js", + "main": "app.js", "scripts": { + "start": "nodemon app", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { diff --git a/schemas/ChatRoomParticipants.js b/schemas/ChatRoomParticipants.js index ad6f74d0844a9e06afab16d994ffc4d7c7630206..09279d1b6ca9c9aaecd466eb23ddeed1598ce59d 100644 --- a/schemas/ChatRoomParticipants.js +++ b/schemas/ChatRoomParticipants.js @@ -1,25 +1,23 @@ -const ChatRoomParticipantSchema = new Schema({ +// schemas/ChatRoomParticipant.js + +const mongoose = require('mongoose'); + +const ChatRoomParticipantSchema = new mongoose.Schema({ chat_room_id: { - type: mongoose.Schema.Types.BigInt, + type: mongoose.Schema.Types.ObjectId, ref: 'ChatRoom', required: true, }, user_id: { - type: mongoose.Schema.Types.BigInt, - ref: 'User', + type: Number, // SQL의 Users 테이블 ID 참조 required: true, }, - joined_at: { - type: Date, - default: Date.now, - }, left_at: { type: Date, default: null, }, +}, { + timestamps: { createdAt: 'joined_at', updatedAt: false }, }); -// 복합 인덱스 생성하여 중복 참여 방지 -ChatRoomParticipantSchema.index({ chat_room_id: 1, user_id: 1 }, { unique: true }); - module.exports = mongoose.model('ChatRoomParticipant', ChatRoomParticipantSchema); diff --git a/schemas/ChatRooms.js b/schemas/ChatRooms.js index 86e3648c32abcb544bfed78cdbd7b21ba4aad4b2..f4a963ef66b49866bd3cc4ebb01220effa3295ef 100644 --- a/schemas/ChatRooms.js +++ b/schemas/ChatRooms.js @@ -1,14 +1,14 @@ +// schemas/ChatRoom.js + const mongoose = require('mongoose'); -const { Schema } = mongoose; -const ChatRoomSchema = new Schema({ +const ChatRoomSchema = new mongoose.Schema({ name: { type: String, required: true, }, meeting_id: { - type: mongoose.Schema.Types.BigInt, // 관계형 DB의 Meetings.id와 연동 - ref: 'Meeting', + type: Number, // SQL의 Meetings 테이블 ID 참조 default: null, }, type: { @@ -17,18 +17,11 @@ const ChatRoomSchema = new Schema({ required: true, }, created_by: { - type: mongoose.Schema.Types.BigInt, // 관계형 DB의 Users.id와 연동 - ref: 'User', + type: Number, // SQL의 Users 테이블 ID 참조 required: true, }, - created_at: { - type: Date, - default: Date.now, - }, - updated_at: { - type: Date, - default: Date.now, - }, +}, { + timestamps: true, // createdAt, updatedAt 자동 관리 }); module.exports = mongoose.model('ChatRoom', ChatRoomSchema); diff --git a/schemas/Messages.js b/schemas/Messages.js index 666289712524068a732777d84fa3c12d0964604f..7c59dcf49a0137362722709dd8941ce5a66990a0 100644 --- a/schemas/Messages.js +++ b/schemas/Messages.js @@ -1,25 +1,23 @@ -const MessageSchema = new Schema({ +// schemas/Message.js + +const mongoose = require('mongoose'); + +const MessageSchema = new mongoose.Schema({ chat_room_id: { - type: mongoose.Schema.Types.BigInt, + type: mongoose.Schema.Types.ObjectId, ref: 'ChatRoom', required: true, }, sender_id: { - type: mongoose.Schema.Types.BigInt, - ref: 'User', + type: Number, // SQL의 Users 테이블 ID 참조 required: true, }, message: { type: String, required: true, }, - sent_at: { - type: Date, - default: Date.now, - }, +}, { + timestamps: { createdAt: 'sent_at', updatedAt: false }, }); -// 인덱스 추가하여 조회 성능 향상 -MessageSchema.index({ chat_room_id: 1, sent_at: -1 }); - module.exports = mongoose.model('Message', MessageSchema); diff --git a/schemas/index.js b/schemas/index.js deleted file mode 100644 index 27a1c429a9b1240f3430eacbd5efe8416651b12b..0000000000000000000000000000000000000000 --- a/schemas/index.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose'); - -// MongoDB 연결 -mongoose.connect('mongodb://localhost:27017/chatDB', { - useNewUrlParser: true, - useUnifiedTopology: true, -}) -.then(() => console.log('MongoDB 연결 성공')) -.catch(err => console.error('MongoDB 연결 실패:', err)); - -// 위에서 정의한 ChatRoom, ChatRoomParticipant, Message 모델을 사용 -const ChatRoom = require('./models/ChatRoom'); -const ChatRoomParticipant = require('./models/ChatRoomParticipant'); -const Message = require('./models/Message'); - -// 예시: 채팅방 생성 -async function createChatRoom(data) { - try { - const chatRoom = new ChatRoom(data); - await chatRoom.save(); - console.log('채팅방 생성 완료:', chatRoom); - } catch (error) { - console.error('채팅방 생성 실패:', error); - } -} - -// 예시 함수 호출 -createChatRoom({ - name: '일반 채팅방', - type: 'OPEN', - created_by: 1, // 관계형 DB의 Users.id와 일치 -}); diff --git a/sync.js b/sync.js new file mode 100644 index 0000000000000000000000000000000000000000..60721173c64df1fd2c31675bfd1d125fe9b7872a --- /dev/null +++ b/sync.js @@ -0,0 +1,26 @@ +// sync.js + +require('dotenv').config(); // 환경 변수 로드 + +const sequelize = require('./config/sequelize'); +const model=require('./models'); // 모델들을 가져옴 (사이드 이펙트로 모델들이 등록됨) + +async function syncDatabase() { + try { + // 데이터베이스 연결 테스트 + await sequelize.authenticate(); + console.log('데이터베이스 연결 성공.'); + + // 모든 모델 동기화 + await sequelize.sync({ force: true }); + console.log('모든 모델이 성공적으로 동기화되었습니다.'); + + // 연결 종료 + await sequelize.close(); + console.log('데이터베이스 연결이 종료되었습니다.'); + } catch (error) { + console.error('데이터베이스 연결 실패:', error); + } +} + +syncDatabase();