first commit
CI / typecheck (push) Successful in 1m8s
CI / format (push) Failing after 1m6s
CI / lint (push) Failing after 49s
CI / test (push) Failing after 1m8s

This commit is contained in:
SDI
2026-07-15 18:05:12 +09:00
commit 12e4f17b62
4633 changed files with 817125 additions and 0 deletions
+308
View File
@@ -0,0 +1,308 @@
# 통합 지원 플랫폼 상세 설계서
## 1. 프로젝트 개요
### 1.1 프로젝트 정보
| 항목 | 내용 |
| --- | --- |
| 플랫폼명 | BARON Q&A System |
| 핵심 목적 | EG-BIM 등 복수 소프트웨어의 Q&A, FAQ, 원격 지원 기능을 통합하고 BARON-SSO 기반 보안을 적용한 전사 기술지원 허브 구축 |
| 주요 대상 | BARON-SSO에 등록된 일반 사용자(User), 소프트웨어 담당자(Support), 시스템 관리자(Admin) |
### 1.2 추진 배경 및 기대 효과
- 여러 제품군에 분산된 기술지원 채널의 단일 플랫폼 통합
- 사용자 질문, FAQ, 원격 지원 이력의 일원화를 통한 대응 품질 및 추적성 향상
- BARON-SSO와 앱 단위 권한 제어를 통한 보안성 및 운영 효율 확보
## 2. 기술 아키텍처
### 2.1 기술 스택
| 구분 | 기술 |
| --- | --- |
| Frontend | Next.js, React, Tailwind CSS, Headless UI |
| Backend | FastAPI, Python, SQLAlchemy, Pydantic |
| Database | PostgreSQL |
| 인증/권한 | BARON-SSO, OAuth 2.0, OpenID Connect |
| 외부 연동 | ABC User Feedback 웹훅, 네이버웍스 알림 연동 |
| 인프라 | Ubuntu 24.04 (WSL2), Docker Compose, Nginx |
### 2.2 아키텍처 방향
- 프론트엔드의 Next.js 기반 구성으로 사용자 경험 및 생산성 확보
- 백엔드의 FastAPI 중심 경량 API 구조 설계를 통한 인증, 게시판, FAQ, 원격 지원 기능 분리 구현
- PostgreSQL과 SQLAlchemy 기반 데이터 계층 구성 및 앱별 접근 제어의 데이터 모델 반영
- BARON-SSO 연동 전제의 인증 구조 적용 및 표준 OAuth 2.0 / OIDC 기반 세션·토큰 검증 수행
- ABC User Feedback 연계를 통한 사용자 의견 수집 및 지원 품질 개선 체계 확보
- ABC User Feedback 웹훅 이벤트와 네이버웍스 알림 연계를 통한 실시간 커뮤니케이션 체계 확보
### 2.3 CI/CD 및 배포 프로세스
```mermaid
graph TD
A[개발자: 코드 작성 및 로컬 테스트] --> B[Main 브랜치 Push]
B --> C{GitHub Actions}
C --> D[Lint 및 Unit Test 실행]
D --> E[Docker Image 빌드]
E --> F[Container Registry 저장]
F --> G[운영 서버 배포]
G --> H[Nginx Proxy 라우팅]
H --> I[서비스 가동 및 모니터링]
```
## 3. 데이터베이스 설계
### 3.1 설계 원칙
권한 기반 데이터 격리(RBAC)를 위해 모든 게시물이 `app_id`를 참조하고, 사용자는 `user_app_access`를 통해 허용된 앱에만 접근하도록 설계
- 신규 앱이 추가되더라도 공통 스키마 변경 없이 `software_apps` 데이터 추가만으로 확장 가능한 구조 적용
- 전역 관리자 권한과 앱별 운영 권한 분리를 통한 멀티앱 확장 대응
- 사용자-앱 매핑의 중복 방지 및 상태값 표준화를 통한 운영 일관성 확보
- 목록 조회 성능 확보를 위한 앱 기준 인덱스 설계 반영
### 3.2 핵심 스키마
```sql
-- 1. 소프트웨어 정보
CREATE TABLE software_apps (
id SERIAL PRIMARY KEY,
app_code VARCHAR(50) UNIQUE NOT NULL,
app_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 사용자 정보 (BARON-SSO 동기화)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
sso_user_id VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100),
company VARCHAR(100),
department VARCHAR(100),
global_role VARCHAR(20) DEFAULT 'USER', -- ADMIN, USER
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 3. 사용자별 앱 접근 권한 및 앱별 역할
CREATE TABLE user_app_access (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
app_id INTEGER NOT NULL REFERENCES software_apps(id),
app_role VARCHAR(20) NOT NULL DEFAULT 'USER', -- SUPPORT, USER
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, app_id)
);
-- 4. Q&A 상태 코드
CREATE TABLE qna_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 5. Q&A 카테고리 코드
CREATE TABLE qna_category_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 6. Q&A 게시글
CREATE TABLE qna_posts (
id SERIAL PRIMARY KEY,
app_id INTEGER NOT NULL REFERENCES software_apps(id),
user_id INTEGER NOT NULL REFERENCES users(id),
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
category_code VARCHAR(20) REFERENCES qna_category_codes(code),
status_code VARCHAR(20) NOT NULL DEFAULT 'RECEIVED' REFERENCES qna_status_codes(code),
is_secret BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 7. 댓글
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
post_id INTEGER NOT NULL REFERENCES qna_posts(id),
author_id INTEGER NOT NULL REFERENCES users(id),
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 8. 첨부파일 통합 관리
CREATE TABLE attachments (
id SERIAL PRIMARY KEY,
parent_type VARCHAR(20) NOT NULL, -- 'POST' 또는 'COMMENT'
parent_id INTEGER NOT NULL,
app_id INTEGER NOT NULL REFERENCES software_apps(id),
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 9. 원격 지원 상태 코드
CREATE TABLE remote_support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 10. 원격 지원 로그
CREATE TABLE remote_support (
id SERIAL PRIMARY KEY,
post_id INTEGER NOT NULL REFERENCES qna_posts(id),
scheduled_time TIMESTAMP,
status_code VARCHAR(20) REFERENCES remote_support_status_codes(code),
support_engineer_id INTEGER REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 11. 주요 조회 인덱스
CREATE INDEX idx_user_app_access_app_role ON user_app_access (app_id, app_role);
CREATE INDEX idx_qna_posts_app_status_created ON qna_posts (app_id, status_code, created_at DESC);
CREATE INDEX idx_qna_posts_user_created ON qna_posts (user_id, created_at DESC);
CREATE INDEX idx_comments_post_created ON comments (post_id, created_at DESC);
CREATE INDEX idx_attachments_app_parent ON attachments (app_id, parent_type, parent_id);
```
## 4. 권한 및 보안 설계
### 4.1 역할 기반 접근 제어(RBAC)
| 역할 | 접근 범위 | 주요 권한 |
| --- | --- | --- |
| Admin | 전사 전체 소프트웨어 | 전체 통계 조회, 모든 게시글 수정/삭제, FAQ 관리, 앱 권한 부여 |
| Support | 본인에게 할당된 소프트웨어 | 담당 앱 Q&A 답변, 원격 지원 시작, 상태 변경 |
| User | 본인이 사용 중인 소프트웨어 | Q&A 작성/조회, FAQ 검색, 원격 지원 신청 |
### 4.2 권한 검증 로직
- 모든 API 요청에서 JWT 토큰 기준 사용자 식별 정보 추출
- 전사 관리자 여부는 `users.global_role` 기준 확인
- 앱 단위 접근 권한과 역할은 `user_app_access.app_role` 기준 검증
- 요청 앱에 대한 권한이 없을 경우 `403 Forbidden` 반환
- 비밀글(`is_secret = true`)의 작성자 본인, 권한 있는 Support, Admin 한정 조회
## 5. 주요 기능 및 UI 설계
### 5.1 통합 Q&A 리스트
- 제품별, 상태별, 날짜별 필터 제공
- 접수중, 검토중, 패치예정, 해결완료 상태의 컬러 배지 구분을 통한 가시성 강화
- MS Q&A 및 EG-BIM 사례를 참고한 검색성·가독성 중심 리스트 구조 적용
### 5.2 지능형 FAQ 및 원격 지원
- 질문 작성 시 제목 키워드 기반 관련 FAQ 실시간 추천
- 게시글 내용이 복잡하거나 재현이 어려운 경우 담당자에 의한 원격 지원 세션 생성 및 링크 전달
- Q&A에서 원격 지원으로 자연스럽게 전환되는 단순 운영 흐름 구성
### 5.3 파일 및 이미지 업로드
- 게시글 본문 및 댓글에서 드래그 앤 드롭 방식의 이미지 첨부 지원
- `attachments` 테이블을 통한 게시글·댓글 출처 구분 및 보존·삭제 이력 관리
- 초기 저장소의 로컬 볼륨 또는 S3 호환 스토리지 기준 검토
### 5.4 웹훅 기반 알림 연동
- ABC User Feedback에서 제공하는 웹훅을 활용한 앱별 Q&A 이벤트 수신
- 각 앱 사용자의 Q&A 화면 접근 시 주요 공지 또는 신규 문의 현황 노출
- 사용자의 신규 Q&A 글 작성 시 담당자 대상 네이버웍스 알림 발송
- 담당자의 답변글 작성 시 작성자 대상 네이버웍스 알림 발송
- 알림 이벤트의 앱별 라우팅, 수신 대상 매핑, 발송 이력 관리 체계 구성
## 6. 역할별 사용 시나리오
### 6.1 일반 사용자(User) 시나리오
- 각 소프트웨어 프로그램 로그인
- Q&A 페이지 접근
- 해당 앱 기준 Q&A 리스트 노출 및 기존 문의 확인
- 신규 문의 글 작성
- 담당자의 답변글 등록 시 네이버웍스 알림 수신
- 알림 확인 후 Q&A 페이지에서 답변글 확인
```mermaid
flowchart LR
A[사용자 로그인] --> B[Q&A 페이지 접근]
B --> C[해당 앱 Q&A 리스트 확인]
C --> D[신규 문의 글 작성]
D --> E[담당자 답변 등록]
E --> F[네이버웍스 알림 수신]
F --> G[답변글 확인]
```
### 6.2 소프트웨어 담당자(Support) 시나리오
- 본인 담당 소프트웨어 관련 글만 노출 및 확인
- 신규 등록 글의 새글 표시 확인
- 문의 내용 검토 후 답변글 작성
- 처리 단계에 따른 상태값 변경
- 답변 등록 시 사용자 대상 네이버웍스 알림 발송
```mermaid
flowchart LR
A[담당 앱 글 목록 확인] --> B[새글 표시 확인]
B --> C[문의 내용 검토]
C --> D[답변글 작성]
D --> E[상태값 변경]
E --> F[사용자 대상 네이버웍스 알림 발송]
```
### 6.3 관리자(Admin) 시나리오
- 로컬 개발 환경에서 기능 개발 및 수정
- Git 저장소 업로드
- CI/CD 파이프라인을 통한 운영 서버 Docker 환경 배포
- 배포 결과 및 운영 상태 확인
```mermaid
flowchart LR
A[로컬 개발 및 수정] --> B[Git 저장소 업로드]
B --> C[CI/CD 파이프라인 실행]
C --> D[운영 서버 Docker 배포]
D --> E[배포 결과 및 운영 상태 확인]
```
## 7. 구현 로드맵
### 7.1 Phase 1. 핵심 인프라 구축
- [ ] Ubuntu 및 Docker 서버 환경 셋업
- [ ] BARON-SSO OAuth2 연동 및 사용자 매핑 로직 구현
- [ ] RBAC 기반 DB 스키마 생성 및 기초 API 개발
### 7.2 Phase 2. 통합 플랫폼 UI 개발
- [ ] 소프트웨어별 격리 게시판 및 통합 리스트 UI 구현
- [ ] 첨부파일 및 이미지 업로드 시스템 구축
- [ ] 원격 지원 신청 기능 및 관리자 대시보드 연동
### 7.3 Phase 3. 고도화 및 운영 최적화
- [ ] AI 기반 FAQ 자동 추천 엔진 탑재
- [ ] ABC User Feedback 웹훅 및 네이버웍스 알림 연동 고도화
- [ ] 이슈 해결 통계 및 제품 품질 인사이트 보고서 자동화
### 7.4 추후 개발 예정 기능
#### 7.4.1 ADC User Feedback 연계 확장 기능
- 앱 메타정보 동기화 기능: BARON-SSO 또는 ADC User Feedback에 등록된 앱 코드, 앱명, 사용 여부 등의 정보를 우리 플랫폼과 자동으로 맞추는 기능
- 상태 변경 이벤트 기반 네이버웍스 추가 알림 기능
- FAQ, 기존 문의, 공지사항 기반 중복 문의 사전 방지 기능
- 앱별 문의 건수, 처리량, 응답 시간 기준 통계 대시보드 기능
- 소프트웨어별 Q&A 딥링크 또는 임베드 연동 기능: 각 소프트웨어 내부에서 해당 앱의 Q&A 화면으로 바로 이동하거나, Q&A 일부 화면을 프로그램 내부에 직접 표시하는 기능
#### 7.4.2 적용 검토 기준
- ADC User Feedback 제공 API, 웹훅, 임베드 기능의 실제 지원 범위 확인
- SSO 앱 메타정보와 플랫폼 내부 운영 메타정보 간 동기화 가능 여부 확인
- 네이버웍스 알림 대상자 매핑 및 부서별 알림 정책 적용 가능 여부 확인
- 운영 복잡도 대비 활용 효과가 높은 기능 우선 적용
+517
View File
@@ -0,0 +1,517 @@
# 사내 지원 플랫폼 상세 설계서
## 1. 프로젝트 개요
### 1.1 프로젝트 정보
| 항목 | 내용 |
| --- | --- |
| 플랫폼명 | BARON Office Support System |
| 핵심 목적 | 기존 통합 Q&A 플랫폼을 공용 기반으로 재사용하되, 인트라넷 진입형 사내 지원 서비스로 확장하여 물품신청, 도서 신청, 출장 차량 신청, 비품 대여, 사내 공지 및 Q&A 기능을 통합한 전사 지원 허브 구축 |
| 주요 대상 | S/W별 Q&A를 이용하는 사내 사용자 및 외부 고객(User), 인트라넷형 사내 지원 서비스를 이용하는 사내 사용자(User), 부서 담당자(Support), 시스템 관리자(Admin) |
### 1.2 추진 배경 및 기대 효과
- 개별 메신저, 이메일, 구두 요청으로 분산된 사내 요청 채널의 단일 플랫폼 통합
- 신청, 승인, 배정, 반납, 이력 조회의 전 과정 추적성 확보
- BARON-SSO 기반 인증과 부서·서비스 단위 권한 제어를 통한 운영 효율 확보
- 신청 현황, 처리 지연, 자산 이용률의 데이터 기반 관리 체계 확보
- 기존 S/W별 Q&A 플랫폼과 동일한 공용 프레임워크 재사용을 통한 개발 및 운영 표준화 확보
- 사내 사용자와 외부 고객을 함께 수용하는 사용자 모델 및 다중 알림 채널 운영 체계 확보
## 2. 기술 아키텍처
### 2.1 기술 스택
| 구분 | 기술 |
| --- | --- |
| Frontend | Next.js, React, Tailwind CSS, Headless UI |
| Backend | FastAPI, Python, SQLAlchemy, Pydantic |
| Database | PostgreSQL |
| 인증/권한 | BARON-SSO, OAuth 2.0, OpenID Connect |
| 외부 연동 | 네이버웍스 알림, SMS 발송 서비스, 사내 자산/사용자 정보 연동 API |
| 인프라 | Ubuntu 24.04 (WSL2), Docker Compose, Nginx |
### 2.2 아키텍처 방향
- 프론트엔드의 Next.js 기반 구성으로 신청, 조회, 승인 화면의 일관된 사용자 경험 확보
- 백엔드의 FastAPI 중심 API 구조 설계를 통한 신청, 승인, 자산관리, Q&A 기능 분리 구현
- PostgreSQL과 SQLAlchemy 기반 데이터 계층 구성 및 요청 유형별 공통 처리 구조 반영
- BARON-SSO 연동 전제의 인증 구조 적용 및 표준 OAuth 2.0 / OIDC 기반 세션·토큰 검증 수행
- 신청 상태 변경과 승인 결과의 네이버웍스 실시간 알림 체계 확보
- 네이버웍스 계정 미보유자 또는 발송 실패 건에 대한 SMS 대체 알림 체계 확보
- 추후 서비스 유형 추가를 고려한 멀티서비스 확장형 모델 적용
- 기존 S/W별 Q&A 플랫폼과 동일한 애플리케이션 기반을 재사용하되, 앱 진입형 구조 대신 인트라넷 진입형 서비스 컨텍스트 구조 적용
### 2.3 플랫폼 진입 구조
- 기존 기술지원 플랫폼은 각 S/W 프로그램 로그인 이후 해당 S/W의 Q&A 화면으로 직접 진입하는 앱 컨텍스트 기반 구조 적용
- 사내 지원 플랫폼은 회사 인트라넷에서 진입한 뒤 서비스 유형별 메뉴를 선택하는 포털 진입형 구조 적용
- 두 플랫폼은 동일한 인증 체계, 공통 UI 프레임워크, 공통 게시판/신청 처리 엔진을 공유하되 진입 URL과 초기 컨텍스트만 다르게 구성
- 외부 진입 컨텍스트인 `app_id` 또는 `service_type_id`를 내부 공통 식별자인 `workspace_id`로 매핑하여 동일 DB 구조에서 처리
### 2.4 CI/CD 및 배포 프로세스
```mermaid
graph TD
A[개발자: 코드 작성 및 로컬 테스트] --> B[Main 브랜치 Push]
B --> C{GitHub Actions}
C --> D[Lint 및 Unit Test 실행]
D --> E[Docker Image 빌드]
E --> F[Container Registry 저장]
F --> G[운영 서버 배포]
G --> H[Nginx Proxy 라우팅]
H --> I[서비스 가동 및 모니터링]
```
## 3. 데이터베이스 설계
### 3.1 설계 원칙
기존 S/W별 Q&A 플랫폼과 인트라넷형 사내 지원 플랫폼을 동일 DB에서 운영하기 위해 모든 게시판·신청 데이터를 `workspace_id` 기준으로 통합 관리하도록 설계
- 외부 진입 채널은 달라도 내부 저장 구조는 공통 `workspace` 기준으로 통합 적용
- S/W별 Q&A와 사내 지원 요청은 공통 본문·댓글·첨부 구조를 공유하고, 승인·자산배정·원격지원 등은 도메인별 확장 테이블로 분리 적용
- 전역 관리자 권한과 워크스페이스별 운영 권한 분리를 통한 멀티플랫폼 확장 대응
- 신규 S/W 또는 신규 사내 서비스 추가 시 공통 스키마 변경 없이 마스터 데이터 추가만으로 확장 가능한 구조 적용
- 목록 조회 성능 확보를 위한 워크스페이스, 상태, 작성자 기준 인덱스 설계 반영
- 사내 사용자와 외부 고객을 모두 지원할 수 있도록 사용자 유형과 다중 알림 채널 정보 관리 구조 반영
### 3.2 핵심 스키마
```sql
-- 1. 소프트웨어 정보
CREATE TABLE software_apps (
id SERIAL PRIMARY KEY,
app_code VARCHAR(50) UNIQUE NOT NULL,
app_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 사내 서비스 유형 정보
CREATE TABLE service_types (
id SERIAL PRIMARY KEY,
service_code VARCHAR(50) UNIQUE NOT NULL,
service_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 3. 사용자 정보 (BARON-SSO 동기화)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
sso_user_id VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100),
company VARCHAR(100),
department VARCHAR(100),
user_type VARCHAR(20) NOT NULL DEFAULT 'INTERNAL', -- INTERNAL, EXTERNAL
phone_number VARCHAR(30),
naverworks_user_key VARCHAR(100),
global_role VARCHAR(20) DEFAULT 'USER', -- ADMIN, USER
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 4. 공통 워크스페이스 마스터
CREATE TABLE workspaces (
id SERIAL PRIMARY KEY,
workspace_type VARCHAR(20) NOT NULL, -- SOFTWARE_APP, INTRANET_SERVICE
software_app_id INTEGER REFERENCES software_apps(id),
service_type_id INTEGER REFERENCES service_types(id),
workspace_code VARCHAR(50) UNIQUE NOT NULL,
workspace_name VARCHAR(100) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CHECK (
(workspace_type = 'SOFTWARE_APP' AND software_app_id IS NOT NULL AND service_type_id IS NULL)
OR
(workspace_type = 'INTRANET_SERVICE' AND service_type_id IS NOT NULL AND software_app_id IS NULL)
)
);
-- 5. 사용자별 워크스페이스 접근 권한 및 역할
CREATE TABLE user_workspace_access (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
workspace_role VARCHAR(20) NOT NULL DEFAULT 'USER', -- SUPPORT, USER
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, workspace_id)
);
-- 6. 공통 상태 코드
CREATE TABLE support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 7. 공통 카테고리 코드
CREATE TABLE support_category_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 8. 공통 게시글/신청 본문
CREATE TABLE support_tickets (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
requester_id INTEGER NOT NULL REFERENCES users(id),
ticket_type VARCHAR(20) NOT NULL, -- QNA, REQUEST
title VARCHAR(255) NOT NULL,
content TEXT,
category_code VARCHAR(20) REFERENCES support_category_codes(code),
status_code VARCHAR(20) NOT NULL DEFAULT 'OPEN' REFERENCES support_status_codes(code),
is_secret BOOLEAN DEFAULT FALSE,
requested_start_at TIMESTAMP,
requested_end_at TIMESTAMP,
priority VARCHAR(20) DEFAULT 'NORMAL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 9. 댓글 및 처리 메모
CREATE TABLE ticket_comments (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
author_id INTEGER NOT NULL REFERENCES users(id),
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 10. 첨부파일 통합 관리
CREATE TABLE attachments (
id SERIAL PRIMARY KEY,
parent_type VARCHAR(20) NOT NULL, -- 'TICKET' 또는 'COMMENT'
parent_id INTEGER NOT NULL,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 11. 사내 지원용 승인 이력
CREATE TABLE request_approvals (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
approver_id INTEGER NOT NULL REFERENCES users(id),
approval_status VARCHAR(20) NOT NULL, -- APPROVED, REJECTED, PENDING
comment TEXT,
approved_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 12. 자산/비품 마스터
CREATE TABLE assets (
id SERIAL PRIMARY KEY,
asset_code VARCHAR(50) UNIQUE NOT NULL,
asset_name VARCHAR(100) NOT NULL,
asset_type VARCHAR(30) NOT NULL, -- SUPPLY, EQUIPMENT, BOOK, VEHICLE
quantity INTEGER DEFAULT 1,
is_active BOOLEAN DEFAULT TRUE,
location VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 13. 자산 배정 및 대여 이력
CREATE TABLE asset_allocations (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
assignee_id INTEGER REFERENCES users(id),
allocation_status VARCHAR(20) NOT NULL, -- RESERVED, LOANED, RETURNED, CANCELLED
loaned_at TIMESTAMP,
due_at TIMESTAMP,
returned_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 14. 차량 운행 일정
CREATE TABLE vehicle_schedules (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
departure_at TIMESTAMP NOT NULL,
arrival_at TIMESTAMP,
destination VARCHAR(255),
driver_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 15. S/W Q&A용 원격 지원 상태 코드
CREATE TABLE remote_support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 16. S/W Q&A용 원격 지원 로그
CREATE TABLE remote_support (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
status_code VARCHAR(20) REFERENCES remote_support_status_codes(code),
support_engineer_id INTEGER REFERENCES users(id),
scheduled_time TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 17. 공통 FAQ
CREATE TABLE faqs (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 18. 알림 발송 이력
CREATE TABLE notification_logs (
id SERIAL PRIMARY KEY,
ticket_id INTEGER REFERENCES support_tickets(id),
recipient_id INTEGER REFERENCES users(id),
channel VARCHAR(20) NOT NULL, -- NAVERWORKS, SMS
target_address VARCHAR(100),
delivery_status VARCHAR(20) NOT NULL, -- SUCCESS, FAILED, FALLBACK
fallback_channel VARCHAR(20),
error_message TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 19. 주요 조회 인덱스
CREATE INDEX idx_user_workspace_access_role ON user_workspace_access (workspace_id, workspace_role);
CREATE INDEX idx_support_tickets_workspace_status_created ON support_tickets (workspace_id, status_code, created_at DESC);
CREATE INDEX idx_support_tickets_requester_created ON support_tickets (requester_id, created_at DESC);
CREATE INDEX idx_ticket_comments_ticket_created ON ticket_comments (ticket_id, created_at DESC);
CREATE INDEX idx_asset_allocations_asset_status ON asset_allocations (asset_id, allocation_status);
CREATE INDEX idx_vehicle_schedules_asset_departure ON vehicle_schedules (asset_id, departure_at);
CREATE INDEX idx_notification_logs_ticket_sent ON notification_logs (ticket_id, sent_at DESC);
```
### 3.3 워크스페이스 구성 예시
| 워크스페이스 유형 | 코드 | 이름 | 주요 처리 내용 |
| --- | --- | --- | --- |
| SOFTWARE_APP | EG_BIM | EG-BIM Q&A | 해당 S/W 전용 Q&A 게시판 및 원격 지원 |
| SOFTWARE_APP | CIVIL_APP | Civil App Q&A | 해당 S/W 전용 문의 접수 및 답변 |
| INTRANET_SERVICE | SUPPLY_REQUEST | 물품신청 | 사무용품, 소모품, 구매 요청 |
| INTRANET_SERVICE | BOOK_REQUEST | 도서 신청 | 업무 도서 구매 요청 또는 사내 도서 배정 |
| INTRANET_SERVICE | VEHICLE_REQUEST | 출장 차량 신청 | 출장 일정 기반 차량 예약 및 배차 요청 |
| INTRANET_SERVICE | EQUIPMENT_RENTAL | 비품 대여 | 노트북, 빔프로젝터, 케이블 등 비품 대여 |
| INTRANET_SERVICE | OFFICE_QNA | 사내 Q&A | 총무, 시설, 복지 관련 문의 접수 및 답변 |
## 4. 권한 및 보안 설계
### 4.1 역할 기반 접근 제어(RBAC)
| 역할 | 접근 범위 | 주요 권한 |
| --- | --- | --- |
| Admin | 전사 전체 워크스페이스 | 전체 통계 조회, 모든 게시글/신청 수정·삭제, 권한 부여, 워크스페이스 관리 |
| Support | 본인 담당 워크스페이스 | 신청 승인/반려, 배정 처리, 상태 변경, FAQ 관리, 답변 작성 |
| User | 본인이 접근 가능한 워크스페이스 | 신청 작성, 문의 작성, 본인 내역 조회, 댓글 작성, FAQ 조회 |
### 4.2 권한 검증 로직
- 모든 API 요청에서 JWT 토큰 기준 사용자 식별 정보 추출
- 전사 관리자 여부는 `users.global_role` 기준 확인
- 워크스페이스 단위 접근 권한과 역할은 `user_workspace_access.workspace_role` 기준 검증
- 요청 워크스페이스에 대한 권한이 없을 경우 `403 Forbidden` 반환
- S/W별 Q&A 게시글과 사내 지원 신청은 모두 작성자 본인, 권한 있는 Support, Admin 한정 조회
- S/W별 Q&A 워크스페이스는 사내 사용자(`INTERNAL`)와 외부 고객(`EXTERNAL`) 모두 접근 가능하도록 설계하고, 인트라넷형 서비스 워크스페이스는 사내 사용자 중심으로 제한 적용
## 5. 주요 기능 및 UI 설계
### 5.1 공통 워크스페이스 리스트
- 워크스페이스별, 상태별, 날짜별 필터 제공
- S/W별 Q&A와 인트라넷형 사내 지원 서비스를 하나의 공통 리스트 엔진으로 구성
- 사용자 진입 컨텍스트에 따라 해당 워크스페이스 화면만 우선 노출하는 구조 적용
- 문의, 요청, 처리중, 완료, 반려 등 상태값의 컬러 배지 구분을 통한 가시성 강화
### 5.2 S/W별 Q&A 기능
- 각 S/W 로그인 이후 해당 앱 전용 Q&A 게시판으로 직접 진입하는 앱 컨텍스트 기반 게시판 기능
- 제품별 문의 작성, 댓글 답변, 비밀글, 상태 변경 기능
- 질문 작성 시 관련 FAQ 추천 및 기존 문의 검색 기능
- 복잡한 문의에 대한 원격 지원 전환 및 지원 이력 관리 기능
- 앱별 공지, 신규 문의 현황, 담당자 답변 상태 표시 기능
### 5.3 인트라넷형 사내 지원 기능
- 물품신청: 품목, 수량, 사용 목적 입력 기반 신청 기능
- 도서 신청: 도서명, 저자, 출판사, 신청 사유 입력 기반 신청 기능
- 출장 차량 신청: 출장 일정, 목적지, 탑승 인원 기반 차량 신청 기능
- 비품 대여: 대여 품목, 사용 기간, 반납 예정일 입력 기반 대여 신청 기능
- 사내 Q&A: 총무, 시설, 복지, 기타 운영 문의 작성 및 답변 기능
### 5.4 승인, 배정 및 원격 처리
- 사내 지원 요청에 대한 담당자 승인 또는 반려 처리 기능
- 차량, 도서, 비품 등 실제 자산 배정 처리 기능
- 반려 사유, 처리 메모, 배정 결과의 이력 관리 기능
- 반납 완료 시 상태 자동 갱신 및 이력 보존 기능
- S/W별 Q&A 문의에 대한 원격 지원 일정 등록 및 처리 상태 관리 기능
### 5.5 FAQ, 공지 및 추천 기능
- 워크스페이스별 FAQ 및 공지사항 분리 관리 기능
- 질문 또는 신청 작성 시 관련 FAQ 및 기존 공지사항 추천 기능
- 자주 발생하는 요청 유형과 반복 문의의 사전 안내를 통한 중복 문의 감소 기능
- S/W별 앱 FAQ와 인트라넷형 서비스 안내 문서를 동일한 추천 구조로 제공
### 5.6 알림 및 이벤트 연동
- S/W별 Q&A 신규 문의 등록 시 담당자 대상 네이버웍스 알림 발송
- S/W별 Q&A 답변 등록 시 작성자 대상 네이버웍스 알림 발송
- 사내 지원 신청 등록 시 담당자 대상 네이버웍스 알림 발송
- 승인, 반려, 배정, 반납 처리 시 신청자 대상 네이버웍스 알림 발송
- 처리 지연 건 발생 시 담당자 리마인드 알림 발송
- 워크스페이스 유형별 알림 대상 라우팅 및 발송 이력 관리 체계 구성
- 네이버웍스 계정이 없는 사용자 또는 네이버웍스 발송 실패 건에 대한 SMS 대체 알림 발송 기능
- 알림 발송 채널, 실패 사유, 대체 발송 결과를 `notification_logs` 기준으로 추적 관리
## 6. 역할별 사용 시나리오
### 6.1 S/W 사용자(User) 시나리오
- 각 S/W 프로그램 로그인
- 사내 사용자 또는 외부 고객 자격으로 해당 앱 접근
- 해당 앱의 Q&A 화면으로 직접 진입
- 해당 앱 기준 Q&A 리스트 노출 및 기존 문의 확인
- 신규 문의 글 작성
- 담당자의 답변글 등록 시 네이버웍스 알림 수신 또는 SMS 대체 알림 수신
- 알림 확인 후 해당 앱 Q&A 화면에서 답변글 확인
```mermaid
flowchart LR
A[사내 사용자 또는 외부 고객 로그인] --> B[해당 S/W Q&A 진입]
B --> C[해당 앱 Q&A 리스트 확인]
C --> D[신규 문의 글 작성]
D --> E[담당자 답변 등록]
E --> F[네이버웍스 또는 SMS 알림 수신]
F --> G[답변글 확인]
```
### 6.2 S/W 담당자(Support) 시나리오
- 본인 담당 S/W 워크스페이스 접근
- 신규 문의 및 새글 표시 확인
- 문의 내용 검토 후 답변글 작성
- 상태값 변경 또는 원격 지원 전환 처리
- 작성자 대상 알림 발송
```mermaid
flowchart LR
A[담당 S/W 워크스페이스 접근] --> B[신규 문의 확인]
B --> C[문의 내용 검토]
C --> D[답변 또는 원격 지원 처리]
D --> E[상태값 변경]
E --> F[사용자 대상 알림 발송]
```
### 6.3 인트라넷 사용자(User) 시나리오
- 회사 인트라넷 접속 및 BARON-SSO 로그인
- 신청 서비스 선택
- 물품신청, 도서 신청, 출장 차량 신청, 비품 대여 또는 사내 Q&A 작성
- 처리 상태 및 승인 결과 확인
- 네이버웍스 알림 수신 후 상세 내역 확인
```mermaid
flowchart LR
A[인트라넷 접속 및 로그인] --> B[신청 서비스 선택]
B --> C[신청서 또는 문의 작성]
C --> D[담당자 처리 진행]
D --> E[승인 또는 반려 결과 확정]
E --> F[네이버웍스 알림 수신]
F --> G[상세 내역 확인]
```
### 6.4 인트라넷 담당자(Support) 시나리오
- 본인 담당 서비스 워크스페이스 목록 확인
- 신규 신청 또는 문의 접수 확인
- 승인, 반려, 배정, 답변 처리 수행
- 상태값 변경 및 처리 메모 등록
- 신청자 대상 알림 발송
```mermaid
flowchart LR
A[담당 서비스 워크스페이스 확인] --> B[신규 요청 접수 확인]
B --> C[승인 또는 반려 검토]
C --> D[배정 또는 답변 처리]
D --> E[상태값 변경 및 메모 등록]
E --> F[신청자 대상 알림 발송]
```
### 6.5 관리자(Admin) 시나리오
- 로컬 개발 환경에서 기능 개발 및 수정
- Git 저장소 업로드
- CI/CD 파이프라인을 통한 운영 서버 Docker 환경 배포
- S/W 앱 마스터, 서비스 유형, 워크스페이스 권한, 자산 마스터 관리
- 배포 결과 및 운영 상태 확인
```mermaid
flowchart LR
A[로컬 개발 및 수정] --> B[Git 저장소 업로드]
B --> C[CI/CD 파이프라인 실행]
C --> D[운영 서버 Docker 배포]
D --> E[앱/서비스/권한/자산 마스터 관리]
E --> F[운영 상태 확인]
```
## 7. 구현 로드맵
### 7.1 Phase 1. 핵심 인프라 구축
- [ ] Ubuntu 및 Docker 서버 환경 셋업
- [ ] BARON-SSO OAuth2 연동 및 사용자 매핑 로직 구현
- [ ] 공용 워크스페이스 기반 DB 스키마 생성 및 기초 API 개발
- [ ] S/W별 Q&A와 인트라넷형 서비스의 공통 인증 및 권한 구조 구현
### 7.2 Phase 2. S/W별 Q&A 및 공용 게시판 기능 개발
- [ ] S/W별 격리 게시판 및 통합 리스트 UI 구현
- [ ] 댓글, 첨부파일, 비밀글, FAQ 추천 기능 구현
- [ ] 원격 지원 전환 및 상태 관리 기능 구축
- [ ] 네이버웍스 알림, SMS 대체 알림 및 앱별 컨텍스트 진입 기능 구현
### 7.3 Phase 3. 인트라넷형 사내 지원 기능 개발
- [ ] 서비스 유형별 신청서 UI 및 통합 리스트 구현
- [ ] 승인/반려/배정 처리 기능 구현
- [ ] 자산 및 차량 일정 관리 기능 구축
- [ ] 첨부파일 및 댓글 시스템 구축
### 7.4 Phase 4. 고도화 및 운영 최적화
- [ ] FAQ 추천 및 중복 문의·중복 신청 사전 방지 기능 탑재
- [ ] 네이버웍스 알림, SMS 대체 발송, 처리 지연 리마인드 기능 고도화
- [ ] S/W별 Q&A 통계와 사내 지원 서비스 운영 인사이트 보고서 자동화
### 7.5 추후 개발 예정 기능
#### 7.5.1 공용 플랫폼 확장 기능
- 조직도 기반 결재선 자동 추천 기능: 신청 유형과 부서 기준으로 결재 대상 자동 추천 기능
- 자산 메타정보 동기화 기능: 사내 자산관리 시스템 또는 외부 마스터 정보와 비품, 차량, 도서 정보를 자동 동기화하는 기능
- 도서 및 비품 재고 예측 기능: 사용량 기반 부족 품목 예측 및 사전 구매 추천 기능
- 서비스별 맞춤 대시보드 기능: 부서별 처리량, 반려율, 평균 승인 시간 시각화 기능
- 앱 메타정보 동기화 기능: BARON-SSO 또는 외부 시스템에 등록된 S/W 정보를 공용 플랫폼과 자동으로 맞추는 기능
- S/W별 Q&A 딥링크 또는 임베드 연동 기능: 각 소프트웨어 내부에서 해당 앱의 Q&A 화면으로 바로 이동하거나 일부 화면을 직접 표시하는 기능
- 사내 포털 딥링크 또는 임베드 연동 기능: 그룹웨어 또는 사내 포털에서 해당 서비스 화면으로 바로 이동하거나 일부 화면을 직접 표시하는 기능
#### 7.5.2 적용 검토 기준
- 사내 자산관리, 그룹웨어, 조직도 API의 실제 연동 가능 범위 확인
- BARON-SSO 또는 외부 시스템의 앱 메타정보 동기화 가능 범위 확인
- 결재 정책과 운영 프로세스의 시스템 반영 가능 여부 확인
- 네이버웍스 알림 대상자 및 부서별 알림 정책 적용 가능 여부 확인
- 외부 고객 대상 SMS 발송 정책 및 개인정보 보관 기준 적용 가능 여부 확인
- 운영 복잡도 대비 활용 효과가 높은 기능 우선 적용
+527
View File
@@ -0,0 +1,527 @@
# 사내 지원 플랫폼 상세 설계서
## 1. 프로젝트 개요
### 1.1 프로젝트 정보
| 항목 | 내용 |
| --- | --- |
| 플랫폼명 | BARON Office Support System |
| 핵심 목적 | 기존 통합 Q&A 플랫폼을 공용 기반으로 재사용하되, 인트라넷 진입형 사내 지원 서비스로 확장하여 물품신청, 도서 신청, 출장 차량 신청, 비품 대여, 사내 공지 및 Q&A 기능을 통합한 전사 지원 허브 구축 |
| 주요 대상 | S/W별 Q&A를 이용하는 사내 사용자 및 외부 고객(User), 인트라넷형 사내 지원 서비스를 이용하는 사내 사용자(User), 부서 담당자(Support), 시스템 관리자(Admin) |
### 1.2 추진 배경 및 기대 효과
- 개별 메신저, 이메일, 구두 요청으로 분산된 사내 요청 채널의 단일 플랫폼 통합
- 신청, 승인, 배정, 반납, 이력 조회의 전 과정 추적성 확보
- BARON-SSO 기반 인증과 부서·서비스 단위 권한 제어를 통한 운영 효율 확보
- 신청 현황, 처리 지연, 자산 이용률의 데이터 기반 관리 체계 확보
- 기존 S/W별 Q&A 플랫폼과 동일한 공용 프레임워크 재사용을 통한 개발 및 운영 표준화 확보
- 사내 사용자와 외부 고객을 함께 수용하는 사용자 모델 및 다중 알림 채널 운영 체계 확보
## 2. 기술 아키텍처
### 2.1 기술 스택
| 구분 | 기술 |
| --- | --- |
| Frontend | Next.js, React, Tailwind CSS, Headless UI |
| Backend | FastAPI, Python, SQLAlchemy, Pydantic |
| Database | PostgreSQL |
| 인증/권한 | BARON-SSO, OAuth 2.0, OpenID Connect |
| 외부 연동 | 네이버웍스 알림, SMS 발송 서비스, 사내 자산/사용자 정보 연동 API |
| 인프라 | Ubuntu 24.04 (WSL2), Docker Compose, Nginx |
### 2.2 아키텍처 방향
- 프론트엔드의 Next.js 기반 구성으로 신청, 조회, 승인 화면의 일관된 사용자 경험 확보
- 백엔드의 FastAPI 중심 API 구조 설계를 통한 신청, 승인, 자산관리, Q&A 기능 분리 구현
- PostgreSQL과 SQLAlchemy 기반 데이터 계층 구성 및 요청 유형별 공통 처리 구조 반영
- BARON-SSO 연동 전제의 인증 구조 적용 및 표준 OAuth 2.0 / OIDC 기반 세션·토큰 검증 수행
- 신청 상태 변경과 승인 결과의 네이버웍스 실시간 알림 체계 확보
- 네이버웍스 계정 미보유자 또는 발송 실패 건에 대한 SMS 대체 알림 체계 확보
- 추후 서비스 유형 추가를 고려한 멀티서비스 확장형 모델 적용
- 기존 S/W별 Q&A 플랫폼과 동일한 애플리케이션 기반을 재사용하되, 앱 진입형 구조 대신 인트라넷 진입형 서비스 컨텍스트 구조 적용
### 2.3 플랫폼 진입 구조
- 기존 기술지원 플랫폼은 각 S/W 프로그램 로그인 이후 해당 S/W의 Q&A 화면으로 직접 진입하는 앱 컨텍스트 기반 구조 적용
- 사내 지원 플랫폼은 회사 인트라넷에서 진입한 뒤 서비스 유형별 메뉴를 선택하는 포털 진입형 구조 적용
- 두 플랫폼은 동일한 인증 체계, 공통 UI 프레임워크, 공통 게시판/신청 처리 엔진을 공유하되 진입 URL과 초기 컨텍스트만 다르게 구성
- 외부 진입 컨텍스트인 `app_id` 또는 `service_type_id`를 내부 공통 식별자인 `workspace_id`로 매핑하여 동일 DB 구조에서 처리
### 2.4 CI/CD 및 배포 프로세스
```mermaid
graph TD
A[개발자: 코드 작성 및 로컬 테스트] --> B[Main 브랜치 Push]
B --> C{GitHub Actions}
C --> D[Lint 및 Unit Test 실행]
D --> E[Docker Image 빌드]
E --> F[Container Registry 저장]
F --> G[운영 서버 배포]
G --> H[Nginx Proxy 라우팅]
H --> I[서비스 가동 및 모니터링]
```
## 3. 데이터베이스 설계
### 3.1 설계 원칙
기존 S/W별 Q&A 플랫폼과 인트라넷형 사내 지원 플랫폼을 동일 DB에서 운영하기 위해 모든 게시판·신청 데이터를 `workspace_id` 기준으로 통합 관리하도록 설계
- 외부 진입 채널은 달라도 내부 저장 구조는 공통 `workspace` 기준으로 통합 적용
- S/W별 Q&A와 사내 지원 요청은 공통 본문·댓글·첨부 구조를 공유하고, 승인·자산배정·원격지원 등은 도메인별 확장 테이블로 분리 적용
- 전역 관리자 권한과 워크스페이스별 운영 권한 분리를 통한 멀티플랫폼 확장 대응
- 신규 S/W 또는 신규 사내 서비스 추가 시 공통 스키마 변경 없이 마스터 데이터 추가만으로 확장 가능한 구조 적용
- 목록 조회 성능 확보를 위한 워크스페이스, 상태, 작성자 기준 인덱스 설계 반영
- 사용자 기본 정보와 tenant 정보는 BARON-SSO를 원본으로 사용하고, 플랫폼 내부에서는 `user_id`, `tenant_id` 및 권한 정보만 관리하는 구조 반영
### 3.2 핵심 스키마
```sql
-- 1. 소프트웨어 정보
CREATE TABLE software_apps (
id SERIAL PRIMARY KEY,
app_code VARCHAR(50) UNIQUE NOT NULL,
app_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 사내 서비스 유형 정보
CREATE TABLE service_types (
id SERIAL PRIMARY KEY,
service_code VARCHAR(50) UNIQUE NOT NULL,
service_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 3. 공통 워크스페이스 마스터
CREATE TABLE workspaces (
id SERIAL PRIMARY KEY,
workspace_type VARCHAR(20) NOT NULL, -- SOFTWARE_APP, INTRANET_SERVICE
software_app_id INTEGER REFERENCES software_apps(id),
service_type_id INTEGER REFERENCES service_types(id),
workspace_code VARCHAR(50) UNIQUE NOT NULL,
workspace_name VARCHAR(100) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CHECK (
(workspace_type = 'SOFTWARE_APP' AND software_app_id IS NOT NULL AND service_type_id IS NULL)
OR
(workspace_type = 'INTRANET_SERVICE' AND service_type_id IS NOT NULL AND software_app_id IS NULL)
)
);
-- 4. 사용자별 워크스페이스 접근 권한 및 역할
CREATE TABLE user_workspace_access (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100) NOT NULL,
tenant_id VARCHAR(100) NOT NULL,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
workspace_role VARCHAR(20) NOT NULL DEFAULT 'USER', -- SUPPORT, USER
can_read BOOLEAN DEFAULT TRUE,
can_write BOOLEAN DEFAULT FALSE,
can_manage BOOLEAN DEFAULT FALSE,
can_approve BOOLEAN DEFAULT FALSE,
page_scope VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, tenant_id, workspace_id)
);
-- 5. 사용자 알림 보조 정보
CREATE TABLE user_notification_profiles (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100) NOT NULL,
tenant_id VARCHAR(100) NOT NULL,
user_type VARCHAR(20) NOT NULL DEFAULT 'INTERNAL', -- INTERNAL, EXTERNAL
phone_number VARCHAR(30),
naverworks_user_key VARCHAR(100),
sms_opt_in BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, tenant_id)
);
-- 6. 공통 상태 코드
CREATE TABLE support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 7. 공통 카테고리 코드
CREATE TABLE support_category_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 8. 공통 게시글/신청 본문
CREATE TABLE support_tickets (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
requester_id VARCHAR(100) NOT NULL,
requester_tenant_id VARCHAR(100) NOT NULL,
ticket_type VARCHAR(20) NOT NULL, -- QNA, REQUEST
title VARCHAR(255) NOT NULL,
content TEXT,
category_code VARCHAR(20) REFERENCES support_category_codes(code),
status_code VARCHAR(20) NOT NULL DEFAULT 'OPEN' REFERENCES support_status_codes(code),
is_secret BOOLEAN DEFAULT FALSE,
requested_start_at TIMESTAMP,
requested_end_at TIMESTAMP,
priority VARCHAR(20) DEFAULT 'NORMAL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 9. 댓글 및 처리 메모
CREATE TABLE ticket_comments (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
author_id VARCHAR(100) NOT NULL,
author_tenant_id VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 10. 첨부파일 통합 관리
CREATE TABLE attachments (
id SERIAL PRIMARY KEY,
parent_type VARCHAR(20) NOT NULL, -- 'TICKET' 또는 'COMMENT'
parent_id INTEGER NOT NULL,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 11. 사내 지원용 승인 이력
CREATE TABLE request_approvals (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
approver_id VARCHAR(100) NOT NULL,
approver_tenant_id VARCHAR(100) NOT NULL,
approval_status VARCHAR(20) NOT NULL, -- APPROVED, REJECTED, PENDING
comment TEXT,
approved_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 12. 자산/비품 마스터
CREATE TABLE assets (
id SERIAL PRIMARY KEY,
asset_code VARCHAR(50) UNIQUE NOT NULL,
asset_name VARCHAR(100) NOT NULL,
asset_type VARCHAR(30) NOT NULL, -- SUPPLY, EQUIPMENT, BOOK, VEHICLE
quantity INTEGER DEFAULT 1,
is_active BOOLEAN DEFAULT TRUE,
location VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 13. 자산 배정 및 대여 이력
CREATE TABLE asset_allocations (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
assignee_id VARCHAR(100),
assignee_tenant_id VARCHAR(100),
allocation_status VARCHAR(20) NOT NULL, -- RESERVED, LOANED, RETURNED, CANCELLED
loaned_at TIMESTAMP,
due_at TIMESTAMP,
returned_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 14. 차량 운행 일정
CREATE TABLE vehicle_schedules (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
departure_at TIMESTAMP NOT NULL,
arrival_at TIMESTAMP,
destination VARCHAR(255),
driver_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 15. S/W Q&A용 원격 지원 상태 코드
CREATE TABLE remote_support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 16. S/W Q&A용 원격 지원 로그
CREATE TABLE remote_support (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
status_code VARCHAR(20) REFERENCES remote_support_status_codes(code),
support_engineer_id VARCHAR(100),
support_engineer_tenant_id VARCHAR(100),
scheduled_time TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 17. 공통 FAQ
CREATE TABLE faqs (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 18. 알림 발송 이력
CREATE TABLE notification_logs (
id SERIAL PRIMARY KEY,
ticket_id INTEGER REFERENCES support_tickets(id),
recipient_id VARCHAR(100) NOT NULL,
recipient_tenant_id VARCHAR(100) NOT NULL,
channel VARCHAR(20) NOT NULL, -- NAVERWORKS, SMS
target_address VARCHAR(100),
delivery_status VARCHAR(20) NOT NULL, -- SUCCESS, FAILED, FALLBACK
fallback_channel VARCHAR(20),
error_message TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 19. 주요 조회 인덱스
CREATE INDEX idx_user_workspace_access_role ON user_workspace_access (workspace_id, workspace_role);
CREATE INDEX idx_support_tickets_workspace_status_created ON support_tickets (workspace_id, status_code, created_at DESC);
CREATE INDEX idx_support_tickets_requester_created ON support_tickets (requester_id, created_at DESC);
CREATE INDEX idx_ticket_comments_ticket_created ON ticket_comments (ticket_id, created_at DESC);
CREATE INDEX idx_asset_allocations_asset_status ON asset_allocations (asset_id, allocation_status);
CREATE INDEX idx_vehicle_schedules_asset_departure ON vehicle_schedules (asset_id, departure_at);
CREATE INDEX idx_notification_logs_ticket_sent ON notification_logs (ticket_id, sent_at DESC);
```
### 3.3 워크스페이스 구성 예시
| 워크스페이스 유형 | 코드 | 이름 | 주요 처리 내용 |
| --- | --- | --- | --- |
| SOFTWARE_APP | EG_BIM | EG-BIM Q&A | 해당 S/W 전용 Q&A 게시판 및 원격 지원 |
| SOFTWARE_APP | CIVIL_APP | Civil App Q&A | 해당 S/W 전용 문의 접수 및 답변 |
| INTRANET_SERVICE | SUPPLY_REQUEST | 물품신청 | 사무용품, 소모품, 구매 요청 |
| INTRANET_SERVICE | BOOK_REQUEST | 도서 신청 | 업무 도서 구매 요청 또는 사내 도서 배정 |
| INTRANET_SERVICE | VEHICLE_REQUEST | 출장 차량 신청 | 출장 일정 기반 차량 예약 및 배차 요청 |
| INTRANET_SERVICE | EQUIPMENT_RENTAL | 비품 대여 | 노트북, 빔프로젝터, 케이블 등 비품 대여 |
| INTRANET_SERVICE | OFFICE_QNA | 사내 Q&A | 총무, 시설, 복지 관련 문의 접수 및 답변 |
## 4. 권한 및 보안 설계
### 4.1 역할 기반 접근 제어(RBAC)
| 역할 | 접근 범위 | 주요 권한 |
| --- | --- | --- |
| Admin | 전사 전체 워크스페이스 | 전체 통계 조회, 모든 게시글/신청 수정·삭제, 권한 부여, 워크스페이스 관리 |
| Support | 본인 담당 워크스페이스 | 신청 승인/반려, 배정 처리, 상태 변경, FAQ 관리, 답변 작성 |
| User | 본인이 접근 가능한 워크스페이스 | 신청 작성, 문의 작성, 본인 내역 조회, 댓글 작성, FAQ 조회 |
### 4.2 권한 검증 로직
- 모든 API 요청에서 BARON-SSO 토큰 기준 `user_id`, `tenant_id` 추출
- 전사 관리자 여부와 사용자 기본 정보는 BARON-SSO 기준 확인
- 워크스페이스 단위 접근 권한과 역할은 `user_workspace_access``can_read`, `can_write`, `can_manage`, `can_approve`, `page_scope` 기준 검증
- 요청 워크스페이스에 대한 권한이 없을 경우 `403 Forbidden` 반환
- S/W별 Q&A 게시글과 사내 지원 신청은 모두 작성자 본인, 권한 있는 Support, Admin 한정 조회
- S/W별 Q&A 워크스페이스는 사내 사용자(`INTERNAL`)와 외부 고객(`EXTERNAL`) 모두 접근 가능하도록 설계하고, 인트라넷형 서비스 워크스페이스는 사내 사용자 중심으로 제한 적용
## 5. 주요 기능 및 UI 설계
### 5.1 공통 워크스페이스 리스트
- 워크스페이스별, 상태별, 날짜별 필터 제공
- S/W별 Q&A와 인트라넷형 사내 지원 서비스를 하나의 공통 리스트 엔진으로 구성
- 사용자 진입 컨텍스트에 따라 해당 워크스페이스 화면만 우선 노출하는 구조 적용
- 문의, 요청, 처리중, 완료, 반려 등 상태값의 컬러 배지 구분을 통한 가시성 강화
### 5.2 S/W별 Q&A 기능
- 각 S/W 로그인 이후 해당 앱 전용 Q&A 게시판으로 직접 진입하는 앱 컨텍스트 기반 게시판 기능
- 제품별 문의 작성, 댓글 답변, 비밀글, 상태 변경 기능
- 질문 작성 시 관련 FAQ 추천 및 기존 문의 검색 기능
- 복잡한 문의에 대한 원격 지원 전환 및 지원 이력 관리 기능
- 앱별 공지, 신규 문의 현황, 담당자 답변 상태 표시 기능
### 5.3 인트라넷형 사내 지원 기능
- 물품신청: 품목, 수량, 사용 목적 입력 기반 신청 기능
- 도서 신청: 도서명, 저자, 출판사, 신청 사유 입력 기반 신청 기능
- 출장 차량 신청: 출장 일정, 목적지, 탑승 인원 기반 차량 신청 기능
- 비품 대여: 대여 품목, 사용 기간, 반납 예정일 입력 기반 대여 신청 기능
- 사내 Q&A: 총무, 시설, 복지, 기타 운영 문의 작성 및 답변 기능
### 5.4 승인, 배정 및 원격 처리
- 사내 지원 요청에 대한 담당자 승인 또는 반려 처리 기능
- 차량, 도서, 비품 등 실제 자산 배정 처리 기능
- 반려 사유, 처리 메모, 배정 결과의 이력 관리 기능
- 반납 완료 시 상태 자동 갱신 및 이력 보존 기능
- S/W별 Q&A 문의에 대한 원격 지원 일정 등록 및 처리 상태 관리 기능
### 5.5 FAQ, 공지 및 추천 기능
- 워크스페이스별 FAQ 및 공지사항 분리 관리 기능
- 질문 또는 신청 작성 시 관련 FAQ 및 기존 공지사항 추천 기능
- 자주 발생하는 요청 유형과 반복 문의의 사전 안내를 통한 중복 문의 감소 기능
- S/W별 앱 FAQ와 인트라넷형 서비스 안내 문서를 동일한 추천 구조로 제공
### 5.6 알림 및 이벤트 연동
- S/W별 Q&A 신규 문의 등록 시 담당자 대상 네이버웍스 알림 발송
- S/W별 Q&A 답변 등록 시 작성자 대상 네이버웍스 알림 발송
- 사내 지원 신청 등록 시 담당자 대상 네이버웍스 알림 발송
- 승인, 반려, 배정, 반납 처리 시 신청자 대상 네이버웍스 알림 발송
- 처리 지연 건 발생 시 담당자 리마인드 알림 발송
- 워크스페이스 유형별 알림 대상 라우팅 및 발송 이력 관리 체계 구성
- 네이버웍스 계정이 없는 사용자 또는 네이버웍스 발송 실패 건에 대한 SMS 대체 알림 발송 기능
- 알림 발송 채널, 실패 사유, 대체 발송 결과를 `notification_logs` 기준으로 추적 관리
## 6. 역할별 사용 시나리오
### 6.1 S/W 사용자(User) 시나리오
- 각 S/W 프로그램 로그인
- 사내 사용자 또는 외부 고객 자격으로 해당 앱 접근
- 해당 앱의 Q&A 화면으로 직접 진입
- 해당 앱 기준 Q&A 리스트 노출 및 기존 문의 확인
- 신규 문의 글 작성
- 담당자의 답변글 등록 시 네이버웍스 알림 수신 또는 SMS 대체 알림 수신
- 알림 확인 후 해당 앱 Q&A 화면에서 답변글 확인
```mermaid
flowchart LR
A[사내 사용자 또는 외부 고객 로그인] --> B[해당 S/W Q&A 진입]
B --> C[해당 앱 Q&A 리스트 확인]
C --> D[신규 문의 글 작성]
D --> E[담당자 답변 등록]
E --> F[네이버웍스 또는 SMS 알림 수신]
F --> G[답변글 확인]
```
### 6.2 S/W 담당자(Support) 시나리오
- 본인 담당 S/W 워크스페이스 접근
- 신규 문의 및 새글 표시 확인
- 문의 내용 검토 후 답변글 작성
- 상태값 변경 또는 원격 지원 전환 처리
- 작성자 대상 알림 발송
```mermaid
flowchart LR
A[담당 S/W 워크스페이스 접근] --> B[신규 문의 확인]
B --> C[문의 내용 검토]
C --> D[답변 또는 원격 지원 처리]
D --> E[상태값 변경]
E --> F[사용자 대상 알림 발송]
```
### 6.3 인트라넷 사용자(User) 시나리오
- 회사 인트라넷 접속 및 BARON-SSO 로그인
- 신청 서비스 선택
- 물품신청, 도서 신청, 출장 차량 신청, 비품 대여 또는 사내 Q&A 작성
- 처리 상태 및 승인 결과 확인
- 네이버웍스 알림 수신 후 상세 내역 확인
```mermaid
flowchart LR
A[인트라넷 접속 및 로그인] --> B[신청 서비스 선택]
B --> C[신청서 또는 문의 작성]
C --> D[담당자 처리 진행]
D --> E[승인 또는 반려 결과 확정]
E --> F[네이버웍스 알림 수신]
F --> G[상세 내역 확인]
```
### 6.4 인트라넷 담당자(Support) 시나리오
- 본인 담당 서비스 워크스페이스 목록 확인
- 신규 신청 또는 문의 접수 확인
- 승인, 반려, 배정, 답변 처리 수행
- 상태값 변경 및 처리 메모 등록
- 신청자 대상 알림 발송
```mermaid
flowchart LR
A[담당 서비스 워크스페이스 확인] --> B[신규 요청 접수 확인]
B --> C[승인 또는 반려 검토]
C --> D[배정 또는 답변 처리]
D --> E[상태값 변경 및 메모 등록]
E --> F[신청자 대상 알림 발송]
```
### 6.5 관리자(Admin) 시나리오
- 로컬 개발 환경에서 기능 개발 및 수정
- Git 저장소 업로드
- CI/CD 파이프라인을 통한 운영 서버 Docker 환경 배포
- S/W 앱 마스터, 서비스 유형, 워크스페이스 권한, 자산 마스터 관리
- 배포 결과 및 운영 상태 확인
```mermaid
flowchart LR
A[로컬 개발 및 수정] --> B[Git 저장소 업로드]
B --> C[CI/CD 파이프라인 실행]
C --> D[운영 서버 Docker 배포]
D --> E[앱/서비스/권한/자산 마스터 관리]
E --> F[운영 상태 확인]
```
## 7. 구현 로드맵
### 7.1 Phase 1. 핵심 인프라 구축
- [ ] Ubuntu 및 Docker 서버 환경 셋업
- [ ] BARON-SSO OAuth2 연동 및 사용자 매핑 로직 구현
- [ ] 공용 워크스페이스 기반 DB 스키마 생성 및 기초 API 개발
- [ ] S/W별 Q&A와 인트라넷형 서비스의 공통 인증 및 권한 구조 구현
### 7.2 Phase 2. S/W별 Q&A 및 공용 게시판 기능 개발
- [ ] S/W별 격리 게시판 및 통합 리스트 UI 구현
- [ ] 댓글, 첨부파일, 비밀글, FAQ 추천 기능 구현
- [ ] 원격 지원 전환 및 상태 관리 기능 구축
- [ ] 네이버웍스 알림, SMS 대체 알림 및 앱별 컨텍스트 진입 기능 구현
### 7.3 Phase 3. 인트라넷형 사내 지원 기능 개발
- [ ] 서비스 유형별 신청서 UI 및 통합 리스트 구현
- [ ] 승인/반려/배정 처리 기능 구현
- [ ] 자산 및 차량 일정 관리 기능 구축
- [ ] 첨부파일 및 댓글 시스템 구축
### 7.4 Phase 4. 고도화 및 운영 최적화
- [ ] FAQ 추천 및 중복 문의·중복 신청 사전 방지 기능 탑재
- [ ] 네이버웍스 알림, SMS 대체 발송, 처리 지연 리마인드 기능 고도화
- [ ] S/W별 Q&A 통계와 사내 지원 서비스 운영 인사이트 보고서 자동화
### 7.5 추후 개발 예정 기능
#### 7.5.1 공용 플랫폼 확장 기능
- 조직도 기반 결재선 자동 추천 기능: 신청 유형과 부서 기준으로 결재 대상 자동 추천 기능
- 자산 메타정보 동기화 기능: 사내 자산관리 시스템 또는 외부 마스터 정보와 비품, 차량, 도서 정보를 자동 동기화하는 기능
- 도서 및 비품 재고 예측 기능: 사용량 기반 부족 품목 예측 및 사전 구매 추천 기능
- 서비스별 맞춤 대시보드 기능: 부서별 처리량, 반려율, 평균 승인 시간 시각화 기능
- 앱 메타정보 동기화 기능: BARON-SSO 또는 외부 시스템에 등록된 S/W 정보를 공용 플랫폼과 자동으로 맞추는 기능
- S/W별 Q&A 딥링크 또는 임베드 연동 기능: 각 소프트웨어 내부에서 해당 앱의 Q&A 화면으로 바로 이동하거나 일부 화면을 직접 표시하는 기능
- 사내 포털 딥링크 또는 임베드 연동 기능: 그룹웨어 또는 사내 포털에서 해당 서비스 화면으로 바로 이동하거나 일부 화면을 직접 표시하는 기능
#### 7.5.2 적용 검토 기준
- 사내 자산관리, 그룹웨어, 조직도 API의 실제 연동 가능 범위 확인
- BARON-SSO 또는 외부 시스템의 앱 메타정보 동기화 가능 범위 확인
- 결재 정책과 운영 프로세스의 시스템 반영 가능 여부 확인
- 네이버웍스 알림 대상자 및 부서별 알림 정책 적용 가능 여부 확인
- 외부 고객 대상 SMS 발송 정책 및 개인정보 보관 기준 적용 가능 여부 확인
- 운영 복잡도 대비 활용 효과가 높은 기능 우선 적용
@@ -0,0 +1,497 @@
# 사내 지원 플랫폼 통합 아키텍처 설계서
## 1. 문서 목적
본 문서는 BARON-SSO 기반 공용 플랫폼으로 다음 두 서비스를 하나의 구조로 통합하는 방안을 설명함.
- 각 S/W 프로그램에서 진입하는 S/W별 Q&A 플랫폼
- 회사 인트라넷에서 진입하는 사내 지원 플랫폼
본 문서는 상세 테이블 설명보다 먼저 서비스의 전체 그림, 사용자 진입 방식, 인증 구조, 핵심 처리 계층, 외부 연동 방식을 이해할 수 있도록 정리함.
## 2. 한눈에 보는 서비스 구조
### 2.1 통합 대상 서비스
| 구분 | 설명 |
| --- | --- |
| S/W Q&A | 각 S/W 프로그램에서 로그인 후 해당 앱 전용 Q&A 게시판으로 연결되는 지원 서비스 |
| 사내 지원 | 인트라넷에서 진입하여 물품신청, 도서 신청, 출장 차량 신청, 비품 대여, 사내 Q&A를 처리하는 지원 서비스 |
### 2.2 핵심 설계 판단
- 사용자와 tenant의 원본 정보는 BARON-SSO에서 관리
- 플랫폼 내부에서는 사용자 마스터를 별도로 두지 않고 `user_id`, `tenant_id` 기반으로 권한만 관리
- 두 서비스는 각각 별도 시스템으로 만들지 않고 공통 `workspace` 기반 플랫폼으로 통합
- 게시글, 신청, 댓글, 첨부, FAQ, 알림은 공통 엔진으로 처리
- 승인, 자산, 차량, 원격지원은 서비스별 확장 기능으로 분리
- 승인 및 반려는 일반 사용자 화면이 아니라 담당자용 운영 페이지에서 처리
## 3. High-Level Architecture
### 3.1 아키텍처 관점
| 관점 | 설명 |
| --- | --- |
| 사용자 접점 | 사용자가 어디서 진입하는지 |
| 인증 계층 | BARON-SSO가 어디에서 인증을 담당하는지 |
| 핵심 서비스 | 어떤 애플리케이션 계층에서 업무를 처리하는지 |
| 인프라 및 외부 연동 | 데이터 저장과 알림, 외부 시스템 연동이 어디서 발생하는지 |
### 3.2 High-Level Architecture 다이어그램
```mermaid
flowchart LR
subgraph U[사용자 영역]
U1[인트라넷 사용자]
U2[사내 S/W 사용자]
U3[외부 고객]
end
subgraph E[사용자 접점]
E1[인트라넷 포털]
E2[각 S/W 프로그램]
end
subgraph A[인증 계층]
A1[BARON-SSO\nOAuth 2.0 / OIDC]
end
subgraph P[플랫폼 시스템]
subgraph T1[UI Tier]
F1[웹 클라이언트\nNext.js]
F2[운영 / 관리 페이지\n담당자 · 승인자 · 관리자]
end
subgraph T2[API Tier]
B1[지원 플랫폼 API\nFastAPI]
B2[권한 제어\nuser_id, tenant_id, workspace 기반]
B3[업무 처리 엔진\nQ&A / 신청 / 승인 / 자산 / 차량 / 원격지원]
B4[알림 처리\nNaver Works 우선, SMS 대체]
end
subgraph T3[Data Tier]
D1[PostgreSQL]
end
end
subgraph X[외부 연동]
X1[Naver Works API]
X2[SMS Gateway]
X3[자산 / 조직도 / 기타 사내 API]
end
U1 --> E1
U2 --> E2
U3 --> E2
E1 --> F1
E2 --> F1
F1 --> A1
A1 --> F1
F1 --> B1
F2 --> A1
A1 --> F2
F2 --> B1
B1 --> B2
B1 --> B3
B2 --> D1
B3 --> D1
B1 --> B4
B4 --> X1
B4 --> X2
B3 --> X3
```
### 3.3 전체 흐름 요약
1. 사용자는 인트라넷 포털 또는 각 S/W 프로그램에서 지원 플랫폼으로 진입함.
2. 웹 클라이언트는 BARON-SSO를 통해 인증을 수행하고 `user_id`, `tenant_id`를 확보함.
3. 플랫폼 API는 진입 경로의 `app_id` 또는 `service_type_id`를 내부 `workspace`로 매핑함.
4. 권한 제어 계층은 사용자별 읽기, 쓰기, 관리, 승인 범위를 확인함.
5. 일반 사용자는 사용자 화면에서 문의 또는 신청을 등록하고, 담당자는 운영 페이지에서 승인, 반려, 답변, 상태 변경을 처리함.
6. 데이터는 PostgreSQL에 저장하고 알림은 네이버웍스 우선, 실패 시 SMS로 대체 발송함.
7. 필요 시 자산 시스템, 조직도, 기타 사내 API와 연계함.
## 4. 서비스 구성
### 4.1 공통 플랫폼으로 통합하는 이유
두 서비스는 진입 채널과 세부 기능은 다르지만, 실제로는 다음 기능을 공통으로 사용함.
- 게시글 또는 신청서 작성
- 담당자 답변 및 처리 이력 관리
- 첨부파일 관리
- FAQ 및 공지 제공
- 권한별 화면 노출
- 상태 변경 및 알림 발송
따라서 서비스별로 별도 시스템을 만드는 대신 공통 플랫폼을 두고, 서비스별 차이는 `workspace`와 확장 테이블로 흡수하는 구조가 적절함.
### 4.2 S/W Q&A 서비스
S/W Q&A 서비스는 각 프로그램 사용자 또는 외부 고객이 해당 앱의 전용 게시판에 접속하여 문의를 등록하고 답변을 받는 구조임.
주요 기능은 다음과 같음.
- 앱별 전용 게시판 제공
- 문의 작성 및 담당자 답변
- 비밀글 처리
- 상태 변경 및 FAQ 추천
- 필요 시 원격지원 일정 등록
- 답변 등록 또는 상태 변경 시 알림 발송
### 4.3 사내 지원 서비스
사내 지원 서비스는 인트라넷에서 접근하는 업무 지원 포털 성격의 서비스임.
지원 범위는 다음과 같음.
- 물품신청
- 도서 신청
- 출장 차량 신청
- 비품 대여
- 사내 Q&A
공통 처리 흐름은 다음과 같음.
- 신청서 작성
- 승인 또는 반려
- 자산 배정 또는 차량 일정 등록
- 처리 결과 알림 발송
### 4.4 운영 및 관리 페이지
사내 지원 서비스에는 담당자가 승인 또는 반려를 처리하는 운영 페이지가 필요함. 이는 단순 상태 변경 화면이 아니라 권한과 이력 관리의 중심 화면 역할을 담당함.
운영 페이지의 필요 이유는 다음과 같음.
- 승인 대기 건을 한 번에 조회 가능
- 신청 상세 내용을 확인한 뒤 승인 또는 반려 처리 가능
- 반려 사유 입력 및 승인 이력 관리 가능
- 승인 이후 자산 배정, 차량 일정 등록, 후속 알림 발송까지 연결 가능
- `can_approve`, `can_manage`, `page_scope` 권한과 직접 연결 가능
운영 페이지는 별도 시스템으로 분리하기보다 동일 플랫폼 내부의 권한 기반 메뉴로 구성하는 방식이 적절함.
## 5. 핵심 구성요소 상세
### 5.1 사용자 접점
| 접점 | 설명 |
| --- | --- |
| 인트라넷 포털 | 사내 지원 서비스 진입점 |
| 각 S/W 프로그램 | S/W별 Q&A 서비스 진입점 |
| 운영 / 관리 페이지 | 담당자, 승인자, 관리자가 사용하는 내부 운영 화면 |
인트라넷에서는 서비스 유형 기준으로 진입하고, S/W 프로그램에서는 앱 기준으로 진입함. 운영 담당자는 별도 운영 메뉴를 통해 진입하지만, 이 역시 내부적으로는 동일한 `workspace`와 권한 체계를 사용함.
### 5.2 인증 및 권한 계층
BARON-SSO는 사용자 인증과 tenant 식별의 원본 시스템 역할을 담당함. 플랫폼은 BARON-SSO로부터 받은 `user_id`, `tenant_id`를 기준으로 내부 권한만 제어함.
플랫폼 내부 권한 항목은 다음과 같음.
- `can_read`
- `can_write`
- `can_manage`
- `can_approve`
- `page_scope`
이 구조를 사용하면 사용자 기본 정보는 외부에서 일관되게 유지하고, 플랫폼 내부에서는 읽기, 쓰기, 승인, 관리 범위만 유연하게 제어 가능함.
특히 승인 또는 반려 처리는 `can_approve` 권한이 있는 담당자만 수행하도록 제한하고, 운영 화면 접근 범위는 `page_scope`로 분리하는 방식이 적절함.
### 5.3 핵심 서비스 계층
핵심 서비스 계층은 FastAPI 기반 API 서버로 구성하며, 다음 기능을 공통 처리함.
| 기능 영역 | 설명 |
| --- | --- |
| Workspace Engine | 앱 또는 인트라넷 서비스를 내부 작업 단위로 매핑 |
| Ticket Engine | Q&A와 신청서를 공통 구조로 저장 및 처리 |
| Comment Engine | 답변, 처리 메모, 협업 이력 관리 |
| Attachment Engine | 첨부파일 저장 및 조회 관리 |
| FAQ Engine | 워크스페이스별 FAQ와 공지성 정보 제공 |
| Approval Extension | 신청 승인 및 반려 처리 |
| Asset Extension | 물품, 비품, 도서, 차량 자산 관리 |
| Remote Support Extension | S/W 문의의 원격지원 일정 및 처리 관리 |
이 중 Approval Extension은 일반 사용자 화면보다 운영 페이지와 더 강하게 연결됨. 승인 담당자는 운영 페이지에서 대기 건 조회, 승인 또는 반려 처리, 반려 사유 작성, 후속 조치 등록을 수행함.
### 5.4 데이터 및 외부 연동 계층
PostgreSQL은 플랫폼의 공통 데이터 저장소 역할을 담당함. 외부 연동은 알림과 운영 정보 보강 목적에 집중함.
| 연동 대상 | 목적 |
| --- | --- |
| Naver Works API | 기본 알림 채널 |
| SMS Gateway | 네이버웍스 실패 또는 미보유 사용자 대체 알림 |
| 자산/조직도/기타 사내 API | 자산 정보 조회, 조직 기반 처리, 추가 업무 연계 |
알림은 네이버웍스를 우선 사용하고, 발송 실패 또는 계정 미보유 시 SMS로 대체하는 정책을 적용함.
## 6. DB 설계 방향
### 6.1 설계 원칙
- 사용자 마스터는 BARON-SSO에서 관리함.
- 로컬 DB는 권한, 워크스페이스, 업무 데이터, 알림 보조 정보만 관리함.
- Q&A와 사내 지원 요청은 분리 저장하지 않고 공통 티켓 구조로 통합함.
- 서비스별 차이는 확장 테이블로 분리하여 향후 신규 앱과 신규 사내 서비스가 추가되어도 구조 변경을 최소화함.
- 운영 페이지는 별도 사용자 테이블 없이 기존 권한 테이블과 승인 이력 테이블을 활용하여 구성함.
### 6.2 데이터 영역 구분
| 데이터 영역 | 주요 테이블 | 설명 |
| --- | --- | --- |
| 서비스 마스터 | `software_apps`, `service_types`, `workspaces` | 진입 경로를 내부 서비스 단위로 매핑 |
| 권한 관리 | `user_workspace_access` | 사용자별 읽기, 쓰기, 관리, 승인 범위 제어 |
| 알림 보조 정보 | `user_notification_profiles` | 네이버웍스 키, 전화번호, SMS 수신 여부 관리 |
| 공통 업무 데이터 | `support_tickets`, `ticket_comments`, `attachments`, `faqs` | Q&A와 신청 데이터를 공통 구조로 관리 |
| 코드 관리 | `support_status_codes`, `support_category_codes`, `remote_support_status_codes` | 상태 및 분류 표준화 |
| 사내 지원 확장 | `request_approvals`, `assets`, `asset_allocations`, `vehicle_schedules` | 승인, 자산, 차량 업무 처리 |
| S/W 지원 확장 | `remote_support` | 원격지원 일정 및 처리 이력 관리 |
| 운영 이력 | `notification_logs` | 알림 발송 및 실패 이력 추적 |
### 6.3 핵심 엔터티 설명
#### 6.3.1 workspace
`workspace`는 이 설계의 중심 엔터티임. 외부에서는 S/W 앱 또는 인트라넷 서비스로 보이지만, 내부에서는 모두 `workspace`로 수렴함. 이 구조를 사용하면 신규 앱 또는 신규 사내 서비스가 생겨도 공통 기능을 재사용 가능함.
#### 6.3.2 support_tickets
Q&A 게시글과 각종 신청서를 별도 본문 테이블로 나누지 않고 `support_tickets`로 통합 관리함. 대신 `ticket_type`, `workspace_id`, `category_code`, `status_code`로 의미를 구분함.
#### 6.3.3 user_workspace_access
플랫폼은 사용자 상세 프로필을 저장하지 않지만, 어떤 사용자가 어떤 워크스페이스에서 무엇을 할 수 있는지는 반드시 관리해야 함. 이 역할을 `user_workspace_access`가 담당함.
운영 페이지 관점에서는 이 테이블이 특히 중요함. 승인 담당자 여부, 운영 메뉴 접근 가능 여부, 특정 워크스페이스에 대한 승인 가능 범위가 모두 이 테이블의 권한 컬럼으로 제어되기 때문임.
#### 6.3.4 request_approvals
`request_approvals`는 승인 또는 반려가 실제로 수행된 결과를 남기는 이력 테이블임. 승인 담당자 정보, 처리 결과, 반려 사유, 승인 시각을 저장하므로 운영 페이지의 감사 추적과 처리 내역 조회에 직접 사용됨.
## 7. DB 스키마 초안
```sql
-- 1. 소프트웨어 정보
CREATE TABLE software_apps (
id SERIAL PRIMARY KEY,
app_code VARCHAR(50) UNIQUE NOT NULL,
app_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 사내 서비스 유형 정보
CREATE TABLE service_types (
id SERIAL PRIMARY KEY,
service_code VARCHAR(50) UNIQUE NOT NULL,
service_name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 3. 공통 워크스페이스 마스터
CREATE TABLE workspaces (
id SERIAL PRIMARY KEY,
workspace_type VARCHAR(20) NOT NULL,
software_app_id INTEGER REFERENCES software_apps(id),
service_type_id INTEGER REFERENCES service_types(id),
workspace_code VARCHAR(50) UNIQUE NOT NULL,
workspace_name VARCHAR(100) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CHECK (
(workspace_type = 'SOFTWARE_APP' AND software_app_id IS NOT NULL AND service_type_id IS NULL)
OR
(workspace_type = 'INTRANET_SERVICE' AND service_type_id IS NOT NULL AND software_app_id IS NULL)
)
);
-- 4. 사용자별 워크스페이스 접근 권한 및 역할
CREATE TABLE user_workspace_access (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100) NOT NULL,
tenant_id VARCHAR(100) NOT NULL,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
workspace_role VARCHAR(20) NOT NULL DEFAULT 'USER',
can_read BOOLEAN DEFAULT TRUE,
can_write BOOLEAN DEFAULT FALSE,
can_manage BOOLEAN DEFAULT FALSE,
can_approve BOOLEAN DEFAULT FALSE,
page_scope VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, tenant_id, workspace_id)
);
-- 5. 사용자 알림 보조 정보
CREATE TABLE user_notification_profiles (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100) NOT NULL,
tenant_id VARCHAR(100) NOT NULL,
user_type VARCHAR(20) NOT NULL DEFAULT 'INTERNAL',
phone_number VARCHAR(30),
naverworks_user_key VARCHAR(100),
sms_opt_in BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, tenant_id)
);
-- 6. 공통 상태 코드
CREATE TABLE support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 7. 공통 카테고리 코드
CREATE TABLE support_category_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 8. 공통 게시글/신청 본문
CREATE TABLE support_tickets (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
requester_id VARCHAR(100) NOT NULL,
requester_tenant_id VARCHAR(100) NOT NULL,
ticket_type VARCHAR(20) NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT,
category_code VARCHAR(20) REFERENCES support_category_codes(code),
status_code VARCHAR(20) NOT NULL DEFAULT 'OPEN' REFERENCES support_status_codes(code),
is_secret BOOLEAN DEFAULT FALSE,
requested_start_at TIMESTAMP,
requested_end_at TIMESTAMP,
priority VARCHAR(20) DEFAULT 'NORMAL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 9. 댓글 및 처리 메모
CREATE TABLE ticket_comments (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
author_id VARCHAR(100) NOT NULL,
author_tenant_id VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 10. 첨부파일 통합 관리
CREATE TABLE attachments (
id SERIAL PRIMARY KEY,
parent_type VARCHAR(20) NOT NULL,
parent_id INTEGER NOT NULL,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
file_name VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 11. 사내 지원용 승인 이력
CREATE TABLE request_approvals (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
approver_id VARCHAR(100) NOT NULL,
approver_tenant_id VARCHAR(100) NOT NULL,
approval_status VARCHAR(20) NOT NULL,
comment TEXT,
approved_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 12. 자산/비품 마스터
CREATE TABLE assets (
id SERIAL PRIMARY KEY,
asset_code VARCHAR(50) UNIQUE NOT NULL,
asset_name VARCHAR(100) NOT NULL,
asset_type VARCHAR(30) NOT NULL,
quantity INTEGER DEFAULT 1,
is_active BOOLEAN DEFAULT TRUE,
location VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 13. 자산 배정 및 대여 이력
CREATE TABLE asset_allocations (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
assignee_id VARCHAR(100),
assignee_tenant_id VARCHAR(100),
allocation_status VARCHAR(20) NOT NULL,
loaned_at TIMESTAMP,
due_at TIMESTAMP,
returned_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 14. 차량 운행 일정
CREATE TABLE vehicle_schedules (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
asset_id INTEGER NOT NULL REFERENCES assets(id),
departure_at TIMESTAMP NOT NULL,
arrival_at TIMESTAMP,
destination VARCHAR(255),
driver_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 15. S/W Q&A용 원격 지원 상태 코드
CREATE TABLE remote_support_status_codes (
code VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
sort_order INTEGER NOT NULL
);
-- 16. S/W Q&A용 원격 지원 로그
CREATE TABLE remote_support (
id SERIAL PRIMARY KEY,
ticket_id INTEGER NOT NULL REFERENCES support_tickets(id),
status_code VARCHAR(20) REFERENCES remote_support_status_codes(code),
support_engineer_id VARCHAR(100),
support_engineer_tenant_id VARCHAR(100),
scheduled_time TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 17. 공통 FAQ
CREATE TABLE faqs (
id SERIAL PRIMARY KEY,
workspace_id INTEGER NOT NULL REFERENCES workspaces(id),
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 18. 알림 발송 이력
CREATE TABLE notification_logs (
id SERIAL PRIMARY KEY,
ticket_id INTEGER REFERENCES support_tickets(id),
recipient_id VARCHAR(100) NOT NULL,
recipient_tenant_id VARCHAR(100) NOT NULL,
channel VARCHAR(20) NOT NULL,
target_address VARCHAR(100),
delivery_status VARCHAR(20) NOT NULL,
fallback_channel VARCHAR(20),
error_message TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
## 8. 정리
이 설계의 핵심은 S/W별 Q&A와 인트라넷 사내 지원을 서로 다른 시스템으로 분리하지 않고, BARON-SSO와 `workspace` 중심 공통 플랫폼으로 통합하는 데 있음. 사용자 정보는 BARON-SSO를 원본으로 유지하고, 플랫폼은 권한과 업무 처리에 집중함. 그 결과 서비스 확장성과 운영 일관성을 동시에 확보 가능함.
다음 단계에서는 상태 코드 표준값, `page_scope` 체계, 주요 API 목록, 화면 구성도를 추가하면 구현 준비 수준의 설계 문서로 확장 가능함.
@@ -0,0 +1,698 @@
# 사내 지원 플랫폼 통합 아키텍처 설계서
## 1. 문서 목적
본 문서는 BARON-SSO 기반 공용 플랫폼으로 다음 두 서비스를 하나의 구조로 통합하는 방안을 설명함.
- 각 S/W 프로그램에서 진입하는 S/W별 Q&A 플랫폼
- 회사 인트라넷에서 진입하는 사내 지원 플랫폼
이번 설계의 핵심은 기존 ABC User Feedback 솔루션을 그대로 폐기하지 않고, 원본 게시글 저장소와 채널 관리 도구로 활용하면서 우리 시스템이 권한 제어, 승인 워크플로우, 동적 폼, 운영 대시보드를 담당하는 구조로 고도화하는 데 있음.
## 2. 한눈에 보는 통합 방향
### 2.1 통합 대상 서비스
| 구분 | 설명 |
| --- | --- |
| S/W Q&A | 각 S/W 프로그램에서 로그인 후 해당 앱 전용 Q&A 채널로 연결되는 지원 서비스 |
| 사내 지원 | 인트라넷에서 진입하여 물품신청, 도서 신청, 출장 차량 신청, 비품 대여, 사내 Q&A를 처리하는 지원 서비스 |
### 2.2 핵심 설계 판단
- 사용자 인증과 `tenant_id` 식별의 원본은 BARON-SSO가 담당함.
- ABC User Feedback는 게시글 원본 저장소이자 관리자 기반 채널/필드 관리 도구로 사용함.
- 우리 시스템은 FastAPI와 자체 DB를 통해 권한 분기, 상태 제어, 승인 이력, 운영 화면을 담당함.
- 외부 진입 경로의 `app_id`, `service_type_id`는 내부 `workspace`로 매핑함.
- 일반 사용자는 Next.js 동적 폼과 조회 화면을 사용하고, 담당자는 운영 페이지에서 승인/반려/후속 조치를 처리함.
- Q&A와 신청은 공통 티켓 모델로 다루되, 실제 원본 본문은 ABC에 저장하고 우리 DB에는 제어용 메타데이터와 매핑 정보를 저장함.
### 2.3 역할 분리 요약
| 구성요소 | 주 역할 | 저장 데이터 |
| --- | --- | --- |
| BARON-SSO | 사용자 인증, `user_id`, `tenant_id` 발급 | 사용자/조직 원본 정보 |
| ABC User Feedback | 게시글 저장, 댓글/첨부 관리, 채널/필드 구성, 기본 목록/상세 UI | 피드백 원본 데이터, 채널 설정, 필드 값 |
| 우리 시스템 | 권한 필터링, 승인 워크플로우, 상태 제어, 운영 페이지, 동적 폼, 외부 연동 오케스트레이션 | 권한, 워크스페이스, 매핑, 승인, 자산, 차량, 알림, 운영 이력 |
## 3. High-Level Architecture
### 3.1 아키텍처 관점
| 관점 | 설명 |
| --- | --- |
| 사용자 접점 | 사용자가 어디서 진입하는지 |
| 인증 계층 | BARON-SSO가 어디에서 인증을 담당하는지 |
| 데이터 저장 계층 | ABC와 자체 DB가 어떤 데이터를 나눠 저장하는지 |
| 제어 계층 | 권한, 승인, 운영 로직이 어디에서 처리되는지 |
| 외부 연동 | 알림, 자산, 조직도, 기타 사내 API가 어디에서 연결되는지 |
### 3.2 High-Level Architecture 다이어그램
아래 다이어그램은 처리 행위를 화살표 라벨로 표시하고, 결과가 쌓이거나 보여지는 지점은 사각형 박스로 구분한 구조임.
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f7f7f7,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
subgraph U[사용자 영역]
U1[인트라넷 사용자]
U2[S/W 사용자]
U3[운영 담당자]
end
subgraph E[진입 채널]
E1[인트라넷 포털]
E2[각 S/W 프로그램]
E3[운영 메뉴]
end
SSO[BARON-SSO\nOAuth 2.0 / OIDC]:::external
subgraph UI[화면 계층]
N1[Next.js 사용자 화면\n동적 폼 / 조회 / 상세]:::result
N2[Next.js 운영 페이지\n승인 / 반려 / 후속 조치]:::result
end
subgraph CTL[우리 시스템\nFastAPI + 자체 DB]
F1[권한 분기 엔진\nuser_id + tenant_id + workspace]:::control
F2[업무 프로세스 엔진\n상태 제어 / 승인 워크플로우 / 후속 조치]:::control
F3[브릿지 API\nABC API 연동 / 매핑 기록]:::control
D1[자체 제어 DB\n권한 / 매핑 / 승인 / 자산 / 차량 / 알림]:::result
end
subgraph ABC[ABC User Feedback]
A1[채널 / 필드 관리자 UI]:::result
A2[Feedback API\nPOST /feedbacks 등]:::control
A3[원본 데이터 저장소\n제목 / 본문 / 댓글 / 첨부 / 필드값]:::result
A4[기본 목록 / 상세 UI]:::result
end
subgraph X[외부 연동]
X1[Naver Works API]:::external
X2[SMS Gateway]:::external
X3[자산 / 조직도 / 기타 사내 API]:::external
end
U1 -->|인트라넷 서비스 진입| E1
U2 -->|앱 내부 지원 메뉴 진입| E2
U3 -->|운영 메뉴 진입| E3
E1 -->|사용자 화면 호출| N1
E2 -->|사용자 화면 호출| N1
E3 -->|운영 페이지 호출| N2
N1 -->|SSO 로그인 요청| SSO
N2 -->|운영자 인증 요청| SSO
SSO -->|user_id, tenant_id, 토큰 반환| N1
SSO -->|운영 권한 토큰 반환| N2
N1 -->|폼/목록 조회 요청| F1
N1 -->|신청/문의 등록 요청| F3
N2 -->|승인 대기/처리 요청| F2
F1 -->|workspace 매핑 및 권한 판정| D1
F2 -->|승인 이력 / 상태 저장| D1
F3 -->|매핑 정보 조회 및 기록| D1
F3 -->|채널/필드 조회| A1
F3 -->|원본 게시글 생성/조회| A2
A2 -->|피드백 원본 저장| A3
A2 -->|기본 목록/상세 제공| A4
F2 -->|알림 발송 요청| X1
F2 -->|실패 시 대체 발송| X2
F2 -->|자산/차량 후속 처리| X3
```
### 3.3 전체 처리 흐름 요약
1. 사용자는 인트라넷 포털 또는 S/W 프로그램에서 Next.js 사용자 화면으로 진입함.
2. 사용자 화면은 BARON-SSO를 통해 인증하고 `user_id`, `tenant_id`를 확보함.
3. 우리 시스템의 권한 분기 엔진은 진입 경로를 `workspace`로 매핑하고 조회/등록 가능 범위를 판단함.
4. 사용자가 문의 또는 신청서를 등록하면 브릿지 API가 ABC Feedback API로 원본 데이터를 저장함.
5. 동시에 우리 DB에는 `workspace`, 상태, 요청 유형, ABC 피드백 ID, 기존 시스템 ID, 승인 필요 여부 등 제어 정보를 저장함.
6. 담당자는 운영 페이지에서 승인 대기 건을 조회하고 `request_approvals` 기반으로 승인/반려/후속 조치를 처리함.
7. 승인 결과와 상태 변경은 우리 DB에 기록되고, 필요 시 Naver Works 또는 SMS, 자산/차량 API 연동이 수행됨.
## 4. 서비스 책임 분리
### 4.1 ABC User Feedback의 역할
ABC User Feedback는 기능 저장소이자 데이터 저장소로 사용함. 즉, 사용자에게 보이는 게시글 원본과 채널 구조는 ABC가 책임지고, 우리 시스템은 이를 직접 대체하지 않음.
ABC가 담당하는 범위는 다음과 같음.
- 게시글 원본 데이터 저장
- 제목, 본문, 댓글, 첨부파일 저장
- 채널 생성 및 채널별 필드 구성
- 신청서 항목을 표현하는 커스텀 필드 저장
- 시스템 API를 통한 피드백 생성 및 조회
- 기본 목록/상세 UI 제공
즉, ABC는 "무엇이 기록되었는가"를 보존하는 원본 시스템임.
### 4.2 우리 시스템의 역할
우리 시스템은 FastAPI, Next.js, 자체 DB를 사용하여 ABC 위에 제어 계층을 추가함.
우리 시스템이 담당하는 범위는 다음과 같음.
- `tenant_id``workspace` 기준 권한 분기
- 사용자별 조회 가능 데이터 필터링
- 신청서 상태 제어: 대기, 승인, 반려, 처리 완료
- `request_approvals` 기반 승인 워크플로우 처리
- 자산 배정, 차량 배차, 원격지원 등 확장 프로세스 처리
- 운영 대시보드 제공
- Next.js 동적 폼 렌더링 및 유효성 검사
- 기존 데이터 마이그레이션 시 ABC ID와 기존 글 ID 매핑 관리
즉, 우리 시스템은 "누가 무엇을 볼 수 있고, 어떤 절차로 처리되는가"를 책임지는 지능형 제어 엔진임.
### 4.3 화면 구성 원칙
| 화면 | 주 시스템 | 설명 |
| --- | --- | --- |
| 일반 사용자 입력 화면 | 우리 시스템 | 진입 경로별 동적 폼, 유효성 검사, 등록 프로세스 제어 |
| 일반 사용자 목록/상세 | 혼합 | 우리 시스템의 권한 필터링 결과와 ABC 원본 데이터를 조합하여 노출 |
| 운영 페이지 | 우리 시스템 | 승인/반려/후속 조치 전용 대시보드 |
| 채널/필드 관리자 화면 | ABC User Feedback | 채널 생성, 필드 구성, 스키마 관리 |
## 5. DB 설계 방향
### 5.1 설계 원칙
- 사용자 마스터와 조직 정보는 BARON-SSO에서 관리함.
- 게시글 원본, 댓글, 첨부, 채널 필드 값은 ABC에 저장함.
- 우리 DB는 제어용 메타데이터와 운영용 확장 데이터만 저장함.
- `support_tickets`는 내부 티켓 식별자이자 ABC 피드백과 연결되는 제어 엔트리 역할을 수행함.
- 마이그레이션과 운영 연계에 필요한 식별자 매핑은 별도 매핑 테이블로 관리함.
- 승인, 자산, 차량, 원격지원은 ABC 원본과 느슨하게 연결된 확장 테이블로 관리함.
### 5.2 데이터 저장 책임 분리
| 데이터 범주 | 저장 위치 | 설명 |
| --- | --- | --- |
| 사용자 인증 정보 | BARON-SSO | `user_id`, `tenant_id`, 토큰, 조직 기준 원본 |
| 게시글 원본 | ABC User Feedback | 제목, 본문, 댓글, 첨부, 사용자 입력 필드 값 |
| 권한/워크스페이스 | 우리 DB | `workspace`, 역할, 읽기/쓰기/승인/관리 권한 |
| 제어용 티켓 메타데이터 | 우리 DB | 내부 티켓 ID, 상태, ABC 피드백 ID, 승인 필요 여부 |
| 업무 확장 데이터 | 우리 DB | 승인, 자산, 차량, 원격지원, 알림 로그 |
| 마이그레이션 매핑 | 우리 DB | 기존 시스템 ID와 ABC 피드백 ID, 내부 티켓 ID 연결 |
### 5.3 핵심 관계 구조
```mermaid
flowchart TD
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.2px,color:#0f172a;
classDef control fill:#f7f7f7,stroke:#334155,stroke-width:1.2px,color:#111827;
W[workspaces]:::result -->|1:N 서비스 범위 정의| UWA[user_workspace_access]:::result
W -->|1:N 내부 티켓 소속| ST[support_tickets]:::result
ST -->|1:1 또는 1:N ABC 원본 연결| AFM[abc_feedback_mappings]:::result
AFM -->|ABC feedback_id 참조 기록| ABCREF[ABC feedback]:::control
ST -->|1:N 승인 이력| RA[request_approvals]:::result
ST -->|1:N 자산 배정| AA[asset_allocations]:::result
ST -->|1:N 차량 일정| VS[vehicle_schedules]:::result
ST -->|1:N 원격지원 이력| RS[remote_support]:::result
ST -->|1:N 알림 이력| NL[notification_logs]:::result
ST -->|1:N 마이그레이션 추적| MM[migration_mappings]:::result
```
## 6. DB 스키마 상세화
### 6.1 자체 DB 데이터 영역
| 데이터 영역 | 주요 테이블 | 설명 |
| --- | --- | --- |
| 서비스 마스터 | `software_apps`, `service_types`, `workspaces` | 진입 채널을 내부 `workspace`로 매핑 |
| 권한 관리 | `user_workspace_access` | 읽기, 쓰기, 운영, 승인 권한 제어 |
| 폼/채널 연동 | `workspace_channel_mappings`, `workspace_field_mappings` | `workspace`와 ABC 채널/필드 연결 |
| 공통 티켓 메타데이터 | `support_tickets` | 내부 상태, 요청자, 티켓 유형, 우선순위 관리 |
| ABC 연동 매핑 | `abc_feedback_mappings` | 내부 티켓과 ABC `feedback_id` 연결 |
| 마이그레이션 추적 | `migration_mappings`, `migration_batches` | 기존 글 ID, 기존 첨부 ID, ABC ID 적재 이력 관리 |
| 승인/운영 | `request_approvals`, `notification_logs` | 승인 및 알림 처리 이력 |
| 업무 확장 | `assets`, `asset_allocations`, `vehicle_schedules`, `remote_support` | 자산, 차량, 원격지원 업무 관리 |
### 6.2 핵심 상세 테이블 제안
아래 스키마는 ABC와 우리 DB의 역할 분리를 반영한 초안임.
```sql
CREATE TABLE software_apps (
id BIGINT NOT NULL AUTO_INCREMENT,
app_code VARCHAR(50) NOT NULL,
app_name VARCHAR(100) NOT NULL,
description TEXT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_software_apps_app_code (app_code),
UNIQUE KEY uq_software_apps_app_name (app_name)
);
CREATE TABLE service_types (
id BIGINT NOT NULL AUTO_INCREMENT,
service_code VARCHAR(50) NOT NULL,
service_name VARCHAR(100) NOT NULL,
description TEXT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_service_types_service_code (service_code),
UNIQUE KEY uq_service_types_service_name (service_name)
);
CREATE TABLE workspaces (
id BIGINT NOT NULL AUTO_INCREMENT,
workspace_type VARCHAR(20) NOT NULL,
software_app_id BIGINT NULL,
service_type_id BIGINT NULL,
workspace_code VARCHAR(50) NOT NULL,
workspace_name VARCHAR(100) NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_workspaces_workspace_code (workspace_code),
CONSTRAINT fk_workspaces_software_app
FOREIGN KEY (software_app_id) REFERENCES software_apps(id),
CONSTRAINT fk_workspaces_service_type
FOREIGN KEY (service_type_id) REFERENCES service_types(id),
CONSTRAINT chk_workspaces_scope
CHECK (
(workspace_type = 'SOFTWARE_APP' AND software_app_id IS NOT NULL AND service_type_id IS NULL)
OR
(workspace_type = 'INTRANET_SERVICE' AND service_type_id IS NOT NULL AND software_app_id IS NULL)
)
);
CREATE TABLE user_workspace_access (
id BIGINT NOT NULL AUTO_INCREMENT,
user_id VARCHAR(100) NOT NULL,
tenant_id VARCHAR(100) NOT NULL,
workspace_id BIGINT NOT NULL,
workspace_role VARCHAR(30) NOT NULL DEFAULT 'USER',
can_read BOOLEAN NOT NULL DEFAULT TRUE,
can_write BOOLEAN NOT NULL DEFAULT FALSE,
can_manage BOOLEAN NOT NULL DEFAULT FALSE,
can_approve BOOLEAN NOT NULL DEFAULT FALSE,
page_scope VARCHAR(50),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_user_workspace_access_user_tenant_workspace (user_id, tenant_id, workspace_id),
CONSTRAINT fk_user_workspace_access_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id)
);
CREATE TABLE workspace_channel_mappings (
id BIGINT NOT NULL AUTO_INCREMENT,
workspace_id BIGINT NOT NULL,
abc_channel_id VARCHAR(100) NOT NULL,
abc_channel_key VARCHAR(100),
form_template_version VARCHAR(30),
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_workspace_channel_mappings_workspace_channel (workspace_id, abc_channel_id),
CONSTRAINT fk_workspace_channel_mappings_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id)
);
CREATE TABLE workspace_field_mappings (
id BIGINT NOT NULL AUTO_INCREMENT,
workspace_id BIGINT NOT NULL,
abc_channel_id VARCHAR(100) NOT NULL,
abc_field_key VARCHAR(100) NOT NULL,
local_field_code VARCHAR(100) NOT NULL,
field_label VARCHAR(100) NOT NULL,
field_type VARCHAR(30) NOT NULL,
is_required BOOLEAN NOT NULL DEFAULT FALSE,
sort_order INT NOT NULL DEFAULT 0,
validation_rule JSON,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_workspace_field_mappings_workspace_channel_field (workspace_id, abc_channel_id, abc_field_key),
CONSTRAINT fk_workspace_field_mappings_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id)
);
CREATE TABLE support_status_codes (
code VARCHAR(20) NOT NULL,
name VARCHAR(50) NOT NULL,
sort_order INT NOT NULL,
PRIMARY KEY (code)
);
CREATE TABLE support_category_codes (
code VARCHAR(20) NOT NULL,
name VARCHAR(50) NOT NULL,
sort_order INT NOT NULL,
PRIMARY KEY (code)
);
CREATE TABLE support_tickets (
id BIGINT NOT NULL AUTO_INCREMENT,
workspace_id BIGINT NOT NULL,
requester_id VARCHAR(100) NOT NULL,
requester_tenant_id VARCHAR(100) NOT NULL,
ticket_type VARCHAR(30) NOT NULL,
source_system VARCHAR(30) NOT NULL DEFAULT 'ABC',
title VARCHAR(255) NOT NULL,
category_code VARCHAR(20),
status_code VARCHAR(20) NOT NULL,
is_secret BOOLEAN NOT NULL DEFAULT FALSE,
requires_approval BOOLEAN NOT NULL DEFAULT FALSE,
current_assignee_id VARCHAR(100),
current_assignee_tenant_id VARCHAR(100),
requested_start_at TIMESTAMP NULL,
requested_end_at TIMESTAMP NULL,
priority VARCHAR(20) NOT NULL DEFAULT 'NORMAL',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_support_tickets_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
CONSTRAINT fk_support_tickets_category_code
FOREIGN KEY (category_code) REFERENCES support_category_codes(code),
CONSTRAINT fk_support_tickets_status_code
FOREIGN KEY (status_code) REFERENCES support_status_codes(code)
);
CREATE TABLE abc_feedback_mappings (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NOT NULL,
workspace_id BIGINT NOT NULL,
abc_channel_id VARCHAR(100) NOT NULL,
abc_feedback_id VARCHAR(100) NOT NULL,
abc_feedback_url TEXT,
sync_status VARCHAR(20) NOT NULL DEFAULT 'SYNCED',
last_synced_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_abc_feedback_mappings_ticket_id (ticket_id),
UNIQUE KEY uq_abc_feedback_mappings_feedback_id (abc_feedback_id),
CONSTRAINT fk_abc_feedback_mappings_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id),
CONSTRAINT fk_abc_feedback_mappings_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id)
);
CREATE TABLE migration_batches (
id BIGINT NOT NULL AUTO_INCREMENT,
batch_name VARCHAR(100) NOT NULL,
source_system VARCHAR(50) NOT NULL,
started_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP NULL,
status VARCHAR(20) NOT NULL DEFAULT 'RUNNING',
executed_by VARCHAR(100),
notes TEXT,
PRIMARY KEY (id)
);
CREATE TABLE migration_mappings (
id BIGINT NOT NULL AUTO_INCREMENT,
batch_id BIGINT NOT NULL,
source_system VARCHAR(50) NOT NULL,
source_entity_type VARCHAR(30) NOT NULL,
source_entity_id VARCHAR(100) NOT NULL,
source_parent_id VARCHAR(100),
workspace_id BIGINT NOT NULL,
ticket_id BIGINT NULL,
abc_feedback_id VARCHAR(100),
migration_status VARCHAR(20) NOT NULL,
error_message TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_migration_mappings_source_entity (source_system, source_entity_type, source_entity_id),
CONSTRAINT fk_migration_mappings_batch
FOREIGN KEY (batch_id) REFERENCES migration_batches(id),
CONSTRAINT fk_migration_mappings_workspace
FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
CONSTRAINT fk_migration_mappings_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id)
);
CREATE TABLE request_approvals (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NOT NULL,
approver_id VARCHAR(100) NOT NULL,
approver_tenant_id VARCHAR(100) NOT NULL,
approval_status VARCHAR(20) NOT NULL,
comment TEXT,
approved_at TIMESTAMP NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_request_approvals_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id)
);
CREATE TABLE assets (
id BIGINT NOT NULL AUTO_INCREMENT,
asset_code VARCHAR(50) NOT NULL,
asset_name VARCHAR(100) NOT NULL,
asset_type VARCHAR(30) NOT NULL,
quantity INT NOT NULL DEFAULT 1,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
location VARCHAR(100),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_assets_asset_code (asset_code)
);
CREATE TABLE asset_allocations (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NOT NULL,
asset_id BIGINT NOT NULL,
assignee_id VARCHAR(100),
assignee_tenant_id VARCHAR(100),
allocation_status VARCHAR(20) NOT NULL,
loaned_at TIMESTAMP NULL,
due_at TIMESTAMP NULL,
returned_at TIMESTAMP NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_asset_allocations_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id),
CONSTRAINT fk_asset_allocations_asset
FOREIGN KEY (asset_id) REFERENCES assets(id)
);
CREATE TABLE vehicle_schedules (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NOT NULL,
asset_id BIGINT NOT NULL,
departure_at TIMESTAMP NOT NULL,
arrival_at TIMESTAMP NULL,
destination VARCHAR(255),
driver_name VARCHAR(100),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_vehicle_schedules_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id),
CONSTRAINT fk_vehicle_schedules_asset
FOREIGN KEY (asset_id) REFERENCES assets(id)
);
CREATE TABLE remote_support (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NOT NULL,
status_code VARCHAR(20) NOT NULL,
support_engineer_id VARCHAR(100),
support_engineer_tenant_id VARCHAR(100),
scheduled_time TIMESTAMP NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_remote_support_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id)
);
CREATE TABLE notification_logs (
id BIGINT NOT NULL AUTO_INCREMENT,
ticket_id BIGINT NULL,
recipient_id VARCHAR(100) NOT NULL,
recipient_tenant_id VARCHAR(100) NOT NULL,
channel VARCHAR(20) NOT NULL,
target_address VARCHAR(100),
delivery_status VARCHAR(20) NOT NULL,
fallback_channel VARCHAR(20),
error_message TEXT,
sent_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT fk_notification_logs_ticket
FOREIGN KEY (ticket_id) REFERENCES support_tickets(id)
);
```
### 6.3 테이블 간 연동 해석
- `workspaces`는 외부 진입 채널과 내부 처리 단위를 연결하는 기준 테이블임.
- `workspace_channel_mappings`는 하나의 `workspace`가 어떤 ABC 채널을 사용하는지 정의함.
- `workspace_field_mappings`는 Next.js 동적 폼과 ABC 커스텀 필드를 동일한 규칙으로 묶어줌.
- `support_tickets`는 우리 시스템이 상태와 권한을 제어하기 위한 내부 티켓 헤더임.
- `abc_feedback_mappings`는 내부 티켓과 ABC 원본 피드백을 1:1로 연결하는 핵심 브릿지 테이블임.
- `migration_mappings`는 기존 시스템 글, 댓글, 첨부가 어느 내부 티켓과 ABC 피드백으로 적재되었는지 추적함.
## 7. API 엔드포인트 설계
### 7.1 API 설계 원칙
- 외부 클라이언트는 직접 ABC API를 호출하지 않고 우리 FastAPI를 경유함.
- FastAPI는 SSO 토큰을 검증하고 `tenant_id`, `workspace`, 권한 범위를 해석함.
- 등록 시에는 ABC API와 자체 DB 쓰기가 하나의 업무 트랜잭션처럼 동작해야 함.
- 조회 시에는 우리 DB에서 권한 필터링을 먼저 수행하고, 필요 시 ABC 원본 데이터를 조합하여 응답함.
### 7.2 브릿지 API 목록
| 메서드 | 경로 | 목적 |
| --- | --- | --- |
| `POST` | `/api/workspaces/{workspaceCode}/tickets` | 사용자 문의/신청 등록, ABC 피드백 생성, 내부 티켓 및 매핑 저장 |
| `GET` | `/api/workspaces/{workspaceCode}/tickets` | 권한 필터링된 목록 조회 |
| `GET` | `/api/workspaces/{workspaceCode}/tickets/{ticketId}` | 내부 상태 + ABC 원본 상세 조합 조회 |
| `POST` | `/api/workspaces/{workspaceCode}/tickets/{ticketId}/comments` | 댓글 또는 처리 메모 등록 |
| `POST` | `/api/workspaces/{workspaceCode}/tickets/{ticketId}/attachments` | 첨부 업로드 브릿지 처리 |
| `GET` | `/api/workspaces/{workspaceCode}/form-template` | 동적 폼 렌더링용 필드 구성 조회 |
| `GET` | `/api/admin/workspaces/{workspaceCode}/pending-approvals` | 운영 페이지 승인 대기 목록 조회 |
| `POST` | `/api/admin/tickets/{ticketId}/approve` | 승인 처리 및 `request_approvals` 기록 |
| `POST` | `/api/admin/tickets/{ticketId}/reject` | 반려 처리 및 반려 사유 기록 |
| `POST` | `/api/admin/tickets/{ticketId}/follow-up/assets` | 자산 배정 후속 처리 |
| `POST` | `/api/admin/tickets/{ticketId}/follow-up/vehicle` | 차량 배차 후속 처리 |
### 7.3 등록 브릿지 API 처리 순서
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.2px,color:#0f172a;
classDef control fill:#f7f7f7,stroke:#334155,stroke-width:1.2px,color:#111827;
C1[클라이언트 요청]:::result -->|SSO 토큰 포함| C2[FastAPI 브릿지]:::control
C2 -->|workspace 및 권한 확인| C3[user_workspace_access 조회]:::result
C2 -->|필드 매핑 로드| C4[workspace_field_mappings 조회]:::result
C2 -->|ABC payload 변환| C5[ABC POST /feedbacks 호출]:::control
C5 -->|feedback_id 반환| C6[ABC 원본 저장 완료]:::result
C2 -->|내부 티켓 생성| C7[support_tickets 저장]:::result
C2 -->|ABC 연결 기록| C8[abc_feedback_mappings 저장]:::result
C2 -->|승인 필요 여부 판정| C9[초기 상태 결정]:::result
```
### 7.4 조회 API 권한 필터링 규칙
| 시나리오 | 필터 기준 |
| --- | --- |
| 일반 사용자 내 글 조회 | `requester_id = current_user_id` and `requester_tenant_id = current_tenant_id` |
| 워크스페이스 담당자 조회 | `user_workspace_access.can_manage = true` |
| 승인 담당자 조회 | `user_workspace_access.can_approve = true` and `page_scope` 일치 |
| 외부 고객 조회 | 본인 글만 조회, 비밀글은 작성자/담당자만 허용 |
### 7.5 예시 응답 모델
```json
{
"ticketId": 1024,
"workspaceCode": "INTRA_BOOK_REQUEST",
"statusCode": "PENDING_APPROVAL",
"approvalRequired": true,
"abc": {
"channelId": "book-request-channel",
"feedbackId": "fb_938421",
"detailUrl": "https://abc.example.com/feedbacks/fb_938421"
},
"requester": {
"userId": "u1001",
"tenantId": "baron"
}
}
```
## 8. 마이그레이션 매핑 로직 설계
### 8.1 마이그레이션 목표
기존 시스템의 게시글, 신청서, 댓글, 첨부를 ABC 원본 구조로 적재하면서, 동시에 우리 시스템의 내부 티켓과 매핑 정보를 남겨 이후 조회, 권한 제어, 운영 처리에 문제없이 연결되도록 해야 함.
### 8.2 배치 처리 단계
1. 기존 시스템에서 대상 데이터와 첨부 메타데이터를 추출함.
2. 기존 글 유형을 `workspace``ticket_type`으로 변환함.
3. 필드 매핑 규칙에 따라 ABC 커스텀 필드 payload를 생성함.
4. ABC API로 게시글 원본을 생성하고 `abc_feedback_id`를 수신함.
5. 우리 DB의 `support_tickets`에 내부 제어용 티켓을 생성함.
6. `abc_feedback_mappings``migration_mappings`에 연결 정보를 저장함.
7. 댓글과 첨부는 원본 글 적재 완료 후 후속 단계로 연결함.
8. 실패 건은 `migration_status = 'FAILED'``error_message`로 남기고 재처리 가능하게 함.
### 8.3 마이그레이션 흐름 다이어그램
```mermaid
flowchart TD
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.2px,color:#0f172a;
classDef control fill:#f7f7f7,stroke:#334155,stroke-width:1.2px,color:#111827;
M1[기존 시스템 데이터]:::result -->|배치가 원본 추출| M2[Migration Script]:::control
M2 -->|workspace 규칙 적용| M3[workspace 결정 결과]:::result
M2 -->|ABC payload 생성| M4[ABC POST /feedbacks]:::control
M4 -->|abc_feedback_id 수신| M5[ABC 원본 생성 결과]:::result
M2 -->|내부 티켓 생성| M6[support_tickets]:::result
M2 -->|브릿지 연결 저장| M7[abc_feedback_mappings]:::result
M2 -->|이관 추적 저장| M8[migration_mappings]:::result
M2 -->|실패 사유 기록| M9[재처리 대상 목록]:::result
```
### 8.4 마이그레이션 스크립트 의사코드
```python
def migrate_record(source_record):
workspace = resolve_workspace(source_record.app_id, source_record.service_type)
template = load_workspace_template(workspace.id)
abc_payload = build_abc_payload(source_record, template)
abc_feedback = abc_client.create_feedback(
channel_id=template.abc_channel_id,
payload=abc_payload,
)
ticket = create_support_ticket(
workspace_id=workspace.id,
requester_id=source_record.user_id,
requester_tenant_id=source_record.tenant_id,
ticket_type=source_record.ticket_type,
title=source_record.title,
status_code=initial_status(source_record),
)
create_abc_feedback_mapping(
ticket_id=ticket.id,
workspace_id=workspace.id,
abc_channel_id=template.abc_channel_id,
abc_feedback_id=abc_feedback.id,
)
create_migration_mapping(
source_system="legacy_support",
source_entity_type="POST",
source_entity_id=source_record.legacy_id,
workspace_id=workspace.id,
ticket_id=ticket.id,
abc_feedback_id=abc_feedback.id,
migration_status="SYNCED",
)
```
### 8.5 운영상 주의점
- 댓글과 첨부는 원본 글 생성 성공 이후 단계적으로 적재해야 함.
- 기존 시스템 ID 중복을 막기 위해 `migration_mappings`에 유니크 제약이 필요함.
- 재실행 가능성을 고려해 배치는 멱등적으로 설계해야 함.
- ABC 적재 성공 후 내부 DB 저장 실패가 발생하면 보상 처리 또는 재동기화 큐가 필요함.
## 9. 정리
이 설계의 핵심은 S/W별 Q&A와 인트라넷 사내 지원을 하나의 `workspace` 기반 플랫폼으로 통합하되, 시스템 역할을 명확히 나누는 데 있음.
- ABC User Feedback는 게시글 원본 저장소이자 채널/필드 관리 도구임.
- 우리 시스템은 FastAPI와 자체 DB를 통해 권한 분기, 승인 워크플로우, 운영 페이지, 동적 폼, 외부 연동을 담당함.
- BARON-SSO는 사용자와 `tenant_id`의 원본 인증 계층으로 유지됨.
- `abc_feedback_mappings`, `workspace_channel_mappings`, `migration_mappings`가 두 시스템을 연결하는 핵심 브릿지 역할을 수행함.
다음 단계에서는 상태 코드 표준값, `page_scope` 체계, 실제 ABC API 스펙, 운영 페이지 화면 와이어프레임을 추가하면 구현 준비 수준의 설계 문서로 확장 가능함.
@@ -0,0 +1,213 @@
# BARON-SSO 권한 및 접근 제어 설계
## 1. 문서 목적
본 문서는 BARON-SSO 연동 시점에 필요한 역할 분리, 테넌트 전략, 로그인 후 페이지 분기, 프로젝트/채널 접근 제어 규칙을 별도로 정리한 문서임.
핵심 목적은 다음과 같음.
- 개발자, 담당자, 사용자의 권한 범위를 명확히 구분함.
- BARON-SSO `tenant_id` 와 우리 시스템의 페이지 분기 기준을 연결함.
- Q&A 관리자 전용 테넌트와 일반 사용자 테넌트의 진입 흐름을 분리 정의함.
- 프로젝트, 채널, 문의 구분, 관리자 콘솔 처리 구조를 현재 구현 방향 기준으로 문서화함.
- 이후 실제 SSO 구현, 테넌트 생성, 라우팅, 권한 테이블 설계의 기준 문서로 사용함.
## 2. 적용 대상 범위
- 인증 원본: BARON-SSO
- 사용자 화면: `/support/[workspaceCode]/new`, `/support/[workspaceCode]/list`, `/support/[workspaceCode]/[ticketId]`
- 관리자 콘솔: `/main/project/[projectId]/feedback?channelId=[channelId]`
- 운영 보조 화면: `/ops`, `/admin/issues`
- 제어 백엔드: `apps/secretary-api`
- 관리자 API: `apps/api`
## 3. 역할 정의
| 역할 | 영문 역할명 | 주요 권한 | 접근 범위 | 로그인 후 기본 진입 화면 |
| --- | --- | --- | --- | --- |
| 개발자 | `SYSTEM_ADMIN`, `SUPER_ADMIN` | 시스템 전체 설정, SSO 연동 관리, 테넌트 관리, 프로젝트/채널 생성 및 삭제, 권한 정책 변경 | 모든 프로젝트, 모든 채널, 모든 관리자 기능 | 관리자 콘솔 또는 시스템 설정 화면 |
| 담당자 | `CHANNEL_MANAGER`, `PROJECT_MANAGER` | 배정된 프로젝트/채널의 피드백 조회, 댓글 처리, 이슈 연동, 채널 운영, 담당자 간 업무 분배 | 본인이 속한 관리자 테넌트 내부의 프로젝트/채널 | 관리자 콘솔 |
| 사용자 | `END_USER`, `FEEDBACK_PROVIDER` | 피드백 작성, 본인 글 조회, 본인 글 상태 확인, 공개된 Q&A 확인 | 본인이 진입한 프로젝트/채널과 본인 작성 데이터 | 사용자 피드백 작성 페이지 |
## 4. 권한 모델 핵심 원칙
### 4.1 1차 판정 기준
- 로그인 자체는 모두 BARON-SSO에서 처리함.
- 우리 시스템은 BARON-SSO 세션 또는 userinfo 기준으로 `user_id`, `tenant_id`, `role_keys` 를 받음.
- 1차 분기는 `Q&A 관리자 전용 tenant` 포함 여부로 처리함.
### 4.2 2차 판정 기준
- 관리자 테넌트에 속한 사용자는 관리자 콘솔 진입 대상으로 처리함.
- 그 외 사용자는 일반 사용자로 처리함.
- 추가 세부 권한은 `tenant_id + project + channel + role` 조합으로 제한함.
### 4.3 3차 판정 기준
- 관리자 콘솔에 진입한 이후에는 프로젝트/채널별 접근 권한을 다시 확인함.
- 동일 관리자 테넌트 소속이라도 모든 프로젝트를 다 보는 구조로 고정하지 않고, 이후 프로젝트/채널별 세분화가 가능하도록 설계함.
## 5. 테넌트 전략
### 5.1 신규 테넌트 구성
- BARON-SSO에 `Q&A 관리자 테넌트`를 신규 생성함.
- 이 테넌트에 속한 인원은 Q&A 관리 권한 후보군으로 사용함.
- 이외 나머지 일반 테넌트 사용자는 사용자 피드백 작성 화면으로 이동시킴.
### 5.2 테넌트 기반 분기 규칙
| BARON-SSO 테넌트 | 기본 사용자 분류 | 기본 이동 경로 | 추가 분기 |
| --- | --- | --- | --- |
| `Q&A 관리자 테넌트` | 관리자/담당자 | 관리자 콘솔 | 프로젝트/채널별 접근 제한 적용 |
| 일반 사용자 테넌트 | 사용자 | 프로젝트별 피드백 작성 페이지 | 본인 글 목록/상세 접근 허용 |
## 6. 로그인 후 페이지 분기 정책
### 6.1 관리자 테넌트 사용자
- 로그인 성공 후 관리자 콘솔로 이동함.
- 기본 진입 후보 경로는 다음과 같음.
- `/main/project/[projectId]/feedback?channelId=[channelId]`
- 필요 시 운영 보조 화면 `/ops`, `/admin/issues` 로 이동 가능
- 이후 프로젝트/채널별 권한에 따라 진입 가능한 콘솔 페이지를 다시 제한함.
### 6.2 일반 사용자
- 로그인 성공 후 각 소프트웨어 또는 서비스가 지정한 피드백 작성 페이지로 이동함.
- 진입 URL에는 프로젝트/채널에 대응되는 `workspaceCode` 또는 서비스 식별자가 함께 전달됨.
- 예시
- `/support/EGBIM/new`
- `/support/TOVA/new`
- `/support/GAIA/new`
- `/support/KNGIL/new`
- `/support/INTRANET_QNA/new`
## 7. 프로젝트 및 채널 초기 운영 구조
### 7.1 초기 프로젝트 생성 대상
| 프로젝트명 | 설명 | 최초 기본 채널 |
| --- | --- | --- |
| `EGBIM` | EGBIM 전용 Q&A | `EGBIM` |
| `TOVA` | TOVA 전용 Q&A | `TOVA` |
| `GAIA` | GAIA 전용 Q&A | `GAIA` |
| `KNGIL` | KNGIL 전용 Q&A | `KNGIL` |
| `INTRANET_QNA` | 인트라넷 공통 Q&A | `INTRANET_QNA` |
### 7.2 채널 운영 확장 계획
- 최초에는 프로젝트당 채널 1개로 시작함.
- 이후 각 프로젝트 내부에서 채널을 별도로 확장하여 문의 유형별로 분리 관리함.
- 예시
- `EGBIM > 일반 문의`, `EGBIM > 장애 문의`, `EGBIM > 기능 개선`
- `INTRANET_QNA > 계정 문의`, `INTRANET_QNA > 권한 문의`, `INTRANET_QNA > 시스템 오류`
## 8. 사용자 진입 구조
### 8.1 기본 시나리오
1. 사용자는 각 소프트웨어에서 이미 BARON-SSO 로그인 상태임.
2. 사용자가 Q&A 이동 버튼을 클릭함.
3. 소프트웨어는 자기 프로젝트에 대응되는 Q&A 진입 URL로 이동시킴.
4. 우리 시스템은 세션에서 `user_id`, `tenant_id` 를 읽음.
5. 관리자 테넌트 여부를 판단함.
6. 일반 사용자면 해당 프로젝트의 작성 페이지로 이동함.
7. 관리자 테넌트면 관리자 콘솔로 이동함.
### 8.2 프로젝트별 사용자 진입 예시
| 진입 서비스 | 사용자 이동 경로 | 관리자 이동 경로 |
| --- | --- | --- |
| EGBIM | `/support/EGBIM/new` | `/main/project/[egbimProjectId]/feedback?channelId=[egbimChannelId]` |
| TOVA | `/support/TOVA/new` | `/main/project/[tovaProjectId]/feedback?channelId=[tovaChannelId]` |
| GAIA | `/support/GAIA/new` | `/main/project/[gaiaProjectId]/feedback?channelId=[gaiaChannelId]` |
| KNGIL | `/support/KNGIL/new` | `/main/project/[kngilProjectId]/feedback?channelId=[kngilChannelId]` |
| 인트라넷 Q&A | `/support/INTRANET_QNA/new` | `/main/project/[intranetProjectId]/feedback?channelId=[intranetChannelId]` |
## 9. 문의 작성과 관리자 콘솔 분기 구조
### 9.1 기본 원칙
- 사용자는 프로젝트 안에서 글을 작성함.
- 글 작성 시 `문의 구분` 값을 함께 선택함.
-`문의 구분` 은 장기적으로 채널 또는 내부 `workspace` 분기 기준으로 사용함.
- 관리자 콘솔에서는 프로젝트/채널 단위로 유입 건을 구분하여 관리함.
### 9.2 현재 구조와 향후 확장 방향
| 항목 | 현재 기준 | 향후 확장 방향 |
| --- | --- | --- |
| 프로젝트 | 서비스 단위 분리 | 유지 |
| 채널 | 프로젝트당 1개 기본 채널 | 프로젝트별 다중 채널 확장 |
| 문의 구분 | 사용자 작성 폼의 선택 값 | 채널 자동 라우팅 또는 하위 큐 분기 |
| 관리자 화면 | 프로젝트/채널별 피드백 목록 | 프로젝트/채널/문의구분 기반 다중 큐 |
## 10. 현재 구현 구조와의 연결 기준
### 10.1 사용자 화면
- 현재 사용자용 지원 화면은 `apps/web/src/pages/support/**` 경로에 구성되어 있음.
- 사용자 상세에서는 관리자 이슈 상태, 댓글, 본인 글 수정/삭제를 제공함.
- 사용자 상세 상태 표시는 현재 ABC 원본 피드백의 연결 이슈 상태를 읽어 반영하도록 확장됨.
### 10.2 관리자 화면
- 실제 관리자 콘솔은 `apps/web/src/pages/main/project/[projectId]/feedback.tsx` 경로를 중심으로 동작함.
- 피드백 상세 시트에서 댓글 CRUD와 이슈 연결 상태를 확인할 수 있도록 연계됨.
- 관리자 콘솔에서 이슈 연결 시 `apps/api``apps/secretary-api` 사이에서 내부 `support_tickets.issue_link_status` 를 함께 동기화하도록 보강됨.
### 10.3 제어 백엔드
- `apps/secretary-api` 는 사용자 화면용 상태, 댓글, 내부 티켓 메타데이터를 관리함.
- `apps/api` 는 ABC 관리자 콘솔의 피드백/이슈 기능을 제공함.
- 장기적으로는 BARON-SSO 로그인 완료 후 `tenant_id` 기반으로 사용자 경로와 관리자 경로를 라우팅하는 정책 계층이 추가되어야 함.
## 11. 권한 처리 시퀀스
```mermaid
flowchart TD
A[사용자 또는 관리자\nBARON-SSO 로그인 상태] --> B[Q&A 이동 버튼 클릭]
B --> C[우리 시스템 진입]
C --> D[세션에서 user_id, tenant_id, role_keys 확인]
D --> E{Q&A 관리자 테넌트 소속인가?}
E -- 예 --> F[관리자 콘솔 진입]
E -- 아니오 --> G[사용자 작성 페이지 진입]
F --> H{프로젝트/채널 접근 권한 존재?}
H -- 예 --> I[프로젝트별 관리자 콘솔 페이지 진입]
H -- 아니오 --> J[권한 없음 또는 다른 프로젝트로 재분기]
G --> K[프로젝트별 사용자 작성 페이지 이동]
K --> L[피드백 작성]
L --> M[문의 구분 값 저장]
M --> N[프로젝트/채널/문의구분 기준 관리자 콘솔 큐 반영]
```
## 12. 권한 매핑 테이블 초안
| 구분 | BARON-SSO 값 | 우리 시스템 해석 | 화면 권한 | 데이터 권한 |
| --- | --- | --- | --- | --- |
| 관리자 테넌트 + 최고 권한 | 관리자 테넌트 + `SUPER_ADMIN` | 시스템 관리자 | 전체 관리자 콘솔, 설정, 프로젝트/채널 관리 | 전체 프로젝트/채널 |
| 관리자 테넌트 + 담당자 권한 | 관리자 테넌트 + `PROJECT_MANAGER` 또는 `CHANNEL_MANAGER` | 운영 담당자 | 담당 프로젝트 콘솔, 채널 설정, 댓글/이슈 처리 | 배정 프로젝트/채널 |
| 일반 테넌트 | 일반 tenant | 사용자 | 사용자 작성/목록/상세 | 본인 작성 글 |
## 13. 구현 시 체크리스트
- BARON-SSO에 `Q&A 관리자 테넌트` 생성
- 관리자 대상 계정들을 해당 테넌트에 배정
- 프로젝트 `EGBIM`, `TOVA`, `GAIA`, `KNGIL`, `INTRANET_QNA` 생성
- 각 프로젝트에 동일명 기본 채널 1개 생성
- 프로젝트/채널별 관리자 접근 정책 정의
- 사용자 Q&A 이동 버튼의 프로젝트별 URL 매핑 정의
- 로그인 후 `tenant_id` 기준 관리자/사용자 라우팅 구현
- 문의 구분 값과 채널 분기 규칙 설계
- 프로젝트별 확장 채널 생성 전략 수립
## 14. 최종 정리
- BARON-SSO는 인증과 1차 권한 분기의 기준 시스템임.
- `Q&A 관리자 테넌트`는 관리자 콘솔 진입 여부를 결정하는 최우선 조건임.
- 일반 사용자는 프로젝트별 피드백 작성 페이지로 이동함.
- 관리자/담당자는 프로젝트/채널별 관리자 콘솔로 이동함.
- 초기에는 프로젝트당 채널 1개로 시작하고, 이후 채널을 세분화하여 문의 구분과 운영 큐를 확장함.
- 현재 구현된 사용자 화면, 관리자 콘솔, 내부 티켓/댓글/이슈 상태 동기화 구조는 이 권한 설계 문서를 기준으로 다음 단계 SSO 분기 구현으로 연결할 수 있음.
@@ -0,0 +1,499 @@
# 사내 지원 플랫폼 환경 셋업 및 Task 목록
## 1. 문서 목적
본 문서는 [architecture_secretary_sso_user_scenarios.md](./architecture_secretary_sso_user_scenarios.md) 에서 정리한 사용자 시나리오와 시스템 역할 분담을 실제 개발 환경으로 옮기기 위한 실행 계획 문서임.
권한, 테넌트, 로그인 후 페이지 분기 설계는 [architecture_secretary_sso_role_access.md](./architecture_secretary_sso_role_access.md) 에 별도 정리함.
핵심 목적은 다음과 같음.
- 어떤 순서로 환경을 셋업해야 하는지 명확히 정리함.
- 개발 착수 전에 필요한 선행 정보와 의존 항목을 체크함.
- 사용자 화면, 운영 화면, 관리자 기능, 외부 연동까지 단계별로 작업을 분해함.
- 시연과 운영 전환을 위한 검증 항목을 체크리스트로 관리함.
## 2. 기본 원칙
- 먼저 ABC User Feedback 기본 환경을 안정적으로 띄움.
- 그 다음 BARON-SSO, 우리 시스템 백엔드, 자체 DB를 연결함.
- 이후 사용자 화면, 운영 화면, 관리자 기능 연계를 붙임.
- 마지막으로 시연 기준 end-to-end 검증을 수행함.
## 2.1 현재 작업 기준선
- 프로젝트/채널 구조 확정과 BARON-SSO `tenant_id` 기반 권한 분기 정책은 최종 완료의 선행 조건으로 유지함.
- 다만 현재 주차에서는 위 선행 조건이 아직 확정되지 않았으므로, 우선 범위를 `프론트 UI 구성 + 우리 시스템 백엔드/DB 구축`까지로 제한함.
- 다음 주 작업 범위는 `BARON-SSO 로그인 연동 + 권한 분기 + 페이지 분기 처리`로 계획함.
- 따라서 현재 문서의 `(완료)` 표시는 SSO/권한 확정 이전에도 독립적으로 검증 가능한 UI, 라우팅, 스텁 API, DB 스키마, 로컬 실행 항목에만 부여함.
## 3. 전체 Task 로드맵
| 단계 | 작업 묶음 | 핵심 목표 | 완료 기준 |
| --- | --- | --- | --- |
| 1 | 로컬 기본 환경 구성 | ABC, DB, 개발 도구를 실행 가능한 상태로 만듦 | 로컬에서 ABC Web/API 접속 가능 |
| 2 | ABC 운영 구조 셋업 | 프로젝트, 채널, 필드, 역할 구조를 준비함 | 서비스별 채널/필드/권한 정책 초안 반영 완료 |
| 3 | BARON-SSO 연동 준비 | 로그인과 사용자 식별 체계를 연결함 | `user_id`, `tenant_id`, 역할 정보를 세션에서 읽을 수 있음 |
| 4 | 우리 시스템 백엔드/DB 셋업 | 내부 티켓/승인/매핑 저장소를 준비함 | `support_tickets`, `request_approvals`, `abc_feedback_mappings` 저장 가능 |
| 5 | 사용자 화면 셋업 | 작성, 목록, 상세 흐름을 연결함 | 사용자 기준 등록/조회 시연 가능 |
| 6 | 운영/관리 화면 셋업 | 승인, 이슈 생성, 처리 결과 입력 흐름을 연결함 | 운영자/관리자 기준 처리 시연 가능 |
| 7 | 외부 연동/알림 준비 | 알림 및 업무 시스템 연계를 준비함 | Mock 또는 실제 연동 경로 확인 완료 |
| 8 | 통합 검증/시연 준비 | 전체 흐름을 점검하고 시연용 데이터를 고정함 | end-to-end 시연 체크리스트 통과 |
## 4. 단계별 상세 Task
### 4.1 로컬 기본 환경 구성
- 작업 기준 저장소: `abcfeedback_test`
- 현재 확인된 로컬 기동 방식: `./start-local.sh` 또는 `docker compose -f docker/docker-compose.yml up -d`
- 선행 확인 항목
- Docker CLI 설치 및 Docker daemon 접근 가능 여부 확인
- Node.js / pnpm 설치 여부 확인
- 로컬 포트 사용 여부 확인: `3001`, `4000`, `5080`, `13306`
- 현재 확인된 기본 접속 URL
- Web UI: `http://localhost:3001`
- API Docs: `http://localhost:4000/docs`
- API Health: `http://localhost:4000/api/health`
- SMTP Test Inbox: `http://localhost:5080`
- 현재 확인된 기본 DB 접속 정보
- DB Engine: MySQL 8.0
- Host: `localhost`
- Port: `13306`
- Database: `userfeedback`
- Username: `userfeedback`
- Password: `userfeedback`
- 현재 확인된 핵심 환경 변수
- Web: `NEXT_PUBLIC_API_BASE_URL=http://localhost:4000`
- API: `JWT_SECRET`, `MYSQL_PRIMARY_URL`, `SMTP_HOST`, `SMTP_PORT`, `SMTP_SENDER`
- 1차 실행 절차
- `cd abcfeedback_test`
- `./start-local.sh` `(완료)`
- `./check-local.sh` `(완료)`
- 기동 후 첫 진입 절차
- 테넌트 생성
- 관리자 계정 생성
- 로그인
- Project 생성
- Channel 생성
- API Key 생성
- 첫 피드백 등록
- 현재 작업 환경 확인 결과
- Docker daemon 기동 후 `start-local.sh`, `check-local.sh` 기준 로컬 컨테이너 실행과 기본 헬스체크 확인 `(완료)`
- Web `3001`, API `4000`, SMTP UI `5080`, MySQL `13306` 포트 매핑 확인 `(완료)`
- 산출물
- 로컬 실행 스크립트 및 접속 URL 문서화 완료
- 4.2 진행 전 선행 조건: ABC Web/API Health check 성공 확인
### 4.2 ABC 운영 구조 셋업
- 설계 기준 문서
- `docs/architecture_secretary_sso_components_v2.md`
- `docs/architecture_secretary_sso_user_scenarios.md`
- 운영 구조 설계 원칙
- ABC Project는 서비스 운영 단위로 생성하고, 세부 신청/문의 유형은 Channel로 분리함
- 외부 진입 식별자 `app_id`, `service_type_id`, 메뉴 코드는 우리 시스템에서 `workspace`로 해석하고, `workspace_channel_mappings`로 ABC Channel에 연결함
- 일반 사용자 입력 스키마는 우리 시스템 동적 폼과 ABC 커스텀 필드를 동시에 맞춰야 하므로 `workspace_field_mappings` 기준으로 관리함
- 역할과 화면 권한은 BARON-SSO 세션을 기준으로 판정하되, ABC 프로젝트 접근 권한은 별도로 부여함
- 1차 운영 구조 초안
- Project 단위
- `INTRANET_SUPPORT`: 인트라넷 기반 사내 지원 업무 공통 Project
- `SOFTWARE_QA`: S/W 프로그램별 문의 접수 공통 Project
- Channel 단위
- `INTRA_SUPPLIES_REQUEST`: 물품 신청
- `INTRA_BOOK_REQUEST`: 도서 신청
- `INTRA_VEHICLE_REQUEST`: 출장 차량 신청
- `INTRA_EQUIPMENT_RENTAL`: 비품 대여
- `INTRA_GENERAL_QNA`: 사내 문의
- `SW_APP_<APP_CODE>_QNA`: 앱별 전용 Q&A 채널
- Field 스키마 초안
- 공통 필드: `request_category`, `title`, `description`, `requester_contact`, `attachment`
- 승인형 업무 필드: `approval_required`, `approver_org`, `requested_date`, `priority`
- 자산/물품형 필드: `asset_type`, `quantity`, `usage_purpose`, `delivery_location`
- 도서형 필드: `book_title`, `author`, `publisher`, `purchase_reason`
- 차량형 필드: `departure_date`, `return_date`, `destination`, `passenger_count`
- Q&A형 필드: `app_version`, `environment`, `error_message`, `expected_result`
- 역할 정의 초안
- `ROLE_USER`: 일반 사용자 작성/본인 조회
- `ROLE_APPROVER`: 승인 대기 조회, 승인/반려 처리
- `ROLE_OPERATOR`: 전체 운영 목록 조회, 상태 변경, 이슈 연결
- `ROLE_ADMIN`: Project/Channel/Field/Member 관리
- 멤버/권한 부여 정책
- Project 멤버는 최소 `승인자`, `운영 담당자`, `관리자` 그룹으로 시작함
- Channel 단위 운영은 가능하면 Project Role로 통일하고, 예외 채널만 추가 권한을 부여함
- 운영 화면 접근 권한과 ABC 관리자 권한은 동일 인원 기준으로 시작하되, 이후 분리 가능하게 설계함
- 1차 실무 작업 순서
- `INTRANET_SUPPORT`, `SOFTWARE_QA` Project 생성
- 인트라넷용 기본 Channel 5종 생성
- 시범 앱 1개를 선정해 `SW_APP_<APP_CODE>_QNA` Channel 생성
- Channel별 필드 스키마 반영
- Project Role 생성 및 멤버 배정
- `workspace_channel_mappings`, `workspace_field_mappings` 초안 작성
- seed 데이터 준비 항목
- 테스트용 일반 사용자 1명, 승인자 1명, 운영 담당자 1명, 관리자 1명
- 인트라넷 업무 5종에 대한 샘플 Channel/Field 정의서
- 앱 Q&A 1종에 대한 샘플 Channel/Field 정의서
- `workspace` 매핑 초안 표
| workspace_code | 진입 구분 | ABC Project | ABC Channel | 주요 Field 그룹 | 승인 필요 기본값 |
| --- | --- | --- | --- | --- | --- |
| `INTRA_SUPPLIES_REQUEST` | 인트라넷 물품 신청 | `INTRANET_SUPPORT` | `INTRA_SUPPLIES_REQUEST` | 공통 + 승인형 + 자산/물품형 | 예 |
| `INTRA_BOOK_REQUEST` | 인트라넷 도서 신청 | `INTRANET_SUPPORT` | `INTRA_BOOK_REQUEST` | 공통 + 승인형 + 도서형 | 예 |
| `INTRA_VEHICLE_REQUEST` | 인트라넷 차량 신청 | `INTRANET_SUPPORT` | `INTRA_VEHICLE_REQUEST` | 공통 + 승인형 + 차량형 | 예 |
| `INTRA_EQUIPMENT_RENTAL` | 인트라넷 비품 대여 | `INTRANET_SUPPORT` | `INTRA_EQUIPMENT_RENTAL` | 공통 + 승인형 + 자산/물품형 | 예 |
| `INTRA_GENERAL_QNA` | 인트라넷 일반 문의 | `INTRANET_SUPPORT` | `INTRA_GENERAL_QNA` | 공통 + Q&A형 | 아니오 |
| `SW_APP_<APP_CODE>_QNA` | S/W 프로그램별 문의 | `SOFTWARE_QA` | `SW_APP_<APP_CODE>_QNA` | 공통 + Q&A형 | 아니오 |
- `workspace_field_mappings` 작성 규칙 초안
- 모든 `workspace`는 공통 필드 `request_category`, `title`, `description`, `requester_contact`, `attachment`를 기본 포함함
- 승인형 업무는 `approval_required=true`를 기본값으로 두고, 승인자 조직/우선순위/희망일자를 추가 매핑함
- Q&A형 업무는 승인 필드 대신 `app_version`, `environment`, `error_message`, `expected_result`를 우선 매핑함
- ABC 커스텀 필드 키는 가능하면 `snake_case`로 고정하고, 우리 시스템 `local_field_code`와 동일한 이름을 사용함
- 첨부는 ABC 첨부 기능을 기본 저장소로 사용하고, 우리 시스템에는 첨부 메타데이터와 내부 티켓 연결 정보만 저장함
- 완료 기준
- 서비스별 Project/Channel/Field/Role 초안이 문서로 정리되어 있어야 함
- 최소 1개 인트라넷 업무와 1개 S/W 앱 Q&A에 대해 실제 ABC 생성 대상 목록이 확정되어 있어야 함
- 현재 메모
- 이 단계는 프론트 UI/백엔드 스텁 완료와 별개로 아직 진행중이며, Project/Channel 구조가 확정되어야 최종 완료 처리 가능함
### 4.3 BARON-SSO 연동 준비
- 확인된 전제
- ABC User Feedback는 커스텀 OAuth 2.0 / OIDC 제공자 연동을 지원함
- 현재 ABC Web의 OAuth 콜백 경로는 `/auth/oauth-callback` 기준으로 동작함
- 현재 Web 외부 노출 포트는 로컬 기준 `3001`이므로, ABC 관리자 UI를 그대로 사용할 경우 개발용 콜백 URI 후보는 `http://localhost:3001/auth/oauth-callback`
- 확보해야 할 BARON-SSO 클라이언트 등록 정보
- `client_id`
- `client_secret`
- `authorization_endpoint`
- `token_endpoint`
- `userinfo_endpoint`
- 가능하면 `jwks_uri`
- `issuer`
- 지원 `scope` 목록: 최소 `openid`, 사용자 식별, 이메일, 조직/역할 관련 scope
- Redirect / Callback / Logout URI 정리 항목
- ABC 관리자 UI OAuth Callback URI: `/auth/oauth-callback`
- 우리 시스템 사용자 포털 Callback URI: 별도 Next.js 앱 경로 확정 필요
- 우리 시스템 운영 포털 Callback URI: 사용자 포털과 분리 여부 확정 필요
- Logout Redirect URI: BARON-SSO 로그아웃 후 복귀할 공통 URL 확정 필요
- 운영 환경별로 `local`, `dev`, `stg`, `prod` URI를 각각 등록 목록으로 정리해야 함
- 세션 저장 구조 초안
- 인증 원본은 BARON-SSO가 담당하고, 우리 시스템은 세션 또는 JWT에 필요한 최소 클레임만 저장함
- 공통 세션 필드: `user_id`, `tenant_id`, `display_name`, `email`, `role_keys`, `workspace_scopes`, `access_token_exp`, `refresh_token_exp`
- 선택 세션 필드: `org_id`, `org_name`, `employee_no`, `position_code`
- 서버 측 권한 판정은 세션에 저장된 역할 문자열만 신뢰하지 않고, `tenant_id + workspace + 내부 권한 테이블`을 함께 사용함
- 역할 판정 기준 초안
- `ROLE_USER`: 본인 작성/조회만 가능
- `ROLE_APPROVER`: 승인 대기 목록, 승인/반려 가능
- `ROLE_OPERATOR`: 운영 목록, 상태 변경, 이슈 연결 가능
- `ROLE_ADMIN`: Project/Channel/Field/Member 관리 가능
- 역할 판정 순서
- 1차: BARON-SSO 토큰 또는 userinfo에서 조직/그룹/역할 claim 확인
- 2차: 우리 시스템 `user_workspace_access` 기준으로 `workspace`별 실제 권한 확정
- 3차: ABC 프로젝트 멤버십과 운영 화면 접근 권한 동기화
- 예외 처리 정책
- 미로그인: SSO 로그인 페이지로 리다이렉트
- 세션 만료: 재로그인 유도 후 원래 진입 경로 복귀
- 권한 부족: 403 화면 + 요청 가능한 담당 조직 안내
- `workspace` 매핑 없음: 일반 오류가 아니라 운영 설정 누락으로 분류하여 관리자 알림 대상에 포함
- BARON-SSO userinfo 조회 실패: 재시도 1회 후 실패 로그 적재 및 운영 알림
- 1차 실무 작업 순서
- BARON-SSO 담당자에게 클라이언트 등록 요청 템플릿 전달
- 환경별 Redirect/Callback/Logout URI 목록 확정
- 토큰 claim 샘플 수집: `user_id`, `tenant_id`, 조직/역할 관련 필드 확인
- 세션 스키마와 내부 권한 매핑 규칙 정의
- 테스트 계정 준비: 일반 사용자, 승인자, 운영 담당자, 관리자
- 로그인 성공/권한 부족/세션 만료/`workspace` 미매핑 시나리오 검증 항목 작성
- 완료 기준
- BARON-SSO 클라이언트 등록에 필요한 입력값 목록이 문서화되어 있어야 함
- 세션 저장 필드와 역할 판정 규칙이 문서화되어 있어야 함
- 개발 환경 기준 Callback URI와 예외 처리 정책이 확정되어 있어야 함
- 현재 메모
- BARON-SSO 로그인과 `tenant_id` 기반 권한/페이지 분기 처리는 다음 주 구현 범위로 계획함
### 4.4 우리 시스템 백엔드/DB 셋업
- 구현 전 정합성 확인
- 4.4 기준 DB 엔진은 MySQL 8.0으로 고정함
- `architecture_secretary_sso_components_v2.md`의 SQL 초안에는 `SERIAL`, `JSONB` 등 PostgreSQL 스타일 표현이 포함되어 있으므로 실제 구현 전 MySQL 문법으로 변환해야 함
- FastAPI 기본 구조 초안
- 실제 생성 경로: `apps/secretary-api`
- `apps/secretary-api/app/api`: 사용자/운영 API 라우터
- `apps/secretary-api/app/core`: 설정, 보안, 세션, 공통 유틸
- `apps/secretary-api/app/models`: SQLAlchemy 모델 또는 ORM 엔티티
- `apps/secretary-api/app/schemas`: 요청/응답 DTO
- `apps/secretary-api/app/services`: 권한 판정, 티켓 처리, 승인 처리, ABC 브릿지
- `apps/secretary-api/app/repositories`: DB 접근 계층
- `apps/secretary-api/app/integrations/abc`: ABC API 클라이언트
- `apps/secretary-api/app/integrations/sso`: BARON-SSO 토큰 검증 또는 userinfo 연동
- `apps/secretary-api/alembic`: 마이그레이션 파일
- `apps/secretary-api/app/seeds`: 코드성 초기 데이터 및 테스트용 seed 스크립트
- 현재 저장소 기준 확인 결과
- `apps/secretary-api/app/main.py`에 FastAPI 엔트리포인트가 존재함
- `apps/secretary-api/app/api/routes/health.py``/api/health` 엔드포인트가 존재함
- `apps/secretary-api/app/api/routes/tickets.py``GET /api/workspaces`, `GET /api/workspaces/{workspace_code}/form-template`, `POST /api/workspaces/{workspace_code}/tickets`, `GET /api/workspaces/{workspace_code}/tickets`, `GET /api/tickets/{ticket_id}`, `POST /api/tickets/{ticket_id}/approve`, `POST /api/tickets/{ticket_id}/issue` 경로가 존재함 `(완료)`
- `apps/secretary-api/alembic/versions/0001_initial_support_schema.py`에 P0 기준 1차 MySQL 마이그레이션이 존재함
- `apps/secretary-api/alembic/versions/0002_support_ticket_content_fields.py`에 현재 UI가 사용하는 `description`, `approval_status`, `sync_status`, `issue_link_status`, `extra_fields` 컬럼 보강이 반영됨 `(완료)`
- 현재 작업 환경에서는 `localhost:13306` 대신 Docker bridge IP 기준 `DATABASE_URL` override 로 실제 MySQL 마이그레이션과 티켓 생성/조회 검증을 완료함 `(부분 완료)`
- 다만 ABC 연동 클라이언트, seed 스크립트 정리, 환경 공통 DB 접속 방식 정리는 아직 후속 작업으로 남아 있음
- DB 구축 순서
- 1단계: 코드 테이블 및 서비스 마스터 생성
- `support_status_codes`
- `support_category_codes`
- `software_apps`
- `service_types`
- `workspaces`
- 2단계: 권한 및 채널 매핑 테이블 생성
- `user_workspace_access`
- `workspace_channel_mappings`
- `workspace_field_mappings`
- 3단계: 핵심 티켓 및 연동 테이블 생성
- `support_tickets`
- `abc_feedback_mappings`
- `request_approvals`
- `notification_logs`
- `operator_histories` 또는 `ticket_activity_logs`
- 4단계: 확장 업무 테이블 생성
- `assets`
- `asset_allocations`
- `vehicle_schedules`
- `remote_support`
- 5단계: 이관 추적 테이블 생성
- `migration_batches`
- `migration_mappings`
- 핵심 테이블 구현 우선순위
- P0: `workspaces`, `workspace_channel_mappings`, `workspace_field_mappings`
- P0: `support_tickets`, `abc_feedback_mappings`
- P0: `user_workspace_access`, `request_approvals`
- P1: `notification_logs`, `ticket_activity_logs`
- P1: `migration_batches`, `migration_mappings`
- P2: `assets`, `asset_allocations`, `vehicle_schedules`, `remote_support`
- MySQL 변환 규칙 초안
- `SERIAL``BIGINT AUTO_INCREMENT` 또는 `INT AUTO_INCREMENT`로 변환
- `JSONB`는 MySQL `JSON`으로 변환
- `BOOLEAN`은 MySQL `BOOLEAN` 또는 `TINYINT(1)` 기준으로 통일
- `TIMESTAMP DEFAULT CURRENT_TIMESTAMP``updated_at` 자동 갱신 규칙을 명시적으로 넣음
- 코드 테이블과 상태값은 가능하면 `ENUM`보다 참조 테이블 방식을 우선 적용함
- 마이그레이션 도구 및 seed 준비
- Alembic 기반 버전 관리 적용
- 최초 마이그레이션은 서비스 마스터, 권한, 채널 매핑, 핵심 티켓 테이블까지 포함
- seed 1차 범위: 상태 코드, 카테고리 코드, 기본 `workspace`, 기본 Project/Channel 매핑, 테스트 사용자 권한
- seed 2차 범위: 샘플 티켓, 샘플 승인 데이터, 샘플 알림 이력
- ABC API 연동용 서비스 계층 초안
- `ABCProjectService`: Project/Channel 조회 및 캐시
- `ABCFeedbackService`: 피드백 생성, 상세 조회, 첨부 업로드
- `ABCIssueService`: 이슈 생성, 피드백-이슈 연결
- `ABCMemberSyncService`: 운영자/승인자 프로젝트 멤버십 동기화
- 1차 실무 작업 순서
- `apps/secretary-api` FastAPI 프로젝트 뼈대 생성
- MySQL 연결 설정 및 로컬 `.env` 정의
- Alembic 초기화 및 1차 마이그레이션 작성
- 코드 테이블 및 `workspace` 관련 테이블 생성
- `support_tickets`, `abc_feedback_mappings`, `request_approvals` 생성
- 상태 코드 및 `workspace` seed 적재
- `GET /api/workspaces`, `POST /api/workspaces/{workspaceCode}/tickets` 스텁 API 구현
- ABC API 클라이언트 골격 구현
- 티켓 생성 시 ABC 저장 후 내부 매핑 저장하는 트랜잭션 흐름 설계
- 완료 기준
- MySQL 기준 1차 마이그레이션이 적용 가능해야 함
- `workspace`와 ABC Channel 간 기본 매핑 데이터가 적재 가능해야 함
- 내부 티켓 생성과 ABC `feedback_id` 매핑 저장 구조가 확정되어 있어야 함
- 승인 이력 저장 구조와 운영 이력 저장 구조가 확정되어 있어야 함
- 현재 메모
- `baron_support` DB에 실제 마이그레이션 적용과 티켓 생성/목록 조회는 검증했으며, 현재 프런트 `/support` 흐름과 연결되는 최소 실DB 경로는 확보된 상태임
- 추가 검증 메모
- 현재 `apps/web` fallback 경로 기준으로 ABC MySQL `userfeedback.feedbacks` 저장 및 관리자 Feedback 화면 조회까지 검증했음
- `workspaceCode`별로 ABC Channel 분기 저장되며, 채널 필드 스키마 기준으로 `title`/`contents` 또는 `message` 필드값만 저장되도록 정리했음
- 다만 이 문서 기준 완료 조건인 내부 `support_tickets` + `abc_feedback_mappings` 동시 저장을 현재 fallback 경로가 모두 대체하는 것은 아니므로, ABC DB 기준으로는 `Create/Read` 검증 완료, 전체 CRUD 완료로 보기는 이름
### 4.5 사용자 화면 셋업
- 현재 저장소 기준 확인 결과
- 실제 서비스 웹앱은 `apps/web/src` 기준으로 운영되고 있음
- 현재 `apps/web/src/pages/support/[workspaceCode]/new|list|[ticketId]|index` 라우트가 존재함 `(완료)`
- 사용자 화면은 실제 서비스 라우트 기준으로 운영되며, 로컬 dev 서버 `3002`에서 시연 가능함 `(완료)`
- 단, `docker compose`만으로는 `3002`가 열리지 않으며 `apps/web`를 별도 실행해야 함
- 예시: `cd apps/web && PORT=3002 pnpm dev`
- 라우팅 구조 초안
- `/support` 또는 `/portal/support`: 공통 진입 라우터
- `/support/:workspaceCode/new`: 사용자 작성 화면 `(완료)`
- `/support/:workspaceCode/list`: 내 접수 목록 `(완료)`
- `/support/:workspaceCode/:ticketId`: 접수 상세 `(완료)`
- `/support/:workspaceCode`: 기본 진입 시 목록으로 리다이렉트 `(완료)`
- 승인형 업무와 Q&A형 업무는 같은 라우팅 패턴을 사용하되, `workspaceCode`에 따라 폼 템플릿과 후처리만 다르게 적용함
- 공통 로그인 후 화면 분기 규칙
- SSO 로그인 완료 후 진입 파라미터 `app_id`, `service_type_id`, 메뉴 코드 중 하나를 받아 `workspaceCode`로 해석함
- `workspaceCode`가 확정되면 `GET /api/workspaces/{workspaceCode}/form-template`로 필드 구성을 조회함
- 권한이 없으면 작성 화면으로 보내지 않고 403 또는 접근 안내 화면으로 분기함
- 사용자 피드백 작성 페이지 구현 항목
- 공통 입력 필드: 제목, 내용, 첨부 `(완료)`
- `workspace`별 동적 필드 렌더링: 현재는 최소 Q&A 작성형으로 단순화하여 일부만 사용 `(부분 완료)`
- 제출 전 유효성 검사: 필수값, 날짜 범위, 숫자 범위, 첨부 제한
- 제출 시 처리 순서: 우리 시스템 API 호출 -> ABC 저장 -> 내부 `support_tickets` 생성 -> `abc_feedback_mappings` 저장
- 현재 검증 상태: `apps/web` fallback 경로에서 ABC `feedbacks` 저장과 관리자 조회는 확인했으며 `(부분 완료)`, 내부 `support_tickets`/`abc_feedback_mappings`까지 같은 요청에서 항상 저장되는 구조는 secretary-api 기준으로 계속 검증 필요
- 완료 화면에는 `ticket_id`, `feedback_id`, 현재 상태값을 함께 보여줌
- 내 피드백 목록 페이지 구현 항목
- 로그인 사용자 기준 `requester_id + requester_tenant_id` 필터 적용 `(완료)`
- 목록 컬럼 초안: 제목, 요청 유형, 작성일, 내부 상태 중심 게시판 형태 구현 `(완료)`
- `workspace` 필터와 상태 필터 제공
- 상단 우측 검색 입력 및 행 전체 클릭 상세 이동 구현 `(완료)`
- 리스트 하단 좌측 작성 페이지 이동 버튼 구현 `(완료)`
- 피드백 상세 페이지 구현 항목
- ABC 원문 본문/첨부/댓글 조회 영역
- 우리 시스템 상태 메타데이터 영역: 현재는 최소 상태 배지와 댓글 입력 영역 중심으로 단순화 `(부분 완료)`
- 승인형 업무는 승인 이력 타임라인 노출
- 일반 Q&A형 업무는 이슈 연결 상태와 답변 상태를 노출
- `workspace`별 채널/필드 자동 선택 로직
- `app_id`, `service_type_id`, 메뉴 코드 -> `workspaceCode` 해석
- `workspaceCode` -> `workspace_channel_mappings`로 ABC Channel 결정
- `workspaceCode` -> `workspace_field_mappings`로 폼 필드와 검증 규칙 로드
- 채널 매핑이 없으면 작성 화면 진입 전 관리자 설정 누락 오류로 처리
- 작성 완료 후 매핑 저장 처리
- 우리 시스템은 ABC API 응답의 `feedback_id`를 수신한 뒤 같은 요청 컨텍스트에서 내부 티켓과 1:1 매핑 저장
- 저장 실패 시 사용자에게는 접수 보류 상태를 안내하고, 운영자에게 재처리 대상 알림을 남김
- 사용자 조회 화면의 상태 노출 원칙
- ABC 상태값이 아니라 우리 시스템 `support_tickets.status_code`를 주 상태값으로 사용함
- 보조 상태로 `approval_status`, `sync_status`, `issue_link_status`를 함께 노출함
- 사용자는 본인 데이터만 조회 가능하고, `tenant_id` 불일치 데이터는 절대 노출하지 않음
- 1차 실무 작업 순서
- 사용자 공통 진입 URL 규칙 확정
- `workspace` 해석 API 또는 미들웨어 구현
- 폼 템플릿 조회 API 구현 `(완료 - 스텁 기준)`
- 작성 API와 목록 API 구현 `(완료 - 현재 secretary-api 연동 기준)`
- 상세 API 구현: 내부 상태 + ABC 원문 조합 응답 `(부분 완료)`
- 샘플 `workspace` 1종으로 작성 -> 목록 -> 상세 흐름 검증 `(완료)`
- 완료 기준
- 최소 1개 `workspace`에서 작성, 목록, 상세 흐름이 연결되어 있어야 함
- 작성 완료 시 `support_tickets``abc_feedback_mappings`가 함께 생성되어야 함
- 현재 확인 범위: ABC `feedbacks` 저장과 관리자 조회까지는 확인 완료, 내부 매핑 저장은 secretary-api 경로 기준 완료 메모를 유지하되 web fallback 경로는 별도 검증 필요
- 목록/상세 화면에서 내부 상태값이 ABC 원문과 함께 노출되어야 함
### 4.6 운영/관리 화면 셋업
- 현재 저장소 기준 확인 결과
- 실제 서비스 웹앱 `apps/web/src/pages` 이하에 `/ops`, `/admin/issues` 라우트가 존재함 `(완료)`
- 운영/관리 화면은 실제 페이지로 1차 이관되었고 승인/이슈 생성 흐름은 현재 secretary-api 및 내부 DB 경로 기준으로 계속 확장 중임 `(부분 완료)`
- 운영 화면 라우팅 구조 초안
- `/ops/approvals`: 승인 대기 목록
- `/ops/tickets`: 운영 전체 목록
- `/ops/tickets/:ticketId`: 운영 상세
- `/admin/issues`: 이슈 생성 대상 목록
- `/admin/issues/:ticketId`: 피드백-이슈 연결 상세
- 승인 대상 조회 및 승인/반려 처리 구현 항목
- 조회 조건: `request_approvals.approval_status = PENDING` 또는 `support_tickets.requires_approval = true and status_code = RECEIVED`
- 승인 화면 컬럼 초안: 제목, 요청 유형, 요청자, 요청일시, 현재 상태, 승인 필요 사유
- 승인 시 처리 순서: 권한 검증 -> `request_approvals` 기록 -> `support_tickets.status_code` 갱신 -> 알림 이벤트 발행
- 반려 시 처리 순서: 반려 사유 저장 -> 사용자 노출 상태 갱신 -> 알림 이벤트 발행
- ABC 관리자 UI 진입 링크 또는 연동 포인트
- 운영 상세에서 대응 ABC 원문 링크와 관리자 UI 바로가기 제공
- 관리자 화면에서는 `abc_feedback_id`, `abc_channel_id`, `abc_feedback_url`을 함께 노출
- 필요 시 ABC 기본 목록/상세 UI를 새 탭으로 열고, 우리 시스템은 상태 제어와 처리 이력만 담당함
- 피드백-이슈 연결 흐름 구현 항목
- 승인 완료 또는 운영 판단 완료 상태의 티켓만 이슈 생성 가능
- 이슈 생성 시 ABC 관리자 API 호출 후 `issue_id`와 연결 시각을 내부 이력에 저장
- 이미 연결된 티켓은 중복 생성이 아니라 기존 이슈 링크로 유도
- 연결 실패 시 내부 상태는 유지하고 `sync_status` 또는 운영 이력에 실패 원인을 저장
- 담당자 배정, 처리 메모, 상태 전이 로직
- 상태 전이 초안: `RECEIVED -> PENDING_APPROVAL -> APPROVED -> IN_PROGRESS -> RESOLVED -> CLOSED`
- 반려 흐름 초안: `PENDING_APPROVAL -> REJECTED`
- 담당자 배정은 `current_assignee_id`, `current_assignee_tenant_id`에 기록
- 처리 메모와 상태 변경 이력은 `operator_histories` 또는 `ticket_activity_logs`에 누적 저장
- 처리 결과/답변 입력 후 사용자 노출 데이터 동기화
- 내부 상태 변경 시 사용자 상세 화면의 상태 배지와 최근 처리 결과를 즉시 반영
- 필요 시 ABC 원문 댓글 또는 이슈 상태와 최소 동기화 규칙을 정의
- 사용자가 보는 최종 상태는 우리 시스템 `support_tickets.status_code`를 기준으로 유지
- 역할별 접근 제한 검증 항목
- 승인자: 승인 대기 목록과 승인/반려만 가능, 전체 운영 설정 변경 불가
- 운영 담당자: 전체 운영 목록, 상태 변경, 담당자 배정, 처리 메모 가능
- 관리자: Project/Channel/Member/이슈 연결 관리 가능
- 일반 사용자: 운영/관리 URL 직접 접근 시 403 처리
- 1차 실무 작업 순서
- 승인 대기 목록 API 구현 `(완료 - 현재 preview 흐름 기준)`
- 승인/반려 API 구현 및 `request_approvals` 저장 `(부분 완료 - 현재 내부 상태 전이 기준)`
- 운영 상세 API 구현: 내부 상태 + ABC 원문 링크 조합
- 담당자 배정 및 처리 메모 API 구현
- 이슈 생성 및 피드백-이슈 연결 API 구현 `(부분 완료 - 현재 secretary-api 연동 기준)`
- 운영/관리 화면을 실제 라우트 구조로 정리 `(완료)`
- 승인 -> 이슈 생성 -> 사용자 상세 반영 시나리오 검증 `(부분 완료)`
- 완료 기준
- 승인자가 승인/반려를 수행하면 내부 승인 이력과 티켓 상태가 함께 갱신되어야 함
- 운영 담당자가 상태 변경과 처리 메모를 남길 수 있어야 함
- 관리자 화면에서 승인 완료 티켓을 이슈 생성 대상으로 식별하고 연결할 수 있어야 함
### 4.7 외부 연동/알림 준비
- 대상 연동 범위 초안
- 메일 알림
- 사내 메신저 또는 협업 도구 알림
- 후속 업무 시스템 연계
- 운영 설정 누락 및 동기화 실패 감지
- 이벤트 기준 초안
- 접수 완료: 요청 제목, 접수 번호, 상세 링크
- 승인 대기: 승인 대상자, 요청 요약, 승인 링크
- 승인 완료: 요청 제목, 승인 결과, 다음 단계, 상세 링크
- 반려 완료: 반려 사유, 재작성 또는 문의 안내
- 처리 완료: 처리 결과 요약, 추가 확인 필요 여부, 상세 링크
- `RESOLVED`: 처리 완료 결과 알림
- 자산/차량 연동형 업무는 승인 완료 후 후속 처리 이벤트를 별도 발행함
- 구현 준비 항목
- 알림 채널별 템플릿 정의
- 이벤트 발생 시점 정의
- 재시도 및 실패 로그 정책 정의
- 민감 정보 마스킹 정책 정의
- 완료 기준
- 승인 완료/처리 완료 이벤트 기준 알림 발송 검증
- Mock 또는 실제 연동 경로가 최소 1개 이상 확인되어야 함
### 4.8 통합 검증/시연 준비
- 시연용 고정 데이터 준비
- 샘플 접수 데이터 3종: 승인형 1건, 일반 Q&A 1건, 처리완료 1건
- 테스트 계정: 일반 사용자 1명, 승인자 1명, 운영 담당자 1명, 관리자 1명
- 체크리스트형 실행 순서
- 일반 사용자 로그인 또는 진입
- 작성 페이지 진입
- 접수 등록
- 목록 확인
- 상세 확인
- 승인자 승인 또는 반려
- 운영 담당자 상태 갱신
- 관리자 이슈 연결 확인
- 사용자 상세 최종 상태 확인
- 실패 케이스 점검
- 권한 없는 사용자 진입 차단
- `workspace` 미매핑 처리
- 세션 만료 후 복귀 흐름
- ABC 또는 내부 DB 저장 실패 시 안내 문구
- 완료 기준
- end-to-end 시연 체크리스트가 역할별로 1회 이상 통과되어야 함
## 5. 우선순위 기준 Task Backlog
- P0
- `workspace`, Project, Channel, Field, 권한 구조 확정
- `support_tickets`, `abc_feedback_mappings`, `request_approvals` 최소 실DB 경로 검증 유지
- 사용자 작성 -> 목록 -> 상세 기본 흐름 안정화
- P1
- 승인/반려, 이슈 연결, 댓글, 상태 반영 흐름 고도화
- 동적 필드, 첨부, 알림, 운영 이력 보강
- P2
- 업무 시스템 연동, 알림 고도화, 확장 업무 테이블, 마이그레이션 추적 체계 보강
- 2, 3은 최종 완료 판단을 위한 선행 조건으로 유지
## 6. 실무용 체크리스트
- 완료: FastAPI 앱 골격, `/api/health`, `/api/workspaces`, `/api/workspaces/{workspaceCode}/form-template`, `POST /api/workspaces/{workspaceCode}/tickets` 스텁, 1차 Alembic 마이그레이션 파일, `apps/web` 사용자 `/support` 라우트, `/ops`, `/admin/issues` 실제 페이지 이관 `(완료)`
| 항목 | 상태 | 메모 |
| --- | --- | --- |
| ABC Web/API 로컬 실행 확인 | 완료 | `start-local.sh`, `check-local.sh` 실행 및 기본 포트/헬스체크 확인 완료 |
| MySQL 스키마 생성 | 진행중 | `apps/secretary-api` Alembic 1차 마이그레이션 파일 생성 완료. 실제 DB 적용 검증은 남아 있음 |
| MySQL 스키마 생성 | 부분 완료 | `baron_support` DB 생성, Alembic 1차/2차 적용, Docker bridge IP 기준 실DB 검증 완료. 로컬 공통 접속 방식 정리는 남아 있음 |
| `support_tickets` 테이블 생성 | 완료 | 실DB 생성 및 `description`, 상태 컬럼, `extra_fields` 포함 티켓 저장/조회 검증 완료 |
| `request_approvals` 테이블 생성 | 부분 완료 | 실DB 생성 확인 완료. 실제 승인 저장 흐름 검증은 다음 단계 |
| `abc_feedback_mappings` 테이블 생성 | 완료 | 실DB 생성 및 티켓 생성 시 매핑 레코드 저장 검증 완료 |
| ABC DB `feedbacks` 저장/조회 | 완료 | `apps/web` fallback 경로 기준으로 `userfeedback.feedbacks` 생성과 관리자 Feedback 화면 조회 검증 완료. 채널 필드 스키마에 맞춰 `contents`/`message` 본문만 저장되도록 정리 완료 |
| 사용자 작성/목록/상세 연결 | 완료 | `apps/web``/support/[workspaceCode]/new|list|[ticketId]|index` 구현 및 작성->목록->상세 흐름 확인 |
| 승인 목록/운영 목록 연결 | 부분 완료 | `/ops`, `/admin/issues` 라우트와 승인/이슈 생성 스텁 흐름 구현. 실DB/실권한 연동은 남아 있음 |
| ABC 이슈 생성/연결 연동 | 부분 완료 | secretary-api 및 `/admin/issues` 경로에 내부 상태 전이/연결 스텁 구현. 실제 ABC API 연동은 남아 있음 |
| 처리 결과 사용자 노출 동기화 | 부분 완료 | 사용자 상세에 상태 배지 및 댓글 UI 노출. 실제 운영 결과 동기화는 남아 있음 |
| end-to-end 시연 검증 | 진행중 | 역할별 시나리오, 고정 데이터, 실패 케이스 체크리스트 초안 반영 |
@@ -0,0 +1,209 @@
# BARON-SSO 연계 Task 정리
## 1. 문서 목적
본 문서는 현재 저장소 기준으로 이미 완료된 작업, 부분 완료 상태인 작업, 앞으로 진행해야 할 작업을 다시 정리한 실행 문서임.
특히 다음 두 문서를 하나의 실행 기준으로 연결하는 목적을 가짐.
- 사용자/운영 흐름 기준: `docs/architecture_secretary_sso_user_scenarios.md`
- 권한/테넌트/분기 기준: `docs/architecture_secretary_sso_role_access.md`
이 문서에서는 기존 초안 중 현재 방향과 맞지 않는 항목은 정리하고, 실제 구현 상태와 다음 작업 순서를 우선으로 기록함.
## 2. 현재 기준선
### 2.1 운영 구조 기준
- 인증 원본은 BARON-SSO 임.
- 1차 사용자 분기는 `Q&A 관리자 테넌트` 소속 여부로 판단함.
- 일반 사용자는 `/support/[workspaceCode]/**` 경로로 진입함.
- 관리자/담당자는 `/main/project/[projectId]/feedback?channelId=[channelId]` 중심 관리자 콘솔로 진입함.
- 초기 프로젝트 기준은 `EGBIM`, `TOVA`, `GAIA`, `KNGIL`, `INTRANET_QNA` 임.
- 초기에는 프로젝트당 기본 채널 1개로 시작하고, 이후 문의 구분 기반 다중 채널로 확장함.
### 2.2 상태 표기 기준
- `완료`: 현재 저장소와 로컬 검증 기준으로 동작 경로가 확인된 작업
- `부분 완료`: 일부 구현 또는 연결은 되었지만, 최종 운영 기준으로는 비어 있는 작업
- `대기`: 설계만 있고 아직 구현 또는 운영 반영이 시작되지 않은 작업
## 3. 완료된 작업 정리
### 3.1 로컬 실행 기반
| 항목 | 상태 | 정리 |
| --- | --- | --- |
| 로컬 ABC/연관 서비스 실행 스크립트 | 완료 | `start-local.sh`, `check-local.sh` 기준 로컬 기동 경로가 정리되어 있음 |
| 기본 개발 저장소 구조 | 완료 | `apps/web`, `apps/api`, `apps/secretary-api`, `apps/e2e` 등 작업 단위가 분리되어 있음 |
| secretary-api 기본 앱 구조 | 완료 | FastAPI 엔트리포인트, health, tickets 라우트, Alembic 구조가 존재함 |
### 3.2 사용자 지원 포털
| 항목 | 상태 | 정리 |
| --- | --- | --- |
| 사용자 작성 페이지 | 완료 | `/support/[workspaceCode]/new` 구현 완료 |
| 사용자 목록 페이지 | 완료 | `/support/[workspaceCode]/list` 구현 완료 |
| 사용자 상세 페이지 | 완료 | `/support/[workspaceCode]/[ticketId]` 구현 완료 |
| 기본 진입 리다이렉트 | 완료 | `/support/[workspaceCode]` 진입 시 목록 흐름 존재 |
| 폼 템플릿 조회 | 완료 | workspace 기반 작성 폼 템플릿 조회 API 연결 완료 |
| 작성/목록/상세 기본 흐름 | 완료 | 최소 1개 workspace 기준 작성 -> 목록 -> 상세 흐름 구현 완료 |
| 댓글 CRUD | 완료 | 사용자 상세와 관리자 상세 시트에서 댓글 생성/수정/삭제 흐름 존재 |
| 상세 상태 반영 | 완료 | 사용자 상세에서 내부 상태와 ABC 이슈 연결 상태를 함께 반영함 |
### 3.3 secretary-api 및 내부 DB
| 항목 | 상태 | 정리 |
| --- | --- | --- |
| support ticket 기본 API | 완료 | workspaces, tickets, ticket detail, comments, approve, issue 관련 기본 라우트 존재 |
| 핵심 마이그레이션 1차/2차 | 완료 | `support_tickets`, 상태 컬럼, `extra_fields` 등 현재 UI 기준 컬럼 반영 완료 |
| 내부 티켓 저장 | 완료 | `support_tickets` 생성 흐름 구현 완료 |
| ABC 피드백 매핑 저장 | 완료 | 내부 티켓 생성 후 `abc_feedback_mappings` 저장 흐름 구현 완료 |
| 승인/이슈 상태 컬럼 | 완료 | `approval_status`, `sync_status`, `issue_link_status` 관리 구조 존재 |
| 코멘트 저장 구조 | 완료 | `ticket_comments` 및 관련 API 흐름 구현 완료 |
| 첨부 메타데이터 테이블 | 완료 | `attachments` 테이블과 ORM 모델 존재 |
### 3.4 첨부파일 업로드 현재 완료 범위
| 항목 | 상태 | 정리 |
| --- | --- | --- |
| 작성 페이지 파일 선택 UI | 완료 | 작성 화면에서 다중 첨부 선택 가능 |
| multipart 프록시 처리 | 완료 | `apps/web` API route 에서 multipart 파싱 후 secretary-api 로 전달함 |
| secretary-api 업로드 수신 | 완료 | multipart 요청에서 `attachments` 수신 가능 |
| 로컬 파일 저장 | 완료 | 업로드 파일을 로컬 디렉터리에 저장하고 메타데이터를 `attachments` 테이블에 기록함 |
| 파일 크기 제한 | 완료 | 30MB 제한 설정 존재 |
### 3.5 운영 보조 화면
| 항목 | 상태 | 정리 |
| --- | --- | --- |
| `/ops` 페이지 | 완료 | 승인 대기/처리 흐름용 운영 보조 화면 존재 |
| `/admin/issues` 페이지 | 완료 | 이슈 연결 대상 확인용 운영 보조 화면 존재 |
| 관리자 상세 시트 댓글 연계 | 완료 | 관리자 피드백 상세 시트에서 support ticket 댓글 흐름 사용 가능 |
## 4. 부분 완료 작업 정리
### 4.1 role_access 기준 운영 구조 반영
| 항목 | 상태 | 남은 내용 |
| --- | --- | --- |
| 프로젝트 구조 문서화 | 부분 완료 | 새 기준 프로젝트 목록은 role_access 에 정리됐지만 실제 운영 seed/매핑 반영은 남아 있음 |
| 프로젝트/채널 실제 생성 | 대기 | `EGBIM`, `TOVA`, `GAIA`, `KNGIL`, `INTRANET_QNA` 프로젝트와 동일명 기본 채널 생성 필요 |
| 관리자 접근 정책 | 대기 | 프로젝트/채널별 운영자 접근 범위와 내부 권한 테이블 반영 필요 |
| 문의 구분 기반 확장 전략 | 부분 완료 | 문서 초안은 있으나 실제 필드/라우팅/큐 분기 규칙은 미구현 |
### 4.2 BARON-SSO 및 권한 분기
| 항목 | 상태 | 남은 내용 |
| --- | --- | --- |
| BARON-SSO 로그인 연동 | 대기 | 실제 OIDC/OAuth 연동 구현 필요 |
| 세션의 `user_id`, `tenant_id`, `role_keys` 처리 | 대기 | 현재 테스트 사용자 상수 기반 흐름을 실제 세션 기반으로 전환해야 함 |
| 관리자 테넌트 여부 판정 | 대기 | `Q&A 관리자 테넌트` 기준 1차 분기 로직 미구현 |
| 사용자/관리자 페이지 분기 | 대기 | 로그인 후 `/support/...` 와 관리자 콘솔 자동 분기 미구현 |
| 프로젝트/채널별 세부 권한 제한 | 대기 | 관리자 콘솔 진입 후 재검증 로직 미구현 |
### 4.3 사용자 지원 포털 보강
| 항목 | 상태 | 남은 내용 |
| --- | --- | --- |
| 동적 필드 전체 사용 | 부분 완료 | 현재 title/description 중심 최소 렌더링만 사용 중 |
| 문의 구분 필드 반영 | 대기 | role_access 기준 문의 구분 저장 및 운영 큐 분기 연결 필요 |
| 첨부파일 상세 조회/다운로드 | 대기 | 업로드 저장은 되지만 목록/상세 응답과 다운로드 경로는 없음 |
| 첨부파일 ABC 연동 | 대기 | 현재 ABC 생성 시 제목/본문만 전송하고 첨부는 내부 로컬 저장만 수행함 |
| 작성 완료 결과 표준화 | 부분 완료 | 현재 ticket 상태는 보이지만 운영 기준 완료 UX 는 추가 정리 필요 |
### 4.4 운영/관리 기능 보강
| 항목 | 상태 | 남은 내용 |
| --- | --- | --- |
| 승인 이력 정교화 | 부분 완료 | 승인 상태 전이와 기본 API 는 있으나 실제 운영 권한/사유/이력 정책 보강 필요 |
| 이슈 생성/연결 운영 흐름 | 부분 완료 | 상태 동기화와 보조 화면은 있으나 실제 운영 정책/권한 제어는 추가 필요 |
| 담당자 배정/처리 메모 | 대기 | 전담 운영 테이블/화면/이력 흐름 미구현 |
| 관리자 콘솔 프로젝트 단위 제한 | 대기 | role_access 기준 프로젝트/채널별 접근 제한 미구현 |
### 4.5 데이터 및 운영 자동화
| 항목 | 상태 | 남은 내용 |
| --- | --- | --- |
| seed 데이터 정리 | 부분 완료 | 테스트 흐름은 있으나 새 프로젝트 기준 seed 재정리 필요 |
| 공통 권한 테이블 | 대기 | `tenant + project + channel + role` 조합 저장 구조 구체화 필요 |
| 알림/후속 연계 | 대기 | 승인 완료, 처리 완료, 설정 누락 알림 등 운영 이벤트 미구현 |
| E2E 시나리오 고정 | 부분 완료 | 화면 시연은 가능하나 role_access 기준 사용자/관리자 분기 시나리오 정리는 부족함 |
## 5. 앞으로 해야 할 작업
### 5.1 P0: role_access 기준 운영 구조 확정
- BARON-SSO `Q&A 관리자 테넌트` 식별값 확정
- 관리자 대상 계정 배정 기준 확정
- 프로젝트 `EGBIM`, `TOVA`, `GAIA`, `KNGIL`, `INTRANET_QNA` 실제 생성
- 각 프로젝트 기본 채널 1개 생성
- 사용자 Q&A 이동 URL과 `workspaceCode` 매핑 표 확정
- 프로젝트/채널별 관리자 접근 정책 확정
### 5.2 P0: 로그인 후 분기와 권한 처리 구현
- BARON-SSO 로그인 연동 구현
- 세션에서 `user_id`, `tenant_id`, `role_keys` 읽는 공통 계층 추가
- 관리자 테넌트 여부에 따른 1차 분기 구현
- 일반 사용자 -> `/support/[workspaceCode]/new` 이동 구현
- 관리자/담당자 -> 관리자 콘솔 기본 진입 경로 이동 구현
- 관리자 콘솔 진입 후 프로젝트/채널별 재검증 구현
### 5.3 P1: 사용자 포털 기능 마감
- 문의 구분 필드 추가 및 저장
- `workspace`별 동적 필드 전체 렌더링 정리
- 첨부파일 응답 스키마 추가
- 사용자 상세 첨부 목록 및 다운로드 구현
- 필요 시 첨부 ABC 저장 전략 확정 후 브릿지 구현
- 업로드 실패/부분 저장 실패 시 사용자 안내 문구 표준화
### 5.4 P1: 운영/관리 기능 마감
- 승인/반려 사유와 승인 이력 화면 정리
- 담당자 배정, 처리 메모, 상태 변경 이력 구현
- 이슈 생성 후 사용자 상세 상태 반영 규칙 정리
- 관리자 콘솔에서 프로젝트/채널/문의구분 기반 큐 분리
- 운영 보조 화면 `/ops`, `/admin/issues` 와 실제 관리자 콘솔 역할 분담 정리
### 5.5 P2: 운영 안정화 및 검증
- role_access 기준 테스트 계정 3종 이상 준비
- 일반 사용자/담당자/시스템 관리자 시나리오별 E2E 체크리스트 작성
- 프로젝트 미매핑, 권한 부족, 세션 만료 예외 처리 검증
- 알림 및 운영 설정 누락 감지 체계 추가
- 문서 간 용어 통일: tenant, workspace, project, channel, 문의 구분
## 6. 바로 실행할 다음 작업 제안
### 6.1 1차 묶음
- `workspaceCode -> project/channel` 새 매핑표 확정
- `Q&A 관리자 테넌트` 식별 규칙 확정
- 로그인 후 사용자/관리자 분기 미들웨어 또는 라우터 초안 작성
### 6.2 2차 묶음
- 첨부파일 조회/다운로드 API 추가
- 사용자 상세 첨부 표시 추가
- 문의 구분 필드 저장 및 관리자 큐 표시 초안 추가
### 6.3 3차 묶음
- 프로젝트/채널별 관리자 접근 제어 테이블 설계
- 운영 보조 화면과 실제 관리자 콘솔 권한 경계 정리
- role_access 기준 E2E 시나리오 문서화
## 7. 이번 정리에서 제거한 구버전 가정
- `INTRANET_SUPPORT`, `SOFTWARE_QA` 중심 Project 초안은 현재 우선 기준에서 제외함.
- 기존 task 문서에 있던 인트라넷 신청형 업무 중심 Channel 목록은 role_access 기준 Q&A 프로젝트 구조가 확정될 때까지 보조 아이디어로만 취급함.
- 테스트 상수 사용자 기준 흐름은 임시 검증 수단으로 유지하되, 운영 기준 완료 항목으로 보지 않음.
## 8. 최종 요약
- 현재 구현은 사용자 지원 포털, 내부 티켓 저장, 댓글, 일부 운영 보조 화면까지는 갖춰져 있음.
- 새 기준선은 role_access 문서의 테넌트 분기, 프로젝트 구조, 관리자 권한 모델임.
- 지금 가장 큰 공백은 SSO 실연동, 로그인 후 분기, 프로젝트/채널별 접근 제어, 첨부 조회/다운로드, 문의 구분 기반 운영 큐 분리임.
- 이후 작업은 기존 범용 초안 확장보다 role_access 기준 운영 구조를 코드와 데이터에 반영하는 순서로 진행해야 함.
@@ -0,0 +1,502 @@
# 사내 지원 플랫폼 사용자별 사용 시나리오
## 1. 문서 목적
본 문서는 [architecture_secretary_sso_components_v2.md](./architecture_secretary_sso_components_v2.md)에서 정의한 통합 아키텍처를 바탕으로, 사용자 유형별 실제 사용 시나리오를 정리한 문서임.
핵심 목적은 다음과 같음.
- 어떤 사용자가 어떤 경로로 진입하는지 명확히 구분함.
- BARON-SSO, 우리 시스템, ABC User Feedback가 각각 어느 시점에 개입하는지 흐름으로 표현함.
- 조회 결과가 보이는 지점과 처리 결과가 저장되는 지점을 시나리오별로 시각화함.
## 2. 사용자 유형 정의
| 사용자 유형 | 주요 진입 경로 | 주요 목적 | 로그인 후 주 분기 화면 |
| --- | --- | --- | --- |
| 인트라넷 일반 사용자 | 인트라넷 포털 또는 공통 업무 진입점 | 물품 신청, 도서 신청, 차량 신청, 사내 문의 등록 | 사용자 피드백 작성 페이지, 내 피드백 목록/상세, ABC 조회 화면 |
| S/W 프로그램 사용자 | 각 S/W 프로그램 메뉴 또는 공통 업무 진입점 | 앱 전용 Q&A 등록, 장애/문의 접수 | 사용자 피드백 작성 페이지, 내 문의 목록/상세, ABC 조회 화면 |
| 승인자 | 인트라넷 또는 운영 포털의 공통 진입점 | 승인 대기 건 검토, 승인/반려 처리 | 승인 대상 목록, 피드백 상세, ABC 관리자 UI |
| 운영 담당자 | 운영 메뉴 또는 공통 진입점 | 전체 티켓 관리, 상태 변경, 후속 조치, 공지/알림 | 운영 목록/상세, 이슈 관리, ABC 관리자 UI |
## 3. 사용 기술 스택
| 영역 | 사용 기술 | 역할 |
| --- | --- | --- |
| 인증/사용자 식별 | BARON-SSO, OAuth 2.0, OIDC | 사용자 로그인, `user_id`, `tenant_id`, 토큰 발급 |
| 사용자/운영 화면 | 사용자 피드백 작성 페이지, ABC User Feedback Web Frontend | 사용자 입력, 목록 조회, 상세 확인, 이슈 관리, 관리자 설정 |
| 제어 백엔드 | FastAPI | `workspace` 매핑, 권한 분기, 승인 워크플로우, 외부 연동 orchestration |
| 제어 데이터 저장소 | 자체 DB (예: MySQL) | `support_tickets`, `request_approvals`, 매핑, 운영 이력 저장 |
| 원본 피드백 저장소 | ABC User Feedback | 피드백 원문, 첨부, 채널, 필드, 이슈 관리 |
| 외부 알림 연동 | Naver Works API, SMS Gateway | 승인/반려/처리 결과 알림 |
| 업무 시스템 연동 | 자산 API, 차량 API, 조직도 API 등 | 후속 처리 자동화 및 업무 데이터 조회 |
기술 스택의 책임 분리는 다음과 같음.
- BARON-SSO는 인증과 조직 식별의 기준 시스템임.
- 사용자와 승인자, 운영 담당자는 동일한 인증 상태에서 접속하고, 로그인 후에는 역할과 업무 컨텍스트에 따라 화면이 분기됨.
- 사용자 피드백 작성 페이지는 일반 사용자의 직접 입력 경험을 담당함.
- ABC User Feedback Web Frontend는 원문 조회와 운영 담당자용 관리 화면을 담당함.
- FastAPI는 ABC와 자체 DB 사이에서 정책과 절차를 제어하는 핵심 백엔드임.
- ABC User Feedback는 게시글 원본과 운영용 채널/이슈 관리 기능을 담당함.
## 4. 사용자별 시나리오 맵
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U1[인트라넷 일반 사용자]
U2[S/W 프로그램 사용자]
U3[승인자]
U4[운영 담당자]
ENTRY[공통 업무 진입점\n포털 / 앱 / 운영 메뉴]:::result
SSO[BARON-SSO]:::external
G1[우리 시스템\n세션 확인 / 역할 판정 / workspace 매핑]:::control
UI1[사용자 화면 분기
작성 / 내 목록 / 내 상세]
:::result
UI2[운영 화면 분기
승인 목록 / 운영 목록 / 상세]
:::result
UI3[ABC User Feedback 관리자 UI]:::result
APP[우리 시스템\n권한/워크플로우/매핑]:::control
ABC[ABC User Feedback\n원본 저장소]:::result
U1 -->|공통 진입| ENTRY
U2 -->|공통 진입| ENTRY
U3 -->|공통 진입| ENTRY
U4 -->|공통 진입| ENTRY
ENTRY -->|로그인 세션 확인 또는 SSO 요청| SSO
SSO -->|user_id, tenant_id, role context 반환| G1
G1 -->|일반 사용자 + 신청/문의 컨텍스트| UI1
G1 -->|승인자/운영자 + 운영 컨텍스트| UI2
UI2 -->|필요 시 ABC 관리자 기능 진입| UI3
UI1 -->|등록/조회 요청| APP
UI2 -->|승인/운영 요청| APP
UI3 -->|원문/이슈 관리 요청| APP
APP -->|원본 데이터 저장/조회| ABC
APP -->|상태/승인/권한 기록| APP
```
## 5. 시나리오 1: 인트라넷 일반 사용자의 신청 등록
### 5.1 시나리오 설명
인트라넷 일반 사용자는 물품 신청, 도서 신청, 차량 신청, 사내 문의와 같은 업무를 등록하는 주체임. 이 사용자는 우리 시스템이 직접 구현한 사용자 피드백 작성 페이지에서 신청 내용을 입력하고, 우리 시스템은 그 뒤의 승인 정책과 처리 상태를 제어하며 원문은 ABC에 저장함.
### 5.2 주요 단계
1. 사용자가 인트라넷 포털에서 특정 지원 서비스를 선택함.
2. 사용자 피드백 작성 페이지가 BARON-SSO 인증을 수행하고 `user_id`, `tenant_id`를 확보함.
3. 우리 시스템이 진입한 서비스 코드를 `workspace`로 매핑하고, 해당 사용자를 적절한 ABC 프로젝트/채널로 연결함.
4. 사용자는 우리 시스템이 직접 구현한 입력 화면에서 신청 내용을 작성함.
5. 사용자가 신청서를 제출하면 ABC가 원본 피드백 데이터를 저장함.
6. 우리 시스템은 생성된 `feedback_id`를 내부 티켓과 매핑하고 상태, 승인 필요 여부, 운영 메타데이터를 저장함.
7. 사용자와 담당자는 ABC UI에서 원문을 보고, 우리 시스템은 상태와 승인 결과를 동기화함.
### 5.3 Flow
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U[인트라넷 일반 사용자]
P[인트라넷 포털]
SSO[BARON-SSO]:::external
UI[사용자 피드백 작성 페이지
우리 시스템]:::result
M1[우리 시스템\nworkspace 매핑 / 접근 제어]:::control
M3[우리 시스템\n티켓 메타데이터 저장]:::control
A1[ABC Feedback 저장 처리]:::control
A2[ABC 원본 데이터 저장소]:::result
D1[우리 DB\nsupport_tickets / approvals / mappings]:::result
R1[ABC 접수 결과 화면\n내 신청 내역]:::result
U -->|지원 서비스 선택| P
P -->|신청 화면 호출| UI
UI -->|SSO 인증 요청| SSO
SSO -->|user_id, tenant_id 반환| UI
UI -->|서비스 코드 전달| M1
M1 -->|workspace 기반 프로젝트/채널 연결| UI
UI -->|입력 화면 작성 및 제출| A1
A1 -->|본문/필드값 저장| A2
A2 -->|feedback_id 생성 이벤트 전달| M3
M3 -->|상태/승인여부/매핑 기록| D1
A2 -->|원문 조회 제공| R1
A2 -->|원본 접수 데이터 확보| R1
```
## 6. 시나리오 2: S/W 프로그램 사용자의 Q&A 등록
### 6.1 시나리오 설명
S/W 프로그램 사용자는 특정 앱 내부의 도움말 또는 지원 메뉴를 통해 진입하며, 본인이 사용 중인 앱에 대응하는 전용 사용자 피드백 작성 페이지로 연결됨. 우리 시스템은 이를 적절한 ABC Q&A 채널에 매핑하여 원문을 저장함.
### 6.2 주요 단계
1. 사용자가 특정 S/W 프로그램 내 지원 메뉴를 클릭함.
2. 앱이 `app_id` 또는 서비스 식별자를 포함한 상태로 사용자 피드백 작성 페이지 진입 URL을 호출함.
3. BARON-SSO 인증 후 우리 시스템이 해당 식별자를 `workspace`와 ABC 채널로 매핑함.
4. 사용자는 우리 시스템의 사용자 피드백 작성 페이지에서 앱 전용 문의 폼을 작성함.
5. 사용자가 문의를 등록하면 ABC에 원본 피드백이 저장됨.
6. 우리 시스템은 내부 티켓과 앱-채널 매핑 정보를 함께 저장함.
7. 사용자는 필요 시 ABC 조회 화면에서 본인 문의 원문을 확인하고, 우리 시스템은 처리 상태를 별도 메타데이터로 관리함.
### 6.3 Flow
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U[S/W 프로그램 사용자]
APP0[각 S/W 프로그램]
SSO[BARON-SSO]:::external
UI[사용자 피드백 작성 페이지
우리 시스템]:::result
B1[우리 시스템\napp_id -> workspace 매핑]:::control
B2[우리 시스템\n권한/채널 판정]:::control
A1[ABC 채널/필드 구성]:::result
A2[ABC Feedback 저장 처리]:::control
A3[ABC 원본 Q&A 저장소]:::result
D1[우리 DB\nworkspace_channel_mappings\nsupport_tickets]:::result
R1[ABC 문의 등록 결과\n내 문의 목록]:::result
U -->|지원 메뉴 클릭| APP0
APP0 -->|app_id 포함 화면 호출| UI
UI -->|SSO 인증 요청| SSO
SSO -->|사용자 식별 정보 반환| UI
UI -->|app_id 전달| B1
B1 -->|workspace 및 채널 결정| B2
B2 -->|작성 페이지용 채널 매핑 전달| UI
B2 -->|채널 필드 정의 참조| A1
UI -->|문의 등록 제출| A2
A2 -->|Q&A 원본 저장| A3
B2 -->|내부 티켓 및 매핑 기록| D1
A3 -->|문의 원본 표시| R1
D1 -->|처리 상태 표시| R1
```
## 7. 시나리오 3: 승인자의 승인/반려 처리
### 7.1 시나리오 설명
승인자는 일반 사용자와 동일한 로그인 상태에서 접속한 뒤, 역할과 업무 컨텍스트에 따라 승인 화면으로 분기되어 원문과 이슈를 확인하면서 우리 시스템이 제어하는 승인 정책에 따라 승인 여부를 결정하는 역할임. 승인 결과는 상태 변화와 알림 발송으로 이어짐.
### 7.2 주요 단계
1. 승인자가 공통 업무 진입점에서 승인 업무로 접속함.
2. 로그인 세션 확인 또는 BARON-SSO 인증 후 우리 시스템이 승인 권한과 ABC 프로젝트 접근 권한을 검증 및 동기화함.
3. 승인자는 역할에 따라 분기된 운영 화면 또는 ABC 관리자 UI에서 승인 대상 피드백과 연결 이슈를 조회함.
4. 승인자가 승인 또는 반려 판단을 수행하면 우리 시스템이 해당 결과를 내부 승인 로직에 반영함.
5. 우리 시스템이 `request_approvals`와 티켓 상태를 갱신함.
6. 필요 시 메신저 또는 SMS 알림을 발송함.
7. 사용자와 운영자는 분기된 조회 화면과 ABC UI, 내부 상태 동기화 결과를 기준으로 처리 결과를 확인함.
### 7.3 Flow
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U[승인자]
UI[승인 화면 분기\n우리 시스템 운영 화면 / ABC 관리자 UI]:::result
SSO[BARON-SSO]:::external
C1[우리 시스템\n승인 권한 판정 / 멤버 동기화]:::control
C2[ABC 피드백 / 이슈 조회]:::control
C3[우리 시스템\n승인/반려 처리]:::control
D1[우리 DB\nrequest_approvals / support_tickets]:::result
X1[Naver Works / SMS]:::external
R1[ABC 결과 화면\n처리 상태]:::result
U -->|공통 진입 후 승인 업무 선택| UI
UI -->|세션 확인 또는 SSO 인증 요청| SSO
SSO -->|user_id, role context 반환| UI
UI -->|승인 대상 조회 요청| C1
C1 -->|권한 확인 후 피드백/이슈 조회| C2
C2 -->|승인 대상 데이터 반환| UI
UI -->|승인/반려 판단 수행| C3
C3 -->|승인 이력 및 상태 갱신| D1
C3 -->|결과 알림 발송 요청| X1
D1 -->|처리 결과 반영| R1
```
## 8. 시나리오 4: 운영 담당자의 후속 조치 및 이슈 관리
### 8.1 시나리오 설명
운영 담당자는 일반 사용자와 동일한 로그인 상태에서 접속한 뒤, 역할과 업무 컨텍스트에 따라 운영 화면으로 분기되어 접수 건을 실제 처리 단계로 연결하는 역할을 담당함. 예를 들어 자산 배정, 차량 배차, 원격지원, Q&A 이슈화, 상태 종료 처리 등을 수행함.
### 8.2 주요 단계
1. 운영 담당자가 공통 업무 진입점에서 운영 업무로 접속함.
2. 로그인 세션 확인 또는 BARON-SSO 인증 후 우리 시스템이 운영 권한과 조회 가능한 `workspace` 범위를 판정함.
3. 분기된 운영 화면 또는 ABC 관리자 UI에서 전체 피드백 또는 특정 `workspace`에 대응되는 채널을 조회함.
4. 우리 시스템이 상태, 우선순위, 요청 유형, 담당자 기준 메타데이터를 ABC 데이터와 동기화함.
5. 운영 담당자가 특정 피드백을 열어 원본 데이터와 승인 이력을 함께 확인함.
6. 필요 시 ABC 원문에 대응되는 이슈를 생성하거나 연결함.
7. 우리 시스템이 자산/차량/원격지원/알림 등의 확장 프로세스를 수행함.
8. 처리 완료 후 내부 상태를 종료하거나 추가 조치 필요 상태로 갱신하고, 필요한 결과를 ABC에 반영함.
9. 사용자와 운영자는 분기된 조회 화면과 ABC UI를 기준으로 최신 원문과 처리 상태를 확인함.
### 8.3 Flow
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U[운영 담당자]
UI[운영 화면 분기\n우리 시스템 운영 화면 / ABC 관리자 UI]:::result
C1[우리 시스템\n목록 필터/상태 조회]:::control
C2[우리 시스템\n후속 조치 엔진]:::control
C3[우리 시스템\n이슈/알림/자산 연계]:::control
D1[우리 DB\n티켓/승인/운영 이력]:::result
A1[ABC 원본 데이터]:::result
A2[ABC 이슈/피드백 연결]:::control
X1[자산/차량/외부 API]:::external
R1[ABC 운영 결과 화면\n최신 상태]:::result
U -->|공통 진입 후 운영 업무 선택| UI
UI -->|조건별 검색 요청| C1
C1 -->|티켓/상태/담당자 조회| D1
D1 -->|목록 및 상세 데이터 반환| UI
UI -->|원문 확인 요청| A1
UI -->|후속 조치 실행| C2
C2 -->|이슈 연결 또는 상태 갱신| A2
C2 -->|운영 이력 저장| D1
C3 -->|자산/차량/알림 API 호출| X1
D1 -->|최신 결과 집계| R1
A2 -->|원본 연계 상태 반영| R1
```
## 9. 권한별 핵심 차이
| 구분 | 일반 사용자 | S/W 사용자 | 승인자 | 운영 담당자 |
| --- | --- | --- | --- | --- |
| 인증 | BARON-SSO | BARON-SSO | BARON-SSO | BARON-SSO |
| 진입 기준 | 서비스 메뉴 | 앱 메뉴 | 승인 업무 메뉴 | 운영 메뉴 |
| 주 작업 | 신청 등록/조회 | 문의 등록/조회 | 승인/반려 | 상태 관리/후속 조치 |
| ABC 직접 사용 여부 | 부분 사용 | 부분 사용 | 직접 사용 | 직접 사용 |
| 우리 시스템 의존도 | 높음 | 높음 | 높음 | 높음 |
| 핵심 저장 위치 | ABC + 우리 DB | ABC + 우리 DB | ABC + 우리 DB | ABC + 우리 DB |
## 10. 문서 활용 가이드
- 화면 설계 시에는 일반 사용자용 작성 화면은 우리 시스템에서 직접 구현하고, 운영/관리 화면은 ABC 기본 UI를 우선 활용함.
- API 설계 시에는 어떤 단계가 우리 시스템 API인지, 어떤 단계가 ABC 연동인지 분리해서 정의함.
- 권한 설계 시에는 `workspace`, `role`, `approval permission`, `operator permission`을 별도 축으로 설계함.
- 운영 정책 수립 시에는 승인자와 운영 담당자의 역할이 섞이지 않도록 본 문서의 시나리오를 기준으로 책임 범위를 정리함.
## 11. 시나리오 기준 ABC User Feedback 활용 기능 및 API
### 11.1 활용 원칙
- 최종 사용자 인증은 BARON-SSO를 기준으로 하고, ABC의 사용자 인증 체계는 운영용 또는 관리용 보조 수단으로만 사용함.
- 일반 사용자는 우리 시스템의 사용자 피드백 작성 페이지를 사용하고, 운영 담당자는 ABC User Feedback UI를 직접 사용함.
- 우리 시스템은 사용자 입력 화면, ABC UI 진입 제어, 권한 동기화, 상태/승인 메타데이터 관리에 집중함.
- 따라서 ABC API는 크게 `프로젝트/채널 사전 구성`, `원본 피드백 저장/조회`, `이슈 관리`, `멤버/역할 동기화`, `운영 자동화` 용도로 사용함.
### 11.2 시나리오별 ABC 활용 기능
| 시나리오 | ABC에서 활용할 기능 | 실제 활용 API | 비고 |
| --- | --- | --- | --- |
| 인트라넷 일반 사용자 신청 등록 | 신청 원문 저장 | `POST /api/projects/:projectId/channels/:channelId/feedbacks` | 우리 작성 페이지에서 API 호출로 ABC 원문 저장 |
| 인트라넷 일반 사용자 신청 등록 | 이미지 포함 신청 저장 | `POST /api/projects/:projectId/channels/:channelId/feedbacks-with-images` | 첨부 업로드 자동화가 필요한 경우 사용 |
| S/W 프로그램 사용자 Q&A 등록 | 앱 전용 문의 원문 저장 | `POST /api/projects/:projectId/channels/:channelId/feedbacks` | 우리 작성 페이지에서 `workspace`와 채널 매핑 후 API 호출 |
| 승인자 승인/반려 | 원문 참조용 피드백 목록 조회 | `POST /api/admin/projects/:projectId/channels/:channelId/feedbacks/search` | ABC 관리자 UI와 병행 사용 |
| 운영 담당자 후속 조치 | 이슈 생성 | `POST /api/admin/projects/:projectId/issues` | 문의를 이슈로 승격할 때 사용 |
| 운영 담당자 후속 조치 | 피드백-이슈 연결 | `POST /api/admin/projects/:projectId/channels/:channelId/feedbacks/:feedbackId/issue/:issueId` | 문의와 처리 이슈 연결 |
| 운영 담당자 후속 조치 | 이슈 목록 조회 | `POST /api/admin/projects/:projectId/issues/search` | 현황판, 대시보드 구성에 사용 |
| 운영 담당자 후속 조치 | 이슈 상세 조회 | `GET /api/admin/projects/:projectId/issues/:issueId` | 연결된 피드백 수, 상태 확인 |
| 운영 담당자 후속 조치 | 피드백 수정 | `PUT /api/admin/projects/:projectId/channels/:channelId/feedbacks/:feedbackId` | 원문 보정 또는 메타 필드 갱신 |
| 운영 담당자 후속 조치 | 피드백 내보내기 | `POST /api/admin/projects/:projectId/channels/:channelId/feedbacks/export` | 운영 보고용 다운로드 |
| 운영 환경 준비 | 프로젝트 생성/조회 | `POST /api/admin/projects`, `GET /api/admin/projects` | 서비스 단위 프로젝트 생성 |
| 운영 환경 준비 | 채널 생성/조회 | `POST /api/admin/projects/:projectId/channels/`, `GET /api/admin/projects/:projectId/channels/` | 서비스별 접수 채널 구성 |
| 운영 환경 준비 | 채널 필드 관리 | `PUT /api/admin/projects/:projectId/channels/:channelId/fields` | 신청서 항목과 채널 필드 정합 |
| 운영 권한 구성 | 프로젝트 멤버 관리 | `POST /api/admin/projects/:projectId/members`, `POST /api/admin/projects/:projectId/members/search` | 운영자/담당자 접근 권한 부여 |
| 운영 권한 구성 | 역할 관리 | `GET /api/admin/projects/:projectId/roles/`, `POST /api/admin/projects/:projectId/roles/` | 프로젝트별 역할 정의 |
일반 사용자와 운영 담당자의 일상 사용 흐름은 ABC UI를 우선 사용하고, 위 API는 다음 목적에서 활용함.
- 초기 프로젝트/채널/역할 셋업 자동화
- BARON-SSO 사용자와 ABC 멤버 구조 동기화
- 내부 상태값과 ABC 피드백/이슈 연계 자동화
- 대량 등록, 이관, 배치 처리, 외부 시스템 연동
### 11.3 ABC에서 주로 재사용할 기능 묶음
| 기능 묶음 | 재사용 목적 | 설명 |
| --- | --- | --- |
| Feedback 저장 기능 | 문의/신청 원문 저장 | 제목, 본문, 필드값, 이미지 등 원본 데이터 보존 |
| Channel/Field 관리 기능 | 서비스별 입력 스키마 구성 | 채널별 신청서 항목과 커스텀 필드 유지 |
| Issue 관리 기능 | 운영 후속 조치 기록 | 피드백을 운영 이슈와 연결하고 상태 추적 |
| Project/Member/Role 관리 기능 | 운영 구조 설정 | 프로젝트, 채널, 담당자, 권한 체계 운영 |
| Export 기능 | 운영 보고/분석 | 피드백 데이터 다운로드 및 외부 분석 활용 |
## 12. 우리가 직접 구현해야 하는 부분
### 12.1 구현 원칙
- ABC는 원본 데이터와 관리자 기능을 담당하고, 실제 서비스 경험은 우리 시스템이 완성함.
- 일반 사용자가 사용하는 사용자 피드백 작성 페이지는 우리 시스템에서 직접 구현하고, 운영/관리 기능은 ABC UI를 최대한 활용함.
- 따라서 인증, 권한, 워크플로우, 업무 상태, 외부 시스템 연계뿐 아니라 일반 사용자 입력 화면도 직접 구현 범위에 포함됨.
### 12.2 직접 구현 범위 요약
| 구현 영역 | 우리가 직접 구현할 내용 | ABC만으로 부족한 이유 |
| --- | --- | --- |
| SSO 연동 | BARON-SSO 로그인, 토큰 검증, `user_id`, `tenant_id` 세션 처리 | ABC 인증은 우리 조직의 통합 인증 기준이 아님 |
| 진입 경로 해석 | `app_id`, `service_type_id`, 메뉴 코드 등을 `workspace`로 매핑 | ABC는 외부 서비스 진입 맥락을 이해하지 못함 |
| 사용자 피드백 작성 화면 | 일반 사용자용 입력 폼, 유효성 검사, 제출 완료 UX, ABC 저장 API 호출 | ABC 기본 화면만으로는 서비스별 사용자 경험과 진입 컨텍스트를 충분히 통제하기 어려움 |
| ABC 진입 제어 | 사용자를 올바른 프로젝트/채널/화면으로 연결하는 리다이렉트 및 딥링크 로직 | ABC는 외부 포털 메뉴 체계와 직접 연결되지 않음 |
| 채널/필드 표준화 | 서비스별 필드 템플릿, 채널 생성 규칙, 운영 정책 자동화 | ABC만으로는 사내 표준 신청서 체계를 일관되게 강제하기 어려움 |
| 내부 티켓 모델 | `support_tickets` 기반 상태, 우선순위, 업무 유형, 담당자 관리 | ABC 피드백 원문만으로 운영 제어 메타데이터를 관리하기 부족함 |
| 승인 워크플로우 | `request_approvals`, 승인선, 승인/반려 이력, 다단계 결재 | 사내 결재 정책은 ABC 기본 기능 범위를 넘음 |
| 권한 동기화 | 사용자별 조회 범위, 승인 권한, 운영 권한, 워크스페이스별 접근 제어를 ABC 멤버/역할과 연동 | 프로젝트/멤버 권한만으로 세밀한 업무 분기 어려움 |
| 원본-내부 매핑 | ABC `feedback_id`와 내부 티켓 ID, 기존 시스템 ID 매핑 | 이관 및 통합 운영을 위한 별도 식별자 체계 필요 |
| 외부 연동 | 자산, 차량, 조직도, 메신저, SMS, 기타 사내 API 연계 | ABC는 사내 업무 시스템 orchestration 역할이 아님 |
| 알림 정책 | 상태 변경별 알림 템플릿, 채널 선택, 재발송 규칙 | 사내 정책 기반 알림 제어가 필요함 |
| 집계/리포팅 | 업무 유형별 KPI, 승인 지연, 처리 SLA, 부서별 통계 | ABC 통계는 일반 피드백 관점이라 업무형 리포트에 한계가 있음 |
| 마이그레이션 도구 | 기존 게시글, 첨부, 댓글, 분류 정보 이관 및 검증 | 기존 시스템 식별자와의 추적 관리가 필요함 |
### 12.3 시나리오별 구현 책임 정리
| 시나리오 | ABC가 담당하는 부분 | 우리가 직접 구현하는 부분 |
| --- | --- | --- |
| 인트라넷 일반 사용자 신청 등록 | 피드백 원문 저장, 첨부 저장 | SSO 로그인, 사용자 피드백 작성 페이지 구현, 서비스 진입 제어, 채널 연결, 신청 상태 저장, 승인선 생성 |
| S/W 프로그램 사용자 Q&A 등록 | 앱 전용 채널에 문의 원문 저장, 목록/상세 UI 제공 | 사용자 피드백 작성 페이지 구현, 앱 식별자 해석, `workspace` 매핑, 사용자 권한 판정, ABC 진입 URL 제어, 상태 메타데이터 관리 |
| 승인자 승인/반려 | 피드백/이슈 조회 UI 제공 | 승인 규칙, 승인 이력, 결과 알림, 상태 전이, ABC 멤버 권한 동기화 |
| 운영 담당자 후속 조치 | 이슈 생성, 피드백-이슈 연결, 원문 검색/수정 UI 제공 | 담당자 배정, 자산/차량 후속 처리, SLA 추적, 내부 상태 관리, 외부 API 실행 |
| 운영 환경 준비 | 프로젝트/채널/필드/멤버/역할 관리 API와 관리자 UI | 서비스 구조 설계, 채널 정책 표준화, 권한 모델링, 셋업 자동화 |
### 12.4 구현 우선순위 제안
1. `BARON-SSO 연동 + 사용자 피드백 작성 페이지 + workspace 매핑 + ABC 진입 제어`를 먼저 구현해야 함.
2. 그 다음 `support_tickets + approvals + abc_feedback_mappings` 중심의 내부 제어 DB를 구축해야 함.
3. 이후 `ABC 멤버/역할 동기화 + 승인 워크플로우 + 외부 연동`을 확장하는 순서가 가장 현실적임.
4. 마지막으로 `마이그레이션 도구 + 통계/리포트 + 셋업 자동화`를 붙여 운영 전환을 마무리하는 구성이 적절함.
## 13. 사용자 작성부터 이슈 생성 및 처리, 답변 입력까지의 시스템 데이터 처리 모식도
### 13.1 목적
이 절은 일반 사용자가 사용자 피드백 작성 페이지에서 문의를 등록한 뒤, 담당자가 이슈를 생성하고 처리한 후 답변 또는 처리 결과를 입력할 때까지 데이터가 어느 시스템에 저장되고 어떻게 연결되는지를 한 번에 보여주기 위한 보조 모식도임.
핵심 확인 포인트는 다음과 같음.
- 일반 사용자는 보통 BARON-SSO 인증을 마치고, 우리 시스템이 접근 권한과 연결 채널을 판정한 뒤 작성 페이지에 진입함.
- 운영 담당자와 관리자도 동일하게 BARON-SSO 인증 또는 세션 확인을 거친 뒤, 역할에 맞는 운영 화면 또는 관리자 화면으로 분기 진입함.
- 사용자 입력 원문은 ABC User Feedback에 저장됨.
- 제어용 상태와 승인/운영 메타데이터는 우리 DB에 저장됨.
- 담당자 이슈 생성과 처리 이력은 ABC 이슈와 우리 DB가 함께 관리함.
- 최종 답변 또는 처리 결과는 사용자에게 보이는 원문/상태 화면으로 다시 동기화됨.
### 13.2 단계별 데이터 처리 요약
| 단계 | 수행 주체 | 주요 처리 | 주요 저장 위치 |
| --- | --- | --- | --- |
| 1 | 일반 사용자 | 신청/문의 메뉴로 진입하고 보호된 작성 페이지 접근을 시도 | 진입 전 상태는 포털 또는 앱 컨텍스트 |
| 2 | BARON-SSO + 우리 시스템 | 로그인 세션 확인 또는 SSO 인증 수행, `user_id`, `tenant_id` 확보 | 우리 시스템 세션 / 인증 컨텍스트 |
| 3 | 우리 시스템 | `workspace`, 채널, 권한, 요청 유형을 판정하고 작성 가능한 대상인지 검증 | 우리 시스템 제어 로직 |
| 4 | 일반 사용자 | 권한이 확인된 작성 페이지에서 문의/신청 내용을 작성하고 제출 | 제출 전 일시 상태는 우리 시스템 화면 메모리 |
| 5 | 우리 시스템 | ABC 저장 API 호출 | 우리 시스템 제어 로직 |
| 6 | ABC User Feedback | 피드백 원문, 필드값, 첨부, 생성된 `feedback_id` 저장 | ABC Feedback 원본 저장소 |
| 7 | 우리 시스템 | `feedback_id`를 받아 내부 티켓, 승인 필요 여부, 상태값 생성 | 우리 DB `support_tickets`, `abc_feedback_mappings` |
| 8 | 운영 담당자/관리자 | 공통 업무 진입점 또는 운영 메뉴로 접속하고 보호된 운영 화면 접근을 시도 | 운영 포털 또는 운영 메뉴 컨텍스트 |
| 9 | BARON-SSO + 우리 시스템 | 로그인 세션 확인 또는 SSO 인증 수행 후 운영 권한, 관리자 권한, 조회 가능한 `workspace` 범위 판정 | 우리 시스템 세션 / 권한 컨텍스트 |
| 10 | 승인자/담당자/관리자 | 역할에 따라 분기된 운영 화면 또는 ABC 관리자 UI에서 승인, 조회, 이슈 작업 수행 | 우리 시스템 운영 화면 + ABC 관리자 UI |
| 11 | 승인자/담당자 | 승인 또는 반려 판단 | 우리 DB `request_approvals`, `support_tickets` |
| 12 | 담당자/관리자 | ABC 관리자 UI에서 이슈 생성 및 피드백-이슈 연결 | ABC Issue, ABC Feedback-Issue 연결 정보 |
| 13 | 우리 시스템 | 담당자 배정, 처리 메모, 외부 연동 결과, SLA 상태 저장 | 우리 DB `support_tickets`, 운영 이력, 알림 이력 |
| 14 | 담당자/관리자 | 처리 결과 또는 답변 입력, 필요 시 원문/상태 반영 | ABC 원문 표시 정보 + 우리 DB 상태값 |
| 15 | 일반 사용자 | ABC 조회 화면 또는 우리 시스템 조회 화면에서 처리 결과 확인 | ABC 원문 + 우리 DB 상태 동기화 결과 |
### 13.3 End-to-End 데이터 흐름 모식도
```mermaid
flowchart LR
classDef result fill:#eef6ff,stroke:#1d4ed8,stroke-width:1.5px,color:#0f172a;
classDef control fill:#f8fafc,stroke:#334155,stroke-width:1.2px,color:#111827;
classDef external fill:#fff7ed,stroke:#c2410c,stroke-width:1.2px,color:#111827;
U[일반 사용자]
OP[운영 담당자]
AD[관리자/승인자]
E1[신청/문의 메뉴 진입\n포털 또는 앱]:::result
E2[운영/관리 메뉴 진입\n운영 포털 또는 관리자 메뉴]:::result
A0[BARON-SSO 인증 / 세션 확인]:::external
G0[우리 시스템\n사용자/운영자/관리자 권한 판정\nworkspace / 채널 / 역할 결정]:::control
W[사용자 화면 분기\n작성 / 내 목록 / 내 상세]:::result
A1[ABC Feedback 저장 API]:::control
A2[ABC 원본 피드백 저장소\n본문/필드값/첨부/feedback_id]:::result
D1[우리 DB\nsupport_tickets\nabc_feedback_mappings]:::result
O0[운영 화면 분기\n운영 목록 / 승인 목록 / 상세]:::result
AP[승인 처리 엔진\n승인/반려/상태 전이]:::control
D2[우리 DB\nrequest_approvals\nstatus history]:::result
O1[ABC 관리자 UI]:::result
I1[ABC Issue 저장소\nissue / feedback-issue link]:::result
O2[우리 시스템\n담당자 배정/처리 메모/외부 연동]:::control
D3[우리 DB\n운영 이력 / 알림 / SLA / 후속조치]:::result
X1[자산/차량/Naver Works/SMS]:::external
A3[결과 반영 화면\nABC 원문 + 우리 시스템 상태 동기화]:::result
R1[최종 사용자 조회 화면]:::result
U -->|신청/문의 메뉴 선택| E1
OP -->|운영 업무 진입| E2
AD -->|관리/승인 업무 진입| E2
E1 -->|로그인 또는 기존 세션 확인| A0
E2 -->|로그인 또는 기존 세션 확인| A0
A0 -->|user_id, tenant_id, role context 확보| G0
G0 -->|일반 사용자 화면 진입| W
W -->|작성 완료 후 제출| A1
A1 -->|피드백 원문 저장| A2
A2 -->|feedback_id 반환 및 내부 매핑 시작| D1
D1 -->|운영/관리 대상 건 생성| O0
G0 -->|운영자/관리자 화면 진입| O0
O0 -->|승인 필요 건은 승인 엔진으로 전달| AP
AP -->|승인/반려 이력 기록| D2
D2 -->|승인 결과 반영| D1
O0 -->|원문 확인 및 관리자 기능 진입| O1
O1 -->|이슈 생성/연결 요청| I1
I1 -->|이슈 식별자/연결 정보 반환| O2
O2 -->|담당자 배정, 처리 메모, 상태 갱신| D3
O2 -->|support_tickets 상태 갱신| D1
O2 -->|외부 업무 시스템 호출| X1
O1 -->|답변/처리 결과 입력| O2
D1 -->|최종 상태 동기화| A3
D3 -->|처리 결과 동기화| A3
O2 -->|답변/처리 결과 반영| A3
A3 -->|내 목록 / 상세 / 결과 조회 제공| R1
```
### 13.4 저장 책임 정리
| 데이터 유형 | 우선 저장 위치 | 설명 |
| --- | --- | --- |
| 사용자 입력 본문, 필드값, 첨부 | ABC User Feedback | 원문 데이터의 기준 저장소 |
| `feedback_id`와 내부 티켓 연결 | 우리 DB | `support_tickets`, `abc_feedback_mappings`에 저장 |
| 승인 상태, 반려 이력, 단계별 결재 결과 | 우리 DB | `request_approvals`, 상태 이력 테이블에 저장 |
| 운영 이슈, 피드백-이슈 연결 | ABC User Feedback | 운영 추적의 기준 이슈 저장소 |
| 담당자 배정, 처리 메모, SLA, 외부 연동 결과 | 우리 DB | 운영 제어와 리포팅을 위한 내부 메타데이터 |
| 사용자에게 보여줄 최종 처리 결과 | ABC 원문 조회 화면 + 우리 DB 동기화 결과 | 원문과 상태를 함께 보여주는 최종 표시 데이터 |
### 13.5 설계 해석 포인트
- 사용자 작성은 인증과 접근 권한 검증, `workspace`-채널 판정이 끝난 뒤 시작되며, 작성 UX와 진입 제어는 우리 시스템이 담당하지만 원문 자체는 ABC에 남김.
- 승인과 운영 처리 단계에서는 우리 DB가 상태 제어의 기준 시스템 역할을 수행함.
- 담당자의 이슈 생성은 ABC를 기준으로 하되, 그 이슈를 어떤 업무 상태로 해석할지는 우리 시스템이 담당함.
- 답변 입력 또는 처리 결과 입력은 단순 텍스트 등록이 아니라 `support_tickets` 상태, 승인 결과, 운영 메모, 외부 연동 결과를 함께 묶어 사용자에게 노출하는 흐름으로 봐야 함.