---
template: flow-doc@1
doc_id: 05-content-board
title: site 게시판·교육·알림·검색 절차군
config: ../_meta/template-config.yaml
last_verified: 767d1e44
flows:
  - id: content-board
    actor: 일반회원
    status: active-prod
    status_source: ./00-ia.md#site-board-param
    evidence: [S-route, S-component]
    limitations:
      - 게시판 종류는 경로 파라미터로 갈리며 그 값의 목록은 서버가 준다. 이 문서는 종류별 권한 차이를 판정하지 않았다
      - 작성·수정 화면이 같은 컴포넌트라 두 라우트의 차이가 파라미터 유무뿐이다. 수정 권한의 서버 판정은 이 문서 밖이다
    refs:
      - ./00-ia.md#site-board-param
      - ./00-ia.md#site-board-param-param
      - ./00-ia.md#site-board-param-add
      - ./00-ia.md#site-board-param-edit-param
    anchors:
      - insuniverse-site/front/src/App.tsx:422
      - insuniverse-site/front/src/App.tsx:425
      - insuniverse-site/front/src/pages/board/BoardPage.tsx:1
      - insuniverse-site/front/src/shared/ui/Header.tsx:47
  - id: content-edu
    actor: 일반회원
    status: conditional-enabled
    status_source: ./00-ia.md#site-edu-list
    evidence: [S-route, S-component]
    limitations:
      - 교육 콘텐츠의 제공 범위와 이수 판정은 서버 소유다. 이 문서는 화면 순서만 갖는다
      - 재생 화면의 외부 플레이어 의존은 이 창에서 전수 확인하지 않았다
    refs:
      - ./00-ia.md#site-edu-list
      - ./00-ia.md#site-edu-detail-param
      - ./00-ia.md#site-edu-play-param
    anchors:
      - insuniverse-site/front/src/App.tsx:434
      - insuniverse-site/front/src/App.tsx:436
      - insuniverse-site/front/src/pages/edu/play/EduPlayPage.tsx:1
      - insuniverse-site/front/src/features/mypage/ui/MyEduCourseListSection.tsx:159
  - id: content-alarm
    actor: 일반회원
    status: conditional-unknown
    status_source: ../06-vendors/04-messaging.md#messaging:fcm:credentials
    unknown_reason: 알림이 단말까지 도달하는 경로가 푸시 공급자 자격에 달려 있고 그 자격의 활성 조건이 배포 환경 게이트에 있어 이 저장소에서 판정할 수 없다. site 코드가 갖는 것은 도착한 알림을 어디로 보내는가뿐이다
    evidence: [S-route, S-component]
    limitations:
      - 알림 종류에 따른 이동 대상 분기는 문자열 비교다. 서버가 보내는 종류 값의 전수는 이 창에서 확인하지 않았다
      - 외부 주소를 여는 갈래는 앱과 웹이 서로 다른 수단을 쓴다. 두 수단의 성공 여부를 site 가 확인하지 않는다
    refs:
      - ./00-ia.md#site-alarm-detail-param
      - ../06-vendors/04-messaging.md#messaging:fcm:credentials
    anchors:
      - insuniverse-site/front/src/App.tsx:365
      - insuniverse-site/front/src/features/alarm/ui/Alarm.tsx:264
      - insuniverse-site/front/src/features/alarm/ui/Alarm.tsx:270
      - insuniverse-site/front/src/pages/alarm/AlarmDetailPage.tsx:1
  - id: content-search
    actor: 일반회원
    status: active-prod
    status_source: ./00-ia.md#site-search
    evidence: [S-route, S-component]
    limitations:
      - 검색 결과의 범위와 정렬은 서버 소유다. 이 문서는 질의를 넣고 결과 화면으로 가는 순서만 쓴다
      - 약관·개인정보 화면은 세션 없이도 열린다. 그 두 화면의 내용 갱신 절차는 이 문서 밖이다
    refs:
      - ./00-ia.md#site-search
      - ./00-ia.md#site-criteria
      - ./00-ia.md#site-terms
      - ./00-ia.md#site-privacy
    anchors:
      - insuniverse-site/front/src/App.tsx:389
      - insuniverse-site/front/src/App.tsx:420
      - insuniverse-site/front/src/App.tsx:263
      - insuniverse-site/front/src/features/searchBox/hooks/useSearchBox.ts:78
---

# site 게시판·교육·알림·검색 절차군

이 문서는 **읽고 쓰고 찾고 알림을 받는** 절차군을 담는다. 화면 구조의 정본은 [화면 인벤토리](./00-ia.md)이고, 권한 규칙의 정본은 [총론](../02-access/02-authz-roles.md)이다. 여기서는 순서만 쓴다.

네 흐름이 서로 다른 것을 보여준다. `content-board` 는 종류로 갈리는 게시판 축, `content-edu` 는 구독 게이트 아래 등록되는 교육 축, `content-alarm` 은 밖에서 들어온 알림이 어느 화면으로 떨어지는가, `content-search` 는 검색과 세션 없이도 열리는 정적 문서 화면들이다.

**교육 세 화면은 구독 게이트 아래 등록된다.** 분석 화면과 같은 조건 블록이며, 구독 판정이 거짓인 계정에는 라우트 자체가 등록되지 않는다. 그래서 `content-edu` 의 status 가 `conditional-enabled` 다.

**약관과 개인정보 화면은 세션 없이 열린다.** 라우트가 세션 가드 밖의 기본 레이아웃 아래 있고, 그래서 `content-search` 는 로그인 여부가 갈리는 유일한 흐름이다.

## 흐름 목록

| flow id | 목적 | actor | status |
|---|---|---|---|
| content-board | 게시판을 읽고 글을 쓰거나 고친다 | 일반회원 | active-prod |
| content-edu | 교육 목록에서 콘텐츠를 골라 재생한다 | 일반회원 | conditional-enabled |
| content-alarm | 받은 알림을 눌러 해당 화면으로 간다 | 일반회원 | conditional-unknown |
| content-search | 검색하고 기준·약관 문서를 연다 | 일반회원 | active-prod |

## 흐름

### content-board

**전제**

- 로그인 세션이 있다
- 열려는 게시판의 종류 값이 경로에 실린다

**절차**

1. 회원이 헤더나 링크로 `site-board-param` 을 연다. 종류 값은 질의 문자열로도 함께 온다 (`Header.tsx:47`).
2. 글을 고르면 `site-board-param-param` 이 상세를 연다.
3. 새 글은 `site-board-param-add` 에서 쓴다.
4. 자기 글을 고치려면 `site-board-param-edit-param` 으로 간다. 3·4단계는 같은 컴포넌트가 맡고 파라미터 유무로 갈린다.

**상품 화면의 문의 진입점이 이 흐름으로 들어온다.** 상품 목록에서 문의를 누르면 문의 게시판의 작성 화면으로 곧장 보낸다 (`ProductsPage.tsx:14`).

**권한**

| 층 | 차단성 | 이 흐름에서의 강제 지점 | 실패 시 |
|---|---|---|---|
| 인증 | 차단 | 라우트 트리의 세션 가드 (`useAuthGuard.tsx:52`) | 로그인 화면으로 이동 |
| 계정 종류 | 차단 | 해당 없음 — site 라우트에 역할 메타데이터가 없다. 종류별 쓰기 권한의 판정은 서버 API 층이며 정본은 [역할 총론](../02-access/02-authz-roles.md)이다 | 해당 없음 |
| 쓰기 스코프 | 차단 | 해당 없음 — 조직관리자 읽기전용 가드는 admin 콘솔 요청에만 발화한다 | 해당 없음 |
| 기업 노출 등급 | 차단 | 해당 없음 — admin 콘솔 축이다 | 해당 없음 |
| 메뉴 노출 | 비차단 | 게시판은 헤더 항목으로 열린다 | URL 을 직접 치면 인증 층만 통과하면 열린다 |

**실패·이탈**

| 지점 | 조건 | 결과 |
|---|---|---|
| 1단계 진입 | 종류 값이 목록에 없다 | 막다름. 빈 목록을 보여준다 |
| 2단계 이동 | 글이 없거나 지워졌다 | HTTP 404. 목록 화면으로 되돌린다 |
| 3단계 저장 | 필수 입력이 비어 있다 | 계속 같은 화면에서 안내한다 |
| 4단계 저장 | 서버가 쓰기 권한을 거부한다 | HTTP 403. 목록 화면에 머문다 |

### content-edu

**전제**

- 로그인 세션이 있고 구독 판정이 참이다. 거짓이면 교육 라우트가 등록되지 않는다

**절차**

1. 회원이 `site-edu-list` 에서 교육 목록을 연다. 마이페이지의 교육 카드에서도 이 목록으로 온다 (`MyEduCourseListSection.tsx:159`).
2. 항목을 고르면 `site-edu-detail-param` 이 상세를 연다.
3. 재생을 누르면 `site-edu-play-param` 이 콘텐츠를 재생한다.

**권한**

| 층 | 차단성 | 이 흐름에서의 강제 지점 | 실패 시 |
|---|---|---|---|
| 인증 | 차단 | 라우트 트리의 세션 가드 (`useAuthGuard.tsx:52`) | 로그인 화면으로 이동 |
| 계정 종류 | 차단 | 해당 없음 — 교육 라우트에 역할 메타데이터가 없다 | 해당 없음 |
| 쓰기 스코프 | 차단 | 해당 없음 — 이 흐름은 읽기뿐이다 | 해당 없음 |
| 기업 노출 등급 | 차단 | 해당 없음 — admin 콘솔 축이다 | 해당 없음 |
| 메뉴 노출 | 비차단 | 구독 판정이 거짓이면 라우트가 아예 등록되지 않는다. 메뉴에서 감추는 것보다 강하다 | 등록되지 않은 경로라 진입 자체가 성립하지 않는다 |

**실패·이탈**

| 지점 | 조건 | 결과 |
|---|---|---|
| 1단계 진입 | 구독 판정이 거짓이다 | 계속 구독 안내 팝업으로 갈린다. 갈림은 분석 절차군의 이탈 표와 같다 |
| 2단계 이동 | 항목이 없다 | HTTP 404. 목록으로 되돌린다 |
| 3단계 재생 | 재생 수단이 응답하지 않는다 | 막다름. 이 경우의 안내는 이 창에서 관측되지 않았다 |

### content-alarm

**전제**

- 로그인 세션이 있다
- 알림 목록에 항목이 도착해 있다. 도착 자체는 푸시 공급자 소관이다

**절차**

1. 회원이 헤더의 알림에서 항목을 고른다.
2. 항목에 외부 주소가 실려 있으면 앱은 브리지로 외부 브라우저를 열고, 웹은 새 창으로 연다 (`Alarm.tsx:264`).
3. 외부 주소가 없으면 알림 종류로 갈린다 — 결제·분석·팩스는 각각 대응 목록 화면으로 보낸다 (`Alarm.tsx:270`).
4. 종류가 셋 중 어느 것도 아니면 `site-alarm-detail-param` 이 상세를 연다.

**어느 갈래에도 걸리지 않는 항목이 있다.** 외부 주소도 없고 종류도 셋이 아니며 상세 식별자도 없으면 아무 데도 가지 않고 경고만 남긴다. 그 상태의 사용자 안내는 이 창에서 관측되지 않았다.

**권한**

| 층 | 차단성 | 이 흐름에서의 강제 지점 | 실패 시 |
|---|---|---|---|
| 인증 | 차단 | 라우트 트리의 세션 가드 (`useAuthGuard.tsx:52`) | 로그인 화면으로 이동 |
| 계정 종류 | 차단 | 해당 없음 — 알림 상세에 역할 메타데이터가 없다 | 해당 없음 |
| 쓰기 스코프 | 차단 | 해당 없음 — 이 흐름은 읽기뿐이다 | 해당 없음 |
| 기업 노출 등급 | 차단 | 해당 없음 — admin 콘솔 축이다 | 해당 없음 |
| 메뉴 노출 | 비차단 | 알림은 헤더에서 열린다. 사이드바 축과 무관하다 | 해당 없음 |

**실패·이탈**

| 지점 | 조건 | 결과 |
|---|---|---|
| 2단계 열기 | 앱인데 브리지가 응답하지 않는다 | fail-open 호출만 하고 화면은 그대로 둔다. 열렸는지 site 가 확인하지 않는다 |
| 2단계 열기 | 웹인데 새 창이 차단됐다 | 막다름. 이 경우의 안내는 이 창에서 관측되지 않았다 |
| 3단계 이동 | 종류가 결제·분석·팩스 중 하나다 | 계속 대응하는 목록 화면으로 보낸다 |
| 4단계 이동 | 상세 식별자도 없다 | 막다름. 아무 데도 가지 않고 경고만 남긴다 |

### content-search

**전제**

- 검색은 로그인 세션을 요구한다
- 약관과 개인정보 화면은 세션 없이도 열린다

**절차**

1. 회원이 검색 입력에 질의를 넣고 확정하면 `site-search` 로 이동한다 (`useSearchBox.ts:78`).
2. 결과 화면이 질의를 질의 문자열로 받아 목록을 그린다.
3. 판단 기준 문서는 `site-criteria` 가 연다.
4. 약관은 `site-terms`, 개인정보 처리방침은 `site-privacy` 가 연다. 두 화면은 세션 가드 밖의 기본 레이아웃 아래 있다.

**권한**

| 층 | 차단성 | 이 흐름에서의 강제 지점 | 실패 시 |
|---|---|---|---|
| 인증 | 차단 | 1~3단계에만 걸린다. 4단계 두 화면은 세션 가드 밖 경로다 | 1~3단계는 로그인 화면으로 이동 |
| 계정 종류 | 차단 | 해당 없음 — 이 화면들에 역할 메타데이터가 없다 | 해당 없음 |
| 쓰기 스코프 | 차단 | 해당 없음 — 이 흐름은 읽기뿐이다 | 해당 없음 |
| 기업 노출 등급 | 차단 | 해당 없음 — admin 콘솔 축이다 | 해당 없음 |
| 메뉴 노출 | 비차단 | 검색은 헤더 입력에서, 기준 문서는 사이드바에서 열린다 | URL 을 직접 치면 인증 층만 통과하면 열린다 |

**실패·이탈**

| 지점 | 조건 | 결과 |
|---|---|---|
| 1단계 확정 | 질의가 비어 있다 | 계속 이동하지 않는다 |
| 2단계 조회 | 결과가 없다 | 계속 빈 결과를 보여준다 |
| 4단계 진입 | 세션이 없다 | 계속 세션 없이 그대로 연다 |
| 1~3단계 진입 | 세션이 없다 | ./00-ia.md#site-auth-login 으로 보낸다 |

## 플랫폼 차이 (웹 / 웹뷰)

`content-alarm` 2단계만 갈린다. 외부 주소를 열 때 앱 웹뷰는 브리지로 외부 브라우저를 띄우고 웹은 새 창을 연다 (`Alarm.tsx:264`). 브리지 존재 판정 규약은 [계정 절차군](./04-mypage-account.md)에 있다.

게시판 상세의 첨부 저장은 [진료·손해 분석 절차군](./01-analysis-flow.md)의 PDF 저장과 같은 갈림을 탄다.

## 연혁

| 릴리스 | 날짜 | SHA | 변경 요약 |
|---|---|---|---|
| — | 2026-08-27 | 767d1e44 | 최초 저작. 동결 HEAD 의 라우트 트리와 게시판·교육·알림·검색 화면 정독에서 네 흐름을 유도했다 |
