507 lines
21 KiB
JavaScript
507 lines
21 KiB
JavaScript
const sqlite3 = require('sqlite3').verbose();
|
|
const path = require('path');
|
|
const bcrypt = require('bcrypt');
|
|
|
|
const DB_PATH = path.join(__dirname, 'database.sqlite');
|
|
|
|
const db = new sqlite3.Database(DB_PATH, (err) => {
|
|
if (err) {
|
|
console.error('데이터베이스 연결 실패:', err.message);
|
|
} else {
|
|
console.log('SQLite 데이터베이스에 연결되었습니다.');
|
|
}
|
|
});
|
|
|
|
// 테이블 초기화
|
|
db.serialize(() => {
|
|
// Users 테이블
|
|
db.run(`CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT UNIQUE NOT NULL,
|
|
email TEXT UNIQUE,
|
|
password TEXT NOT NULL,
|
|
name TEXT,
|
|
phone TEXT,
|
|
role TEXT DEFAULT 'user',
|
|
approved INTEGER DEFAULT 0,
|
|
email_verified INTEGER DEFAULT 0,
|
|
verification_token TEXT,
|
|
reset_token TEXT,
|
|
reset_token_expiry DATETIME,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
|
|
// 기존 테이블에 새 컬럼 추가 (이미 존재하면 무시)
|
|
db.run("ALTER TABLE users ADD COLUMN email TEXT UNIQUE", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN email_verified INTEGER DEFAULT 0", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN verification_token TEXT", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN reset_token TEXT", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN reset_token_expiry DATETIME", (err) => {});
|
|
// OAuth 컬럼 추가
|
|
db.run("ALTER TABLE users ADD COLUMN oauth_provider TEXT", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN oauth_provider_id TEXT", (err) => {});
|
|
db.run("ALTER TABLE users ADD COLUMN profile_image TEXT", (err) => {});
|
|
// 크레딧 컬럼 추가 (무료 플랜 기본값 10)
|
|
db.run("ALTER TABLE users ADD COLUMN credits INTEGER DEFAULT 10", (err) => {});
|
|
|
|
// 구독 플랜 컬럼 추가 (free, basic, pro, business)
|
|
db.run("ALTER TABLE users ADD COLUMN plan_type TEXT DEFAULT 'free'", (err) => {});
|
|
// 최대 펜션 수 (free/basic: 1, pro: 5, business: unlimited)
|
|
db.run("ALTER TABLE users ADD COLUMN max_pensions INTEGER DEFAULT 1", (err) => {});
|
|
// 월간 크레딧 한도 (플랜별 다름, 무료=10)
|
|
db.run("ALTER TABLE users ADD COLUMN monthly_credits INTEGER DEFAULT 10", (err) => {});
|
|
// 구독 시작일
|
|
db.run("ALTER TABLE users ADD COLUMN subscription_started_at DATETIME", (err) => {});
|
|
// 구독 만료일
|
|
db.run("ALTER TABLE users ADD COLUMN subscription_expires_at DATETIME", (err) => {});
|
|
|
|
// ============================================
|
|
// 펜션/브랜드 프로필 테이블 (다중 펜션 지원)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS pension_profiles (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
is_default INTEGER DEFAULT 0,
|
|
brand_name TEXT,
|
|
brand_name_en TEXT,
|
|
region TEXT,
|
|
address TEXT,
|
|
pension_types TEXT,
|
|
target_customers TEXT,
|
|
key_features TEXT,
|
|
nearby_attractions TEXT,
|
|
booking_url TEXT,
|
|
homepage_url TEXT,
|
|
kakao_channel TEXT,
|
|
instagram_handle TEXT,
|
|
languages TEXT DEFAULT 'KO',
|
|
price_range TEXT,
|
|
description TEXT,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// 펜션별 is_default 컬럼 추가 (기존 테이블용)
|
|
db.run("ALTER TABLE pension_profiles ADD COLUMN is_default INTEGER DEFAULT 0", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
// 펜션별 YouTube 플레이리스트 ID 직접 연결
|
|
db.run("ALTER TABLE pension_profiles ADD COLUMN youtube_playlist_id TEXT", (err) => {});
|
|
db.run("ALTER TABLE pension_profiles ADD COLUMN youtube_playlist_title TEXT", (err) => {});
|
|
|
|
// ============================================
|
|
// YouTube 분석 데이터 캐시 테이블 (펜션별)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS youtube_analytics (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pension_id INTEGER NOT NULL,
|
|
playlist_id TEXT NOT NULL,
|
|
date DATE NOT NULL,
|
|
views INTEGER DEFAULT 0,
|
|
playlist_starts INTEGER DEFAULT 0,
|
|
average_time_in_playlist REAL DEFAULT 0,
|
|
estimated_minutes_watched REAL DEFAULT 0,
|
|
subscribers_gained INTEGER DEFAULT 0,
|
|
likes INTEGER DEFAULT 0,
|
|
comments INTEGER DEFAULT 0,
|
|
shares INTEGER DEFAULT 0,
|
|
cached_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE CASCADE,
|
|
UNIQUE(pension_id, date)
|
|
)`);
|
|
|
|
// 펜션별 월간 요약 통계 테이블
|
|
db.run(`CREATE TABLE IF NOT EXISTS pension_monthly_stats (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pension_id INTEGER NOT NULL,
|
|
year_month TEXT NOT NULL,
|
|
total_views INTEGER DEFAULT 0,
|
|
total_videos INTEGER DEFAULT 0,
|
|
total_watch_time REAL DEFAULT 0,
|
|
avg_view_duration REAL DEFAULT 0,
|
|
top_video_id TEXT,
|
|
growth_rate REAL DEFAULT 0,
|
|
cached_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE CASCADE,
|
|
UNIQUE(pension_id, year_month)
|
|
)`);
|
|
|
|
|
|
// ============================================
|
|
// YouTube OAuth 토큰 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS youtube_connections (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
google_user_id TEXT,
|
|
google_email TEXT,
|
|
youtube_channel_id TEXT,
|
|
youtube_channel_title TEXT,
|
|
access_token TEXT,
|
|
refresh_token TEXT,
|
|
token_expiry DATETIME,
|
|
scopes TEXT,
|
|
connected_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// YouTube 업로드 설정 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS youtube_settings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
default_privacy TEXT DEFAULT 'private',
|
|
default_category_id TEXT DEFAULT '19',
|
|
default_tags TEXT,
|
|
default_hashtags TEXT,
|
|
auto_upload INTEGER DEFAULT 0,
|
|
upload_timing TEXT DEFAULT 'manual',
|
|
scheduled_day TEXT,
|
|
scheduled_time TEXT,
|
|
default_playlist_id TEXT,
|
|
notify_on_upload INTEGER DEFAULT 1,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// YouTube 플레이리스트 캐시 테이블 (펜션별 연결 지원)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS youtube_playlists (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
playlist_id TEXT NOT NULL,
|
|
title TEXT,
|
|
item_count INTEGER DEFAULT 0,
|
|
cached_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
UNIQUE(user_id, playlist_id)
|
|
)`);
|
|
|
|
// 플레이리스트에 pension_id 컬럼 추가 (기존 테이블용)
|
|
db.run("ALTER TABLE youtube_playlists ADD COLUMN pension_id INTEGER", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
// ============================================
|
|
// 업로드 히스토리 테이블 (펜션별 연결 지원)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS upload_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
history_id INTEGER,
|
|
youtube_video_id TEXT,
|
|
youtube_url TEXT,
|
|
title TEXT,
|
|
privacy_status TEXT,
|
|
playlist_id TEXT,
|
|
uploaded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
status TEXT DEFAULT 'completed',
|
|
error_message TEXT,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(history_id) REFERENCES history(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// 업로드 히스토리에 pension_id 컬럼 추가 (기존 테이블용)
|
|
db.run("ALTER TABLE upload_history ADD COLUMN pension_id INTEGER", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
// ============================================
|
|
// Instagram 연결 정보 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS instagram_connections (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
instagram_username TEXT NOT NULL,
|
|
encrypted_password TEXT NOT NULL,
|
|
encrypted_session TEXT,
|
|
is_active INTEGER DEFAULT 1,
|
|
last_login_at DATETIME,
|
|
two_factor_required INTEGER DEFAULT 0,
|
|
connected_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// Instagram 업로드 설정 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS instagram_settings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
auto_upload INTEGER DEFAULT 0,
|
|
upload_as_reel INTEGER DEFAULT 1,
|
|
default_caption_template TEXT,
|
|
default_hashtags TEXT,
|
|
max_uploads_per_week INTEGER DEFAULT 1,
|
|
notify_on_upload INTEGER DEFAULT 1,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// Instagram 업로드 히스토리 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS instagram_upload_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
history_id INTEGER,
|
|
instagram_media_id TEXT,
|
|
instagram_post_code TEXT,
|
|
permalink TEXT,
|
|
caption TEXT,
|
|
upload_type TEXT DEFAULT 'reel',
|
|
status TEXT DEFAULT 'pending',
|
|
error_message TEXT,
|
|
retry_count INTEGER DEFAULT 0,
|
|
uploaded_at DATETIME,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(history_id) REFERENCES history(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// ============================================
|
|
// TikTok 연결 정보 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS tiktok_connections (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
open_id TEXT NOT NULL,
|
|
display_name TEXT,
|
|
avatar_url TEXT,
|
|
follower_count INTEGER DEFAULT 0,
|
|
following_count INTEGER DEFAULT 0,
|
|
access_token TEXT NOT NULL,
|
|
refresh_token TEXT,
|
|
token_expiry DATETIME,
|
|
scopes TEXT,
|
|
connected_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// TikTok 업로드 설정 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS tiktok_settings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER UNIQUE NOT NULL,
|
|
default_privacy TEXT DEFAULT 'SELF_ONLY',
|
|
disable_duet INTEGER DEFAULT 0,
|
|
disable_comment INTEGER DEFAULT 0,
|
|
disable_stitch INTEGER DEFAULT 0,
|
|
auto_upload INTEGER DEFAULT 0,
|
|
upload_to_inbox INTEGER DEFAULT 1,
|
|
default_hashtags TEXT,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
)`);
|
|
|
|
// ============================================
|
|
// TikTok 업로드 히스토리 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS tiktok_upload_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
history_id INTEGER,
|
|
publish_id TEXT,
|
|
video_id TEXT,
|
|
title TEXT,
|
|
privacy_level TEXT DEFAULT 'SELF_ONLY',
|
|
status TEXT DEFAULT 'pending',
|
|
error_message TEXT,
|
|
uploaded_at DATETIME,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(history_id) REFERENCES history(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// ============================================
|
|
// 플랫폼 통합 통계 테이블 (YouTube, Instagram, TikTok)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS platform_stats (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
platform TEXT NOT NULL,
|
|
date DATE NOT NULL,
|
|
views INTEGER DEFAULT 0,
|
|
likes INTEGER DEFAULT 0,
|
|
comments INTEGER DEFAULT 0,
|
|
shares INTEGER DEFAULT 0,
|
|
followers_gained INTEGER DEFAULT 0,
|
|
impressions INTEGER DEFAULT 0,
|
|
reach INTEGER DEFAULT 0,
|
|
engagement_rate REAL DEFAULT 0,
|
|
cached_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
UNIQUE(user_id, pension_id, platform, date)
|
|
)`);
|
|
|
|
// ============================================
|
|
// 시스템 활동 로그 테이블 (어드민 분석용)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS activity_logs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER,
|
|
action_type TEXT NOT NULL,
|
|
action_detail TEXT,
|
|
ip_address TEXT,
|
|
user_agent TEXT,
|
|
metadata TEXT,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// ============================================
|
|
// 시스템 통계 스냅샷 테이블 (일별 집계)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS system_stats_daily (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date DATE UNIQUE NOT NULL,
|
|
total_users INTEGER DEFAULT 0,
|
|
new_users INTEGER DEFAULT 0,
|
|
active_users INTEGER DEFAULT 0,
|
|
total_videos_generated INTEGER DEFAULT 0,
|
|
total_uploads INTEGER DEFAULT 0,
|
|
youtube_uploads INTEGER DEFAULT 0,
|
|
instagram_uploads INTEGER DEFAULT 0,
|
|
tiktok_uploads INTEGER DEFAULT 0,
|
|
total_credits_used INTEGER DEFAULT 0,
|
|
avg_generation_time REAL DEFAULT 0,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
|
|
// ============================================
|
|
// 사용자 에셋 테이블 (이미지, 오디오, 비디오)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS user_assets (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
pension_id INTEGER,
|
|
history_id INTEGER,
|
|
asset_type TEXT NOT NULL,
|
|
source_type TEXT NOT NULL,
|
|
file_name TEXT NOT NULL,
|
|
file_path TEXT NOT NULL,
|
|
file_size INTEGER DEFAULT 0,
|
|
mime_type TEXT,
|
|
thumbnail_path TEXT,
|
|
duration REAL,
|
|
width INTEGER,
|
|
height INTEGER,
|
|
metadata TEXT,
|
|
is_deleted INTEGER DEFAULT 0,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(pension_id) REFERENCES pension_profiles(id) ON DELETE SET NULL,
|
|
FOREIGN KEY(history_id) REFERENCES history(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// 사용자별 스토리지 한도 컬럼 추가 (MB 단위, 기본 500MB)
|
|
db.run("ALTER TABLE users ADD COLUMN storage_limit INTEGER DEFAULT 500", (err) => {});
|
|
// 현재 사용 용량 (캐시)
|
|
db.run("ALTER TABLE users ADD COLUMN storage_used INTEGER DEFAULT 0", (err) => {});
|
|
|
|
// ============================================
|
|
// 크레딧 요청 테이블
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS credit_requests (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
requested_credits INTEGER DEFAULT 10,
|
|
status TEXT DEFAULT 'pending',
|
|
reason TEXT,
|
|
admin_note TEXT,
|
|
processed_by INTEGER,
|
|
processed_at DATETIME,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(processed_by) REFERENCES users(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// ============================================
|
|
// 크레딧 히스토리 테이블 (변동 내역 추적)
|
|
// ============================================
|
|
db.run(`CREATE TABLE IF NOT EXISTS credit_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL,
|
|
amount INTEGER NOT NULL,
|
|
type TEXT NOT NULL,
|
|
description TEXT,
|
|
balance_after INTEGER,
|
|
related_request_id INTEGER,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
FOREIGN KEY(related_request_id) REFERENCES credit_requests(id) ON DELETE SET NULL
|
|
)`);
|
|
|
|
// 기존 테이블에 business_name 컬럼 추가 (존재하지 않을 경우를 대비해 try-catch 대신 별도 실행)
|
|
// SQLite는 IF NOT EXISTS 컬럼 추가를 지원하지 않으므로, 에러를 무시하는 방식으로 처리하거나 스키마 버전을 관리해야 함.
|
|
// 여기서는 간단히 컬럼 추가 시도 후 에러 무시 패턴을 사용.
|
|
db.run("ALTER TABLE users ADD COLUMN business_name TEXT", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
db.run("ALTER TABLE history ADD COLUMN final_video_path TEXT", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
db.run("ALTER TABLE history ADD COLUMN poster_path TEXT", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
db.run("ALTER TABLE history ADD COLUMN pension_id INTEGER", (err) => {
|
|
// 이미 존재하면 에러가 발생하므로 무시
|
|
});
|
|
|
|
// History 테이블
|
|
db.run(`CREATE TABLE IF NOT EXISTS history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER,
|
|
business_name TEXT,
|
|
details TEXT,
|
|
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
|
)`);
|
|
|
|
// 기본 관리자 계정 생성 (존재하지 않을 경우)
|
|
const adminUsername = 'admin';
|
|
const adminPassword = 'admin123'; // 초기 비밀번호
|
|
|
|
db.get("SELECT * FROM users WHERE username = ?", [adminUsername], (err, row) => {
|
|
if (!row) {
|
|
const salt = bcrypt.genSaltSync(10);
|
|
const hash = bcrypt.hashSync(adminPassword, salt);
|
|
|
|
db.run(`INSERT INTO users (username, password, name, phone, role, approved, credits)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
[adminUsername, hash, 'Super Admin', '000-0000-0000', 'admin', 1, 999999],
|
|
(err) => {
|
|
if (err) console.error("초기 관리자 생성 실패:", err);
|
|
else console.log(`초기 관리자 계정 생성 완료. (ID: ${adminUsername}, PW: ${adminPassword})`);
|
|
});
|
|
} else if (row.role === 'admin' && (row.credits === null || row.credits < 999999)) {
|
|
// 기존 관리자에게 무제한 크레딧 부여
|
|
db.run("UPDATE users SET credits = 999999 WHERE id = ?", [row.id]);
|
|
}
|
|
});
|
|
});
|
|
|
|
module.exports = db;
|