File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
-- 공통코드. 진행단계·처리결과·공공누리유형 같은 선택지를 소스가 아니라 데이터로 관리한다.
--
-- 저장값(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);