# ITN-HUB 47개 신유형 사업 신청기관의 명부·담당자 정보를 관리하고, 기관별 Mattermost 채널(문정원/법률검토) 생성을 자동화하는 웹 애플리케이션이다. 기존 Excel VBA 매크로(`M06_Mattermost_기관목록`, `M07_Mattermost_채널일괄생성`) 워크플로를 웹으로 옮긴 후속 단계로, 신청목록 시트 업로드로 기관 정보를 시드하고, 부서/담당자 정보를 입력한 뒤, 기관당 Mattermost 비공개 채널 2개 (`문정원`, `법률검토`)를 생성·복구한다. ## ⚠️ 실행 전 반드시 읽을 것 - **이 애플리케이션은 실제 운영 Mattermost 서버(`https://hub.iten.co.kr`)에 실제 채널을 생성한다.** 테스트 목적으로 함부로 실행하면 운영 팀에 실제 채널이 생긴다. - Mattermost `MATTERMOST_TOKEN`(Personal Access Token)은 **시스템 관리자(system-admin) 권한**을 가진 계정의 토큰이어야 한다. 비공개(private) 채널을 팀 전체 범위에서 조회(레거시 채널 복구용 표시명 검색, `GET /api/v4/teams/{teamId}/channels`)하려면 이 권한이 필요하다. 일반 권한 토큰을 쓰면 레거시 채널을 못 찾아 매번 중복 채널이 생성될 수 있다. - **최초 사용 전에는 실제 신청기관이 아니라 테스트용 기관(예: 연번 `999`, 임시 기관명)으로 먼저 스모크 테스트를 해볼 것을 권장한다.** 시드 업로드 → 담당자 입력 → 채널 생성까지 한 번 돌려보고, Mattermost 서버에서 실제로 의도한 이름의 비공개 채널 2개가 만들어지는지 확인한 뒤 실제 기관 데이터를 올린다. ## 환경변수 `.env.example`을 참고해 실제 값을 채운 `.env`(또는 배포 환경의 환경변수)를 준비한다. **`.env`나 실제 값이 든 파일은 절대 커밋하지 않는다.** | 변수 | 설명 | 예시 값 | |---|---|---| | `DB_URL` | PostgreSQL 16 JDBC URL | `jdbc:postgresql://localhost:5432/itnhub` | | `DB_USERNAME` | DB 접속 계정 | `itnhub_app` | | `DB_PASSWORD` | DB 접속 비밀번호 | `changeme-please` | | `MATTERMOST_URL` | Mattermost 서버 베이스 URL | `https://hub.iten.co.kr` | | `MATTERMOST_TOKEN` | system-admin 권한 Personal Access Token | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | | `MATTERMOST_TEAM_ID` | 채널을 생성할 Mattermost 팀 ID | `abcdefghijklmnopqrstuvwxyz` | | `APP_ADMIN_USERNAME` | 앱 로그인 관리자 계정 | `admin` | | `APP_ADMIN_PASSWORD` | 앱 로그인 관리자 비밀번호(충분히 긴 무작위 문자열 권장) | `use-a-long-random-value` | 이 8개는 전부 `${...}` 플레이스홀더로 `application.yml`에 선언되어 있어 값이 없으면 애플리케이션이 기동하지 않는다. ### 왜 `spring.datasource.hikari.schema: itnhub`가 있는가 `application.yml`의 `spring.datasource.hikari.schema: itnhub` 설정은 지우면 안 된다. `spring.flyway.schemas`는 Flyway 전용 커넥션에만 적용되는 설정이라, 애플리케이션이 실제 쿼리를 실행하는 HikariCP 커넥션 풀은 이 설정이 없으면 기본 `search_path`(보통 `public`)를 써서 `relation "organization" does not exist` 오류가 난다. Flyway가 만드는 스키마와 런타임 커넥션이 바라보는 스키마를 반드시 일치시켜야 한다. ## 빌드 ```bash mvn -DskipTests package ``` `pom.xml`의 `frontend-maven-plugin`이 `mvn package` 과정에서 `frontend/`의 React 앱을 함께 빌드해 `src/main/resources/static/`에 넣고, 그 결과를 Spring Boot의 단일 jar에 패키징한다. 별도로 프론트엔드를 먼저 빌드할 필요는 없다. ## 실행 ```bash export DB_URL=jdbc:postgresql://localhost:5432/itnhub export DB_USERNAME=itnhub_app export DB_PASSWORD=... export MATTERMOST_URL=https://hub.iten.co.kr export MATTERMOST_TOKEN=... export MATTERMOST_TEAM_ID=... export APP_ADMIN_USERNAME=admin export APP_ADMIN_PASSWORD=... java -jar target/itnhub-0.1.0.jar ``` ## 최초 사용 순서 1. PostgreSQL 16 인스턴스를 준비하고 위 환경변수로 접속 정보를 지정한다. 기동 시 Flyway가 `itnhub` 스키마와 테이블을 자동으로 만든다(수동 DDL 불필요). 2. 브라우저로 접속해 `APP_ADMIN_USERNAME` / `APP_ADMIN_PASSWORD`로 로그인한다. 3. 좌측 하단 "신청목록 시트 올리기"로 기관 신청목록 엑셀(`.xlsx`/`.xlsm`)을 업로드해 기관 명부를 시드한다. 4. 기관을 선택해 부서명/담당자명/연락처/이메일(직급/직함은 선택)을 입력하고 저장한다. 5. "채널 생성"을 눌러 Mattermost에 문정원/법률검토 채널 2개를 생성한다. 이미 생성된 채널은 재실행해도 다시 만들지 않는다(idempotent) - 실패한 채널만 다시 시도된다. ## 개발 워크플로 ```bash cd frontend npm install npm run dev ``` Vite 개발 서버가 `/api` 요청을 `:8080`(백엔드)으로 프록시한다. 백엔드는 별도로 `mvn spring-boot:run` 등으로 띄워둔 상태에서 프론트엔드만 `npm run dev`로 반복 개발하면 된다. 프론트엔드 테스트: `cd frontend && npm test` 백엔드 테스트(Testcontainers로 PostgreSQL을 띄우므로 Docker 필요): `mvn test`