HBGA230_공지
(Hereby) 총무 > 공지
| 앱 | 총무 (HBGA) |
| 대상 사용자 | 조건1 [GA_ADMIN] / 조건2 [SUPER_ADMIN] |
| 프로토타입 | TBU |
| 관련 정책 | [[POL_공지 게시]] (token TBU) |
| Status | review |
| Owner | 카나 (PM) |
개요
- 총무 공지 발행/확인 화면. 이 화면은 Admin 공지([[HBAD280_공지]])의 임베드로, 컬럼·작성 폼·확인 내역은 HBAD280과 동일하다.
- 카테고리 필터(6종) + 상태 필터(4종) + "공지 작성" 버튼(2026-08-18 정정: "+" 접두 없음) + 8컬럼 그리드로 구성(2026-10-21 「작성자」 컬럼 추가 실측, #1263).
- 게시/만료 공지는 "확인 내역"(notice_acknowledgments)으로 대상자별 확인 현황을 연다. Employee App의 "확인했어요" 읽음 처리와 cross-app 연동(검증됨).
- 게시 공지는 HBEA300_메신저를 통해 직원에게 수신된다(연계 후보).
- row action = 미게시: "수정"/"삭제", 게시 중·만료: "보기"/"확인 내역".
문서 히스토리
| 날짜 | 작성자 | 팀 | 변경 내용 |
|---|---|---|---|
| 2026-07-06 | 카나 | PM | 최초 작성 |
| 2026-07-10 | 카나 | PM | 라이브 기능 검토 반영 |
| 2026-07-13 | 카나 | PM | 버튼 행동 명세 보강 |
| 2026-07-21 | 카나 | PM | GC700 깊이 재작성 + 확정 스타일 |
| 2026-07-21 | 카나 | PM | TC 크로스체크 확정분 반영 (🟡) |
| 2026-07-29 | 카나 | PM | 코드 변경 반영(b61038f) |
| 2026-08-18 | 카나 | 라이브 재검증 정정 | 공지 작성 버튼 라벨 = "공지 작성"("+" 접두 없음) 라이브 확인. 카테고리6·상태4·컬럼7·무기한 표기 일치 |
| 2026-09-10 | 카나 | PM | 정보 게시글(확인 불필요)·관리자 대리 확인·확인 인원 override 반영(#638, ed374cb/0466d8d, CS-LOC-260909-0008/0009) |
| 2026-10-01 | 카나 | PM | 공지 작성·미게시 행 수정/삭제 버튼 총무 쓰기 권한자만 노출(8593f083, #921) — 커밋 근거, 라이브 실사 이월(TBU) |
| 2026-10-21 | 카나 | PM | (10/20 머지분, #1263 155ef3a) 공지 작성자 표시 — 목록에 「작성자」 컬럼 추가(7→8컬럼), 상세 보기에 작성자 줄 추가. 서버는 createdById만 저장, 조회 3종(관리 목록·단건·직원용 게시 목록)이 직원 이름을 붙임(퇴직자 포함, 조직 밖은 비움). 수정 이력의 수정자 이름도 동일 도우미. 10/21 라이브 실측: 목록 「작성자」 컬럼(예 "이용구") + 상세 모달 "작성자 이용구 게시일 2026.10.10. 만료일 무기한 게시 팀 전체 게시" 원문 확인. 직원 앱 메신저 공지 쪽 표시는 components 경유(간접) — HBEA300 쪽 실사 보류 |
| 2026-10-10 | 카나 | PM | (10/9 머지분) PR #1126(MED-974) 반영: 게시 중·만료 공지 수정 허용 — 「공지 수정」 모달(ㄴ45)·「직원에게 다시 확인받기」(확인 회차 +1)·「수정됨」 표시·수정 이력(ㄴ46) 신설, ㄴ42·ㄴ43 관리 액션에 "수정" 추가 — 모달·버튼 라이브 실증 완료, 수정 후 배지·이력 UI는 TBU |
| 2026-10-22 | 카나 | PM | (10/21 머지분, PR #1257 126a5b6) 작성 폼 재편 + 확인 내역 비교형 라이브 실측 — 폼 섹션화(내용/분류/게시 종류/게시 설정), 「게시 종류」 라디오화(공지 vs 정보 게시글, 도움말 원문 채록), 「확인 인원 직접 입력 (선택)」 라벨·도움말 교체, 「저장하면 바로 게시」 토글 원문, 확인 내역 = 확인/미확인 비교형(「확인 인원 n / 대상 N명」·팀 필터·확인한 직원 표(확인 시각·「관리자 처리」)·미확인 직원 표(「선택 직원 확인 처리」)) — 30·ㄴ36·ㄴ37·ㄴ44 갱신. 스샷 live-1022-ga-notice-confirm-compare.png |
Data I/O
Server → Client
| 변수 | 엔티티.컬럼 | 값 없을 때 | 비고 |
|---|---|---|---|
| $ | general_affairs_notices[] (title/category/priority/isPublished/publishedAt/expiresAt + createdByName) | empty | 8컬럼 목록 소스 — createdByName은 조회 시 직원 이름 join(#1263), 조직 밖 작성자는 빈 값 |
| $ | notice_acknowledgments[] | empty | 대상자별 확인 내역. 조회 = generalAffairs.notice.getAcknowledgedEmployees(noticeId) (TC 확정: 05:5.2 / 06:6.8) |
Client → Server
| 액션 | 전달 값 | tRPC procedure | 권한 토큰 |
|---|---|---|---|
| 공지 작성 | title, content, category, priority, expiresAt, isPublished | generalAffairs.notice.create() | GA_ADMIN |
| 공지 수정 | noticeId + 폼 값 | generalAffairs.notice.update() | GA_ADMIN |
| 공지 삭제 | noticeId | generalAffairs.notice.delete() | GA_ADMIN |
| 공지 게시 | id | generalAffairs.notice.publish(id) (TC 확정: 05:5.2 / 06:6.8) | GA_ADMIN |
| 공지 확인 처리 | noticeId | generalAffairs.notice.acknowledge(noticeId) (TC 확정: 05:5.2) | 직원(self, cross-app) |
| 관리자 대리 확인 | noticeId + employeeId | acknowledgeOnBehalf (processedById=관리자, 코드 반영: 0466d8d) | GA_ADMIN |
| 미읽음 수 | - | generalAffairs.notice.unreadCount() (TC 확정: 05:5.2) | 직원(self) |
| 게시 목록 | - | generalAffairs.notice.listPublished() (TC 확정: 05:5.2) | 직원/GA_ADMIN |
| 확인 내역 조회 | noticeId | generalAffairs.notice.getAcknowledgedEmployees(noticeId) (TC 확정: 05:5.2 / 06:6.8) — read-only. 이전 추정 noticeAcknowledgement.list 는 실재하지 않음(정정) | GA_ADMIN, read-only |
게시 mutation은 사람이 실행한다. procedure는 TC 크로스체크로 확정됨(추정 제거). token 내부 key 미확정 (OQ).
권한 경계 (TC 확정: 06:6.8): 일반 [EMPLOYEE]가 generalAffairs.notice.create 호출 시 throw(거부)된다. 공지 생성/수정/삭제/게시는 GA_ADMIN 전용.
외부 통합 (cross-app)
| 외부 시스템 | 데이터 | 방향 | 비고 |
|---|---|---|---|
| Employee App (HBEA300_메신저) | 게시 공지 수신 / "확인했어요" 읽음 | 양방향 | 확인 읽음 cross-app 검증됨 |
| Admin 공지 (HBAD280) | 컬럼·폼·확인 내역 정의 | 임베드 원본 | 동일 컴포넌트 |
화면 플로우
공지 사양표
| 번호 | 항목/기능명 | 타입 | 사양 및 기능 설명 | 연관/영향 범위 | 비고 |
|---|---|---|---|---|---|
| 00 | 노출 조건 | - | • "공지" 메뉴 클릭 시 /general-affairs/notices 진입 | HBGA100_Shell·사이드바 | |
| 01 | 초기 상태 | - | • 필터 "전체" 기준으로 8컬럼 공지 목록 노출 (census 총 8건) | general_affairs_notices | 작성자 컬럼 포함(#1263) |
| 10 | 카테고리 필터 | Dropdown | • 카테고리 기준으로 목록을 거르는 필터 • 선택 시: 해당 카테고리 행만 표시 ("전체" / "교육마감" / "시설" / "안전" / "정책" / "일반") | general_affairs_notices.category | 6종 |
| 20 | 상태 필터 | Dropdown | • 게시 상태 기준으로 목록을 거르는 필터 • 선택 시: 해당 상태 행만 표시 ("전체" / "미게시" / "게시 중" / "만료") | isPublished + expiresAt 파생 | 4종 |
| 30 | 공지 작성 | Button | • 새 공지 작성 폼을 여는 버튼 (HBAD280과 동일 폼) • 클릭 시: 작성 폼 오픈 • (10/21 재편, #1257 126a5b6 — 10/22 실측) 폼이 섹션 묶음으로 재편: 「내용」(제목* · 내용*) / 「분류」(카테고리: 교육마감·시설·안전·정책·일반 + 우선순위: 참고·일반·중요·긴급) / 「게시 종류」(ㄴ36 라디오) / 「확인 인원 직접 입력 (선택)」(ㄴ37) / 「게시 설정」(게시 팀 다중 선택 "선택하지 않으면 전체 직원에게 게시돼요." · 만료일시*·무기한 · 「저장하면 바로 게시」 토글 — 도움말 원문 "끄면 게시하지 않고 저장해요. 목록에서 「수정」으로 열어 나중에 게시할 수 있어요.") - STEP1 필수값(제목/내용/만료일시) 입력 - STEP2 저장: 바로 게시 ON이면 게시 중, OFF면 미게시로 저장 | notice create · mutation | 사람 게시 총무 쓰기 권한( generalAffairs:create/update/manage 중 하나) 보유 시에만 노출(#921) · 폼 재편(#1257) 10/22 실측(열람 후 취소) |
| ㄴ36 | 게시 종류 (공지/정보 게시글) | Radio | • 작성 폼 「게시 종류」 — (10/21 재편, #1257 — 10/22 실측) 라디오 2종 + 도움말 원문: - 「공지」: "직원이 읽고 「확인했어요」를 눌러야 해요. 누가 확인했는지 볼 수 있어요." - 「정보 게시글」: "확인 없이 읽기만 해요. 미확인 알림에서 빠져요." (requiresAcknowledgment=false) - CASE01 [정보 게시글]: 직원 메신저에서 「확인했어요」 버튼·미확인 배지에서 제외, 서버 unreadCount 집계에서도 제외 · 목록 확인 컬럼 = 「확인 불필요」(10/22 실측) | general_affairs_notices.requiresAcknowledgment · [[HBEA300_메신저]] unreadCount | 신설 (#638) · 라디오화+도움말 원문(#1257) 10/22 실측 |
| ㄴ37 | 확인 인원 직접 입력 | Input | • 작성 폼·확인 내역(게시 후)에서 실제 확인 인원과 별개인 표시값을 지정(acknowledgedCountOverride) • (10/21, #1257 — 10/22 실측) 라벨 「확인 인원 직접 입력 (선택)」 + 도움말 원문 "종이 등 다른 방법으로 확인받은 인원을 포함할 때 써요. 확인 내역에 실제 확인 인원도 함께 보여요." — 확인 내역 쪽에도 같은 입력+「저장」(도움말 "…실제 확인 인원은 위에 함께 보여요.") | general_affairs_notices.acknowledgedCountOverride | 신설 (0466d8d, #638) · 라벨·도움말 원문(#1257) 10/22 실측 |
| ㄴ35 | 무기한 체크박스 | Checkbox | • "만료일시" 라벨 우측 "무기한" 체크박스 — 체크 시 만료일 필수(*) 해제, 만료 date/time picker 숨김, 안내문 "만료일 없이 무기한으로 게시돼요." 표시, expiresAt=null 저장(만료 없이 게시) - CASE01 [체크]: 만료일 없어도 저장 가능(제목·내용만 필수) - CASE02 [미체크]: 만료일시 필수 유지 | notice create/update · expiresAt(nullable) · noticeForm.indefinite | 신설 (코드 반영: b61038f) |
| 40 | 공지 목록 | Table | • 공지를 8컬럼으로 나열하는 그리드 ("제목 / 카테고리 / 우선순위 / 게시 / 작성자 / 게시일 / 만료일 / 관리") • 행 상태별 관리 액션이 41~43로 분기 • 만료일 없음(무기한) 행은 만료일 컬럼에 "무기한" 표시 - 「작성자」 = createdByName(퇴직자 포함, 조직 밖 작성자는 빈칸) — 2026-10-21 라이브 실측(예 "이용구"/"안세희") | general_affairs_notices | 무기한 표시 (코드 반영: b61038f) · 작성자 컬럼 신설 (#1263, 실측) |
| ㄴ41 | 미게시 row | ListItem | • 아직 게시되지 않은 공지 행. 예: "test / 일반 / 보통 / 미게시 / — / 2026.07.03." • "수정" 클릭 시: 공지 수정 폼(기존 값 채움) 오픈 • "삭제" 클릭 시: 컨펌 "공지를 삭제할까요?" → 실행 | notice update / delete | 관리 액션 "수정 | 삭제" #921: 미게시 행 "수정"/"삭제"는 쓰기 권한자만 |
| ㄴ42 | 게시 중 row | ListItem | • 현재 게시 중인 공지 행. 예: "전체 공지 / 일반 / 보통 / 게시 중 / 2026.06.30. / 2026.07.03." • "보기" 클릭 시: 공지 상세 보기 오픈 • (10/9 머지, #1126, MED-974) "수정" 클릭 시: 「공지 수정」 모달(ㄴ45) 오픈 — 종전엔 게시된 공지 수정 불가(화면·서버 모두 차단) • "확인 내역" 클릭 시: 44 확인 내역 오픈 • 상세 보기 만료일도 만료일 없을 시 "무기한" 표시 | notice_acknowledgments · notice update | 관리 액션 "보기 | 수정 | 확인 내역"(라이브 실증 2026-10-10) · 무기한 표시 (코드 반영: b61038f) |
| ㄴ43 | 만료 row | ListItem | • 만료된 공지 행. 예: "전사 ESG를 위한 안내 사항 / 정책 / 보통 / 만료 / 2026.04.10. / 2026.04.09." • "보기" 클릭 시: 공지 상세 보기 오픈 • (10/9 머지, #1126) "수정" 클릭 시: 「공지 수정」 모달(ㄴ45) 오픈 — 만료 공지도 수정 가능(만료일 실수 복구 용도) • "확인 내역" 클릭 시: 44 확인 내역 오픈 | notice_acknowledgments | 만료일 < 게시일 validation gap · 관리 액션 "보기 | 수정 | 확인 내역"(라이브 실증 2026-10-10) |
| ㄴ45 | 공지 수정 모달 (게시 중·만료) | Modal | • (10/9 머지, #1126, MED-974) 제목 「공지 수정」 + 부제 "게시 중인(또는 만료된) 공지를 수정해요. 직원 화면에 「수정됨」이 표시되고, 수정 전 내용은 「보기」의 수정 이력에 남아요." (라이브 원문) • 폼 = 작성 폼과 동일 구성(제목*/내용*/카테고리/우선순위/정보 게시글 체크/확인 인원 표시값/만료일시·무기한/게시 팀/첨부파일) + 하단 토글 1종: - 「직원에게 다시 확인받기」 — "내용이 크게 바뀌었을 때 켜요. 모든 직원이 「확인 전」으로 돌아가고 다시 알림이 가요. 지금까지의 확인 기록은 이력에 남아요." (라이브 원문) • 저장 시: 직원 열람 화면에 「수정됨」 표시 + 수정 전 내용이 수정 이력에 적재. 「다시 확인받기」 켜면 확인 회차(acknowledgmentRound) +1 — 이전 회차 확인 기록은 이력 보존, 「확인함」 판정은 현재 회차 행만 | general_affairs_notices.acknowledgmentRound · notice_acknowledgments.round · 마이그레이션 1965 | 신설 (#1126) · 모달 라이브 실증 2026-10-10 · 수정 후 「수정됨」 배지·이력 UI는 TBU(실사는 저장 금지 수칙상 미실행) |
| ㄴ46 | 보기 — 수정 이력 | Section | • (10/9 머지, #1126) 수정된 공지의 「보기」 상세에 수정 이력(수정 전 내용·수정자·시각) 표시. 미수정 공지에는 섹션 미노출(라이브 확인) | notice revision history | 신설 (#1126) · 커밋 근거 — 이력 UI 원문 TBU |
| ㄴ44 | 확인 내역 (비교형) | Button/Modal | • 대상자별 확인자/확인시각을 조회하는 뷰(generalAffairs.notice.getAcknowledgedEmployees(noticeId)). Employee App "확인했어요"(.acknowledge(noticeId)) 읽음 처리와 연동• (10/21 재편, #1257 126a5b6 — 10/22 실측) 클릭 시 「확인 내역」 모달 — 확인/미확인 비교형: - 요약 「확인 인원 {n} / 대상 {N}명」 + 팀 필터(전체 팀/부서·팀 목록) - 「확인 인원 직접 입력」 + 「저장」(ㄴ37) - 「확인한 직원 {n}명」 표(사번/직원/팀/확인 시각 — 대리 확인 행은 시각 뒤 「관리자 처리」 라벨, 10/22 실측) - 「미확인 직원 {m}명」 표(체크박스/사번/직원/팀) + 「선택 직원 확인 처리」 버튼(acknowledgeOnBehalf, processedById 기록) - 정보 게시글 행은 목록 확인 컬럼 「확인 불필요」로 이 모달 대상 아님 | notice_acknowledgments / HBEA300_메신저 | cross-app 확인 검증됨 (TC 확정: 05:5.2 / 06:6.8) · 대리 확인·override(#638) · 비교형 레이아웃(#1257) 10/22 실측(스샷 live-1022-ga-notice-confirm-compare.png) |
| 50 | 페이지네이션 | Pagination | • 목록을 페이지 단위로 이동하는 컨트롤 ("총 8건 중 1-8건", "« ‹ 1 › »") • 클릭 시: 해당 페이지로 이동 | general_affairs_notices | |
| 60 | 공지 수신 연계 | - | • 게시 공지는 직원 메신저/공지 수신으로 전달됨 (연계 후보) | HBEA300_메신저 | 동선 TBU |
| 70 | AI — 공지 초안 작성 | AI/Suggest | • 교육마감/시설/안전/정책 공지 초안을 작성하는 보조 (greenfield, 사람 게시) • 클릭 시: TBU (라이브 표면 없음) | notice | ga.noticeDraft TBU |
권한·상태 분기 요약
| 시나리오 | 트리거 | 결과 | 비고 |
|---|---|---|---|
조건1 [GA_ADMIN] | 공지 화면 진입 | 필터 + 목록 + 작성 노출 | token 내부 key TBU |
CASE01 [미게시 삭제] | 미게시 row → 삭제 | 컨펌 "공지를 삭제할까요?" → 삭제 실행 | 컨펌 있음 |
CASE02 [공지 게시] | 작성 폼 즉시 게시 ON 저장 | isPublished=true, 게시 중 전환 | 사람 실행 |
CASE03 [확인 내역 조회] | 게시 중·만료 row → 확인 내역 | 대상자별 확인 현황 표시 (getAcknowledgedEmployees) | cross-app 검증됨 |
CASE04 [일반 직원 작성 거부] | 일반 [EMPLOYEE]가 notice.create 호출 | throw(거부) — GA_ADMIN 전용 | 권한 경계 (TC 확정: 06:6.8) |
CASE05 [쓰기 권한 없음 화면] | generalAffairs:read만 보유로 공지 화면 진입 | "공지 작성"·미게시 행 "수정"/"삭제" 숨김, 확인 내역만 | #921 |
Open Question
- 확인 내역(notice_acknowledgments) 상세 구조(확인자/확인시각/미확인자) UI = TBU
- 게시 공지 → HBEA300_메신저 수신 동선(자동 발송/구독) = TBU
- 만료일 < 게시일 validation gap 처리 방침 = TBU
- 관련 정책 [[POL_공지 게시]] 토큰명 확정 = TBU
- 대상 사용자 권한 토큰 내부 key(GA_ADMIN / SUPER_ADMIN) = TBU