wing-ops/database/auth_init.sql
htlee a0f64e4b11 style: 기존 코드 ESLint/TypeScript 에러 수정
- frontend: ESLint 에러 86건 수정 (unused-vars, set-state-in-effect, static-components 등)
- backend: simulation.ts req.params 타입 단언 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:47:29 +09:00

289 lines
13 KiB
SQL

-- ================================================================
-- WING 인증 시스템 데이터베이스 (wing_auth)
-- 공공데이터베이스 표준화 관리 매뉴얼(2021.06) 기준 적용
-- PostgreSQL 16
-- ================================================================
-- ============================================================
-- 1. 사용자 및 데이터베이스 생성
-- ============================================================
CREATE USER wing_auth WITH PASSWORD 'WingAuth!2026';
CREATE DATABASE wing_auth OWNER wing_auth;
-- wing_auth 데이터베이스로 전환
\c wing_auth
-- ============================================================
-- 2. 확장 설치
-- ============================================================
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS pgcrypto;
GRANT ALL ON SCHEMA public TO wing_auth;
-- ============================================================
-- 3. 조직 (AUTH_ORG)
-- ============================================================
CREATE TABLE AUTH_ORG (
ORG_SN SERIAL NOT NULL,
ORG_NM VARCHAR(100) NOT NULL,
ORG_ABBR_NM VARCHAR(20) NOT NULL,
ORG_TP_CD VARCHAR(20) NOT NULL,
UPPER_ORG_SN INTEGER,
REG_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_ORG PRIMARY KEY (ORG_SN),
CONSTRAINT FK_AUTH_ORG_UPPER FOREIGN KEY (UPPER_ORG_SN) REFERENCES AUTH_ORG(ORG_SN)
);
COMMENT ON TABLE AUTH_ORG IS '인증조직';
COMMENT ON COLUMN AUTH_ORG.ORG_SN IS '조직순번';
COMMENT ON COLUMN AUTH_ORG.ORG_NM IS '조직명';
COMMENT ON COLUMN AUTH_ORG.ORG_ABBR_NM IS '조직약칭명';
COMMENT ON COLUMN AUTH_ORG.ORG_TP_CD IS '조직유형코드 (HEADQUARTERS, REGIONAL, STATION, AGENCY)';
COMMENT ON COLUMN AUTH_ORG.UPPER_ORG_SN IS '상위조직순번';
COMMENT ON COLUMN AUTH_ORG.REG_DTM IS '등록일시';
-- ============================================================
-- 4. 역할 (AUTH_ROLE)
-- ============================================================
CREATE TABLE AUTH_ROLE (
ROLE_SN SERIAL NOT NULL,
ROLE_CD VARCHAR(20) NOT NULL,
ROLE_NM VARCHAR(50) NOT NULL,
ROLE_DC VARCHAR(200),
DFLT_YN CHAR(1) NOT NULL DEFAULT 'N',
REG_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_ROLE PRIMARY KEY (ROLE_SN),
CONSTRAINT UK_AUTH_ROLE_CD UNIQUE (ROLE_CD),
CONSTRAINT CK_AUTH_ROLE_DFLT CHECK (DFLT_YN IN ('Y','N'))
);
COMMENT ON TABLE AUTH_ROLE IS '인증역할';
COMMENT ON COLUMN AUTH_ROLE.ROLE_SN IS '역할순번';
COMMENT ON COLUMN AUTH_ROLE.ROLE_CD IS '역할코드 (ADMIN, MANAGER, USER, VIEWER)';
COMMENT ON COLUMN AUTH_ROLE.ROLE_NM IS '역할명';
COMMENT ON COLUMN AUTH_ROLE.ROLE_DC IS '역할설명';
COMMENT ON COLUMN AUTH_ROLE.DFLT_YN IS '기본여부 (Y:신규 사용자 기본 역할)';
COMMENT ON COLUMN AUTH_ROLE.REG_DTM IS '등록일시';
-- ============================================================
-- 5. 사용자 (AUTH_USER)
-- ============================================================
CREATE TABLE AUTH_USER (
USER_ID UUID NOT NULL DEFAULT uuid_generate_v4(),
USER_ACNT VARCHAR(50) NOT NULL,
PSWD_HASH VARCHAR(255) NOT NULL,
USER_NM VARCHAR(50) NOT NULL,
RNKP_NM VARCHAR(30),
ORG_SN INTEGER,
USER_STTS_CD VARCHAR(20) NOT NULL DEFAULT 'PENDING',
FAIL_CNT INTEGER NOT NULL DEFAULT 0,
LAST_LOGIN_DTM TIMESTAMPTZ,
REG_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
MDFCN_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_USER PRIMARY KEY (USER_ID),
CONSTRAINT UK_AUTH_USER_ACNT UNIQUE (USER_ACNT),
CONSTRAINT FK_AUTH_USER_ORG FOREIGN KEY (ORG_SN) REFERENCES AUTH_ORG(ORG_SN),
CONSTRAINT CK_AUTH_USER_STTS CHECK (USER_STTS_CD IN ('PENDING','ACTIVE','LOCKED','INACTIVE','REJECTED'))
);
COMMENT ON TABLE AUTH_USER IS '인증사용자';
COMMENT ON COLUMN AUTH_USER.USER_ID IS '사용자아이디 (UUID)';
COMMENT ON COLUMN AUTH_USER.USER_ACNT IS '사용자계정 (로그인 ID)';
COMMENT ON COLUMN AUTH_USER.PSWD_HASH IS '비밀번호해시 (bcrypt)';
COMMENT ON COLUMN AUTH_USER.USER_NM IS '사용자명';
COMMENT ON COLUMN AUTH_USER.RNKP_NM IS '직급명';
COMMENT ON COLUMN AUTH_USER.ORG_SN IS '조직순번';
COMMENT ON COLUMN AUTH_USER.USER_STTS_CD IS '사용자상태코드 (PENDING:승인대기, ACTIVE:활성, LOCKED:잠김, INACTIVE:비활성, REJECTED:거절)';
COMMENT ON COLUMN AUTH_USER.FAIL_CNT IS '로그인실패횟수';
COMMENT ON COLUMN AUTH_USER.LAST_LOGIN_DTM IS '최종로그인일시';
COMMENT ON COLUMN AUTH_USER.REG_DTM IS '등록일시';
COMMENT ON COLUMN AUTH_USER.MDFCN_DTM IS '수정일시';
-- ============================================================
-- 6. 사용자-역할 매핑 (AUTH_USER_ROLE)
-- ============================================================
CREATE TABLE AUTH_USER_ROLE (
USER_ID UUID NOT NULL,
ROLE_SN INTEGER NOT NULL,
REG_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_USER_ROLE PRIMARY KEY (USER_ID, ROLE_SN),
CONSTRAINT FK_AUR_USER FOREIGN KEY (USER_ID) REFERENCES AUTH_USER(USER_ID) ON DELETE CASCADE,
CONSTRAINT FK_AUR_ROLE FOREIGN KEY (ROLE_SN) REFERENCES AUTH_ROLE(ROLE_SN) ON DELETE CASCADE
);
COMMENT ON TABLE AUTH_USER_ROLE IS '사용자역할매핑';
COMMENT ON COLUMN AUTH_USER_ROLE.USER_ID IS '사용자아이디';
COMMENT ON COLUMN AUTH_USER_ROLE.ROLE_SN IS '역할순번';
COMMENT ON COLUMN AUTH_USER_ROLE.REG_DTM IS '등록일시';
-- ============================================================
-- 7. 역할별 권한 (AUTH_PERM)
-- ============================================================
CREATE TABLE AUTH_PERM (
PERM_SN SERIAL NOT NULL,
ROLE_SN INTEGER NOT NULL,
RSRC_CD VARCHAR(50) NOT NULL,
GRANT_YN CHAR(1) NOT NULL DEFAULT 'Y',
REG_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_PERM PRIMARY KEY (PERM_SN),
CONSTRAINT FK_AP_ROLE FOREIGN KEY (ROLE_SN) REFERENCES AUTH_ROLE(ROLE_SN) ON DELETE CASCADE,
CONSTRAINT UK_AUTH_PERM UNIQUE (ROLE_SN, RSRC_CD),
CONSTRAINT CK_AUTH_PERM_GRANT CHECK (GRANT_YN IN ('Y','N'))
);
COMMENT ON TABLE AUTH_PERM IS '역할별권한';
COMMENT ON COLUMN AUTH_PERM.PERM_SN IS '권한순번';
COMMENT ON COLUMN AUTH_PERM.ROLE_SN IS '역할순번';
COMMENT ON COLUMN AUTH_PERM.RSRC_CD IS '리소스코드 (탭 ID: prediction, hns, rescue 등)';
COMMENT ON COLUMN AUTH_PERM.GRANT_YN IS '부여여부 (Y:허용, N:거부)';
COMMENT ON COLUMN AUTH_PERM.REG_DTM IS '등록일시';
-- ============================================================
-- 8. 로그인 이력 (AUTH_LOGIN_HIST)
-- ============================================================
CREATE TABLE AUTH_LOGIN_HIST (
HIST_SN SERIAL NOT NULL,
USER_ID UUID NOT NULL,
LOGIN_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
IP_ADDR VARCHAR(45),
USER_AGENT VARCHAR(500),
SUCCESS_YN CHAR(1) NOT NULL DEFAULT 'Y',
CONSTRAINT PK_AUTH_LOGIN_HIST PRIMARY KEY (HIST_SN),
CONSTRAINT FK_ALH_USER FOREIGN KEY (USER_ID) REFERENCES AUTH_USER(USER_ID) ON DELETE CASCADE,
CONSTRAINT CK_ALH_SUCCESS CHECK (SUCCESS_YN IN ('Y','N'))
);
COMMENT ON TABLE AUTH_LOGIN_HIST IS '로그인이력';
COMMENT ON COLUMN AUTH_LOGIN_HIST.HIST_SN IS '이력순번';
COMMENT ON COLUMN AUTH_LOGIN_HIST.USER_ID IS '사용자아이디';
COMMENT ON COLUMN AUTH_LOGIN_HIST.LOGIN_DTM IS '로그인일시';
COMMENT ON COLUMN AUTH_LOGIN_HIST.IP_ADDR IS 'IP주소';
COMMENT ON COLUMN AUTH_LOGIN_HIST.USER_AGENT IS '유저에이전트';
COMMENT ON COLUMN AUTH_LOGIN_HIST.SUCCESS_YN IS '성공여부 (Y:성공, N:실패)';
-- ============================================================
-- 8-1. 시스템 설정 (AUTH_SETTING)
-- ============================================================
CREATE TABLE AUTH_SETTING (
SETTING_KEY VARCHAR(100) NOT NULL,
SETTING_VAL VARCHAR(500) NOT NULL,
SETTING_DC VARCHAR(200),
MDFCN_DTM TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT PK_AUTH_SETTING PRIMARY KEY (SETTING_KEY)
);
COMMENT ON TABLE AUTH_SETTING IS '시스템설정';
COMMENT ON COLUMN AUTH_SETTING.SETTING_KEY IS '설정키';
COMMENT ON COLUMN AUTH_SETTING.SETTING_VAL IS '설정값';
COMMENT ON COLUMN AUTH_SETTING.SETTING_DC IS '설정설명';
COMMENT ON COLUMN AUTH_SETTING.MDFCN_DTM IS '수정일시';
-- ============================================================
-- 9. 인덱스
-- ============================================================
CREATE INDEX IDX_AUTH_USER_STTS ON AUTH_USER (USER_STTS_CD);
CREATE INDEX IDX_AUTH_USER_ORG ON AUTH_USER (ORG_SN);
CREATE INDEX IDX_AUTH_PERM_ROLE ON AUTH_PERM (ROLE_SN);
CREATE INDEX IDX_AUTH_PERM_RSRC ON AUTH_PERM (RSRC_CD);
CREATE INDEX IDX_AUTH_LOGIN_USER ON AUTH_LOGIN_HIST (USER_ID);
CREATE INDEX IDX_AUTH_LOGIN_DTM ON AUTH_LOGIN_HIST (LOGIN_DTM);
-- ============================================================
-- 10. 초기 데이터: 역할
-- ============================================================
INSERT INTO AUTH_ROLE (ROLE_CD, ROLE_NM, ROLE_DC, DFLT_YN) VALUES
('ADMIN', '관리자', '시스템 전체 관리 권한', 'N'),
('MANAGER', '운영자', '운영 및 사용자 관리 권한', 'N'),
('USER', '일반사용자', '기본 업무 기능 접근 권한', 'Y'),
('VIEWER', '뷰어', '조회 전용 접근 권한', 'N');
-- ============================================================
-- 11. 초기 데이터: 역할별 권한 (탭 접근 매트릭스)
-- ============================================================
-- ADMIN (ROLE_SN=1): 모든 탭 접근
INSERT INTO AUTH_PERM (ROLE_SN, RSRC_CD, GRANT_YN) VALUES
(1, 'prediction', 'Y'), (1, 'hns', 'Y'), (1, 'rescue', 'Y'),
(1, 'reports', 'Y'), (1, 'aerial', 'Y'), (1, 'assets', 'Y'),
(1, 'scat', 'Y'), (1, 'incidents', 'Y'), (1, 'board', 'Y'),
(1, 'weather', 'Y'), (1, 'admin', 'Y');
-- MANAGER (ROLE_SN=2): admin 탭 제외
INSERT INTO AUTH_PERM (ROLE_SN, RSRC_CD, GRANT_YN) VALUES
(2, 'prediction', 'Y'), (2, 'hns', 'Y'), (2, 'rescue', 'Y'),
(2, 'reports', 'Y'), (2, 'aerial', 'Y'), (2, 'assets', 'Y'),
(2, 'scat', 'Y'), (2, 'incidents', 'Y'), (2, 'board', 'Y'),
(2, 'weather', 'Y'), (2, 'admin', 'N');
-- USER (ROLE_SN=3): assets, admin 탭 제외
INSERT INTO AUTH_PERM (ROLE_SN, RSRC_CD, GRANT_YN) VALUES
(3, 'prediction', 'Y'), (3, 'hns', 'Y'), (3, 'rescue', 'Y'),
(3, 'reports', 'Y'), (3, 'aerial', 'Y'), (3, 'assets', 'N'),
(3, 'scat', 'Y'), (3, 'incidents', 'Y'), (3, 'board', 'Y'),
(3, 'weather', 'Y'), (3, 'admin', 'N');
-- VIEWER (ROLE_SN=4): reports, assets, scat, admin 제외
INSERT INTO AUTH_PERM (ROLE_SN, RSRC_CD, GRANT_YN) VALUES
(4, 'prediction', 'Y'), (4, 'hns', 'Y'), (4, 'rescue', 'Y'),
(4, 'reports', 'N'), (4, 'aerial', 'Y'), (4, 'assets', 'N'),
(4, 'scat', 'N'), (4, 'incidents', 'Y'), (4, 'board', 'Y'),
(4, 'weather', 'Y'), (4, 'admin', 'N');
-- ============================================================
-- 12. 초기 데이터: 조직
-- ============================================================
INSERT INTO AUTH_ORG (ORG_NM, ORG_ABBR_NM, ORG_TP_CD) VALUES
('해양경찰청', '해경청', 'HEADQUARTERS'),
('남해지방해양경찰청', '남해청', 'REGIONAL'),
('제주지방해양경찰청', '제주청', 'REGIONAL'),
('여수해양경찰서', '여수서', 'STATION'),
('서귀포해양경찰서', '서귀포서', 'STATION'),
('제주해양경찰서', '제주서', 'STATION');
UPDATE AUTH_ORG SET UPPER_ORG_SN = 1 WHERE ORG_SN IN (2, 3);
UPDATE AUTH_ORG SET UPPER_ORG_SN = 2 WHERE ORG_SN = 4;
UPDATE AUTH_ORG SET UPPER_ORG_SN = 3 WHERE ORG_SN IN (5, 6);
-- ============================================================
-- 13. 초기 데이터: 관리자 계정 (admin / admin1234)
-- ============================================================
INSERT INTO AUTH_USER (USER_ACNT, PSWD_HASH, USER_NM, RNKP_NM, ORG_SN, USER_STTS_CD)
VALUES ('admin', crypt('admin1234', gen_salt('bf', 10)), '관리자', '경정', 1, 'ACTIVE');
-- admin 사용자에 ADMIN 역할 할당
INSERT INTO AUTH_USER_ROLE (USER_ID, ROLE_SN)
SELECT USER_ID, 1 FROM AUTH_USER WHERE USER_ACNT = 'admin';
-- ============================================================
-- 14. 초기 데이터: 시스템 설정
-- ============================================================
INSERT INTO AUTH_SETTING (SETTING_KEY, SETTING_VAL, SETTING_DC) VALUES
('registration.auto-approve', 'true', '신규 사용자 자동 승인 여부 (true: 즉시 ACTIVE, false: PENDING 대기)'),
('registration.default-role', 'true', '신규 사용자에게 기본 역할(DFLT_YN=Y) 자동 할당 여부');
-- ============================================================
-- 15. 권한 부여
-- ============================================================
GRANT ALL ON ALL TABLES IN SCHEMA public TO wing_auth;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO wing_auth;
-- ============================================================
-- 데이터베이스 코멘트
-- ============================================================
COMMENT ON DATABASE wing_auth IS 'WING 인증 시스템 - 사용자 인증, 역할, 권한 관리';