운영 이관 준비
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
!.env.example
|
!.env.example
|
||||||
.vite
|
.vite
|
||||||
.windsurfrules
|
.windsurfrules
|
||||||
config.js
|
|
||||||
backend/node_modules/*
|
backend/node_modules/*
|
||||||
frontend/node_modules/*
|
frontend/node_modules/*
|
||||||
backend/uploads/*
|
backend/uploads/*
|
||||||
|
frontend/dist/*
|
||||||
+41
-4
@@ -51,11 +51,39 @@ app.set('io', io);
|
|||||||
|
|
||||||
// app.js 또는 서버 초기화 파일
|
// app.js 또는 서버 초기화 파일
|
||||||
const session = require('express-session');
|
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({
|
app.use(session({
|
||||||
|
key: 'bowling_session',
|
||||||
secret: process.env.JWT_SECRET,
|
secret: process.env.JWT_SECRET,
|
||||||
|
store: sessionStore,
|
||||||
resave: false,
|
resave: false,
|
||||||
saveUninitialized: 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/notifications', notificationRoutes);
|
||||||
app.use('/api/menus', menuRoutes);
|
app.use('/api/menus', menuRoutes);
|
||||||
|
|
||||||
// 루트 경로 핸들러
|
// 정적 파일 제공 설정
|
||||||
app.get('/', (req, res) => {
|
const path = require('path');
|
||||||
res.json({ message: '볼링 클럽 매니저 API 서버에 오신 것을 환영합니다!' });
|
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'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 서버 시작
|
// 서버 시작
|
||||||
|
|||||||
Executable
+33
@@ -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'
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -23,13 +23,13 @@ const syncModels = async () => {
|
|||||||
try {
|
try {
|
||||||
// 외래 키 제약 조건을 비활성화하고 테이블 재생성
|
// 외래 키 제약 조건을 비활성화하고 테이블 재생성
|
||||||
// 개발
|
// 개발
|
||||||
await sequelize.query('SET FOREIGN_KEY_CHECKS = 0');
|
// await sequelize.query('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
await sequelize.sync({ force: true });
|
// await sequelize.sync({ force: true });
|
||||||
await sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
|
// await sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
|
||||||
|
|
||||||
// 운영 alter: true - 구조변경만 alter처리
|
// 운영 alter: true - 구조변경만 alter처리
|
||||||
// await sequelize.sync({ alter: true });
|
// await sequelize.sync({ alter: true });
|
||||||
// await sequelize.sync();
|
await sequelize.sync();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('모델 동기화 중 오류 발생:', error);
|
console.error('모델 동기화 중 오류 발생:', error);
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+74
@@ -16,6 +16,7 @@
|
|||||||
"csv-parser": "^3.2.0",
|
"csv-parser": "^3.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
|
"express-mysql-session": "^3.0.3",
|
||||||
"express-session": "^1.18.1",
|
"express-session": "^1.18.1",
|
||||||
"express-validator": "^7.2.1",
|
"express-validator": "^7.2.1",
|
||||||
"helmet": "^8.0.0",
|
"helmet": "^8.0.0",
|
||||||
@@ -1750,6 +1751,79 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"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": {
|
"node_modules/express-session": {
|
||||||
"version": "1.18.1",
|
"version": "1.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
"cleanup": "lsof -ti:3030 | xargs kill -9 || true",
|
"cleanup": "lsof -ti:3030 | xargs kill -9 || true",
|
||||||
"dev": "npm run cleanup && NODE_ENV=development nodemon app.js",
|
"dev": "npm run cleanup && NODE_ENV=development nodemon app.js",
|
||||||
"test": "NODE_ENV=test jest",
|
"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": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
"csv-parser": "^3.2.0",
|
"csv-parser": "^3.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
|
"express-mysql-session": "^3.0.3",
|
||||||
"express-session": "^1.18.1",
|
"express-session": "^1.18.1",
|
||||||
"express-validator": "^7.2.1",
|
"express-validator": "^7.2.1",
|
||||||
"helmet": "^8.0.0",
|
"helmet": "^8.0.0",
|
||||||
|
|||||||
Executable
+6
@@ -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,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 { useRouter, useRoute } from 'vue-router';
|
||||||
import { useToast } from 'primevue/usetoast';
|
import { useToast } from 'primevue/usetoast';
|
||||||
import scoreService from '@/services/scoreService';
|
import scoreService from '@/services/scoreService';
|
||||||
import meetingService from '@/services/meetingService';
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|||||||
Reference in New Issue
Block a user