docs: README를 현재 시스템 기준으로 다시 씀
기능이 대폭 늘었는데 README는 기관 명부·채널 생성까지만 설명하고 있어 실제와 어긋났다. 대시보드·사업관리·시스템관리·권리확인/처리·도움말까지 반영하고, 읽는 순서대로 다시 배치한다. - 화면 구성, 12단계 흐름, 최초 사용 순서를 표와 도식으로 정리 - 환경변수를 필수 8개와 기본값 있는 선택 2개로 나눠 표기 - 수정할 때 깨뜨리면 안 되는 약속(채널 2종, 재실행 안전, 채널⇔단계 불변식, 엑셀 재업로드 병합 규칙, 제3자 권리처리 정책, 연번 문자열)을 한 표로 모음 - 패키지·화면 구조와 API 목록, 배포(deploy/README.md 연결) 추가 Yona 렌더러에서 깨지지 않도록 GitHub 전용 문법(경고 블록, HTML 표) 대신 표준 마크다운만 쓴다. Co-Authored-By: Claude Opus 5 (1M context)
@41ea29b1bcf6e196454294f1b06909b6553f533b
--- README.md
+++ README.md
... | ... | @@ -1,66 +1,91 @@ |
| 1 | 1 |
# ITN-HUB |
| 2 | 2 |
|
| 3 |
-47개 신유형 사업 신청기관의 명부·담당자 정보를 관리하고, 기관별 Mattermost 채널(문정원/법률검토) |
|
| 4 |
-생성을 자동화하는 웹 애플리케이션이다. 기존 Excel VBA 매크로(`M06_Mattermost_기관목록`, |
|
| 5 |
-`M07_Mattermost_채널일괄생성`) 워크플로를 웹으로 옮긴 후속 단계로, 신청목록 시트 업로드로 |
|
| 6 |
-기관 정보를 시드하고, 부서/담당자 정보를 입력한 뒤, 기관당 Mattermost 비공개 채널 2개 |
|
| 7 |
-(`문정원`, `법률검토`)를 생성·복구한다. |
|
| 3 |
+> **2026 신유형 공공저작물 개방사업 · 3단계 법률검토 관리 시스템** |
|
| 4 |
+> |
|
| 5 |
+> 신청기관 명부·담당자 관리부터 Mattermost 채널 자동 생성, 권리확인·권리처리 판정, |
|
| 6 |
+> 사업 현황 대시보드까지 한 곳에서 처리한다. |
|
| 8 | 7 |
|
| 9 |
-## ⚠️ 실행 전 반드시 읽을 것 |
|
| 8 |
+`Spring Boot 3.3.5` `Java 21` `React 18` `PostgreSQL 16` `MyBatis` `Flyway` `Mattermost` |
|
| 10 | 9 |
|
| 11 |
-- **이 애플리케이션은 실제 운영 Mattermost 서버(`https://hub.iten.co.kr`)에 실제 채널을 생성한다.** |
|
| 12 |
- 테스트 목적으로 함부로 실행하면 운영 팀에 실제 채널이 생긴다. |
|
| 13 |
-- Mattermost `MATTERMOST_TOKEN`(Personal Access Token)은 **시스템 관리자(system-admin) 권한**을 |
|
| 14 |
- 가진 계정의 토큰이어야 한다. 비공개(private) 채널을 팀 전체 범위에서 조회(레거시 채널 |
|
| 15 |
- 복구용 표시명 검색, `GET /api/v4/teams/{teamId}/channels`)하려면 이 권한이 필요하다.
|
|
| 16 |
- 일반 권한 토큰을 쓰면 레거시 채널을 못 찾아 매번 중복 채널이 생성될 수 있다. |
|
| 17 |
-- **최초 사용 전에는 실제 신청기관이 아니라 테스트용 기관(예: 연번 `999`, 임시 기관명)으로 |
|
| 18 |
- 먼저 스모크 테스트를 해볼 것을 권장한다.** 시드 업로드 → 담당자 입력 → 채널 생성까지 |
|
| 19 |
- 한 번 돌려보고, Mattermost 서버에서 실제로 의도한 이름의 비공개 채널 2개가 만들어지는지 |
|
| 20 |
- 확인한 뒤 실제 기관 데이터를 올린다. |
|
| 10 |
+--- |
|
| 21 | 11 |
|
| 22 |
-## 환경변수 |
|
| 12 |
+## 목차 |
|
| 23 | 13 |
|
| 24 |
-`.env.example`을 참고해 실제 값을 채운 `.env`(또는 배포 환경의 환경변수)를 준비한다. |
|
| 25 |
-**`.env`나 실제 값이 든 파일은 절대 커밋하지 않는다.** |
|
| 14 |
+- [무엇을 하는 시스템인가](#무엇을-하는-시스템인가) |
|
| 15 |
+- [화면 구성](#화면-구성) |
|
| 16 |
+- [시작하기](#시작하기) |
|
| 17 |
+- [환경변수](#환경변수) |
|
| 18 |
+- [업무 흐름](#업무-흐름) |
|
| 19 |
+- [핵심 규칙](#핵심-규칙) |
|
| 20 |
+- [프로젝트 구조](#프로젝트-구조) |
|
| 21 |
+- [API](#api) |
|
| 22 |
+- [테스트](#테스트) |
|
| 23 |
+- [배포](#배포) |
|
| 26 | 24 |
|
| 27 |
-| 변수 | 설명 | 예시 값 | |
|
| 28 |
-|---|---|---| |
|
| 29 |
-| `DB_URL` | PostgreSQL 16 JDBC URL | `jdbc:postgresql://localhost:5432/itnhub` | |
|
| 30 |
-| `DB_USERNAME` | DB 접속 계정 | `itnhub_app` | |
|
| 31 |
-| `DB_PASSWORD` | DB 접속 비밀번호 | `changeme-please` | |
|
| 32 |
-| `MATTERMOST_URL` | Mattermost 서버 베이스 URL | `https://hub.iten.co.kr` | |
|
| 33 |
-| `MATTERMOST_TOKEN` | system-admin 권한 Personal Access Token | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | |
|
| 34 |
-| `MATTERMOST_TEAM_ID` | 채널을 생성할 Mattermost 팀 ID | `abcdefghijklmnopqrstuvwxyz` | |
|
| 35 |
-| `APP_ADMIN_USERNAME` | 앱 로그인 관리자 계정 | `admin` | |
|
| 36 |
-| `APP_ADMIN_PASSWORD` | 앱 로그인 관리자 비밀번호(충분히 긴 무작위 문자열 권장) | `use-a-long-random-value` | |
|
| 25 |
+--- |
|
| 37 | 26 |
|
| 38 |
-이 8개는 전부 `${...}` 플레이스홀더로 `application.yml`에 선언되어 있어 값이 없으면
|
|
| 39 |
-애플리케이션이 기동하지 않는다. |
|
| 27 |
+## 무엇을 하는 시스템인가 |
|
| 40 | 28 |
|
| 41 |
-### 왜 `spring.datasource.hikari.schema: itnhub`가 있는가 |
|
| 29 |
+기존 Excel VBA 매크로(`M06_Mattermost_기관목록`, `M07_Mattermost_채널일괄생성`)로 하던 작업을 |
|
| 30 |
+웹으로 옮긴 것이다. 47개 신청기관을 대상으로 다음 흐름을 처리한다. |
|
| 42 | 31 |
|
| 43 |
-`application.yml`의 `spring.datasource.hikari.schema: itnhub` 설정은 지우면 안 된다. |
|
| 44 |
-`spring.flyway.schemas`는 Flyway 전용 커넥션에만 적용되는 설정이라, 애플리케이션이 실제 |
|
| 45 |
-쿼리를 실행하는 HikariCP 커넥션 풀은 이 설정이 없으면 기본 `search_path`(보통 `public`)를 |
|
| 46 |
-써서 `relation "organization" does not exist` 오류가 난다. Flyway가 만드는 스키마와 |
|
| 47 |
-런타임 커넥션이 바라보는 스키마를 반드시 일치시켜야 한다. |
|
| 32 |
+``` |
|
| 33 |
+ 신청목록 엑셀 담당자 채널 2종 권리확인 / 권리처리 보고서 |
|
| 34 |
+ 업로드 → 배정 → 자동 생성 → 변호사 판정 → 제출 |
|
| 35 |
+ 기관 명부 신청기관·문정원 문정원·법률검토 엑셀 업로드 후 사업관리 |
|
| 36 |
+ 아이티앤·변호사 + 안내글 핀 고정 건별 판정 |
|
| 37 |
+``` |
|
| 48 | 38 |
|
| 49 |
-## 빌드 |
|
| 39 |
+> **⚠ 주의** |
|
| 40 |
+> |
|
| 41 |
+> 이 애플리케이션은 **실제 운영 Mattermost 서버(`https://hub.iten.co.kr`)에 실제 채널을 만든다.** |
|
| 42 |
+> 처음 쓸 때는 실제 기관이 아니라 테스트 기관(예: 연번 `999`)으로 한 바퀴 돌려보고 시작할 것. |
|
| 43 |
+> |
|
| 44 |
+> `MATTERMOST_TOKEN`은 **시스템 관리자(system-admin) 권한** 계정의 Personal Access Token이어야 한다. |
|
| 45 |
+> 팀 전체 범위에서 비공개 채널을 조회해야(레거시 채널 복구) 중복 생성을 막을 수 있기 때문이다. |
|
| 46 |
+ |
|
| 47 |
+--- |
|
| 48 |
+ |
|
| 49 |
+## 화면 구성 |
|
| 50 |
+ |
|
| 51 |
+| 메뉴 | 하는 일 | |
|
| 52 |
+| :-- | :-- | |
|
| 53 |
+| **Dashboard** | KPI 7타일 · 단계별 칸반(카드 드래그로 단계 이동) · 최근 진행 기관 | |
|
| 54 |
+| **채널관리** | 신청목록 시트 업로드 · 담당자 4역할 배정 · Mattermost 채널 2종 생성 | |
|
| 55 |
+| **기관관리** | 기관 상세. 업무단계 스트립 + 7개 탭(채팅·자료·권리확인·권리처리·RE·타임라인·업무메모) | |
|
| 56 |
+| **담당자관리** | 담당자 등록·수정·삭제, 회원명단 엑셀 일괄 업로드 | |
|
| 57 |
+| **사업관리** | 3단계 대상 기관 현황 · 신청 확인 연락 이력 · 기관별 최종 보고서 | |
|
| 58 |
+| **시스템관리** | 채널 초기화(미리보기 → 확인문구 → 실행) | |
|
| 59 |
+ |
|
| 60 |
+화면 곳곳의 버튼 옆 **`?` 아이콘**을 누르면 실제 화면 캡처가 담긴 설명서가 열린다(19개 항목). |
|
| 61 |
+ |
|
| 62 |
+--- |
|
| 63 |
+ |
|
| 64 |
+## 시작하기 |
|
| 65 |
+ |
|
| 66 |
+### 요구사항 |
|
| 67 |
+ |
|
| 68 |
+| 항목 | 버전 / 비고 | |
|
| 69 |
+| :-- | :-- | |
|
| 70 |
+| JDK | **21** | |
|
| 71 |
+| PostgreSQL | **16** | |
|
| 72 |
+| Node.js | 불필요 — `mvn package`가 v20.17.0을 내려받아 프런트를 함께 빌드한다 | |
|
| 73 |
+| Docker | 백엔드 테스트에만 필요(Testcontainers) | |
|
| 74 |
+ |
|
| 75 |
+### 빌드 |
|
| 50 | 76 |
|
| 51 | 77 |
```bash |
| 52 | 78 |
mvn -DskipTests package |
| 53 | 79 |
``` |
| 54 | 80 |
|
| 55 |
-`pom.xml`의 `frontend-maven-plugin`이 `mvn package` 과정에서 `frontend/`의 React 앱을 |
|
| 56 |
-함께 빌드해 `src/main/resources/static/`에 넣고, 그 결과를 Spring Boot의 단일 jar에 |
|
| 57 |
-패키징한다. 별도로 프론트엔드를 먼저 빌드할 필요는 없다. |
|
| 81 |
+`frontend-maven-plugin`이 React 앱을 빌드해 `src/main/resources/static/`에 넣고, |
|
| 82 |
+그 결과가 **단일 jar 하나**로 패키징된다. 프런트를 따로 빌드할 필요가 없다. |
|
| 58 | 83 |
|
| 59 |
-## 실행 |
|
| 84 |
+### 실행 |
|
| 60 | 85 |
|
| 61 | 86 |
```bash |
| 62 | 87 |
export DB_URL=jdbc:postgresql://localhost:5432/itnhub |
| 63 |
-export DB_USERNAME=itnhub_app |
|
| 88 |
+export DB_USERNAME=itnhub |
|
| 64 | 89 |
export DB_PASSWORD=... |
| 65 | 90 |
export MATTERMOST_URL=https://hub.iten.co.kr |
| 66 | 91 |
export MATTERMOST_TOKEN=... |
... | ... | @@ -68,30 +93,169 @@ |
| 68 | 93 |
export APP_ADMIN_USERNAME=admin |
| 69 | 94 |
export APP_ADMIN_PASSWORD=... |
| 70 | 95 |
|
| 71 |
-java -jar target/itnhub-0.1.0.jar |
|
| 96 |
+java -jar target/itnhub-0.1.0.jar --server.port=8091 |
|
| 72 | 97 |
``` |
| 73 | 98 |
|
| 74 |
-## 최초 사용 순서 |
|
| 99 |
+기동하면 Flyway가 `itnhub` 스키마와 테이블(V1~V12)을 **자동으로 만든다.** 수동 DDL은 없다. |
|
| 75 | 100 |
|
| 76 |
-1. PostgreSQL 16 인스턴스를 준비하고 위 환경변수로 접속 정보를 지정한다. 기동 시 Flyway가 |
|
| 77 |
- `itnhub` 스키마와 테이블을 자동으로 만든다(수동 DDL 불필요). |
|
| 78 |
-2. 브라우저로 접속해 `APP_ADMIN_USERNAME` / `APP_ADMIN_PASSWORD`로 로그인한다. |
|
| 79 |
-3. 좌측 하단 "신청목록 시트 올리기"로 기관 신청목록 엑셀(`.xlsx`/`.xlsm`)을 업로드해 |
|
| 80 |
- 기관 명부를 시드한다. |
|
| 81 |
-4. 기관을 선택해 부서명/담당자명/연락처/이메일(직급/직함은 선택)을 입력하고 저장한다. |
|
| 82 |
-5. "채널 생성"을 눌러 Mattermost에 문정원/법률검토 채널 2개를 생성한다. 이미 생성된 |
|
| 83 |
- 채널은 재실행해도 다시 만들지 않는다(idempotent) - 실패한 채널만 다시 시도된다. |
|
| 84 |
- |
|
| 85 |
-## 개발 워크플로 |
|
| 101 |
+### 프런트만 반복 개발할 때 |
|
| 86 | 102 |
|
| 87 | 103 |
```bash |
| 88 |
-cd frontend |
|
| 89 |
-npm install |
|
| 90 |
-npm run dev |
|
| 104 |
+cd frontend && npm install && npm run dev # Vite가 /api 를 :8080 으로 프록시 |
|
| 105 |
+mvn spring-boot:run # 백엔드는 따로 띄워 둔다 |
|
| 91 | 106 |
``` |
| 92 | 107 |
|
| 93 |
-Vite 개발 서버가 `/api` 요청을 `:8080`(백엔드)으로 프록시한다. 백엔드는 별도로 |
|
| 94 |
-`mvn spring-boot:run` 등으로 띄워둔 상태에서 프론트엔드만 `npm run dev`로 반복 개발하면 된다. |
|
| 108 |
+--- |
|
| 95 | 109 |
|
| 96 |
-프론트엔드 테스트: `cd frontend && npm test` |
|
| 97 |
-백엔드 테스트(Testcontainers로 PostgreSQL을 띄우므로 Docker 필요): `mvn test` |
|
| 110 |
+## 환경변수 |
|
| 111 |
+ |
|
| 112 |
+`.env.example`을 복사해 값을 채운다. **실제 값이 든 파일은 커밋하지 않는다.** |
|
| 113 |
+ |
|
| 114 |
+### 필수 — 하나라도 비면 기동하지 않는다 |
|
| 115 |
+ |
|
| 116 |
+| 변수 | 설명 | 예시 | |
|
| 117 |
+| :-- | :-- | :-- | |
|
| 118 |
+| `DB_URL` | PostgreSQL JDBC URL | `jdbc:postgresql://192.168.0.60:5432/itnhub` | |
|
| 119 |
+| `DB_USERNAME` | DB 계정 | `itnhub` | |
|
| 120 |
+| `DB_PASSWORD` | DB 비밀번호 | | |
|
| 121 |
+| `MATTERMOST_URL` | Mattermost 베이스 URL | `https://hub.iten.co.kr` | |
|
| 122 |
+| `MATTERMOST_TOKEN` | **system-admin 권한** Personal Access Token | | |
|
| 123 |
+| `MATTERMOST_TEAM_ID` | 채널을 만들 팀 ID | | |
|
| 124 |
+| `APP_ADMIN_USERNAME` | 앱 로그인 계정 | `admin` | |
|
| 125 |
+| `APP_ADMIN_PASSWORD` | 앱 로그인 비밀번호(충분히 긴 무작위 값) | | |
|
| 126 |
+ |
|
| 127 |
+### 선택 — 기본값 있음 |
|
| 128 |
+ |
|
| 129 |
+| 변수 | 기본값 | 설명 | |
|
| 130 |
+| :-- | :-- | :-- | |
|
| 131 |
+| `MATTERMOST_TEAM_NAME` | `itn-hub` | 채널 URL을 만들 때 쓰는 팀 이름 | |
|
| 132 |
+| `MATTERMOST_DEFAULT_USER_PASSWORD` | `test1234!` | 자동 생성되는 담당자 계정의 초기 비밀번호 | |
|
| 133 |
+ |
|
| 134 |
+> **참고 —** `application.yml`의 `spring.datasource.hikari.schema: itnhub` 는 **지우면 안 된다.** |
|
| 135 |
+> `spring.flyway.schemas`는 Flyway 전용 커넥션에만 적용돼서, 이 설정이 없으면 런타임 커넥션이 |
|
| 136 |
+> `public` 스키마를 보고 `relation "organization" does not exist` 로 죽는다. |
|
| 137 |
+ |
|
| 138 |
+--- |
|
| 139 |
+ |
|
| 140 |
+## 업무 흐름 |
|
| 141 |
+ |
|
| 142 |
+### 진행단계 12단계 |
|
| 143 |
+ |
|
| 144 |
+``` |
|
| 145 |
+ ① 신청 → ② 목록접수 → ③ 예비검토 → ④ 변호사 배당 |
|
| 146 |
+ → ⑤ 법률검토(권리확인) → ⑥ RE:확인 → ⑦ 법률검토(권리확인) 완료 |
|
| 147 |
+ → ⑧ 법률검토(권리처리) → ⑨ RE:처리 → ⑩ 법률검토(권리처리) 완료 |
|
| 148 |
+ → ⑪ 법률검토 최종완료 → ⑫ 보고서 작성 |
|
| 149 |
+``` |
|
| 150 |
+ |
|
| 151 |
+- 채널을 만들면 **①신청이 자동으로 시작**된다. 그 뒤로는 **전부 수동**이다 — 자료를 올리거나 |
|
| 152 |
+ 게시글을 써도 단계가 저절로 넘어가지 않는다(요청자 확정 사항). |
|
| 153 |
+- 단계 변경 이력은 전부 **타임라인 탭**에 남는다. |
|
| 154 |
+ |
|
| 155 |
+### 최초 사용 순서 |
|
| 156 |
+ |
|
| 157 |
+1. PostgreSQL을 준비하고 환경변수를 채운다 → 기동하면 스키마가 만들어진다 |
|
| 158 |
+2. 브라우저로 접속해 관리자 계정으로 로그인 |
|
| 159 |
+3. **담당자관리** 에서 담당자를 등록한다(회원명단 엑셀 일괄 업로드 가능) |
|
| 160 |
+4. **채널관리** 에서 신청목록 시트를 올려 기관 명부를 만들고, 기관마다 담당자 4역할을 배정한다 |
|
| 161 |
+5. **채널 생성** — 채널 2종 + 담당자 계정 + 안내글이 한 번에 준비된다 |
|
| 162 |
+6. **기관관리 › 권리확인/권리처리** 탭에서 조사 엑셀을 올리고 건별로 판정한다 |
|
| 163 |
+7. **사업관리** 에서 연락 이력을 남기고 최종 보고서를 올린다 |
|
| 164 |
+ |
|
| 165 |
+--- |
|
| 166 |
+ |
|
| 167 |
+## 핵심 규칙 |
|
| 168 |
+ |
|
| 169 |
+수정할 때 깨뜨리면 안 되는 약속들이다. |
|
| 170 |
+ |
|
| 171 |
+| 규칙 | 내용 | |
|
| 172 |
+| :-- | :-- | |
|
| 173 |
+| **채널은 항상 2개** | 기관마다 `NNN_기관명 (문정원)` · `NNN_기관명 (법률검토)` 가 쌍으로 만들어진다. 게시글·자료도 늘 양쪽에 함께 반영된다. 한쪽만 처리하는 코드는 버그다. | |
|
| 174 |
+| **재실행 안전** | 채널 생성·시드 업로드·채널 초기화 모두 여러 번 실행해도 안전하다. 이미 처리된 것은 건너뛰고 없는 것만 만든다. 새 로직에서도 이 원칙을 지킨다. | |
|
| 175 |
+| **채널 ⇔ 단계** | 채널이 있으면 진행단계가 반드시 있고, 단계가 없으면 채널도 없다(V11이 이 불변식을 맞춘다). 대시보드 칸반의 **단계 미지정** 컬럼은 **채널 미생성 기관만** 담는다. | |
|
| 176 |
+| **엑셀 재업로드** | 같은 파일을 다시 올려도 **웹에서 고친 값(`web_edited_at`)은 보존**되고 조사원 영역만 덮어쓴다. 병합 기준은 순번이 아니라 **파일의 행 순서**다(원본에 순번 중복이 있다). | |
|
| 177 |
+| **제3자 권리처리** | 권리 일부 보유·권리 미보유는 `권리처리 추진` / `권리처리 추진 미희망` 택일, 초상권 포함은 `개방불가`까지 3택. 추진이면 공공누리 유형이 `보류`로, 미희망이면 기존 유형이 자동 선택되고 비고에 사유가 적힌다. | |
|
| 178 |
+| **작성자 자동 기록** | 업무메모·연락 이력의 작성자는 화면에서 고르지 않는다. 로그인 사용자를 서버가 기록하고, 수정해도 최초 작성자·작성시각은 유지된다. | |
|
| 179 |
+| **연번은 문자열** | 기관 코드는 `연번1_연번2`(`001_00`) 형식이다. 숫자로 바꾸면 앞자리 0이 사라져 매칭이 전부 깨진다. | |
|
| 180 |
+ |
|
| 181 |
+--- |
|
| 182 |
+ |
|
| 183 |
+## 프로젝트 구조 |
|
| 184 |
+ |
|
| 185 |
+``` |
|
| 186 |
+itnhub/ |
|
| 187 |
+├─ src/main/java/kr/itn/itnhub/ |
|
| 188 |
+│ ├─ org/ 기관 명부·배정 ├─ review/ 권리확인 |
|
| 189 |
+│ ├─ contact/ 담당자 ├─ process/ 권리처리 |
|
| 190 |
+│ ├─ provision/ 채널 생성(멱등) ├─ stage/ 진행단계·이력 |
|
| 191 |
+│ ├─ mattermost/ Mattermost API 클라이언트 ├─ timeline/ 타임라인 집계 |
|
| 192 |
+│ ├─ feed/ 채널 게시글·파일 ├─ memo/ 업무메모 |
|
| 193 |
+│ ├─ dashboard/ 대시보드 집계 ├─ project/ 사업관리 |
|
| 194 |
+│ ├─ seed/ 신청목록 시트 시드 └─ system/ 채널 초기화 |
|
| 195 |
+│ └─ config/ 보안·설정 |
|
| 196 |
+│ |
|
| 197 |
+├─ src/main/resources/ |
|
| 198 |
+│ ├─ db/migration/ Flyway V1~V12 |
|
| 199 |
+│ ├─ mapper/ MyBatis XML |
|
| 200 |
+│ └─ application.yml |
|
| 201 |
+│ |
|
| 202 |
+├─ frontend/src/ |
|
| 203 |
+│ ├─ components/ 화면 19개 (Dashboard, OrgOverview, ReviewBoard …) |
|
| 204 |
+│ ├─ help/ 버튼 옆 「?」 도움말 — 본문과 캡처가 여기 한 곳에 있다 |
|
| 205 |
+│ ├─ api/client.ts 모든 서버 호출이 지나는 단일 창구 |
|
| 206 |
+│ └─ stages.ts 12단계 라벨 정본 |
|
| 207 |
+│ |
|
| 208 |
+├─ deploy/ 176 서버 배포 정의 (compose · env 템플릿 · 절차서) |
|
| 209 |
+└─ Dockerfile 프런트까지 함께 빌드하는 멀티스테이지 |
|
| 210 |
+``` |
|
| 211 |
+ |
|
| 212 |
+--- |
|
| 213 |
+ |
|
| 214 |
+## API |
|
| 215 |
+ |
|
| 216 |
+| 영역 | 엔드포인트 | |
|
| 217 |
+| :-- | :-- | |
|
| 218 |
+| 기관 | `GET /api/orgs` · `PUT /api/orgs/{id}/assignments` · `POST /api/orgs/{id}/channels` |
|
|
| 219 |
+| 진행단계 | `PUT /api/orgs/{id}/stage` · `GET /api/orgs/{id}/stage-history` |
|
|
| 220 |
+| 채팅·자료 | `/api/orgs/{id}/posts` `messages` `notice` `files` · `GET /api/files/{fileId}` |
|
|
| 221 |
+| 권리확인 | `/api/orgs/{id}/review` `import` `download` · `PUT …/review/bulk` |
|
|
| 222 |
+| 권리처리 | `/api/orgs/{id}/process` `import` `download` · `PUT …/process/bulk` |
|
|
| 223 |
+| 대시보드 | `GET /api/dashboard` — KPI·칸반·최근 진행 기관을 한 번에 | |
|
| 224 |
+| 사업관리 | `GET /api/projects` · `/api/orgs/{id}/contact-logs` · `/api/orgs/{id}/reports` |
|
|
| 225 |
+| 업무메모 | `GET` `POST` `PUT` `DELETE /api/orgs/{id}/memos` |
|
|
| 226 |
+| 타임라인 | `GET /api/orgs/{id}/timeline` |
|
|
| 227 |
+| 시스템 | `GET /api/system/reset/preview` · `POST /api/system/reset/channels` | |
|
| 228 |
+ |
|
| 229 |
+전 구간 로그인이 필요하고(`/api/auth/login` 제외), 변경 요청은 CSRF 토큰을 함께 보낸다. |
|
| 230 |
+ |
|
| 231 |
+--- |
|
| 232 |
+ |
|
| 233 |
+## 테스트 |
|
| 234 |
+ |
|
| 235 |
+```bash |
|
| 236 |
+mvn test # 백엔드 221건 — Testcontainers로 PostgreSQL을 띄우므로 Docker 필요 |
|
| 237 |
+cd frontend && npm test # 프런트 191건 |
|
| 238 |
+``` |
|
| 239 |
+ |
|
| 240 |
+--- |
|
| 241 |
+ |
|
| 242 |
+## 배포 |
|
| 243 |
+ |
|
| 244 |
+Docker 기준 상세 절차는 **[`deploy/README.md`](deploy/README.md)** 에 있다. |
|
| 245 |
+ |
|
| 246 |
+```bash |
|
| 247 |
+docker build -t itnhub:latest . |
|
| 248 |
+sudo cp deploy/itnhub.env.example /etc/itnhub/itnhub.env # 값 채우기 |
|
| 249 |
+cd /opt/itnhub && sudo docker compose up -d |
|
| 250 |
+``` |
|
| 251 |
+ |
|
| 252 |
+| | | |
|
| 253 |
+| :-- | :-- | |
|
| 254 |
+| 산출물 | **단일 jar** — React가 그 안에 있어 서버에 Node도 웹서버도 필요 없다 | |
|
| 255 |
+| 영속 볼륨 | **불필요** — 업로드 파일은 DB(`org_report`)와 Mattermost에 저장된다 | |
|
| 256 |
+| DB | 컨테이너로 띄우지 않고 기존 PostgreSQL을 그대로 쓴다 | |
|
| 257 |
+| 시간대 | 컨테이너를 `Asia/Seoul`로 고정 — UTC면 도달 일시·D+n이 9시간 어긋난다 | |
|
| 258 |
+| 헬스체크 | `GET /login` 200 (actuator 미포함) | |
|
| 259 |
+ |
|
| 260 |
+> **⚠ 빌드 머신에는 인터넷이 필요하다**(Node·npm·Maven을 내려받는다). 실행 서버는 필요 없다. |
|
| 261 |
+> 사내망이 막혀 있으면 Maven 미러와 `nodeDownloadRoot`를 사내 저장소로 돌려야 한다. |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?