diff --git a/src/main/java/egovframework/com/cmm/privacy/account/AccountMngController.java b/src/main/java/egovframework/com/cmm/privacy/account/AccountMngController.java
index d7c59dc..ec6f9a2 100644
--- a/src/main/java/egovframework/com/cmm/privacy/account/AccountMngController.java
+++ b/src/main/java/egovframework/com/cmm/privacy/account/AccountMngController.java
@@ -29,6 +29,10 @@ public class AccountMngController {
/** 현황 목록(#11). page 파라미터는 좌측메뉴 하이라이트(left.jsp 9100037 분기)용이라 유지한다. */
private static final String DORMANT_LIST_REDIRECT = "redirect:/mnt/sec/dormantStatus/listView.do?page=9100037";
+ /** 관리자 알림 테스트 발송(제안서 slide15 "관리자 알림"). */
+ @Resource(name = "privacyAdminAlertService")
+ private egovframework.com.cmm.privacy.batch.PrivacyAdminAlertService privacyAdminAlertService;
+
@Resource(name = "accountMngPolicyService")
private AccountMngPolicyService accountMngPolicyService;
@@ -45,6 +49,35 @@ public class AccountMngController {
return "jsonView";
}
+ /**
+ * 관리자 알림 테스트 발송.
+ *
+ *
실제 알림(무결성 위반·이상행위 탐지)은 월 1회 배치에서만 나가서, 수신 주소를
+ * 바꾼 관리자가 그것이 맞는지 한 달을 기다려야 확인할 수 있었다. 같은 발송 경로를
+ * 그대로 타는 테스트를 눌러 즉시 결과를 본다.
+ *
+ *
상태를 바꾸지는 않지만 외부로 메일이 나가는 동작이라 POST·동일출처만 받는다 —
+ * 링크 한 번으로 반복 발송되면 안 된다.
+ */
+ @RequestMapping(value = "/mnt/privacy/accountPolicyTestAlert.do",
+ method = org.springframework.web.bind.annotation.RequestMethod.POST)
+ public String testAlert(HttpServletRequest request, ModelMap model) throws Exception {
+ LoginVO loginVO = handlerUser();
+ if (loginVO == null) {
+ return denyJson(model);
+ }
+ if (!isSameOrigin(request)) {
+ model.addAttribute("result", "fail");
+ model.addAttribute("message", "잘못된 요청 경로입니다.");
+ return "jsonView";
+ }
+ String resultMsg = privacyAdminAlertService.sendTestMail(loginVO.getId());
+ // 성공·실패 모두 사유를 그대로 화면에 보여준다. "실패했습니다"만 뜨면 원인을 못 찾는다.
+ model.addAttribute("result", resultMsg != null && resultMsg.startsWith("테스트 메일을 발송") ? "success" : "fail");
+ model.addAttribute("message", resultMsg);
+ return "jsonView";
+ }
+
/** #13 정책 수정. */
@RequestMapping(value = "/mnt/privacy/accountPolicyUpdate.do")
public String updatePolicy(@ModelAttribute("policy") AccountMngPolicyVO policy,
diff --git a/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertService.java b/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertService.java
index 0992ad6..9fc36fc 100644
--- a/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertService.java
+++ b/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertService.java
@@ -54,4 +54,17 @@ public interface PrivacyAdminAlertService {
* @return 발송 건수(0 = 미발송)
*/
int alertAbnormalAccess(String periodFrom, String periodTo, String summary, int detected);
+
+ /**
+ * 테스트 발송 — 알림 설정이 실제로 동작하는지 확인한다.
+ *
+ *
실제 알림은 월 1회 배치에서만 나가므로, 설정을 바꾼 관리자가 그것이 맞는지
+ * 한 달을 기다려 확인해야 하는 문제가 있었다. 이 메서드는 같은 경로(수신주소 조회 →
+ * 메일 모듈 적재·발송)를 그대로 타서 즉시 결과를 알려준다 — 경로가 다르면
+ * 테스트가 통과해도 실제 알림은 실패할 수 있으므로 반드시 같은 경로여야 한다.
+ *
+ * @param requesterId 발송을 요청한 취급자 계정ID(본문에 기록해 누가 눌렀는지 남긴다)
+ * @return 사람이 읽을 결과 문자열. 성공하면 수신 주소를, 실패하면 사유를 담는다.
+ */
+ String sendTestMail(String requesterId);
}
diff --git a/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertServiceImpl.java b/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertServiceImpl.java
index af42808..1bde24a 100644
--- a/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertServiceImpl.java
+++ b/src/main/java/egovframework/com/cmm/privacy/batch/PrivacyAdminAlertServiceImpl.java
@@ -87,43 +87,87 @@ public class PrivacyAdminAlertServiceImpl implements PrivacyAdminAlertService {
return send("접속기록 이상행위 탐지", body.toString(), "이상행위 탐지");
}
- /**
- * 관리자 메일 적재. 수신자 미설정이면 보내지 않되 로그는 남긴다 —
- * "알림이 안 왔다"와 "보낼 주소가 없다"를 구분할 수 있어야 한다.
- */
- private int send(String subject, String body, String kind) {
- String adminEmail = null;
- try {
- AccountMngPolicyVO policy = accountMngDAO.selectPolicy();
- if (policy != null) {
- adminEmail = policy.getAdminEmail();
- }
- } catch (Exception e) {
- LOG.warn("[개인정보/알림] 정책 조회 실패 — {} 알림을 보내지 못했습니다: {}", kind, e.toString());
- return 0;
+ @Override
+ public String sendTestMail(String requesterId) {
+ String adminEmail = resolveAdminEmail();
+ if (adminEmail == null) {
+ return "관리자 수신 이메일이 설정되어 있지 않습니다."
+ + " 이 화면의 [관리자 수신 이메일] 항목에 주소를 입력하고 저장한 뒤 다시 시도하세요.";
}
- if (adminEmail == null || adminEmail.trim().length() == 0) {
+ StringBuilder body = new StringBuilder();
+ body.append("개인정보보호 관리자 알림 테스트 메일입니다.\n\n");
+ body.append("이 메일이 도착했다면 아래 알림이 같은 경로로 정상 발송됩니다.\n");
+ body.append(" - 접속기록 무결성 위반 탐지 (매월 1일 03:00 검증 배치)\n");
+ body.append(" - 접속기록 이상행위 탐지 (매월 1일 05:00 정기점검 배치)\n");
+ body.append(" - 계정 휴면 사전알림 (매일 06:00, D-30 / D-7 / D-Day)\n\n");
+ body.append("- 요청자 : ").append(nvl(requesterId)).append('\n');
+ body.append("- 수신주소 : ").append(adminEmail).append('\n');
+ body.append("- 발송시각 : ").append(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date())).append('\n');
+
+ String err = doSend(adminEmail, "관리자 알림 테스트", body.toString(), "테스트");
+ if (err == null) {
+ return "테스트 메일을 발송했습니다. 수신함(" + adminEmail + ")을 확인하세요."
+ + " 도착하지 않으면 메일서버 설정과 발송 이력(COMTNSNDNGMAIL)을 확인해야 합니다.";
+ }
+ return "발송에 실패했습니다: " + err;
+ }
+
+ /** 정책에서 관리자 수신 주소를 읽는다. 미설정·조회실패면 null. */
+ private String resolveAdminEmail() {
+ try {
+ AccountMngPolicyVO policy = accountMngDAO.selectPolicy();
+ if (policy != null && policy.getAdminEmail() != null
+ && policy.getAdminEmail().trim().length() > 0) {
+ return policy.getAdminEmail().trim();
+ }
+ } catch (Exception e) {
+ LOG.warn("[개인정보/알림] 정책 조회 실패: {}", e.toString());
+ }
+ return null;
+ }
+
+ /**
+ * 관리자 메일 적재·발송. 수신자 미설정이면 보내지 않되 로그는 남긴다 —
+ * "알림이 안 왔다"와 "보낼 주소가 없다"를 구분할 수 있어야 한다.
+ *
+ *
표준 메일 모듈은 적재와 발송을 한 번에 한다({@code insertSndngMail} 이
+ * COMTNSNDNGMAIL 적재 후 곧바로 전송하고, 실패하면 발송결과코드를 'F' 로 갱신한다).
+ * 그래서 반환값 false 도 실패로 취급한다 — 예외가 없다고 발송된 것이 아니다.
+ *
+ * @return 성공이면 null, 실패면 사유 문자열
+ */
+ private String doSend(String adminEmail, String subject, String body, String kind) {
+ try {
+ SndngMailVO vo = new SndngMailVO();
+ vo.setDsptchPerson(SENDER);
+ vo.setRecptnPerson(adminEmail);
+ vo.setSj(SUBJECT_PREFIX + subject);
+ vo.setEmailCn(body);
+ vo.setAtchFileId("");
+ boolean ok = sndngMailRegistService.insertSndngMail(vo);
+ if (!ok) {
+ LOG.error("[개인정보/알림] {} 알림 발송 실패(메일모듈이 false 반환) → {}", kind, adminEmail);
+ return "메일 모듈이 발송 실패를 반환했습니다. 메일서버 설정을 확인하세요.";
+ }
+ LOG.info("[개인정보/알림] {} 알림 발송 완료 → {}", kind, adminEmail);
+ return null;
+ } catch (Exception e) {
+ // 발송 실패로 파기·검증 배치가 멈추면 본말이 전도된다.
+ LOG.error("[개인정보/알림] {} 알림 발송 오류 — 배치는 계속합니다: {}", kind, e.toString());
+ return e.toString();
+ }
+ }
+
+ /** 배치용 발송 — 결과를 건수로만 돌려준다. */
+ private int send(String subject, String body, String kind) {
+ String adminEmail = resolveAdminEmail();
+ if (adminEmail == null) {
LOG.warn("[개인정보/알림] 관리자 수신 이메일 미설정(ACCOUNT_MNG_POLICY.ADMIN_EMAIL) —"
+ " {} 알림을 보내지 못했습니다. 계정 관리 정책 화면에서 주소를 등록하십시오.", kind);
return 0;
}
-
- try {
- SndngMailVO vo = new SndngMailVO();
- vo.setDsptchPerson(SENDER);
- vo.setRecptnPerson(adminEmail.trim());
- vo.setSj(SUBJECT_PREFIX + subject);
- vo.setEmailCn(body);
- vo.setAtchFileId("");
- sndngMailRegistService.insertSndngMail(vo);
- LOG.info("[개인정보/알림] {} 알림 발송 적재 완료 → {}", kind, adminEmail.trim());
- return 1;
- } catch (Exception e) {
- // 발송 실패로 파기·검증 배치가 멈추면 본말이 전도된다.
- LOG.error("[개인정보/알림] {} 알림 발송 실패 — 배치는 계속합니다: {}", kind, e.toString());
- return 0;
- }
+ return doSend(adminEmail, subject, body, kind) == null ? 1 : 0;
}
private String nvl(Object v) {
diff --git a/src/main/webapp/WEB-INF/jsp/site/mnt/sec/accountPolicy/policy.jsp b/src/main/webapp/WEB-INF/jsp/site/mnt/sec/accountPolicy/policy.jsp
index ee0a343..1405c8e 100644
--- a/src/main/webapp/WEB-INF/jsp/site/mnt/sec/accountPolicy/policy.jsp
+++ b/src/main/webapp/WEB-INF/jsp/site/mnt/sec/accountPolicy/policy.jsp
@@ -93,6 +93,16 @@ function fn_save() {
}
}, "json").fail(function() { alert("저장 처리 중 오류가 발생하였습니다."); });
}
+/* 관리자 알림 테스트 발송 — 실제 알림과 같은 경로로 즉시 보내 설정을 확인한다.
+ 저장된 주소로 나가므로, 입력칸만 고친 상태에서 눌러도 예전 주소로 간다(안내 문구 참조). */
+function fn_testAlert() {
+ if (!confirm("저장된 관리자 수신 이메일로 테스트 메일을 발송합니다.\n계속하시겠습니까?")) { return; }
+ $.post("", {}, function(data) {
+ /* 성공·실패 모두 서버가 준 사유를 그대로 보여준다.
+ "실패했습니다"만 뜨면 주소 미설정인지 메일서버 문제인지 구분할 수 없다. */
+ alert((data && data.message) ? data.message : "결과를 확인할 수 없습니다.");
+ }, "json").fail(function() { alert("테스트 발송 요청 중 오류가 발생하였습니다."); });
+}
function fn_reload() {
location.href = "?page=9100038";
}
@@ -207,8 +217,12 @@ function fn_reload() {
-
- 사전알림 관리자 사본 수신 주소 (미입력 시 관리자 알림 미발송)
+
+
+ 사전알림·무결성 위반·이상행위 탐지 알림의 수신 주소 (미입력 시 관리자 알림 미발송)
+ 테스트 발송은 실제 알림과 같은 경로로 메일을 보냅니다 —
+ 주소를 바꾼 뒤 이 버튼으로 확인하세요(실제 알림은 월 1회 배치에서만 나갑니다).
+ 주소를 바꿨다면 먼저 [저장]한 뒤 테스트하세요. 테스트는 저장된 주소로 발송합니다.
diff --git a/발주기관 확인 항목.txt b/발주기관 확인 항목.txt
new file mode 100644
index 0000000..c517733
--- /dev/null
+++ b/발주기관 확인 항목.txt
@@ -0,0 +1,294 @@
+================================================================================
+ 2026년 문화품앗이 개인정보보호 기능개선 용역 — 발주기관 확인 항목
+--------------------------------------------------------------------------------
+ 작성일 : 2026-08-27
+ 대상 : 한국문화원연합회 (발주기관)
+ 근거 : 붙임2_제안요청서.hwp / 개인정보보호강화 파일럿 개발항목.pptx(제안요약서)
+ 작성 : 개발 수행 중 소스·DB 실측으로 확인된 사항
+--------------------------------------------------------------------------------
+ 이 문서는 개발을 진행하면서 "제안요청서·제안서만으로는 결정할 수 없어 발주기관의
+ 확인이나 결정이 필요한 항목"을 모은 것입니다. 각 항목에는 근거 문구, 현재 구현
+ 상태, 결정이 필요한 내용, 미확정 시의 영향을 함께 적었습니다.
+
+ 임의로 값을 정하지 않고 제안서 근거값(또는 법정 기준)으로 잠정 구현해 둔 상태이며,
+ 확인 결과에 따라 설정값 변경 또는 추가 개발로 반영합니다.
+================================================================================
+
+
+================================================================================
+ [A] 확정되어야 개발이 완료되는 항목 (미확정 시 해당 기능 미완)
+================================================================================
+
+--------------------------------------------------------------------------------
+ A-1. 휴대폰(SMS) 인증 — 문자발송모듈 연동 규격
+--------------------------------------------------------------------------------
+ 근거 : SFR-003 "OTP, 휴대폰인증, 공동인증서 등 안전한 인증수단을 적용하여야 한다"
+ IAR-001 "휴대폰 인증 적용 시 기존 문자발송모듈과 연계 가능하여야 한다"
+ 제안요청서 운영환경 : 문자발송모듈 = KT-TCS / MCSAgent3.0
+
+ 현재 : 2단계 인증 3종 중
+ - OTP : 구현 완료 (TOTP RFC6238, 비밀키 암호화 저장, 실동작)
+ - 공동인증서 : 구현 완료 (기존 GPKI 자산 위임, 인증서 DN 만 대조)
+ - 휴대폰SMS : 인터페이스와 빈 등록까지만 되어 있고 실제 발송·검증 미구현
+
+ 확인요청 : ① KT-TCS / MCSAgent3.0 연동 규격서(발송 API, 인증정보, 발신번호)
+ ② 발송 비용 부담 주체 및 월 발송 한도
+ ③ 인증번호 유효시간(제안 설계값 3분)과 재발송 제한 정책
+
+ 미확정시 : 인증수단 3종 중 1종(휴대폰)이 미완 상태로 남습니다.
+ 현재 OTP·공동인증서만으로도 2단계 인증은 동작하므로 SFR-003 의
+ "추가 인증 절차 제공"은 충족하나, "휴대폰인증 적용"은 미충족입니다.
+
+
+--------------------------------------------------------------------------------
+ A-2. 회원정보 암호화 마스터 키 — 운영 환경 확인 필요 ★ 시급 ★
+--------------------------------------------------------------------------------
+ 근거 : 제안서 추가제안 Action4 "회원정보 암호화 저장"
+ 개인정보 보호법 제29조 / 안전성 확보조치 기준 제7조
+
+ 현재 : 회원 이름(COMTNGNRLMBER.MBER_NM)을 AES-128/GCM 으로 암호화하도록
+ 개발 완료되어 있고, 개발 PC 기준 77,053건이 이미 암호화되어 있습니다.
+ 그런데 암호화 키를 서버에 영구 보관하는 설정이 어느 환경에도 없습니다.
+ - 개발서버 기동 설정(arko-dev.service) : 키 설정 없음
+ - 운영 WAS 컨테이너 설정(01-was-setup.sh) : 키 설정 없음
+ 키는 프로세스 실행 시점에만 존재하는 값이라, 서버를 재기동하면
+ 사라지고 기존 암호문을 복호화할 수 없게 됩니다.
+
+ 확인요청 : ① 운영 DB(csv)의 COMTNGNRLMBER 에 암호문이 이미 적재되어 있는지
+ SELECT COUNT(*), COUNT(MBER_NM_ENC) FROM COMTNGNRLMBER;
+ ② 적재되어 있다면 그때 사용한 마스터 키/pepper 값의 보관처
+ ③ 키 보관 방식 결정 (서버 환경변수 / 권한 600 키파일 / 별도 금고)
+ ④ 키 관리 책임자 지정
+
+ 미확정시 : 회원 이름을 표시하는 관리자 화면이 동작하지 않습니다.
+ ※ 키를 새로 만들면 기존 암호문을 영구히 읽을 수 없습니다. 운영 데이터에
+ 대해서는 절대 새 키로 재암호화하지 마시고, 반드시 원래 키를 확보한 뒤
+ 적용해야 합니다.
+
+
+--------------------------------------------------------------------------------
+ A-3. 계정 삭제 — 보존기간 및 자동 삭제 시행 여부
+--------------------------------------------------------------------------------
+ 근거 : 과업내용 가 "장기 미사용 계정 및 회원 탈퇴 후 보존기간이 경과한 계정의
+ 삭제 기능 구현"
+
+ 현재 : 삭제 기능은 개발 완료되었으나 안전을 위해 기본 비활성 상태입니다.
+ - 보존기간 기본값 : 365일 (ACCOUNT_MNG_POLICY.DELETE_PRESERVE_DAY)
+ - 자동삭제 사용여부: '아니오' (PURGE_USE_YN = 'N')
+ 현재는 관리자가 화면에서 개별 승인해 말소하는 방식만 동작합니다.
+
+ 확인요청 : ① 탈퇴 후 보존기간 일수 (내부 규정/타 시스템 기준)
+ ② 보존기간 경과 계정을 자동 삭제할지, 관리자 승인 후 삭제할지
+ ③ 삭제 대상에 일반회원도 포함할지, 개인정보취급자 계정만 대상으로 할지
+ (현재는 취급자 계정 한정으로 구현)
+
+ 미확정시 : 자동 삭제가 계속 비활성으로 남습니다. 되돌릴 수 없는 처리라 임의로
+ 켜지 않았습니다.
+
+
+================================================================================
+ [B] 운영 환경 정보가 있어야 정확해지는 항목
+================================================================================
+
+--------------------------------------------------------------------------------
+ B-1. 내부망 IP 대역 / 신뢰 프록시 대역
+--------------------------------------------------------------------------------
+ 근거 : SFR-003 "개인정보취급자의 외부 접속 시 추가인증 절차를 제공하여야 한다"
+ SFR-004 "접속기록에는 접속지 정보(IP)가 포함되어야 한다"
+
+ 현재 : 잠정값으로 사설 대역(127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12,
+ 192.168.0.0/16)을 내부망으로 간주하고 있습니다.
+ 판정이 불가능하면 안전측으로 '외부 접속'으로 보아 추가 인증을 요구합니다.
+
+ 확인요청 : ① 실제 내부망(사내/전용선) IP 대역
+ ② 웹서버 구성(Apache + L4 등) 및 프록시 헤더 전달 여부
+ - 접속기록의 IP 가 L4 장비 IP 로 고정되어 쌓이면 접속기록의
+ "접속지 정보"가 사실상 무의미해집니다.
+
+ 미확정시 : ① 외부 접속인데 내부로 오판하여 추가 인증을 건너뛸 수 있습니다.
+ ② 접속기록의 IP 가 전부 동일한 값으로 남을 수 있습니다.
+
+
+--------------------------------------------------------------------------------
+ B-2. 배치 스케줄러 운영 방식
+--------------------------------------------------------------------------------
+ 근거 : SFR-002(휴면 배치), SFR-004(파기·무결성검증·정기점검 배치)
+
+ 현재 : 개인정보보호 배치는 애플리케이션 스케줄러(@Scheduled)로 구현되어 있습니다.
+ - 매일 01:00 휴면 전환 / 06:00 휴면 사전알림
+ - 매월 1일 02:00 접속기록 파기 / 03:00 무결성 검증
+ 04:00 권한이력 파기 / 05:00 정기점검 리포트
+
+ 확인요청 : ① 기존 운영 배치(crontab 등)와 중복 실행 우려가 있는지
+ ② WAS 이중화 시 배치가 양쪽에서 동시에 도는 구성인지
+
+ 미확정시 : 동일 배치가 중복 실행될 수 있습니다(파기 배치는 중복 실행되어도
+ 결과가 같도록 만들었으나, 운영 구성 확인이 필요합니다).
+
+
+--------------------------------------------------------------------------------
+ B-3. 기존 로그인 인증 인터셉터 재활성 여부
+--------------------------------------------------------------------------------
+ 근거 : SER-001 "비인가자의 개인정보처리시스템 접근을 통제하여야 한다"
+
+ 현재 : 접근통제 인터셉터는 ① 인증판정 → ② 2차 인증 → ③ 권한 판정 3단으로
+ 설계되어 있으나, ① 인증판정(로그인 체크)은 본 사업 착수 전부터
+ 비활성(주석) 상태였습니다. ②③은 활성화되어 동작합니다.
+ 개인정보 관련 화면은 화면별로 로그인 여부를 다시 확인하도록 보완했습니다.
+
+ 확인요청 : ① 기존에 비활성화한 사유가 있는지
+ ② 재활성 시 영향받는 화면 범위를 함께 점검할 수 있는지
+
+ 미확정시 : 개인정보 화면은 보호되지만, 그 밖의 관리자 화면은 종전 상태 그대로입니다.
+
+
+================================================================================
+ [C] 제안서·제안요청서에 명시가 없어 판단이 필요한 항목
+================================================================================
+
+--------------------------------------------------------------------------------
+ C-1. "관리자 알림"의 통보 수단
+--------------------------------------------------------------------------------
+ 근거 : 제안요약서 slide15 "정기 점검 레포트 / 관리자 알림"
+ SFR-002 "계정 비활성화 전 관리자 알림 기능을 제공하여야 한다"
+
+ 확인사항 : 두 문서 어디에도 알림 수단(메일/문자/화면)이 명시되어 있지 않습니다.
+
+ 현재 : 메일로 구현했습니다.
+ - 계정 휴면 사전알림 : D-30 / D-7 / D-Day, 본인과 관리자에게 발송
+ - 접속기록 무결성 위반 탐지 시 관리자에게 발송
+ - 이상행위 탐지 시(정기점검 배치) 관리자에게 발송
+ 수신 주소는 관리자가 [계정 관리 정책] 화면에서 설정합니다.
+ 메일 본문에는 개인정보를 담지 않고 건수·기간·요약만 넣었습니다.
+
+ 확인요청 : ① 메일로 충분한지, 문자(SMS) 또는 화면 알림이 필요한지
+ ② SFR-002 의 "관리자 알림"이 가리키는 대상
+ - (해석1) 시스템 관리자에게 "이 계정들이 곧 비활성화된다"고 보고
+ - (해석2) 비활성화될 당사자에게 "곧 잠긴다"고 통지
+ 현재는 두 해석을 모두 만족하도록 본인과 관리자 양쪽에 발송합니다.
+ ③ 로그인 시 화면 팝업 안내가 필요한지
+ ※ 참고 : 로그인하면 최종접속일이 갱신되어 미접속 일수가 0이 되므로,
+ 화면 안내는 "곧 잠깁니다"가 아니라 "오랫동안 접속하지 않으셨습니다"
+ 형태가 됩니다.
+
+ 미확정시 : 메일 기준으로 유지합니다. 문자 발송은 A-1(문자발송모듈 규격) 확정
+ 이후에만 추가할 수 있습니다.
+
+
+--------------------------------------------------------------------------------
+ C-2. 접속·처리기록 관리 화면 구성
+--------------------------------------------------------------------------------
+ 근거 : 과업내용 다 "로그 조회 및 관리 기능 구현 — 관리자용 로그 조회 화면 개발"
+ 제안요약서 slide14~15 화면 시안
+
+ 확인사항 : 제안요청서가 요구하는 화면은 "관리자용 로그 조회 화면" 한 개이고,
+ 제안요약서 시안도 "접속기록 조회 및 감사" 한 장만 그려져 있습니다.
+ 다만 시안의 좌측 메뉴에는 4개 항목(① 접속기록 조회 ② 개인정보 처리기록
+ ③ 이상행위 감사 ④ 정기 점검 리포트)이 이름만 나열되어 있습니다.
+
+ 현재 : 화면 하나("접속기록 조회 및 감사")로 구성하고, 나머지 기능은 그 화면
+ 안에서 제공합니다.
+ - 처리기록 조회 : 처리구분(조회/등록/수정/삭제) 필터
+ - 이상행위 감사 : 목록의 '감사' 칸에 이상/점검 표시
+ - 정기점검 : 월 1회 배치가 집계·적재
+ - 파기이력 : 화면 내 '파기이력' 버튼
+
+ 확인요청 : 시안의 좌측 메뉴 4개를 각각 별도 화면으로 만들어야 하는지,
+ 현재처럼 한 화면에서 제공하는 것으로 충분한지
+
+ 미확정시 : 현재 구성(화면 1개)을 유지합니다. 별도 화면이 필요하면 기능은 이미
+ 있으므로 메뉴와 화면만 분리하면 됩니다.
+
+
+--------------------------------------------------------------------------------
+ C-3. 개인정보 처리기록의 "처리 항목"·"처리 목적"
+--------------------------------------------------------------------------------
+ 근거 : 제안요약서 slide13 처리기록 예시
+ 처리자 / 처리 일시 / 처리 정보주체 / 처리 항목(성명·연락처·주소) /
+ 처리 유형 / 처리 목적(봉사활동 매칭 상담)
+
+ 확인사항 : 위 6개 항목 중 "처리 항목"과 "처리 목적"은 현재 접속기록에 수집되지
+ 않습니다. 나머지 4개는 수집·저장되고 있습니다.
+ - 처리 항목 : 어떤 정보를 열람했는지. 화면 단위로 매핑 정의가 필요합니다.
+ - 처리 목적 : 시스템이 알 수 없는 값으로, 취급자가 직접 입력해야 합니다.
+
+ 확인요청 : ① 두 항목을 접속기록에 반드시 남겨야 하는지
+ ② "처리 목적"을 남긴다면, 개인정보 취급 화면에 들어갈 때마다 사유를
+ 입력받는 방식을 수용할 수 있는지 (취급자 업무 흐름에 매번 입력이
+ 추가됩니다)
+ ③ 대상 화면 범위 (전 화면 / 특정 화면 한정)
+
+ 미확정시 : 현재 수집 항목(접속자·일시·IP·업무유형·처리대상·처리구분·결과)을
+ 유지합니다. 안전성 확보조치 기준 제8조의 필수 5개 항목은 충족합니다.
+
+
+--------------------------------------------------------------------------------
+ C-4. 개인정보 마스킹 적용 범위 (추가제안)
+--------------------------------------------------------------------------------
+ 근거 : 제안요약서 slide17 "개인정보 마스킹 처리(추가제안)"
+ - 신청자 목록 화면과 다운로드 엑셀에 이름·휴대폰번호가 평문 노출
+ - 다운로드 파일이 외부 업체 전달 양식으로 추정되는 정황
+
+ 현재 : 마스킹 기능(이름·휴대폰·이메일)은 개발되어 있고 회원정보 관리 화면과
+ 2단계 인증 화면에 적용되어 있습니다.
+ 신청자 목록·엑셀 다운로드에는 아직 적용하지 않았습니다.
+
+ 확인요청 : ① 신청자 목록 화면을 마스킹할 경우 담당자 업무에 지장이 없는지
+ ② 다운로드 엑셀의 실제 사용처(외부 업체 전달 여부)와, 마스킹 시
+ 해당 업무가 가능한지
+ ③ 마스킹 예외가 필요한 화면/역할이 있는지
+
+ 미확정시 : 업무 영향이 커서 임의로 적용하지 않았습니다. 확인 후 반영합니다.
+
+
+================================================================================
+ [D] 사업관리·산출물 관련
+================================================================================
+
+--------------------------------------------------------------------------------
+ D-1. 성능 검증 기준선
+--------------------------------------------------------------------------------
+ 근거 : PSR-001 시스템 성능 유지 / 제안요약서 slide19 "기능개선 전·후 성능 측정"
+
+ 확인사항 : 제안서는 개선 전과 후의 응답속도를 비교하도록 계획하고 있으나,
+ 개선 전 시점의 측정치가 확보되어 있지 않습니다.
+
+ 확인요청 : ① 측정 대상 서비스와 시나리오
+ ② 측정 시점 및 방법(운영 부하 영향 고려)
+ ③ 개선 전 측정치가 없을 경우의 대안(현재 상태를 기준선으로 삼을지)
+
+
+--------------------------------------------------------------------------------
+ D-2. 산출물 목록·양식
+--------------------------------------------------------------------------------
+ 근거 : 각 요구사항의 "산출정보" 항목
+ 요구사항정의서 / 기능설계서 / 인터페이스설계서 / 데이터정의서 /
+ 로그정책서 / 테스트결과서 / 적용결과보고서 등
+
+ 확인요청 : ① 발주기관 표준 양식 제공 여부
+ ② 제출 시점 및 형태(문서/전자)
+ ③ 개인정보보호위원회 점검 대응용 조치결과보고서 양식의 필요 여부
+
+
+================================================================================
+ [참고] 확인 없이 진행한 사항 (근거를 명시해 두었습니다)
+================================================================================
+
+ · 접속기록 보관기간 : 730일(2년)
+ → SFR-004 "최소 2년 이상 보관". 관리자가 화면에서 늘릴 수 있으나 2년 미만으로는
+ 줄일 수 없도록 화면·서버·배치 세 곳에서 막았습니다.
+
+ · 권한 변경 이력 보관기간 : 1,095일(3년)
+ → SFR-001 "최소 3년 이상 보관".
+
+ · 계정 잠금 임계 : 5회 / 자동 로그아웃 : 30분
+ → 제안서 slide10 "잠금 5회, 로그아웃 30분으로 강화".
+
+ · 휴면 전환 기준 : 정책 테이블 설정값(기본 365일, 사전알림 D-30/D-7/D-Day)
+ → 제안서 slide7 시안은 "60일 휴면예정 / 90일 자동잠금"을 예시로 들고 있어
+ 설정값 변경만으로 시안과 동일하게 맞출 수 있습니다. 운영 기준 확정 시 반영합니다.
+
+================================================================================
+ 문의: 본 문서의 각 항목은 개발 소스와 DB 실측을 근거로 작성되었습니다.
+ 항목별 상세 근거(파일·행 번호)가 필요하시면 별도로 제공해 드립니다.
+================================================================================