From b5a119e7bdb55deeb006ddf6a12b970204d6434a Mon Sep 17 00:00:00 2001 From: tpgus2603 <kakaneymar2424@gmail.com> Date: Mon, 11 Nov 2024 11:53:55 +0900 Subject: [PATCH] model design --- models/Friends.js | 47 +++++++ models/index.js | 81 ++++++----- models/meeting.js | 64 +++++++++ models/meetingParticipant.js | 39 ++++++ models/schedule.js | 48 +++++++ models/user.js | 42 ++++++ package-lock.json | 235 ++++++++++++++++++++++++++++++++ package.json | 1 + schemas/ChatRoomParticipants.js | 25 ++++ schemas/ChatRooms.js | 34 +++++ schemas/Messages.js | 25 ++++ schemas/index.js | 32 +++++ 12 files changed, 632 insertions(+), 41 deletions(-) create mode 100644 models/Friends.js create mode 100644 schemas/ChatRoomParticipants.js create mode 100644 schemas/ChatRooms.js create mode 100644 schemas/Messages.js create mode 100644 schemas/index.js diff --git a/models/Friends.js b/models/Friends.js new file mode 100644 index 0000000..77b56cf --- /dev/null +++ b/models/Friends.js @@ -0,0 +1,47 @@ +// 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/index.js b/models/index.js index 024200e..a7921ee 100644 --- a/models/index.js +++ b/models/index.js @@ -1,43 +1,42 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const Sequelize = require('sequelize'); -const process = require('process'); -const basename = path.basename(__filename); -const env = process.env.NODE_ENV || 'development'; -const config = require(__dirname + '/../config/config.json')[env]; -const db = {}; - -let sequelize; -if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); -} else { - sequelize = new Sequelize(config.database, config.username, config.password, config); -} - -fs - .readdirSync(__dirname) - .filter(file => { - return ( - file.indexOf('.') !== 0 && - file !== basename && - file.slice(-3) === '.js' && - file.indexOf('.test.js') === -1 - ); - }) - .forEach(file => { - const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); - db[model.name] = model; +// 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을 수동으로 관리 }); -Object.keys(db).forEach(modelName => { - if (db[modelName].associate) { - db[modelName].associate(db); - } -}); - -db.sequelize = sequelize; -db.Sequelize = Sequelize; - -module.exports = db; + return User; +}; diff --git a/models/meeting.js b/models/meeting.js index e69de29..537335b 100644 --- a/models/meeting.js +++ b/models/meeting.js @@ -0,0 +1,64 @@ +// 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; +}; diff --git a/models/meetingParticipant.js b/models/meetingParticipant.js index e69de29..a989460 100644 --- a/models/meetingParticipant.js +++ b/models/meetingParticipant.js @@ -0,0 +1,39 @@ +// 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; +}; diff --git a/models/schedule.js b/models/schedule.js index e69de29..e32af03 100644 --- a/models/schedule.js +++ b/models/schedule.js @@ -0,0 +1,48 @@ +// 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; +}; diff --git a/models/user.js b/models/user.js index e69de29..a7921ee 100644 --- a/models/user.js +++ b/models/user.js @@ -0,0 +1,42 @@ +// 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을 수동으로 관리 + }); + + return User; +}; diff --git a/package-lock.json b/package-lock.json index 6b09354..1a8403b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "dotenv": "^16.4.5", "express": "^4.21.1", "express-session": "^1.18.1", + "mongoose": "^8.8.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql2": "^3.11.4", @@ -40,6 +41,15 @@ "node": ">=12" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@one-ini/wasm": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", @@ -86,6 +96,21 @@ "integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==", "license": "MIT" }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -265,6 +290,15 @@ "node": ">=8" } }, + "node_modules/bson": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1390,6 +1424,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1463,6 +1506,12 @@ "node": ">=0.12" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -1580,6 +1629,90 @@ "node": "*" } }, + "node_modules/mongodb": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz", + "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==", + "license": "MIT", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "~6.10.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -1608,6 +1741,50 @@ "node": ">= 0.8" } }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "license": "MIT", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1945,6 +2122,15 @@ "dev": true, "license": "MIT" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -2334,6 +2520,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -2359,6 +2551,15 @@ "node": ">=10" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -2572,6 +2773,18 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/type": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", @@ -2694,6 +2907,28 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 048867e..e756213 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dotenv": "^16.4.5", "express": "^4.21.1", "express-session": "^1.18.1", + "mongoose": "^8.8.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql2": "^3.11.4", diff --git a/schemas/ChatRoomParticipants.js b/schemas/ChatRoomParticipants.js new file mode 100644 index 0000000..ad6f74d --- /dev/null +++ b/schemas/ChatRoomParticipants.js @@ -0,0 +1,25 @@ +const ChatRoomParticipantSchema = new Schema({ + chat_room_id: { + type: mongoose.Schema.Types.BigInt, + ref: 'ChatRoom', + required: true, + }, + user_id: { + type: mongoose.Schema.Types.BigInt, + ref: 'User', + required: true, + }, + joined_at: { + type: Date, + default: Date.now, + }, + left_at: { + type: Date, + default: null, + }, +}); + +// 복합 인덱스 생성하여 중복 참여 방지 +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 new file mode 100644 index 0000000..86e3648 --- /dev/null +++ b/schemas/ChatRooms.js @@ -0,0 +1,34 @@ +const mongoose = require('mongoose'); +const { Schema } = mongoose; + +const ChatRoomSchema = new Schema({ + name: { + type: String, + required: true, + }, + meeting_id: { + type: mongoose.Schema.Types.BigInt, // 관계형 DB의 Meetings.id와 연동 + ref: 'Meeting', + default: null, + }, + type: { + type: String, + enum: ['OPEN', 'CLOSE'], + required: true, + }, + created_by: { + type: mongoose.Schema.Types.BigInt, // 관계형 DB의 Users.id와 연동 + ref: 'User', + required: true, + }, + created_at: { + type: Date, + default: Date.now, + }, + updated_at: { + type: Date, + default: Date.now, + }, +}); + +module.exports = mongoose.model('ChatRoom', ChatRoomSchema); diff --git a/schemas/Messages.js b/schemas/Messages.js new file mode 100644 index 0000000..6662897 --- /dev/null +++ b/schemas/Messages.js @@ -0,0 +1,25 @@ +const MessageSchema = new Schema({ + chat_room_id: { + type: mongoose.Schema.Types.BigInt, + ref: 'ChatRoom', + required: true, + }, + sender_id: { + type: mongoose.Schema.Types.BigInt, + ref: 'User', + required: true, + }, + message: { + type: String, + required: true, + }, + sent_at: { + type: Date, + default: Date.now, + }, +}); + +// 인덱스 추가하여 조회 성능 향상 +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 new file mode 100644 index 0000000..27a1c42 --- /dev/null +++ b/schemas/index.js @@ -0,0 +1,32 @@ +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와 일치 +}); -- GitLab