-- WING-OPS Database Schema: Auth Tables -- auth 스키마 9개 테이블 (인증/인가/감사) -- ============================================================ -- 1. auth_role — 역할 (FK 없음, 최상위) -- ============================================================ CREATE TABLE auth.auth_role ( role_sn integer NOT NULL, role_cd character varying(20) NOT NULL, role_nm character varying(50) NOT NULL, role_dc character varying(200), dflt_yn character(1) DEFAULT 'N'::bpchar NOT NULL, reg_dtm timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT pk_auth_role PRIMARY KEY (role_sn), CONSTRAINT uk_auth_role_cd UNIQUE (role_cd), CONSTRAINT ck_auth_role_dflt CHECK ((dflt_yn = ANY (ARRAY['Y'::bpchar, 'N'::bpchar]))) ); CREATE SEQUENCE auth.auth_role_role_sn_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE auth.auth_role_role_sn_seq OWNED BY auth.auth_role.role_sn; ALTER TABLE ONLY auth.auth_role ALTER COLUMN role_sn SET DEFAULT nextval('auth.auth_role_role_sn_seq'::regclass); -- ============================================================ -- 2. auth_org — 조직 (자기참조 FK) -- ============================================================ CREATE TABLE auth.auth_org ( org_sn integer NOT NULL, org_nm character varying(100) NOT NULL, org_abbr_nm character varying(20) NOT NULL, org_tp_cd character varying(20) NOT NULL, upper_org_sn integer, reg_dtm timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT pk_auth_org PRIMARY KEY (org_sn) ); CREATE SEQUENCE auth.auth_org_org_sn_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE auth.auth_org_org_sn_seq OWNED BY auth.auth_org.org_sn; ALTER TABLE ONLY auth.auth_org ALTER COLUMN org_sn SET DEFAULT nextval('auth.auth_org_org_sn_seq'::regclass); -- ============================================================ -- 3. auth_user — 사용자 (FK: auth_org) -- ============================================================ CREATE TABLE auth.auth_user ( user_id uuid DEFAULT public.uuid_generate_v4() NOT NULL, user_acnt character varying(50) NOT NULL, pswd_hash character varying(255), user_nm character varying(50) NOT NULL, rnkp_nm character varying(30), org_sn integer, user_stts_cd character varying(20) DEFAULT 'ACTIVE'::character varying NOT NULL, fail_cnt integer DEFAULT 0 NOT NULL, last_login_dtm timestamp with time zone, reg_dtm timestamp with time zone DEFAULT now() NOT NULL, mdfcn_dtm timestamp with time zone DEFAULT now() NOT NULL, oauth_provider character varying(20), oauth_sub character varying(255), email character varying(255), CONSTRAINT pk_auth_user PRIMARY KEY (user_id), CONSTRAINT uk_auth_user_acnt UNIQUE (user_acnt), CONSTRAINT ck_auth_user_stts CHECK (((user_stts_cd)::text = ANY (ARRAY[('ACTIVE'::character varying)::text, ('LOCKED'::character varying)::text, ('INACTIVE'::character varying)::text]))) ); -- 조건부 유니크 인덱스 (NULL 값 제외) CREATE UNIQUE INDEX uk_auth_user_email ON auth.auth_user USING btree (email) WHERE (email IS NOT NULL); CREATE UNIQUE INDEX uk_auth_user_oauth ON auth.auth_user USING btree (oauth_provider, oauth_sub) WHERE (oauth_provider IS NOT NULL); -- ============================================================ -- 4. auth_user_role — 사용자-역할 매핑 (FK: auth_user, auth_role) -- ============================================================ CREATE TABLE auth.auth_user_role ( user_id uuid NOT NULL, role_sn integer NOT NULL, reg_dtm timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT pk_auth_user_role PRIMARY KEY (user_id, role_sn) ); -- ============================================================ -- 5. auth_perm_tree — 권한 트리 (자기참조 FK) -- ============================================================ CREATE TABLE auth.auth_perm_tree ( rsrc_cd character varying(50) NOT NULL, parent_cd character varying(50), rsrc_nm character varying(100) NOT NULL, rsrc_desc character varying(200), icon character varying(20), rsrc_level smallint DEFAULT 0 NOT NULL, sort_ord smallint DEFAULT 0 NOT NULL, use_yn character(1) DEFAULT 'Y'::bpchar NOT NULL, CONSTRAINT pk_perm_tree PRIMARY KEY (rsrc_cd) ); -- ============================================================ -- 6. auth_perm — 역할별 권한 (FK: auth_role) -- ============================================================ CREATE TABLE auth.auth_perm ( perm_sn integer NOT NULL, role_sn integer NOT NULL, rsrc_cd character varying(50) NOT NULL, grant_yn character(1) DEFAULT 'Y'::bpchar NOT NULL, reg_dtm timestamp with time zone DEFAULT now() NOT NULL, oper_cd character varying(20) NOT NULL, CONSTRAINT pk_auth_perm PRIMARY KEY (perm_sn), CONSTRAINT uk_auth_perm UNIQUE (role_sn, rsrc_cd, oper_cd), CONSTRAINT ck_auth_perm_grant CHECK ((grant_yn = ANY (ARRAY['Y'::bpchar, 'N'::bpchar]))), CONSTRAINT ck_auth_perm_oper CHECK (((oper_cd)::text = ANY (ARRAY[('READ'::character varying)::text, ('CREATE'::character varying)::text, ('UPDATE'::character varying)::text, ('DELETE'::character varying)::text, ('MANAGE'::character varying)::text, ('EXPORT'::character varying)::text]))) ); CREATE SEQUENCE auth.auth_perm_perm_sn_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE auth.auth_perm_perm_sn_seq OWNED BY auth.auth_perm.perm_sn; ALTER TABLE ONLY auth.auth_perm ALTER COLUMN perm_sn SET DEFAULT nextval('auth.auth_perm_perm_sn_seq'::regclass); -- ============================================================ -- 7. auth_setting — 시스템 설정 -- ============================================================ CREATE TABLE auth.auth_setting ( setting_key character varying(100) NOT NULL, setting_val text NOT NULL, setting_dc character varying(500), mdfcn_dtm timestamp without time zone DEFAULT now(), CONSTRAINT auth_setting_pkey PRIMARY KEY (setting_key) ); -- ============================================================ -- 8. auth_login_hist — 로그인 이력 (FK: auth_user) -- ============================================================ CREATE TABLE auth.auth_login_hist ( hist_sn integer NOT NULL, user_id uuid NOT NULL, login_dtm timestamp with time zone DEFAULT now() NOT NULL, ip_addr character varying(45), user_agent character varying(500), success_yn character(1) DEFAULT 'Y'::bpchar NOT NULL, CONSTRAINT pk_auth_login_hist PRIMARY KEY (hist_sn), CONSTRAINT ck_alh_success CHECK ((success_yn = ANY (ARRAY['Y'::bpchar, 'N'::bpchar]))) ); CREATE SEQUENCE auth.auth_login_hist_hist_sn_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE auth.auth_login_hist_hist_sn_seq OWNED BY auth.auth_login_hist.hist_sn; ALTER TABLE ONLY auth.auth_login_hist ALTER COLUMN hist_sn SET DEFAULT nextval('auth.auth_login_hist_hist_sn_seq'::regclass); -- ============================================================ -- 9. auth_audit_log — 감사 로그 -- ============================================================ CREATE TABLE auth.auth_audit_log ( log_sn integer NOT NULL, user_id uuid, action_cd character varying(30) NOT NULL, action_dtl character varying(100), http_method character varying(10), crud_type character varying(10), req_url character varying(500), req_dtm timestamp with time zone DEFAULT now() NOT NULL, res_dtm timestamp with time zone, res_status smallint, res_size integer, ip_addr character varying(45), user_agent character varying(500), extra jsonb, CONSTRAINT pk_auth_audit_log PRIMARY KEY (log_sn) ); CREATE SEQUENCE auth.auth_audit_log_log_sn_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE auth.auth_audit_log_log_sn_seq OWNED BY auth.auth_audit_log.log_sn; ALTER TABLE ONLY auth.auth_audit_log ALTER COLUMN log_sn SET DEFAULT nextval('auth.auth_audit_log_log_sn_seq'::regclass); -- ============================================================ -- FK 제약조건 -- ============================================================ ALTER TABLE ONLY auth.auth_org ADD CONSTRAINT fk_auth_org_upper FOREIGN KEY (upper_org_sn) REFERENCES auth.auth_org(org_sn); ALTER TABLE ONLY auth.auth_user ADD CONSTRAINT fk_auth_user_org FOREIGN KEY (org_sn) REFERENCES auth.auth_org(org_sn); ALTER TABLE ONLY auth.auth_user_role ADD CONSTRAINT fk_aur_user FOREIGN KEY (user_id) REFERENCES auth.auth_user(user_id) ON DELETE CASCADE; ALTER TABLE ONLY auth.auth_user_role ADD CONSTRAINT fk_aur_role FOREIGN KEY (role_sn) REFERENCES auth.auth_role(role_sn) ON DELETE CASCADE; ALTER TABLE ONLY auth.auth_perm_tree ADD CONSTRAINT fk_perm_tree_parent FOREIGN KEY (parent_cd) REFERENCES auth.auth_perm_tree(rsrc_cd); ALTER TABLE ONLY auth.auth_perm ADD CONSTRAINT fk_ap_role FOREIGN KEY (role_sn) REFERENCES auth.auth_role(role_sn) ON DELETE CASCADE; ALTER TABLE ONLY auth.auth_login_hist ADD CONSTRAINT fk_alh_user FOREIGN KEY (user_id) REFERENCES auth.auth_user(user_id) ON DELETE CASCADE; -- ============================================================ -- 인덱스 -- ============================================================ CREATE INDEX idx_auth_user_org ON auth.auth_user USING btree (org_sn); CREATE INDEX idx_auth_user_stts ON auth.auth_user USING btree (user_stts_cd); CREATE INDEX idx_auth_perm_role ON auth.auth_perm USING btree (role_sn); CREATE INDEX idx_auth_perm_rsrc ON auth.auth_perm USING btree (rsrc_cd); CREATE INDEX idx_auth_perm_oper ON auth.auth_perm USING btree (oper_cd); CREATE INDEX idx_perm_tree_parent ON auth.auth_perm_tree USING btree (parent_cd); CREATE INDEX idx_auth_login_user ON auth.auth_login_hist USING btree (user_id); CREATE INDEX idx_auth_login_dtm ON auth.auth_login_hist USING btree (login_dtm); CREATE INDEX idx_audit_log_user ON auth.auth_audit_log USING btree (user_id); CREATE INDEX idx_audit_log_action ON auth.auth_audit_log USING btree (action_cd); CREATE INDEX idx_audit_log_dtm ON auth.auth_audit_log USING btree (req_dtm);