- wing + wing_auth DB를 wing 단일 DB로 통합 (wing/auth 스키마 분리) - wingPool 단일 Pool + search_path 설정, authPool 하위 호환 유지 - 게시판 BOARD_POST DDL + 초기 데이터 10건 마이그레이션 - boardService/boardRouter CRUD 구현 (페이징, 검색, 소유자 검증, 논리삭제) - requirePermission 카테고리별 서브리소스 동적 적용 (board:notice, board:qna 등) - 프론트엔드 boardApi 서비스 + BoardListTable mock→API 전환 - CRUD-API-GUIDE (범용 가이드 + 게시판 튜토리얼) 문서 작성 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import pg from 'pg'
|
|
|
|
const { Pool } = pg
|
|
|
|
// ============================================================
|
|
// wing DB 통합 Pool (wing 스키마 + auth 스키마)
|
|
// - wing 스키마: 운영 데이터 (LAYER, BOARD_POST 등)
|
|
// - auth 스키마: 인증/인가 데이터 (AUTH_USER, AUTH_ROLE 등)
|
|
// - public 스키마: PostGIS 시스템 테이블만 유지
|
|
// ============================================================
|
|
const wingPool = new Pool({
|
|
host: process.env.DB_HOST || process.env.WING_DB_HOST || 'localhost',
|
|
port: Number(process.env.DB_PORT || process.env.WING_DB_PORT) || 5432,
|
|
database: process.env.DB_NAME || process.env.WING_DB_NAME || 'wing',
|
|
user: process.env.DB_USER || process.env.WING_DB_USER || 'wing',
|
|
password: process.env.DB_PASSWORD || process.env.WING_DB_PASSWORD || 'Wing2026',
|
|
max: 20,
|
|
idleTimeoutMillis: 30000,
|
|
connectionTimeoutMillis: 5000,
|
|
})
|
|
|
|
// 연결 시 search_path 자동 설정 (public 미사용)
|
|
wingPool.on('connect', (client) => {
|
|
client.query('SET search_path = wing, auth, public')
|
|
})
|
|
|
|
wingPool.on('error', (err) => {
|
|
console.error('[db] 예기치 않은 연결 오류:', err.message)
|
|
})
|
|
|
|
export async function testWingDbConnection(): Promise<boolean> {
|
|
try {
|
|
const client = await wingPool.connect()
|
|
await client.query('SELECT 1')
|
|
client.release()
|
|
console.log('[db] wing 데이터베이스 연결 성공 (wing + auth 스키마)')
|
|
return true
|
|
} catch (err) {
|
|
console.warn('[db] wing 데이터베이스 연결 실패:', (err as Error).message)
|
|
return false
|
|
}
|
|
}
|
|
|
|
export { wingPool }
|