운영 이관 준비

This commit is contained in:
2025-06-05 08:09:05 +09:00
parent 989b29437b
commit 1a3706d7a5
9 changed files with 163 additions and 12 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
!.env.example
.vite
.windsurfrules
config.js
backend/node_modules/*
frontend/node_modules/*
backend/uploads/*
frontend/dist/*
+41 -4
View File
@@ -51,11 +51,39 @@ app.set('io', io);
// app.js 또는 서버 초기화 파일
const session = require('express-session');
const MySQLStore = require('express-mysql-session')(session);
// MySQL 세션 저장소 옵션 설정
const options = {
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'bowlingmanager',
// 세션 테이블 설정
schema: {
tableName: 'sessions',
columnNames: {
session_id: 'session_id',
expires: 'expires',
data: 'data'
}
}
};
// MySQL 세션 저장소 생성
const sessionStore = new MySQLStore(options);
app.use(session({
key: 'bowling_session',
secret: process.env.JWT_SECRET,
store: sessionStore,
resave: false,
saveUninitialized: false,
cookie: { secure: process.env.NODE_ENV === 'production' } // https 환경이면 true, 개발환경은 false
cookie: {
secure: process.env.NODE_ENV === 'production',
maxAge: 24 * 60 * 60 * 1000 // 1일
}
}));
// 데이터베이스 연결 및 모델 동기화 실행
@@ -83,9 +111,18 @@ app.use('/api/users', userRoutes);
app.use('/api/notifications', notificationRoutes);
app.use('/api/menus', menuRoutes);
// 루트 경로 핸들러
app.get('/', (req, res) => {
res.json({ message: '볼링 클럽 매니저 API 서버에 오신 것을 환영합니다!' });
// 정적 파일 제공 설정
const path = require('path');
app.use(express.static(path.join(__dirname, '../frontend/dist')));
// API 요청이 아닌 모든 요청은 Vue 앱으로 라우팅
app.get('*', (req, res, next) => {
// API 요청은 무시하고 다음 미들웨어로 전달
if (req.path.startsWith('/api/')) {
return next();
}
// Vue 앱의 index.html 반환
res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
});
// 서버 시작
+33
View File
@@ -0,0 +1,33 @@
require('dotenv').config({
path: require('path').resolve(
process.cwd(),
`.env.${process.env.NODE_ENV || 'development'}`
)
});
module.exports = {
development: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mysql'
},
test: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME_TEST || process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mysql'
},
production: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME_PROD || process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mysql'
}
};
+4 -4
View File
@@ -23,13 +23,13 @@ const syncModels = async () => {
try {
// 외래 키 제약 조건을 비활성화하고 테이블 재생성
// 개발
await sequelize.query('SET FOREIGN_KEY_CHECKS = 0');
await sequelize.sync({ force: true });
await sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
// await sequelize.query('SET FOREIGN_KEY_CHECKS = 0');
// await sequelize.sync({ force: true });
// await sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
// 운영 alter: true - 구조변경만 alter처리
// await sequelize.sync({ alter: true });
// await sequelize.sync();
await sequelize.sync();
} catch (error) {
console.error('모델 동기화 중 오류 발생:', error);
}
+74
View File
@@ -16,6 +16,7 @@
"csv-parser": "^3.2.0",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-mysql-session": "^3.0.3",
"express-session": "^1.18.1",
"express-validator": "^7.2.1",
"helmet": "^8.0.0",
@@ -1750,6 +1751,79 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/express-mysql-session": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/express-mysql-session/-/express-mysql-session-3.0.3.tgz",
"integrity": "sha512-sEYrzFrOs3er+Ie/uk1dt93qz4AQ9SU1mpJJ0HPs0MJ4t4hE9AcDRNq0sZQUwy2F/SbXusBt1E5+FY6KzSqXNg==",
"license": "MIT",
"dependencies": {
"debug": "4.3.4",
"mysql2": "3.10.2"
}
},
"node_modules/express-mysql-session/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/express-mysql-session/node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/express-mysql-session/node_modules/lru-cache": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
"integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
"license": "ISC",
"engines": {
"node": ">=16.14"
}
},
"node_modules/express-mysql-session/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/express-mysql-session/node_modules/mysql2": {
"version": "3.10.2",
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.2.tgz",
"integrity": "sha512-KCXPEvAkO0RcHPr362O5N8tFY2fXvbjfkPvRY/wGumh4EOemo9Hm5FjQZqv/pCmrnuxGu5OxnSENG0gTXqKMgQ==",
"license": "MIT",
"dependencies": {
"denque": "^2.1.0",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
"long": "^5.2.1",
"lru-cache": "^8.0.0",
"named-placeholders": "^1.1.3",
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.2"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/express-session": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
+3 -1
View File
@@ -7,7 +7,8 @@
"cleanup": "lsof -ti:3030 | xargs kill -9 || true",
"dev": "npm run cleanup && NODE_ENV=development nodemon app.js",
"test": "NODE_ENV=test jest",
"db:seed:init": "npx sequelize-cli db:seed --seed 20250423-init-admin-user.js && npx sequelize-cli db:seed --seed 20250423-init-features.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-01-plans.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-02-plan-features.js && npx sequelize-cli db:seed --seed 20250424-init-menus.js"
"db:seed:init": "NODE_ENV=development npx sequelize-cli db:seed --seed 20250423-init-admin-user.js && npx sequelize-cli db:seed --seed 20250423-init-features.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-01-plans.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-02-plan-features.js && npx sequelize-cli db:seed --seed 20250424-init-menus.js",
"db:seed:init:prod": "NODE_ENV=production npx sequelize-cli db:seed --seed 20250423-init-admin-user.js && npx sequelize-cli db:seed --seed 20250423-init-features.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-01-plans.js && npx sequelize-cli db:seed --seed 20250423-init-subscription-02-plan-features.js && npx sequelize-cli db:seed --seed 20250424-init-menus.js"
},
"keywords": [],
"author": "",
@@ -21,6 +22,7 @@
"csv-parser": "^3.2.0",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-mysql-session": "^3.0.3",
"express-session": "^1.18.1",
"express-validator": "^7.2.1",
"helmet": "^8.0.0",
+6
View File
@@ -0,0 +1,6 @@
// API 설정
export const API_URL = 'http://localhost:3030/api';
// 기타 설정 값들
export const APP_NAME = '볼링 클럽 매니저';
export const APP_VERSION = '1.0.0';
+1 -1
View File
@@ -1,4 +1,4 @@
import apiClient from './apiClient';
import apiClient from './api';
/**
* 점수 관리 서비스
@@ -199,7 +199,6 @@ import { ref, reactive, computed, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import scoreService from '@/services/scoreService';
import meetingService from '@/services/meetingService';
const router = useRouter();
const route = useRoute();