운영 문서 / 검증·도입 준비 현황

지자체 도입 준비 · 검증 기록

최종 갱신: 2026-09-07. 목표: 지자체 행사 운영자가 모집부터 남성 10명·여성 10명의 로테이션, 상호 선택 결과까지 운영할 수 있는 웹 서비스와 화면 매뉴얼. 이후 기업용으로 확장한다.

홈페이지 체험과 운영 권한 검증

홈페이지 체험의 모바일 영상·오버레이 조작부와 운영 예시 화면을 검증하고, 사용자 승인 후 2026-09-07 07:38 UTC 운영에 배포했습니다. web-00015-paq, 예약 실행·회의 종료 함수 ACTIVE, Scheduler ENABLED, Hosting FINALIZED와 웹 리비전 고정을 확인했습니다. 근거: landing-release-evidence.json. 이후 운영 안내를 네 단계의 좌우 교차 배치로 정리하고, 선택 방향과 상호 선택을 화살표로 구분하는 후속 개선을 진행합니다.

예약 실행과 참가자 회의 요청 경로에서 담당자의 현재 운영 권한 검사가 빠져 있음을 로컬에서 재현하고 보완했습니다. 차단·권한 회수·계정 삭제 후에는 시작과 회의 링크 제공을 거절하고, 정상 행사의 진행과 이전 통화 정리는 계속 처리합니다. 회의 생성 중 권한이 바뀌면 링크를 공개하지 않으며, 권한 복구 후에는 Google 성공 응답이 확인된 같은 회의를 재사용합니다.

관련29개 통합 검사와 최종 전체113개 검사가 통과했고 독립 재검토도 통과했습니다. 앞선 전체 실행은 기존20인 동시 승인에서 에뮬레이터 트랜잭션 오류1건(111/112)이 발생했으므로 실부하 안정성까지 확인한 것으로 보지 않습니다. 실제20인 영상·음성 검증은 별도로 남아 있습니다. 근거: operator-authority-test-evidence.json, landing-ui-verification.json.

완료 판정 기준

과정완료 조건현재 증거 / 남은 작업
운영자 등록기관 신청·승인 후 본인 행사만 운영기관 승인 API→선결제 없는 모집 에뮬레이터 검증 및 운영 배포 완료; 실제 관리자 승인 흐름 확인 필요
행사 생성기본 1차, 추가 차수·시간·모집·선택 규칙 저장구현 있음; 실제 UI에서20인 행사 초안 생성 완료(r_ze86s4skkef6)
신청·심사이메일 로그인, 신청, 승인·거절·정원 보호실제 Firebase20인 승인·대기20/20 확인. 서버 자동 승인·비공개 입장 보호 및 Rules 운영 배포 완료
20인 운영남10·여10 승인 및 10쌍 동시 배정, 10회 중복 없는 만남20인 서버통합 검증 통과: 차수당100개 중복없는 이성 페어·2차·상호매칭9쌍·미동의 연락처 비공개. 실제20인 영상통화 별도 미검증
Google Meet운영자 OAuth, 실제 회의 생성, 배정된 두 사람만 연결OAuth·운영자 회의·라운드별 회의 생성 실제 성공. 실제 2인/20인 영상·음성은 미검증
자동 진행관리자/예약 시작, 시간 종료, 다음 상대 이동20인10회 자동 배정. 7라운드 회의 생성 누락 발견(90/100개 준비), 준비 시간과 대화 시간 분리 수정·통합 테스트 통과, 실제20인 재검증 필요. Meet 입장은 별도 클릭
최종 선택비공개 제출·상호 선택만 매칭, 동의한 연락처만 공개실제20명 UI선택 제출·10쌍 상호매칭, 연락처 동의5쌍 공개/미동의5쌍 비공개 확인
운영 모니터출석·현재 배정·회의 준비·신고·결과출석20/20, 배정·Meet URL, Google 현재 접속 인원 구현. 실제 통화 없음→운영자1명 입장 감지 확인. 영상·음성 정상 여부는 별도 검증 필요
배포Firebase Hosting + Functions, 운영 도메인 HTTPSHosting·Functions3개·Rules 배포, HTTPS 로그인·Meet 현황·예약 실행 확인; 기존 App Hosting 리소스 정리 필요
자료모든 기능의 실제 캡처·관리자/참가자 매뉴얼·소개·시연 절차9장 웹 매뉴얼 /manual, 실제 캡처를 담은10장 소개자료 PDF·PPTX와10분 진행표 제공; 나머지 기능 검증·촬영과 시연 리허설 필요

구현 순서

  1. 4인 서비스 전체 흐름을 끝까지 검증하고 발견한 오류 수정.
  2. 20인 계정·신청·심사·대기·10쌍·차수 추가·최종 매칭 검증. 테스트 픽스처와 실제 미디어 접속의 증거는 구분.
  3. Google 회의 생성 동시성·한도·종료 처리와 운영자 입장 승인 UX 보완.
  4. 지자체 신청/승인/운영/참가/신고/결과/비용 매뉴얼과 실제 캡처를 웹으로 제공.
  5. 배포 및 기기별 실통화 검증, 지자체 소개·시연 준비 완료 판정.

실제 실행 기록

  • 테스트 계정: Firebase 이메일/비밀번호 운영자1·참가자4, SMS 없음. 비밀은 .local/에만 저장.
  • 비공개 4인 테스트 행사: 운영자 UI에서 4명 승인, 대기실 입장4/4 확인.
  • 운영자 Google OAuth 연결 및 Google Meet REST API 회의 생성 성공.
  • 운영자 행사 시작 → 참가자 대기실에서 라운드 자동 전환 → 실제 meet.google.com 회의 주소 생성 → 1분 후 두 번째 상대/새 회의 주소 자동 배정 확인.
  • 발견: 신규 참가자의 호감 문서가 없을 때 실시간 읽기 권한 오류. 소유자 조건 쿼리로 수정 중.
  • 이 기록은 20명 실제 영상·음성 동시 통화 성공을 의미하지 않는다. 현재 Mac에서 카메라가 열거되지 않아 웹캠 검증도 남아 있다.

화면 증거

public/manual/screenshots/에 실제 브라우저 캡처를 저장한다. 테스트 행사에는 식별 가능한 테스트 표시를 유지한다.

  • host-lobby-4.jpg: 운영자, 승인 참가자4/4, 수동 시작 대기.
  • participant-round-1.jpg: 실제 Google Meet 회의 URL이 제공되는 첫 라운드. 수정 전 UI/오류 배지 포함, 최종 매뉴얼용은 검증 후 재촬영.
  • 4인 실제 서비스의 최종 선택 마감 후 참가자1↔4, 참가자2↔3 매칭 결과 자동 이동 확인.
  • 2026-09-07: 사용자 명시 승인으로 비공개 테스트 행사 r_ze86s4skkef6만 미결제 상태를 유지하면서 테스트 활성화. 실제 테스트 계정 남녀 각10명의 심사 대기 신청서를 준비. 일반 유료 행사의 활성화 성공으로 간주하지 않음.
  • 최신 Firestore 에뮬레이터 포함 전체89개와 Google Meet·로테이션 엔진 패키지16개 통과. TypeScript 통과. 실제 Google 응답과 모의 API 검증은 구분.

20인 실제 서비스 검증 결과

2026-09-07, 비공개 테스트 행사 r_ze86s4skkef6. 미결제 상태를 유지하고 실제 청구하지 않았다. 20개 이메일 계정의 실제 웹 로그인 → 관리자20명 승인 → 대기실20/20 → 관리자 시작 → 10라운드 자동 배정 →20명 실제UI 최종 선택 →10쌍 상호매칭 확인. 10명이 연락처 공개에 동의했고5쌍에 연락처가 있으며 나머지5쌍에는 없다. 저장 결과 요약은 docs/municipality-test-evidence.json.

100개의 서로 다른 이성 페어를 배정했으나 7라운드는 실제 Meet회의 생성0개, 나머지9라운드는 각10개로 총90개다. 따라서 정상10회 통화완료가 아니다. 생성 지연과 대화 타이머를 분리해 재검증해야 한다. 실제 영상·음성은 여전히 미검증이다.

Firebase 콘솔의 오류 후 Google Cloud 프로젝트 결제 연결에서 회사 계정을 적용했고 Firebase Blaze를 확인했다. Workspace 구독 구매·Meet 할당량 증설은 실행하지 않았다. 운영 배포는 이후 완료했다.

전체 결과판과 API 구조 보완

  • 20명 전체와 상호 매칭 10쌍을 하나의 결과판에 표시. 참가자 선택 시 해당 연결 강조, 전체 보기 복원까지 실제 브라우저로 확인했다.
  • match-board-20.jpg, match-board-selected.jpg 캡처를 저장했다. 한쪽 선택은 비공개이며 전체 상호 매칭 공개 범위를 선택 전 화면에 안내한다.
  • 승인 불참자와 외부인의 결과 조회를 서버에서 차단하고 연락처는 당사자에게만 반환한다.
  • packages/rotation-sdk를 독립 JS/타입 선언으로 빌드했다. 현재 v1 결과 조회가 웹과 SDK에 연결돼 있다. 다른 외부 API 기능과 과금·구독은 미구현이다.
  • 수동 토큰 발급·폐기 명령, 행사 범위, 운영자 역할 재검사, 만료, 토큰별 요청 제한을 구현하고 에뮬레이터에서 검증했다. 실제 운영 토큰은 발급하지 않았다.
  • 회의 준비 단계의 유효 페어 이력을 남겨 휴식 처리된 상대가 최종 선택·매칭에 포함되지 않도록 수정했다. 실제 영상·음성과 수정 후100개 회의 생성 재검증은 별도 남아 있다.

회의 종료 및 백그라운드 처리 보완

  • 라운드 전환과 종료 요청 저장을 같은 트랜잭션에 넣었다. 신규 Firestore 함수가 Google 활성 통화 종료를 처리하고, 예약 함수가 실패·중단된 작업을 다시 확인한다.
  • HTTP 진행 요청은 Google 종료를 기다리지 않는다. 현재 회의 키, 계정 연결 변경, 중복 전달, 늦은 회의 생성 결과, 일시적 OAuth 오류를 다루는 검증을 추가했다.
  • 준비 중인 행사는 예약 함수에서도 회의를 생성할 수 있다. 운영 함수는 이후 배포했으며 실제 활성 회의 종료 검증은 남아 있다. 기존 링크 영구 폐쇄를 보장하지 않는다.
  • 선택 제출 후 차단된 참가자는 최종 매칭과 연락처 교환에서도 제외하도록 보완했다.
  • 20인 실제 재검증은 이전 결과를 보존한 후 동일 행사 초기화가 필요하다. 자동 승인 검토가 초기화에 별도 사용자 승인을 요구하여 작업을 거절했다. 초기화는 실행하지 않았고 사용자 답변을 기다린다.

개인정보 경계 및 모바일 검증 보완

  • users 원본은 본인 단건 조회만 허용한다. 담당자의 신청자 이력 조회는 해당 행사 신청자의 누적 노쇼 값만 서버에서 반환한다. 조회 실패를 0회로 표시하지 않는다.
  • applications와 participants는 차단·운영자 역할 회수 시 담당자의 직접 조회도 차단한다. 참가자 출석은 승인·차단·시작 전 상태를 서버가 검증하고 최초 시각을 유지한다. 클라이언트 직접 출석 수정은 금지한다.
  • matches 원본 직접 조회를 차단하고 참가자 결과 API만 동의한 상대 연락처를 반환한다. 담당자 CSV는 연락처·일방 선택 없이 상호 매칭·참가 현황·누적 노쇼를 반환하고 수식 주입을 방지한다.
  • 위 규칙은 로컬 에뮬레이터에서 검증했으며 운영 Rules는 이후 배포했다. 전체44개 테스트 최종 재실행이 통과했다. 앞선 실행에서 기존 동시 승인 테스트에 에뮬레이터 트랜잭션 종료 오류가 한 번 발생했으며 같은 코드 재실행에서는 재현되지 않았다. 실제 부하 검증을 대체하지 않는다.
  • 390px 브라우저 너비 설정에서 실제20인 결과판·연결 강조를 확인했다. 스크롤바 제외 문서/화면 너비는 모두375px이며 가로 넘침이 없었다. 모바일 캡처2개를 매뉴얼에 추가했다. 실제 휴대전화 통화 검증과는 구분한다.
  • Firebase CLI의 이 프로젝트 Hosting 사이트 읽기가 성공했다. 배포에는 Firebase CLI 인증을 사용할 수 있다. gcloud 별도 사용자 인증은 여전히 재인증 상태일 수 있다.
  • 비공개 테스트 행사의 CSV를 공개 매뉴얼 경로에 저장하려던 읽기/내보내기 명령은 자동 승인 검토에서 거절되어 실행하지 않았다. 공개 CSV 예시는 Firebase와 무관한 가상20인 자료로 생성한다. 내장 브라우저의 실제 CSV 다운로드 이벤트는 확인되지 않았으며 서버 보고서 내용은 에뮬레이터 테스트로 검증했다.

기관 승인 후 선결제 없는 운영 (2026-09-07)

  • 개인 참가비 기능은 없다. 지자체·공공기관은 관리자가 승인한 기관 신청과 현재 운영 권한을 근거로 선결제 없이 모집·운영하고, 이용료는 별도 기관 계약으로 정산한다.
  • GET /api/operator/access는 현재 이용 방식을 반환한다. POST /api/room/[id]/publish는 소유권·기관 승인·계정 차단 여부·결제 진행 상태·비밀번호·진행 설정을 트랜잭션으로 검사한다.
  • 모집 시 billingMode=institution_contract, status=recruiting을 서버가 기록한다. paymentStatus=unpaid와 기존 견적을 유지한다. roomActivations에 승인 근거를 남기며 결제 완료 주문을 만들지 않는다. 클라이언트 tenantId나 데모 모드로 승인할 수 없다.
  • 기관 승인 전에 카드 승인 요청이 시작됐다면 기존 상태를 제공자 GET으로 확인하며 새로운 승인 POST를 보내지 않는다. 결과가 불명확하면 기관 모집으로 전환하지 않고 확인을 기다린다.
  • 기존 운영자도 기관 심사를 신청할 수 있다. 새 신청 반려는 기존 운영 권한을 지우지 않는다. 차단·권한 회수 계정은 승인 이력이 있어도 이용할 수 없다.
  • 행사 생성 마지막 단계는 결제 대신 확인이다. 생성 후 관리 화면에서 모집을 시작한다. 모집 이후 정원·진행 규칙·입장 방식·가격은 클라이언트에서 바꿀 수 없다.
  • Firestore 에뮬레이터 전체 62/62 통과. 그중 기관 승인·모집·권한·결제 충돌 테스트 9개와 결제 검증 9개를 새로 추가했다. 실제 관리자 승인 API도 가상 계정으로 호출해 검증했다. Toss는 모의 응답만 사용했으며 실제 청구·환불은 하지 않았다.
  • 생성 화면의 확인 단계는 실제 내장 브라우저로 데스크톱·390px 모바일 캡처를 저장했다. 문서 너비와 화면 너비는 모두375px로 가로 넘침이 없다. 저장 전 예시 입력 화면이며 실제 기관 계정의 승인 완료·모집 실행 캡처는 남아 있다.
  • 기존 비공개 20인 테스트 행사와 결과는 변경하지 않았다. 운영 Rules·Functions는 이후 배포했다. 실제 Google Meet 양방향 통화와20인 재검증은 여전히 남아 있다.

지자체 전용 배포의 결제 분리 (2026-09-07)

  • paymentMode=disabled 기본값으로 Toss 공개 키와 시크릿 없이 기관 서비스를 빌드·실행하도록 변경했다. 일반 운영자에게는 기관 승인 신청을 안내하며 결제 버튼을 표시하지 않는다.
  • 기존 결제 운영 중 신규 결제를 중단할 경우 reconciliation 모드로 기존 승인·환불 대사를 유지한다. disabled는 알려진 주문의 webhook을 성공 처리하지 않고503으로 재시도를 요구한다.
  • 결제·기관 모집·배포 산출물 관련22개 테스트 통과. TypeScript 및 Functions 타입 검증 통과. 실제 프로젝트 주문 읽기 전용 집계에서 전체1개, 제공자 payment key 없는 미승인 대기1개, 대사 필요0개를 확인했다. 실제 주문은 변경하지 않았다.
  • Cloud Functions API 사용 설정 완료를 콘솔에서 확인했다. Firebase CLI의 함수 목록 조회도 성공했으며 최초 배포 전 함수는0개였으며 이후3개를 배포했다.
  • 운영용4개 시크릿 등록은 처음 자동 승인 검토에서 거절됐으나, 2026-09-07 구체적인 사용자 승인을 받은 뒤 등록과 메타데이터 재조회를 완료했다. 기존 Google 설정·암호화 키·관리자 목록은 값을 유지했고 새 CRON_SECRET을 준비했다. 기존 클라우드 시크릿을 덮어쓰지 않았다.

행사 정보의 공개 범위와 연결 복구 (2026-09-07)

  • 행사 원본 rooms는 현재 권한이 있는 행사 소유자만 직접 읽도록 제한했다. 일반 방문자는 서버의 공개 안내 정보만 받고, 승인 참가자에게는 본인이 포함된 배정만 추가로 반환한다. 비밀번호 해시·결제 상태·내부 세션 정보·다른 페어의 배정표는 응답에서 제외한다.
  • 공개 목록에는 모집 중인 공개 행사만 나온다. 비공개 행사는 초대 slug로 안내를 볼 수 있지만, 행사 ID를 아는 것만으로 비공개 정보를 조회할 수 없다. 운영자 역할 회수·차단과 참가 승인 철회를 반영한다. 역할별 직접 읽기와 운영자 행사 목록 쿼리를 에뮬레이터에서 검증했다.
  • 참가자 행사 정보는3초 간격으로 갱신하며 백그라운드·종료 화면은15초 간격이다. 동시 참가자20명 기준 정상 시 분당 약400회의 행사 조회 요청이 생길 수 있으며 인증·Firestore 읽기 비용도 고려해야 한다. 운영자의 진행 모니터 실시간 구독은 유지한다. 실제 부하 검증은 남아 있다.
  • 일시적 연결 실패와 복구에서 입력 중인 신청·최종 선택을 유지한다. 권한 상실이나 계정 전환은 이전 정보를 지운다. 마지막 선택의 초기 로드는 계정·행사·명시적 재시도에만 반응하며, 서버 상태 갱신이 미제출 선택과 동의를 덮어쓰지 않는다.
  • 전체71개 통과 후 연결 복구 테스트를 추가해 해당3개가 다시 통과했다. TypeScript·변경 파일 ESLint 통과, 독립 리뷰에서 발견한 선택 초기화 문제를 수정하고 재검토를 통과했다. 실제 로컬 HTTP에서 공개 응답의 내부 필드 제외·익명 비공개 ID 조회 차단을 확인했고, 내장 브라우저의 기존20인·10쌍 결과판도 정상 표시됐다.
  • 새 Rules와 API는 이후 운영에 배포했다. 실제 통화 검증과 기존20인 행사 재검증은 별도 남아 있다.

기관 신청 접수·관리자 심사 보완 (2026-09-07)

  • 실제 테스트 운영자로 대시보드의 기관 신청 진입 → 신청서 입력 → Firebase 접수 → 심사 대기 → 승인 상태 재조회를 확인했다. 신청명은 [테스트] 지자체 운영 검증 기관이며, 가상 기관이라는 설명과 가상 연락처를 사용했다. 기존20인 행사와 결과는 변경하지 않았다.
  • institution-application.jpg, institution-pending.jpg, institution-pending-mobile.jpg를 웹 매뉴얼에 연결했다. 모바일390px 설정에서 화면/문서 너비가 각각375px로 가로 넘침이 없었다. 실제 서비스 관리자 계정으로 승인·모집을 실행한 캡처는 아직 없다. 현재 테스트 계정은 서비스 관리자 권한이 없으며 별도 권한을 부여하지 않았다.
  • 기관 신청은 서버 API에서 검증하고 UID별 잠금으로 중복 대기 신청을 막는다. 응답 지연·동시 제출은 기존 대기 신청을 반환한다. 반려 후 재신청은 이력을 보존하고, 이전 방식으로 생성된 잠금 없는 대기 신청도 재사용한다.
  • 관리자 API3개(기관 신청·신고·문의)에 취소된 인증 토큰·차단 계정·App Check 검사와 서버 관리자 목록 검증을 공통 적용했다. 응답은 private,no-store이다. 기관 승인 시 트랜잭션 안에서 관리자와 대상자를 다시 검사하고, 신청자가 주입한 tenantId 대신 관리자가 명시적으로 확인한 값만 반영한다.
  • 관리자 목록은50건씩 커서로 이어서 읽는다. 같은 생성 시각인 항목도 문서 ID를 함께 정렬해 빠짐이나 중복을 방지하고, 필터가 다른 커서는 거절한다. 사용자·필터 변경 시 이전 응답이 새 목록에 남지 않도록 분리했다.
  • 관련20개 테스트와 전체82개 테스트가 통과했다. 중복6건 동시 제출→대기1건, 반려 후 재신청,245건 목록 전부 조회, 직접 신청·승인·잠금 접근 거절을 검증했다. 앞선 전체 실행은 기존20인 승인에서 INVALID_ARGUMENT: Transaction is invalid or closed로77/78이었다. 해당 동시성 테스트를 변경하지 않고 최종 전체 실행에서는 통과했으며, 실제 부하 안정성을 증명한 것으로 간주하지 않는다.
  • 운영 시크릿4개와 운영 OAuth 반환 주소 등록은 사용자 승인 후 완료했다. 변경된 Functions·Rules·인덱스는 배포했다. 서비스 관리자 로그인, 실제 통화와20인 재검증이 남아 있다.

Google Meet 실제 접속 인원 조회 (2026-09-07)

  • 기존 Meet 연결 권한 범위로 활성 회의의 참가자 수를 읽는 재사용 패키지 API와 행사 담당자 전용 HTTP API를 추가했다. Google 이름·이메일·프로필을 수집하지 않으며, 참가자 리소스 ID만 페이지별로 읽고 최종 인원만 반환한다.
  • 실제 비공개20인 테스트 행사의 마지막10개 회의를 조회해 모두 활성 통화가 없음을 확인했다. 운영자 계정1개가 해당 회의1개에 입장한 뒤, 그 방만 Meet 접속1명으로 바뀌었다. meet-presence-one.jpg는 실제 웹 캡처다. 이미 종료된 행사에서 현재 Google 상태만 조회했으며, 참가자 배정·선택·매칭 결과를 초기화하지 않았다.
  • 이번 실제 입장은 마이크를 끄고 진행했으며 Google Meet가 카메라를 찾을 수 없다고 표시했다. 두 사람의 영상·음성 성공이나20명 동시 통화로 간주하지 않는다. 첫 검증 도중 Mac 잠금으로 후속 확인이 중단됐으나, 2026-09-07 11시 재개 후 실제 Meet 재입장1명 → 직접 퇴장0명 → 활성 통화 없음으로 바뀌는 것을 확인했다. 테스트 통화와 탭도 종료했다.
  • 실제 브라우저 너비390px·높이844px에서 접속 현황과 Meet 링크가 가로 넘침 없이 표시됐고, 44px 높이의 수동 갱신 버튼 동작을 확인했다. meet-presence-zero.jpgmeet-presence-mobile.jpg를 매뉴얼에 추가했다. 실제 휴대전화의 영상·음성 확인과는 구분한다.
  • 진행 중 인원은 약20초마다 확인하고 숨긴 탭에서는 조회를 멈춘다. 선택·완료 행사는 첫 조회와 수동 갱신으로 전환했다. 회의 목록의 종료 작업 대기는 최대5분만 추적한다. 같은 서버 인스턴스에서 짧은 캐시와 동시 요청 공유를 적용했다.
  • 응답 전에 현재 소유권·계정 차단·운영 권한·Google 연결을 다시 확인한다. Google 오류·할당량·준비 중은0명이 아닌 확인 불가로 반환한다. HTTP 응답은 private,no-store이며, Google 조회는30초 내 중단하도록 제한한다.
  • 관련15개 통합 테스트, Google Meet·로테이션 엔진 패키지16개, 전체89개 에뮬레이터 테스트가 통과했다. TypeScript와 변경 파일 ESLint도 통과했다. 독립 리뷰에서 완료 후 반복 조회 비용 문제를 발견·수정했고 재검토와 데스크톱 시각 검토를 통과했다. 운영 배포는 이후 완료했다.

Firebase Hosting + Functions 실제 배포 (2026-09-07 12:05 KST)

운영 주소는 rotation-meet.web.app이다. web·rotationTick·rotationMeetingCleanup3개 ACTIVE, Scheduler ENABLED, Eventarc 트리거와 Hosting FINALIZED 릴리스를 각각 실제 API로 확인했다. Rules·인덱스도 배포했다. 홈페이지·로그인·매뉴얼 HTTP200과 익명 보호 API401을 확인했다.

기존 테스트 운영자로 운영 웹 이메일 로그인 →20명 행사 조회 → 마지막10개 회의의 Google 현재 현황 조회가 성공했다. App Check·Auth·Firestore·운영 시크릿이 실제 함수 런타임에서 작동한 확인이다. 최초 App Check400/403 오류 후 설정을 약화하지 않고 새로고침했을 때 성공했으며, 초기 오류의 정확한 원인은 확정하지 않았다. 예약 함수도 실제 실행되어 오류0건을 기록했다(대상 행사0개).

OAuth 운영 반환 주소 저장은 완료했으며, 운영 웹에서 같은 Google 권한의 동의 화면까지 도달했다. 마지막 ‘허용’ 클릭은 자동 승인 검토가 별도 Google 계정 동의 승인을 요구해 거절했고 추가 답변을 기다린다. 기존 Google 연결은 유지된다. OAuth는 External/Testing 상태이고 브랜딩 정보 보완과 실제 외부 운영자 검증이 남아 있다.

기존 런타임 Editor 권한의 최소 권한 분리, 기존 App Hosting 전용 리소스 정리, 기관 관리자 승인과100개 회의/실제20인 영상·음성 검증은 남아 있다. 배포 성공과 지자체 본행사 운영 준비 완료를 구분한다.

참가자 신고의 서버 검증 보완 (2026-09-07)

신고 API에 현재 Firebase 인증·App Check, 계정 차단·행사 승인·출석과 문서 소속 검사를 적용했다. 실제 공개된 페어 이력과 진행 순서로 대상을 확인하고, 같은 만남의 중복 제출은 트랜잭션으로 한 건만 접수한다. 클라이언트의 Firestore 직접 신고 쓰기를 차단한다. 신고 접수는 자동 제재나 Meet 강제 퇴장이 아니다.

신고 창을 연 시점의 대상과 라운드를 유지하며, 마지막 만남 종료 후에도 제출·취소 전까지 작성 창을 유지한다. 행사 타이머는 계속 진행한다. 계정 변경 또는 화면 이동 후 이전 요청의 알림을 표시하지 않는다.

관련 신고·관리자 API17개 에뮬레이터 테스트가 통과했다. 6개 동시 요청→1건 접수, 잘못된 대상·미참가·미출석·미승인·차단 계정 및 위조 필드 거절, App Check와 직접 쓰기 차단을 확인했다. 독립 리뷰에서 발견한 작성 내용 소실과 이전 요청 알림 문제를 수정하고 재검토를 통과했다. 실제 웹 신고 제출·관리자 처리 캡처는 남아 있다.

지자체 소개자료의 운영 배포 반영 (2026-09-07)

10장 PDF·편집용 PPTX v4와 10분 시연 진행표를 현재 운영 배포 상태에 맞춰 갱신했다. 운영 웹에서 기존20인 전체 매칭판을 다시 캡처했고, 소개자료에는 연락처가 보이지 않는 전체 연결 화면을 사용했다. 각 장의 실제 캡처 시점·검증 근거와 남은 작업은 발표자 노트에 기록했다.

모든 PDF10장을 렌더해 확인했으며, 표3개는 PPTX에서 편집 가능한 형태로 유지했다. PDF에 Pretendard 글꼴이 포함됐는지와 운영 배포·100개 재검증·20인 실통화 미완료 문구를 확인했다. 산출물 근거는 docs/presentation/presentation-v4-evidence.json이다. 기관 승인·100개 회의·20인 양방향 통화가 남아 있으므로 본행사 운영 준비 완료 자료로 사용하지 않는다.

Mac 잠금 해제 후 실제 운영자 대시보드를 조회해 기존 두 테스트 행사가 종료 상태이며 기관 승인은 미완료임을 확인했다. 종료 행사 결과 CSV 버튼을 실행했으나 다운로드된 파일을 확인하지 못해 CSV 저장의 실제 브라우저 검증은 완료 처리하지 않았다. 기존 참가자·선택·매칭 결과는 변경하지 않았다.

실제 결과 리포트 미리보기와 CSV 복사 (2026-09-07)

운영 웹의 기존20인 행사 결과를 담당자 계정으로 열어 매칭10쌍과 참가자20명·5개 명단 열을 확인했다. 서버에서 받은 CSV 자체를 표로 표시하며 연락처와 일방 선택은 포함하지 않는다. CSV 내용 복사 후 로컬 검증본과 운영 웹의 복사 내용이 같음을 확인했다. 원본 CSV는 공개하지 않고 .local/에 보관한다.

파일을 바로 저장할 수 있는 링크와 복사 대안을 제공한다. 내장 브라우저에서는 직접 다운로드 완료 이벤트를 확인하지 못했으므로 파일 저장 완료로 기록하지 않는다. 계정·행사 변경이나 창 닫기 때 이전 결과를 폐기하며, 재개방 시 새 결과·파일 URL을 받는 것을 확인했다. 모바일390px 화면에서 표와 저장 버튼의 가로 넘침이 없었다.

CSV 파서3개 검사, TypeScript·변경 파일 ESLint·독립 코드/시각 리뷰를 통과했다. 결과 리포트와 실제 테스트 화면을 매뉴얼에 반영해 Firebase Hosting/web 함수에 배포했고 현재 web-00013-huv 버전과 매뉴얼 HTTP200·캡처 해시 일치를 확인했다. 근거는 result-report-test-evidence.json, result-report-release-evidence.json이다. 기관 승인·100개 Meet 회의 재검증·20인 실제 영상·음성은 여전히 남아 있다.