Skip to content

포탈별 도메인 기능 개발·운영 가이드 ​

적용 범위: Process Center, Guide Portal, ARISAM 등 Portal Foundation 공통 기반을 사용하는 모든 포탈의 공통 UI 이외 업무 기능입니다.

이 문서는 포탈별 업무 화면과 도메인 로직을 독립적으로 개발하면서도, DirectoryService 중심의 인증·보안·운영 정책을 일관되게 유지하기 위한 필수 기준을 정의합니다.

1. 기본 원칙 ​

포탈마다 업무 도메인은 독립적으로 설계합니다. 예를 들어 Process Center의 프로세스·결재·전결규정, Guide Portal의 매뉴얼·번역 검토, ARISAM의 문서·아카이브 규칙은 각 포탈의 서버와 데이터베이스에 남깁니다. 반면 사용자·조직·권한·전문용어·암호화 상위키·운영 UI는 중앙 또는 공통 패키지를 통해 사용합니다.

구분공통 기반에 둬야 하는 것포탈 도메인에 둬야 하는 것
사용자·조직DirectoryService 조회·동기화·상태 보고도메인별 책임자·담당 조직 매핑
인증·권한중앙 로그인, 세션 검증, scope·관리자 판정기능별 권한 조합과 업무 승인 규칙
번역중앙 전문용어 조회, 캐시·폴백 정책포탈 콘텐츠 유형별 번역 흐름과 검토 절차
데이터암호화 어댑터, 감사 이벤트 형식포탈 고유 테이블·도메인 이벤트·보존 기간
UIPortalFrame, 상태·운영 컴포넌트, 테마업무 편집기, 다이어그램, 특화 폼과 목록
운영헬스 체크, 관측 이벤트, 작업 상태 계약포탈별 SLO·업무 지표·알림 수신 대상

업무 기능을 만들 때는 먼저 다음 질문에 답해야 합니다.

  1. 이 기능이 다른 포탈에도 동일한 정책으로 필요할 가능성이 있는가?
  2. DirectoryService의 사용자·조직·권한·용어 데이터에 의존하는가?
  3. 개인정보, 인증 정보, 비밀값 또는 감사가 필요한 변경을 다루는가?
  4. 처리 시간이 길거나 재시도가 필요한가?
  5. 실패했을 때 관리자에게 보일 상태·조치가 필요한가?

첫 번째 질문만 예라면 공통 패키지 확장 후보입니다. 나머지 질문 중 하나라도 예라면 이 문서의 보안·운영 규칙을 반드시 적용합니다.

2. 패키지 사용 기준 ​

포탈별 서버는 아래 패키지를 업무 로직의 기반으로 사용합니다. 각 패키지는 업무 규칙을 구현하지 않고, 재사용 가능한 계약과 안전장치만 제공합니다.

패키지사용 목적도메인 기능에서의 사용 예
@hohyun94/portal-foundation공통 관리자 프레임과 운영 UI관리자 화면의 PortalFrame, 상태 배지, 운영 섹션
@hohyun94/directory-syncDirectoryService 동기화, 전문용어 조회, 캐시·폴백사용자·조직 동기화, 번역 전 사전 조회
@hohyun94/portal-securityscope 검증, 서명 세션, 감사 이벤트, 암호화 어댑터관리자 권한 판정, 감사 로그, 상위키 암호화 연결
@hohyun94/portal-operations파일 검증, 알림 중복 방지, 비동기 작업 전이문서 업로드, 동기화 실패 알림, 장기 작업 재시도
@hohyun94/portal-runtime검색 파라미터, 기능 플래그, 헬스 체크, 관측 이벤트목록 API, 점진 배포, /health, 구조화 로그

포탈별 기능은 공통 패키지 내부 파일을 직접 import하지 않습니다. 반드시 패키지의 공개 export만 사용합니다. 이 원칙은 내부 구현 교체, 보안 패치, 버전 호환성 검증을 가능하게 합니다.

ts
// 허용: 공개 API 사용
import { createResilientGlossaryRuntime } from "@hohyun94/directory-sync";
import { hasAllScopes, createAuditEvent } from "@hohyun94/portal-security";

// 금지: 패키지 내부 경로 의존
// import { ... } from "@hohyun94/directory-sync/dist/glossaryRuntime.js";

3. 포탈별 도메인 아키텍처 ​

각 신규 기능은 화면 → API 라우터 → 도메인 서비스 → 저장소 계층을 따릅니다. 라우터에는 인증·입력 검증·응답 변환만 두고, 업무 규칙은 서비스에, SQL/ORM 접근은 저장소에 둡니다. React 컴포넌트에서 DB 구조나 DirectoryService 호출 세부사항을 직접 알아서는 안 됩니다.

계층책임금지 사항
화면사용자 입력, 상태 표현, 공통 UI 조합비밀값 보관, DB 직접 접근, 권한 우회
API 라우터세션 확인, scope 확인, 입력 형식 검증복잡한 트랜잭션·업무 규칙 혼합
도메인 서비스업무 규칙, 트랜잭션 경계, 상태 전이HTTP 객체·React 상태 의존
저장소조회·저장·잠금·정렬권한 판정·화면 메시지 생성
공통 어댑터DirectoryService, 암호화, 파일·알림·관측성포탈 고유 업무 규칙 포함

도메인 엔티티는 안정적인 식별자, 상태값, 생성·수정 시각, 버전 또는 낙관적 잠금 값을 원칙적으로 갖습니다. 상태가 있는 엔티티는 가능한 상태 전이만 서비스에서 강제해야 합니다. 화면에서 버튼을 숨기는 것만으로는 권한·상태 통제가 되지 않습니다.

4. 사용자·조직·권한 규칙 ​

사용자와 조직의 원장은 DirectoryService입니다. 포탈은 자신의 업무에 필요한 최소 데이터를 암호화된 로컬 저장소에 동기화하거나, 실시간 조회 계약을 사용합니다. 포탈이 사용자 이름, 이메일, 조직명 등을 독자적으로 원장처럼 수정해서는 안 됩니다.

  1. 사용자·조직 표시에는 DirectoryService 식별자와 동기화된 로컬 사본을 사용합니다.
  2. 도메인 책임자·담당 조직 매핑에는 사용자 ID·조직 코드를 저장하고, 표시명은 동기화 데이터에서 읽습니다.
  3. 포탈 관리자 여부와 API 접근은 중앙 세션 claim 및 scope를 검증합니다.
  4. 화면의 메뉴 노출은 보조 수단일 뿐이며, 모든 변경 API에서 서버 측 권한 검사를 다시 수행합니다.
  5. 한 포탈에서만 의미가 있는 역할은 포탈 도메인 역할로 관리하되, 중앙 사용자 식별자와 연결합니다.
ts
if (!hasAllScopes(principal, "directory:read")) {
  throw new Error("권한이 없습니다.");
}

// 도메인별 추가 규칙은 별도로 적용한다.
if (!canManageApprovalRule(principal, approvalRule)) {
  throw new Error("전결규정 변경 권한이 없습니다.");
}

5. 전문용어·LLM 번역 규칙 ​

전문용어 사전은 DirectoryService가 관리하는 중앙 원장입니다. 포탈은 사전 전체를 장기 복제하지 않으며, @hohyun94/directory-sync의 복원력 있는 런타임을 사용합니다.

순서필수 처리
1원본·대상 언어로 중앙 사전을 조회한다.
2정상 캐시, ETag 재검증, 마지막 정상 사전, 필수 정적 용어 순으로 폴백한다.
3긴 용어와 높은 우선순위 용어를 먼저 적용한다.
4LLM에는 용어가 확정된 문장 또는 변경 불가 용어 목록을 전달한다.
5결과에서 필수 용어 보존 여부를 검증하고, 불일치 시 검토 대기열로 보낸다.

DirectoryService가 일시적으로 불가하더라도 일반 번역을 즉시 중단하지 않습니다. 다만 마지막 정상 사전의 사용 시각이 최대 허용 기간을 넘겼거나 필수 정적 용어도 없는 경우에는 번역 결과를 검토 필요 상태로 저장해야 합니다. 관리자에게는 정상, 캐시 사용, 정적 폴백, 사전 사용 불가를 명확히 표시합니다.

6. 데이터·암호화·감사 규칙 ​

포탈은 자체 마스터키를 새로 만들거나 소스코드·DB에 저장해서는 안 됩니다. 암호화가 필요한 필드는 DirectoryService를 상위키 제공자로 하는 Envelope Encryption 어댑터를 통해 처리합니다. 암호화 문맥은 portal:entity:id:field처럼 안정적이고 재현 가능한 형식으로 설계합니다.

데이터 유형저장 규칙감사 규칙
사용자 PII암호화 저장, 필요한 경우 blind index 사용이메일·전화·주소 원문을 남기지 않음
API 키·토큰·쿠키비밀 저장소 또는 암호화 envelope만 저장항상 [REDACTED] 처리
관리자 변경변경 전·후 스냅샷을 마스킹 후 저장actor, action, entity, 결과, 상관관계 ID 기록
일반 업무 데이터도메인 보존 정책에 따라 저장민감 필드만 마스킹

모든 관리자 변경은 createAuditEvent와 같은 공통 형식을 사용합니다. 감사 로그에는 원문 암호·세션·토큰·키·쿠키를 절대 넣지 않습니다. 대량 변경은 하나의 상관관계 ID를 공유하여 사후 추적할 수 있어야 합니다.

7. 파일 업로드 규칙 ​

파일 업로드는 파일명만 믿지 않습니다. 서버에서 용량, 허용 확장자, MIME 타입, 지원 가능한 형식의 magic number를 함께 검사해야 합니다. 업로드 후 저장 경로는 사용자 입력 파일명을 경로에 포함하지 않고 createSafeObjectKey로 생성합니다.

  1. 허용 형식과 최대 용량은 기능별 정책으로 명시합니다.
  2. 경로 탐색 문자열, 제어문자, 이중 확장자를 포함한 파일명은 표시용으로만 사용합니다.
  3. 객체 저장소 키는 포탈·엔티티·날짜·무작위 식별자로 생성합니다.
  4. 다운로드는 직접 public URL 대신 시간 제한 서명 URL 또는 권한 확인 API를 사용합니다.
  5. 바이러스 검사나 문서 변환이 필요하면 업로드 요청 안에서 수행하지 않고 비동기 작업으로 분리합니다.

8. 비동기 작업·알림 규칙 ​

동기화, 대량 번역, 문서 변환, 대량 알림처럼 오래 걸리는 업무는 HTTP 요청에서 끝까지 처리하지 않습니다. 도메인 DB에 작업 레코드를 만들고 QUEUED → RUNNING → SUCCEEDED/FAILED/CANCELLED 상태 전이를 사용합니다.

재시도는 오류 원인을 저장하고 지수 backoff를 적용합니다. 재시도 한도를 넘기면 FAILED 상태로 두고 관리자 조치가 가능해야 합니다. 작업 재실행 API는 idempotency key 또는 도메인 식별자를 사용해 중복 실행을 막아야 합니다.

알림은 포탈·수신자·업무 이벤트를 결합한 dedupeKey를 둡니다. 동일한 동기화 실패나 동일한 검토 요청을 반복 발송하지 않습니다. 알림 전송 채널이 실패하더라도 업무 트랜잭션 자체를 되돌리지 말고, 알림 작업을 실패·재시도 가능한 별도 상태로 관리합니다.

9. 검색·목록·기능 플래그 규칙 ​

목록 API는 normalizeSearchQuery로 검색어, 페이지, 페이지 크기, 정렬 키를 정규화합니다. 클라이언트가 전달한 정렬 필드를 그대로 SQL에 붙이면 안 됩니다. 기능별 허용 정렬 키 목록을 서버에서 선언합니다.

신규 기능은 전 포탈·전 사용자에게 즉시 노출하지 않고 기능 플래그를 사용합니다. 플래그는 다음 순서로 평가합니다.

  1. 기능 자체가 비활성인지 확인합니다.
  2. 대상 포탈 제한이 있는지 확인합니다.
  3. 명시적 허용 사용자 목록이 있는지 확인합니다.
  4. 점진 배포 비율이 있으면 포탈·사용자·플래그 키 기반의 안정적 hash로 판정합니다.

플래그는 보안 권한을 대체하지 않습니다. 플래그가 켜져 있더라도 API 권한과 도메인 상태 검증은 항상 수행해야 합니다.

10. 관측성·헬스 체크·장애 대응 규칙 ​

각 포탈은 중앙 연동 상태, DB, 객체 저장소, 비동기 작업, 번역 사전 캐시 상태를 헬스 체크에 포함합니다. 외부 시스템 장애가 포탈 전체 장애로 번지지 않도록 타임아웃, 재시도, 회로 차단, 마지막 정상값 폴백을 적용합니다.

구조화 관측 이벤트에는 안정적인 이벤트명, 수준, 포탈 ID, 상관관계 ID, 숫자·불리언·문자열 형태의 제한된 필드만 기록합니다. PII와 비밀값은 이벤트 필드에 넣지 않습니다.

상황필수 사용자 경험필수 운영 기록
DirectoryService 일시 장애마지막 정상 사용자·용어 데이터 사용 여부 표시directory.unavailable, 캐시 나이, 회로 상태
사전 캐시 폴백번역 계속, 검토 필요 여부 표시glossary.cache_stale, source, ageMs
파일 검사 실패안전한 오류 메시지와 재업로드 안내파일 형식·크기 정책 위반 이벤트
작업 재시도진행 중/재시도/실패 상태 표시작업 ID, 시도 횟수, 오류 분류
권한 거부기능 접근 불가 메시지actor, 요구 scope, 대상 엔티티

11. 테스트·리뷰·배포 체크리스트 ​

새 도메인 기능은 PR 전에 아래 항목을 모두 충족해야 합니다.

  • [ ] 화면·API·서비스·저장소 책임이 분리되어 있다.
  • [ ] 모든 변경 API가 서버에서 인증·권한을 확인한다.
  • [ ] 입력값, 정렬 키, 페이지 크기, 파일 형식과 용량을 검증한다.
  • [ ] 민감 필드는 암호화·마스킹되고 로그·감사 기록에 원문이 없다.
  • [ ] 관리자 변경에 감사 이벤트와 상관관계 ID가 있다.
  • [ ] 오래 걸리는 업무가 작업 상태·재시도·중복 방지 규칙을 가진다.
  • [ ] DirectoryService·용어사전 장애 시 폴백과 사용자 메시지가 정의되어 있다.
  • [ ] 기능 플래그 또는 점진 배포 계획이 있다.
  • [ ] 성공·권한 거부·유효성 실패·외부 장애·재시도 시나리오를 자동 테스트한다.
  • [ ] 헬스 체크와 구조화 관측 이벤트가 추가되었다.
  • [ ] 공통 UI 이외 도메인 UI라도 Portal Foundation의 색상·여백·상태 표현 규칙을 준수한다.

12. 포탈 적용 순서 ​

개별 포탈 적용은 공통 패키지 설치 권한이 준비된 뒤 아래 순서로 진행합니다.

순서대상우선 적용 기능
1Process CenterDirectorySync 런타임, 보안·감사 어댑터, 운영 관리자 패널
2Guide Portal중앙 용어사전 런타임, 번역 작업·검토 큐, 기능 플래그
3ARISAM중앙 인증·권한, 파일 보안 정책, 비동기 문서 처리·알림
4전체 포탈공통 헬스 체크, 관측 이벤트, 검색 계약, 관리자 UI 확장

각 포탈은 read:packages 권한이 있는 패키지 토큰을 CI와 배포 환경에 설정해야 합니다. 설치 후에는 패키지 버전을 명시적으로 고정하고, 공통 패키지 업데이트는 별도 PR·테스트·점진 배포를 거쳐 적용합니다.