-- 공통코드. 진행단계·처리결과·공공누리유형 같은 선택지를 소스가 아니라 데이터로 관리한다.
--
-- 저장값(code)은 지금 각 업무 테이블에 들어 있는 한글 문자열을 그대로 쓴다. 영문 코드키로
-- 바꾸면 기존 데이터를 전부 변환해야 하고 엑셀 업로드/다운로드 양식까지 손봐야 해서,
-- 위험 대비 실익이 없다. 진행단계만 예외로 숫자 문자열이며 organization.stage는 smallint 유지.

create table code_group (
    group_id   varchar(50)  primary key,
    group_name varchar(100) not null,
    description text,
    -- 관리 화면에서 코드 추가·삭제를 허용할지. 로직과 강하게 묶인 그룹(STAGE 등)은 false로 두고
    -- 표시명·순서만 바꾸게 한다. 단계 추가는 마이그레이션으로 한다.
    editable   boolean      not null default true
);

create table code (
    group_id   varchar(50)  not null references code_group(group_id),
    -- 저장값. review_item.review_minor가 varchar(300)이라 그 길이에 맞춘다.
    code       varchar(300) not null,
    -- 화면 표시명. 저장값과 다를 수 있다 - 권리확인 세부항목은 저장값이
    -- '2. 후천적 권리 전부 보유(계약서 확인 필요)'인데 화면에는 짧은 형태로 나온다.
    label      varchar(200) not null,
    sort_order int          not null,
    active     boolean      not null default true,
    -- 코드별 부가 속성. 값만 담고 동작은 담지 않는다 - 동작까지 밀어넣으면
    -- DB 안에 규칙 언어를 새로 만드는 꼴이 되어 오히려 읽기 어려워진다.
    attrs      jsonb        not null default '{}'::jsonb,
    primary key (group_id, code)
);

create index idx_code_group_sort on code (group_id, sort_order);


-- ============================================================
-- 시드
-- ============================================================

insert into code_group (group_id, group_name, description, editable) values
 ('STAGE',           '진행단계',       'organization.stage에 번호로 저장. 단계 추가는 마이그레이션으로 한다', false),
 ('STAGE_GROUP',     '업무구간',       '칸반 컬럼 색과 카드 모양을 결정한다', false),
 ('REVIEW_MAJOR',    '권리확인 대분류', null, true),
 ('REVIEW_MINOR',    '권리확인 세부',   '제3자 권리를 골랐을 때만 노출된다', true),
 ('REVIEW_RESULT',   '권리확인 처리결과', null, true),
 ('KOGL_TYPE',       '공공누리 유형',   'scopes로 사용처를 구분한다', true),
 ('PROCESS_STATUS',  '권리처리 상태',   null, false),
 ('CONTRACT_DOC',    '계약 서류',       null, true),
 ('CONTACT_METHOD',  '연락 방법',       null, true),
 ('CONTACT_CATEGORY','담당자 구분',     null, false),
 ('ATTACHMENT_YN',   '첨부파일 여부',   null, false),
 ('KOGL_ATTACHED',   '기존 공공누리 부착 여부', null, false);

-- 진행단계. progress는 대시보드 진행상태 필터(신청/진행중/완료)를,
-- kpiFrom은 "이 단계부터 해당 KPI에 집계"라는 임계값을 뜻한다.
-- 원문자(①②)는 저장하지 않는다 - 단계 번호에서 계산한다.
insert into code (group_id, code, label, sort_order, attrs) values
 ('STAGE','1', '신청',                    1, '{"groupKey":"intake","progress":"applied"}'::jsonb),
 ('STAGE','2', '목록접수',                2, '{"groupKey":"intake","progress":"active","kpiFrom":"docSubmitted"}'::jsonb),
 ('STAGE','3', '예비검토',                3, '{"groupKey":"intake","progress":"active"}'::jsonb),
 ('STAGE','4', '변호사 배당',             4, '{"groupKey":"assign","progress":"active"}'::jsonb),
 ('STAGE','5', '법률검토(권리확인)',      5, '{"groupKey":"check","progress":"active"}'::jsonb),
 ('STAGE','6', 'RE:확인',                 6, '{"groupKey":"check","progress":"active"}'::jsonb),
 ('STAGE','7', '법률검토(권리확인) 완료', 7, '{"groupKey":"check","progress":"active"}'::jsonb),
 ('STAGE','8', '법률검토(권리처리)',      8, '{"groupKey":"process","progress":"active"}'::jsonb),
 ('STAGE','9', 'RE:처리',                 9, '{"groupKey":"process","progress":"active"}'::jsonb),
 ('STAGE','10','법률검토(권리처리) 완료',10, '{"groupKey":"process","progress":"active"}'::jsonb),
 ('STAGE','11','법률검토 최종완료',      11, '{"groupKey":"closing","progress":"active"}'::jsonb),
 ('STAGE','12','보고서 작성',            12, '{"groupKey":"closing","progress":"active","kpiFrom":"reportWriting"}'::jsonb),
 ('STAGE','13','보고서 제출 완료',       13, '{"groupKey":"closing","progress":"done","kpiFrom":"completed"}'::jsonb);

-- 업무구간. tone은 의미 토큰이며 실제 CSS 클래스는 프론트가 갖는다 - DB에 Tailwind 클래스를
-- 넣으면 화면 스타일을 바꿀 때마다 DB를 고쳐야 한다.
-- cardBody는 칸반 카드에 진척 막대를 몇 줄 그릴지를 뜻한다.
insert into code (group_id, code, label, sort_order, attrs) values
 ('STAGE_GROUP','intake', '접수',    1, '{"tone":"slate","cardBody":"plain"}'::jsonb),
 ('STAGE_GROUP','assign', '배당',    2, '{"tone":"violet","cardBody":"assign"}'::jsonb),
 ('STAGE_GROUP','check',  '권리확인',3, '{"tone":"sky","cardBody":"review1"}'::jsonb),
 ('STAGE_GROUP','process','권리처리',4, '{"tone":"amber","cardBody":"review2"}'::jsonb),
 ('STAGE_GROUP','closing','마감',    5, '{"tone":"emerald","cardBody":"plain"}'::jsonb);

-- 권리확인 대분류. suggest는 이 대분류를 고르면 자동으로 채워줄 처리결과,
-- hasMinor는 세부항목을 노출할지를 뜻한다(제3자 권리에서만 세부가 나온다).
insert into code (group_id, code, label, sort_order, attrs) values
 ('REVIEW_MAJOR','만료 저작물',  '만료 저작물',  1, '{"suggest":"신유형 개방","hasMinor":false}'::jsonb),
 ('REVIEW_MAJOR','업무상 저작물','업무상 저작물',2, '{"suggest":"신유형 개방","hasMinor":false}'::jsonb),
 ('REVIEW_MAJOR','제3자 권리',   '제3자 권리',   3, '{"hasMinor":true}'::jsonb),
 ('REVIEW_MAJOR','개인정보 포함','개인정보 포함',4, '{"suggest":"개방불가","hasMinor":false}'::jsonb);

-- 권리확인 세부. code는 저장값 원문이고 label은 화면 표시용(짧은 형태)이다.
-- note는 라벨 아래 회색 부연설명, allowed는 고를 수 있는 처리결과 제한이다
-- (2026-07-20 정책변경: 3·4번은 추진/미희망 택일, 초상권은 개방불가까지 3택).
insert into code (group_id, code, label, sort_order, attrs) values
 ('REVIEW_MINOR','1. 원시적 권리 전부 보유','1. 원시적 권리 전부 보유',1,
   '{"suggest":"신유형 개방"}'::jsonb),
 ('REVIEW_MINOR','2. 후천적 권리 전부 보유(계약서 확인 필요)','2. 후천적 권리 전부 보유',2,
   '{"note":"(계약에 의한 전부 양수)","suggest":"계약서 등 재확인"}'::jsonb),
 ('REVIEW_MINOR','3. 권리 일부(공동) 보유','3. 권리 일부(공동) 보유',3,
   '{"note":"(보도자료·제3자저작물, 계약에 의한 전부/공동 보유 등)","suggest":"권리처리 추진","allowed":["권리처리 추진","권리처리 추진 미희망"]}'::jsonb),
 ('REVIEW_MINOR','4. 권리 미보유','4. 권리 미보유',4,
   '{"note":"(공모전 수상작 등)","suggest":"권리처리 추진","allowed":["권리처리 추진","권리처리 추진 미희망"]}'::jsonb),
 ('REVIEW_MINOR','초상권 포함','초상권 포함',5,
   '{"suggest":"권리처리 추진","allowed":["권리처리 추진","권리처리 추진 미희망","개방불가"]}'::jsonb);

-- 권리확인 처리결과. needsProcessing/koglSet은 값이고, 실제로 폼을 어떻게 채울지는 코드가 정한다.
-- koglCopiesPrior가 참이면 기존 부착 유형을 복사하고 비고에 안내문구를 덧붙인다 - 이 "동작"까지
-- 데이터로 옮기면 attrs 안에 규칙 언어를 만들게 되므로 코드에 남긴다.
insert into code (group_id, code, label, sort_order, attrs) values
 ('REVIEW_RESULT','신유형 개방',         '신유형 개방',         1,'{"tone":"emerald","openable":"Y"}'::jsonb),
 ('REVIEW_RESULT','계약서 등 재확인',    '계약서 등 재확인',    2,'{"tone":"amber"}'::jsonb),
 ('REVIEW_RESULT','권리처리 추진',       '권리처리 추진',       3,'{"tone":"blue","needsProcessing":true,"koglSet":"보류"}'::jsonb),
 ('REVIEW_RESULT','개방불가',            '개방불가',            4,'{"tone":"red","needsProcessing":false,"koglSet":"개방불가"}'::jsonb),
 ('REVIEW_RESULT','권리처리 추진 미희망','권리처리 추진 미희망',5,'{"tone":"slate","needsProcessing":false,"koglCopiesPrior":true}'::jsonb);

-- 공공누리 유형. 세 화면의 목록이 서로 달랐던 이유는 쓰이는 자리가 달라서다.
--   review  = 변호사 판정값 / process = 권리처리 판정값 / prior = 기존에 부착돼 있던 유형
-- 이 구분 없이 하나로 합치면 권리처리 화면에 '보류'가 잘못 노출된다.
-- firstRow는 라디오 첫 줄에 놓을 자리를 뜻한다.
insert into code (group_id, code, label, sort_order, attrs) values
 ('KOGL_TYPE','0유형',   '0유형',   1,'{"scopes":["review","process","prior"],"firstRow":["review","process"]}'::jsonb),
 ('KOGL_TYPE','1유형',   '1유형',   2,'{"scopes":["review","process","prior"],"firstRow":[]}'::jsonb),
 ('KOGL_TYPE','2유형',   '2유형',   3,'{"scopes":["review","process","prior"],"firstRow":[]}'::jsonb),
 ('KOGL_TYPE','3유형',   '3유형',   4,'{"scopes":["review","process","prior"],"firstRow":[]}'::jsonb),
 ('KOGL_TYPE','4유형',   '4유형',   5,'{"scopes":["review","process","prior"],"firstRow":[]}'::jsonb),
 ('KOGL_TYPE','개방불가','개방불가',6,'{"scopes":["review","process"],"firstRow":["review","process"]}'::jsonb),
 ('KOGL_TYPE','보류',    '보류',    7,'{"scopes":["review"],"firstRow":["review"]}'::jsonb);

insert into code (group_id, code, label, sort_order, attrs) values
 ('PROCESS_STATUS','미처리',  '미처리',  1,'{"done":false}'::jsonb),
 ('PROCESS_STATUS','처리완료','처리완료',2,'{"done":true,"stampsProcessedAt":true}'::jsonb);

-- freeText가 참인 코드는 '기타:자유텍스트' 형태로 직렬화된다(직렬화 규칙 자체는 코드).
insert into code (group_id, code, label, sort_order, attrs) values
 ('CONTRACT_DOC','양도계약서',    '양도계약서',    1,'{}'::jsonb),
 ('CONTRACT_DOC','제안요청서',    '제안요청서',    2,'{}'::jsonb),
 ('CONTRACT_DOC','초상이용동의서','초상이용동의서',3,'{}'::jsonb),
 ('CONTRACT_DOC','공공누리동의서','공공누리동의서',4,'{}'::jsonb),
 ('CONTRACT_DOC','공문',          '공문',          5,'{}'::jsonb),
 ('CONTRACT_DOC','기타',          '기타',          6,'{"freeText":true}'::jsonb);

-- 요구사항 [24]는 미응답이라 현행 4종을 그대로 옮긴다. 답이 오면 데이터만 바꾸면 된다.
-- 지금까지 서버 검증이 없어 아무 값이나 저장됐는데, 코드테이블 도입으로 검증도 생긴다.
insert into code (group_id, code, label, sort_order, attrs) values
 ('CONTACT_METHOD','전화','전화',1,'{}'::jsonb),
 ('CONTACT_METHOD','메일','메일',2,'{}'::jsonb),
 ('CONTACT_METHOD','방문','방문',3,'{}'::jsonb),
 ('CONTACT_METHOD','기타','기타',4,'{}'::jsonb);

-- importAlias는 담당자 명부 엑셀의 한글 구분값이다(MemberDirectoryParser가 쓰던 매핑).
insert into code (group_id, code, label, sort_order, attrs) values
 ('CONTACT_CATEGORY','APPLICANT','신청기관',       1,'{"tone":"sky","importAlias":"신청기관"}'::jsonb),
 ('CONTACT_CATEGORY','MJ',       '주관기관',       2,'{"tone":"violet","importAlias":"주관기관"}'::jsonb),
 ('CONTACT_CATEGORY','LAWYER',   '변호사',         3,'{"tone":"emerald","importAlias":"변호사"}'::jsonb),
 ('CONTACT_CATEGORY','OPERATOR', '수행기관',       4,'{"tone":"amber","importAlias":"수행기관"}'::jsonb),
 ('CONTACT_CATEGORY','ITN',      '아이티앤 담당자',5,'{"tone":"slate","importAlias":"아이티앤 담당자"}'::jsonb);

insert into code (group_id, code, label, sort_order, attrs) values
 ('ATTACHMENT_YN','있음','있음',1,'{}'::jsonb),
 ('ATTACHMENT_YN','없음','없음',2,'{}'::jsonb),
 ('KOGL_ATTACHED','부착',  '부착',  1,'{}'::jsonb),
 ('KOGL_ATTACHED','미부착','미부착',2,'{}'::jsonb);
