wing-ops/backend/src/db/wingDb.ts
htlee 2b88455a30 feat(backend): DB 통합 + 게시판 CRUD API + RBAC 적용 가이드
- 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>
2026-02-28 18:37:14 +09:00

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 }