Files
hop.noname.company/docs/VERIFICATION.md

33 KiB

검증 기록

현재 적용 범위는 파일·링크 통합 수정안이다. 아래 초기 단계의 텍스트 관련 기록은 수정 이전 검증 이력이다.

Phase 1 — 2026-10-08

  • npm run build, npm run typecheck: 성공.
  • npm test: 실제 SQLite·Socket.IO 통합 테스트 21개 성공.
  • npm run test:e2e: 격리된 두 Chromium 문맥에서 코드 연결, 수락 전 본문 비공개, 실제 텍스트 전달, HTML 비실행, 읽음 동기화, 이름 재접속 유지, 다중 탭, 모바일 폭 390px 가로 넘침 없음 확인.
  • docker build -t hop-phase1-check:local .: 성공. 운영 이미지의 워크스페이스 내부 의존성 누락을 발견하여 수정 후 재빌드.
  • node tests/docker/persistence.mjs: 운영 모드 시작, Secure 쿠키, 마이그레이션, 재시작 후 세션·이름 보존, SQLite integrity check 성공. 고유 임시 컨테이너/볼륨을 생성하고 검증 후 제거. 호스트 포트는 공개하지 않음.
  • 운영 의존성 audit: 알려진 취약점 없음. Docker 빌드용 개발 의존성에서 기존 esbuild-loader 경고가 남아 있으며 운영 이미지에서는 제거됨.

실제 NAS/Nginx Proxy Manager/Cloudflare 접속 경로, 실제 스마트폰·PWA 설치는 아직 검증하지 않았다. 앱 내 브라우저 연결이 없어 별도 자동 테스트용 Chromium을 사용했다. 포트와 운영 프록시 신뢰 범위는 배포 전에 사용자에게 확인한다.

Phase 2 — 2026-10-08

  • 전체 빌드 성공. Phase 1 회귀 포함 API·Socket.IO·실제 HTTP 업로드 테스트 32개 성공.
  • 수락 전 업로드 금지, 실제 파일 다운로드와 권한 격리, 메타데이터 불일치·부분 실패 재시도, 원자적 전체/개별 용량 예약, 이미지 미리보기·SVG 차단, 5초 복원·마지막 접근권 정리, 업로드 확정 중복·payload 충돌 확인.
  • 실제 HTTP 업로드를 중단하여 임시 파일·예약 회수 확인.
  • 두 Chromium 문맥에서 실제 파일 전달·다운로드, 모바일 크기에서 합성 터치 포인터로 가로/세로 의도 구분·밀기만으로 삭제되지 않음·삭제 버튼·실행 취소·서버 실패 선택 복구 확인. 실물 스마트폰 제스처 확인은 별도 필요.
  • Phase 1 본문과 접근권이 있는 DB를 Phase 2로 마이그레이션하여 데이터와 외래 키 유지 확인. SQLite 테이블 재구성은 전체 마이그레이션 트랜잭션 안에서 참조 검사를 통과해야 커밋함.
  • docker build -t hop-phase2-check:local ., HOP_CHECK_IMAGE=hop-phase2-check:local node tests/docker/persistence.mjs: 운영 모드와 실제 파일 업로드 후 재시작·다운로드 보존 성공. 호스트 포트 미공개.

사용자 결정: Phase 3 계정 저장은 기존 익명 접근권을 제거하는 이동 방식. 원래 만료와 상대 접근권은 유지.

Phase 3 — 진행 중, 2026-10-08

  • 기존 단계 회귀 포함 DB·API 테스트 44개 성공. Argon2id, 인증 전 권한 차단, 토큰 해시·일회용, 로그인 회전, 비밀번호 재설정 세션 폐기, 낯선 발신자 수락, 허용 발신자의 오프라인 전달, 자기 보관함, 차단 우선, 계정 파일 용량·다운로드, 익명 접근권의 계정 이동과 파일 소유 용량 이동 확인.
  • 실제 Chromium 두 문맥에서 가입·토큰 인증·로그인·원격 요청 수락과 실제 전달·읽음 동기화·즐겨찾기·삭제/복원·자기 보관함·로그아웃 화면 정리 확인. 메일은 테스트 내 수집 어댑터를 사용하며 실제 Resend 발송 성공을 뜻하지 않음.
  • 전체 빌드·타입 검사 성공. 계정 확장을 적용한 뒤 Phase 1·2 API 회귀도 유지.
  • 실제 Resend 발송 어댑터는 사용자 기존 코드 위치 또는 API 규격 확인을 기다림. 이 연결 전 Phase 3 완료로 처리하지 않으며 Phase 4로 넘어가지 않음.
  • 현재 개발 QR의 loopback 주소는 휴대폰에서 PC로 접속할 수 없으므로 UI와 README에 안내. 개발 포트는 OS가 배정하고 서버 자동 재시작 중에는 유지. 실제 LAN·공개 HTTPS 검증은 미실시.

개발 DB에서 이전 계정 마이그레이션이 이미 적용된 버전 차이를 확인했다. 정확한 기존 버전만 후속 0005 마이그레이션으로 보정하고 원래 마이그레이션 기록을 유지한다. 실제 개발 DB의 integrity check ok, 외래 키 오류 0, 서버 정상 시작과 고정된 임시 포트에서 재시작을 확인했다. 동일 상태를 재현한 보존 테스트를 추가하여 44개 테스트 모두 통과했다. 데이터·캐시 폴더는 서버 코드 감시에서 제외하여 불필요한 재시작을 방지했다.

최종 현재 코드의 Docker 이미지 hop-phase3-check:local 빌드 및 익명 세션·이름·실제 파일 업로드/다운로드의 재시작 보존 검증도 성공했다. 이는 계정 Resend 발송 검증은 포함하지 않는다. npm audit --omit=dev 결과 운영 의존성의 알려진 취약점 0건. 로컬 Docker는 개발 Mac의 ARM64 환경이며 실제 AMD64 NAS·프록시 경로 검증은 배포 단계에서 별도 수행한다.

파일·URL 통합 UX 수정 — 2026-10-08

  • 일반 텍스트 신규 요청·확정을 제거하고 API 거절 테스트 추가. 파일·URL만 현재 목록과 요청에 표시. 기존 저장 DB 기록은 보존하며 진행 중 텍스트 요청은 0006 마이그레이션으로 취소.
  • 파일·링크 유형 탭 제거. 기기 선택 시 클립보드 URL 제안, 권한 거부·일반 텍스트 무시, 파일 선택·드래그 앤 드롭 유지, 링크 직접 붙여넣기 확인. 읽기만으로 전송 요청이 생성되지 않는 것을 실제 브라우저에서 확인.
  • 지연된 과거 snapshot 응답이 수락 이벤트와 겹치는 경우를 재현하여 후속 조회와 실제 전달 성공 확인. 단일 snapshot API로 상태를 일관되게 읽고 중복 조회가 요청 제한을 소진하는 문제 수정.
  • 수신·받는 중·도착 카드를 뷰포트 상단에 고정. 자료 보기는 해당 묶음으로 이동. 하단 삭제 실행 취소와 겹치지 않음 확인.
  • 기본 검정·중립 회색·흰색 버튼, 라이트·시스템 테마 및 이전 기본 설정 전환 확인. 네이티브 업로드 진행률도 중립 색상으로 표시.
  • npm run build, npm run typecheck, npm test 50개 성공. 실제 브라우저 즉석 전송과 계정 전송 회귀 성공. 클립보드 거부 상태의 실제 파일 드래그 업로드·다운로드, 복수 URL 전달, 재연결·CSRF 재확인 후 기기 이름 변경 확인.
  • docker build -t hop-ux-check:local ., HOP_CHECK_IMAGE=hop-ux-check:local node tests/docker/persistence.mjs: 운영 모드·마이그레이션·재시작 후 익명 세션/이름/파일 보존 성공. 호스트 포트 미공개.
  • Resend HTTPS 발송 어댑터와 실패/중복 요청 계약 테스트 완료. .env의 키 설정 여부만 확인했으며 실제 키를 출력하지 않음. 실제 수신 검증은 사용자 테스트 주소 확인을 기다리고 있고, 실제 이메일 발송 성공으로 주장하지 않음.
  • Android PWA Web Share Target는 사용자 지정 2차 구현 범위. 실물 스마트폰 클립보드·공유 메뉴 검증은 아직 하지 않음.

기기 카드·링크 열기·JavaScript 전환 1단계 — 2026-10-12

  • 중복 참여자 목록을 제거하고 큰 기기 카드에 HOST 표시와 방장용 더보기 메뉴를 통합. 승인·빨간색 내보내기, 메뉴 외부 클릭·Escape 닫기, 양쪽 브라우저의 퇴출 반영 및 모바일 화면 검증 성공.
  • 수신 URL을 직접 클릭하는 네이티브 새 탭 링크로 변경. 도착 알림과 익명·계정 목록에서 실제 목적지 새 탭 열기 및 opener 격리 검증 성공.
  • Vue 컴포넌트는 유지하고 모든 프런트엔드 script setup, 클라이언트·테마·조회 큐·진입점·Vite 설정을 JavaScript로 전환. 웹 tsconfig와 vue-tsc, @types/qrcode 직접 의존성 제거. 서버와 공통 모듈의 TypeScript는 다음 전환 단계까지 유지.
  • 전체 빌드와 남은 서버·공통 모듈 타입 검사 성공. 실제 로컬 서버 실행 권한으로 API 회귀 테스트 50개 성공. 익명 전송·계정 전송·기기 메뉴의 Chromium 자동 테스트 3개 스위트 성공.
  • 실제 Resend 수신, 실물 모바일 기기, 운영 NAS 배포는 이번 검증에 포함하지 않음.

수락 후 자동 실행·같은 자리 취소·개발 계정 — 2026-10-12

  • 수락 클릭 시 링크 탭을 준비하고 전달 완료 시 실제 URL로 이동. 파일은 수락한 탭에서 자동 다운로드하며 실제 파일 내용 일치 확인. 도착 안내와 추가 열기 확인 제거. 탭 차단 시에만 수동 열기 예외 안내 검증.
  • 한 개·여러 URL의 실제 자동 새 탭 이동, opener 제거, 읽음 동기화, 새로고침 후 과거 자료 재실행 없음 확인. 지연된 과거 조회와 수락 이벤트가 겹치는 회귀도 유지.
  • 비로그인 이번 기기 메뉴·목록 제거. 전송 버튼 자리에서 링크·파일 요청 취소, 업로드 시작 후 취소 확인. 서버 취소 상태가 API 응답보다 먼저 도착하는 경우에도 의도한 취소를 업로드 오류로 표시하지 않도록 수정.
  • 수락 팝업의 흰색 배경과 뷰포트 중앙 위치를 모바일에서 검사하고 화면 이미지 확인. 검정·라이트 테마, 기기 관리와 계정 보관함 기능 유지.
  • 개발·테스트 비밀번호 최소 1자, 운영 최소 12자 적용. 서버가 제공하는 최소 길이에 맞춰 가입·재설정 화면 갱신. 운영에서 짧은 새 비밀번호 거절 테스트 성공.
  • 실제 개발 DB에 일반 사용자 test1@hop.test, test2@hop.test 생성. 둘 다 1234로 로그인 검증, active·인증 완료 상태 확인. 실제 메일은 발송하지 않음. DB integrity ok, 외래 키 오류 0.
  • 전체 빌드·남은 타입 검사·API 테스트 51개 성공. 익명 전송·1234를 사용하는 실제 가입/인증/로그인과 계정 전송·기기 메뉴 Chromium 스위트 성공. 실제 Resend 수신·실물 모바일의 브라우저별 자동 다운로드 권한은 별도 검증 필요.

기기 중심 단일 화면·단일 콘텐츠·7일 보관함 — 2026-10-12

  • 메인은 기기 카드와 QR 카드를 함께 보여주는 중앙 화면. 내 기기의 이름·발견 상태·설정은 푸터로 이동. 자연스러운 스크롤과 짧은 화면에서 하단 배치, 작은 헤더 로고·보조 문구, 푸터의 서버 경유 문구 제거.
  • 실제 12개 Socket.IO 기기와 브라우저를 연결해 PC 4열·태블릿 3열·모바일 2열과 줄바꿈 검증. 선택 전 전송 입력 없음, 선택 후 PC 중앙 모달·모바일 하단 시트, Escape와 포커스 순환 확인. 화면 이미지 직접 확인.
  • 클립보드 URL이 기본 콘텐츠이고 실제 파일 선택이 URL을 대체. 파일/URL/로그인 보관함 메뉴를 바꿔도 모달의 너비·높이가 동일하고 콘텐츠 내부만 스크롤. 전송/취소 버튼은 한 개. 빈 클립보드·직접 URL 입력, 페이지 복귀·재선택·가져오기 갱신, 드래그 업로드, 브라우저 차단 예외 확인.
  • 보관함 선택은 미리보기만 변경하며 단일 전송 버튼에서 요청 생성. 직접 저장과 받은 항목의 본인 자료를 전송 소스로 제공. 실제 저장 파일 재업로드 없이 수락 후 원본 다운로드 바이트 일치 검증.
  • 로그인 중 수신만 계정에 날짜별 기록. 로그인 전 자료 사후 가져오기 제거, logout 전후 세션 경계 확인. 직접 저장의 메모·수정·검색, 7일 만료·실제 항목 삭제와 마지막 원본 참조 정리, 영구 즐겨찾기 우회 제거.
  • 한 기기 한 방의 DB 유일 제약, 승인 대기도 주변에서 격리, 방 생성/다른 방 참여 거절, QR 참여 시 초대·참여 모달 자동 닫기, 방장 나가기의 전체 종료·진행 중 전송 취소, 주변 복귀 확인.
  • 마이그레이션 보존·7일 상한 테스트 성공. 실제 개발 DB 백업 후 마이그레이션 확인: integrity ok, 외래 키 오류 0, 기존 테스트 계정 2개 유지.
  • 전체 빌드·남은 서버/공통 모듈 타입 검사 성공. API 회귀 59개 성공. 익명 전송·계정/보관함·기기 관리·레이아웃의 Chromium 스위트 성공.
  • hop-temporary-vault-check:local 운영 이미지 빌드와 격리 컨테이너의 마이그레이션·Secure 쿠키·세션/이름/실제 파일 재시작 보존 검증. 호스트 포트는 공개하지 않음.
  • 실제 Resend 수신, 실물 iOS/Android의 브라우저별 권한, 운영 NAS·프록시·실제 LAN 경로는 이번 자동 검증에 포함하지 않음.

NAS 업데이트·분할 업로드·PWA·개인 한도 — 2026-10-12

  • API 테스트 67개 통과. 신뢰한 프록시의 CF-Connecting-IP 기준 자동 발견, 실제 소켓의 같은/다른 공인 IP 격리와 발견 해제, 보호된 운영 진단을 검증했다.
  • 8MiB 조각의 수락·발신자·Origin·CSRF 검사, 중복·순서·전체 내용 검증, 이어 받는 위치와 중단 쓰기 복구·만료·취소 정리 검증. 기존 업로드 API는 유지했다.
  • Chromium의 익명 전송·계정 보관함·기기 메뉴·레이아웃·대용량 분할·PWA 스위트 통과. 실제 101MiB 파일을 전송하고 응답 유실·재시도 소진 후 같은 버튼에서 이어 보내기·수락 후 자동 다운로드·최종 바이트를 확인했다.
  • PWA manifest·PNG 아이콘·실제 Service Worker·iPhone 설치 안내·설치 이벤트·설치 후 숨김·320px 헤더·오프라인 안내·민감한 데이터 캐시 없음 검증. 실제 OS 설치와 실물 Safari/Android는 사용자 기기에서 확인해야 한다.
  • 개인 보관함 2GiB의 직접 저장·받은 파일 합산, 다른 계정 격리, 한도 초과 수신의 다운로드 유지·계정 기록 생략, 삭제 후 공간 회수·초과 복원 거절을 확인했다.
  • 전체 빌드와 남은 타입 검사 통과. 운영 Docker 이미지 빌드와 재시작 후 SQLite integrity·세션·기기명·기존 파일·미완료 업로드 조각의 위치 보존 및 이어 보내기 완료 검증. 실제 NAS·Cloudflare·NPM 경로 활성화는 deploy.md의 운영 진단으로 수행한다.

2026-10-12 위치 검색과 접속 상태 UI 업데이트

  • 전체 빌드와 남은 타입 검사 통과. API 테스트 73개 통과.
  • 양쪽 위치 동의·100m 반경·좌표 오차/유효성·여러 탭·만료·발견 허용 끄기·방 격리·기존 접근 경계·수락 직전 위치 해제를 검사했다. 위치는 서버 메모리에만 저장한다.
  • 실제 Chrome 브라우저에서 위치 권한 허용 후 별도 검색 버튼·거리 안내 없이 자동 발견, 대기 중 반복 API 요청 없음, 모바일·탭 숨김 후 위치 삭제/복귀, 거리 밖 제외·권한 거절 후 반복 요청 없음, 수락 후 링크 자동 열기를 검증했다. 좌표는 테스트 브라우저의 위치 시뮬레이션을 사용했으며 실제 NAS 주변 GPS 환경은 배포 후 확인해야 한다.
  • 별도 브라우저 검증에서 새 기기 이벤트 후 서버 조회를 지연시켜 카드 스켈레톤을 확인하고, 정보 도착 후 실제 카드로 교체·직접 지정한 이름 우선·모델별 이름·제조사 제한 추정·연결 해제 애니메이션·메타데이터 정리를 검사했다. 기기 12대의 4/3/2열 반응형과 빈 화면도 확인했다.
  • 기존 브라우저 테스트 5종(익명 전송, 계정 보관함, 방 기기 관리, 분할 업로드, PWA) 모두 통과했다. 수락 팝업·자동 열기/다운로드·재시도·7일 보관·2GiB 용량 경계는 유지한다.
  • 운영 Docker 이미지 빌드 및 재시작 후 SQLite integrity·세션·기기명·파일·미완료 분할 업로드 복구 테스트 통과. 화면 정리 이후에도 같은 검증을 완료했다.
  • NAS 업데이트 순서는 deploy.md에 기록했다. 새 도메인·포트는 필요 없고 실제 NAS에 대한 원격 배포는 수행하지 않았다.

2026-10-12 연결 모달과 모바일 입력 업데이트

  • 새 연결 모달은 만들기/참여하기 선택 → 각각의 화면으로 이동한다. 승인 옵션은 만들기 화면에만 표시하고 QR 아래 개발 주소 설명을 제거했다. 코드·유효 시간·복사 버튼을 표시한다.

  • 기본 4자리 코드와 설정 변경 후 6자리 발급, 기존 8자리 초대 참여, 충돌 재생성과 재시도 제한을 검증했다. 기존 유일한 코드 해시 제약과 참여 시도 제한을 유지하며 DB 마이그레이션은 추가하지 않았다.

  • 전체 빌드·타입 검사, API 테스트 75개 통과. 기존 브라우저 7종 모두 통과.

  • 브라우저에서 연결 선택 화면의 두 행동 분리, 승인 옵션 이동, 4자리 입력 검사, 초대 코드·QR 생성과 참여 시 자동 닫힘을 검증했다.

  • 모바일 파일 업로드를 실제 진행하면서 파일명이 한 번만 표시되고 바로 아래 진행률 바가 나오며 중복 진행 문구가 없는지 확인했다. 취소·재시도·복수 파일의 전송 인덱스는 유지한다.

  • 모바일 로그인 이메일/비밀번호·기기 이름의 실제 계산된 글자 크기 16px, 가로 넘침 없음, 설정 시트의 하단 배치·자동 포커스 없음, 키보드 가시 영역을 줄였을 때 높이 조정을 검증했다. 실제 iPhone Safari 키보드·자동 확대는 사용자 기기에서 최종 확인해야 한다.

  • 최신 Docker 이미지 빌드 및 재시작 후 DB·파일·세션·미완료 분할 업로드 복구 검증 통과. NAS 원격 배포는 수행하지 않았다.

  • 헤더 보조 기능은 로그인/보관함 뒤 더보기로 모았다. 메뉴의 앱 설치·테마·서비스 정보, 바깥 클릭/Escape 닫힘과 방향키 이동, 모바일 메뉴 경계를 검증했다. 메뉴가 닫혀도 설치 이벤트 수신을 유지해 PWA 설치 기능이 사라지지 않도록 했다.

  • 서비스 정보는 hop. 제목을 유지하고 운영체제 설명과 아이콘 목록으로 정리했다. 제작사명은 왼쪽, 웹 패키지 버전(v0.1.0)은 오른쪽에 표시한다. PC·모바일 화면을 확인했다. 연결 참여/만들기 폼의 설명 여백과 간격을 줄이고 기기 카드의 온라인 표시는 제거했으며 승인 대기 표시는 유지했다.

  • 기기 목록의 수동 새로고침 버튼을 제거했다. 접속 이벤트에 따른 목록 자동 갱신은 유지한다. 사용자가 수정한 헤더 버튼 간격과 서비스 정보 줄 간격도 함께 반영했다.

2026-10-12 사용자 로고·아이콘과 기기 설정 마무리

  • 사용자가 넣은 logo.svg를 헤더와 서비스 정보에 적용했다. 폰트 대신 SVG 경로를 사용하고 흰 글자를 테마 색상으로 바꾸며 청록색 점은 유지한다. 동시에 표시되는 SVG clipPath ID도 분리한다.
  • 새 icon.svg로 192px·512px PNG와 Android maskable PNG를 재생성했다. maskable은 중앙 안전 영역에 글자와 점이 들어오도록 여백을 넣는다. 재생성 스크립트를 추가했다.
  • 발견 허용은 실제 체크박스 입력과 switch 역할을 유지한 Tailwind 토글로 표시한다. 키보드 포커스·비활성·동작 줄이기 상태를 지원하고 아래 구분선을 제거했다.
  • 이름 저장 버튼은 ‘저장’으로 변경하고 입력창과 44px 높이·둥근 모서리를 맞췄다. PC 폼의 이전 30px 고정 높이를 없애 제목과 입력창이 겹치지 않도록 했다.
  • 전체 빌드, PC/모바일 레이아웃·테마별 로고 색·기기명 유지·토글 및 방 관리·파일/링크 전송·PWA 브라우저 검증을 통과했다. PNG 크기·청록색 점 보존과 maskable의 불투명 배경·중앙 안전 영역도 확인했다. 실제 Galaxy/iPhone의 설치 아이콘 반영은 운영 재배포 후 확인한다.

2026-10-13 클립보드 텍스트 확장

  • 기존 URL/파일 API와 DB 텍스트 컬럼을 재사용해 텍스트 요청·수락 후 확정·조회·계정 기록·보관함 저장/재전송을 확장했다. 마이그레이션이나 텍스트용 파일 생성은 없다. UTF-8 기준 기본 한도는 사용자 선택대로 256KiB다.
  • API 테스트 80개 통과: 수락 전 비공개, 발신자/수신자 접근 격리, 원문과 CRLF·공백·한글·일본어·이모지 보존, 256KiB 경계, 본문 타입/크기 변경, 빈 내용, 멱등성, 7일 기록·검색·재전송·만료를 검사했다.
  • 새 두 브라우저 테스트에서 단일 URL·www 주소는 링크로 열고, 일반 문장·여러 줄·여러 URL·URL 포함 문장·장문은 텍스트 미리보기와 복사로 처리했다. 미리보기 스크롤·복사 피드백·HTML 이스케이프·입력 중 포커스/클립보드 변화 보존·명시적 다시 읽기·빈/거절된 클립보드·직접 입력·URL/텍스트 전환·크기 제한을 검증했다.
  • 초기 스켈레톤과 안내 문구 사이 간격, 기기명 현재/최대 40자 표시, 카드 텍스트 선택 방지와 모바일/미지원 브라우저에서 의도하지 않은 클립보드 읽기 방지를 검증했다. Safari의 네이티브 붙여넣기 확인은 공식 WebKit 동작을 참고했으며 실제 기기 확인은 운영 재배포 후 진행한다.
  • 기존 복수 URL API·수락 후 자동 탭 열기·파일 자동 다운로드·101MiB 조각 업로드·계정 보관함·방 승인/내보내기·PWA·위치 자동 발견의 회귀 검증을 통과했다. 운영 Docker 이미지 빌드와 재시작 뒤 원문 유니코드 텍스트·DB·파일·미완료 조각 업로드 보존 및 이어 보내기를 확인했다.

2026-10-13 보관함과 계정 설정 정리

  • 보관함 진입·로그인 후 받은 항목을 기본 선택하고, 제목 아래 중복 안내를 제거했다. 하단 용량 안내에 항목별 최대 7일 보관을 표시한다.
  • 이메일·비밀번호 항목별 변경 버튼으로 해당 폼에 진입한다. PC 중앙 모달·모바일 하단 시트, 제목/입력 간격·가로 넘침 없음·모바일 16px 입력·자동 키보드 포커스 없음·뒤로가기/닫기 시 비밀 초안 제거·Escape/Tab 포커스 유지 등을 실제 Chromium 브라우저로 확인했다. 실제 휴대폰 Safari 키보드는 운영 재배포 후 확인한다.
  • 내 기기 설정의 발견 허용 스위치를 제거했다. 이전 버전에서 발견을 꺼둔 세션도 재접속 시 켜지며 기기 ID·저장한 이름을 유지하는지 검증했다. 기존 서버의 접근 제어·방 격리와 발견 차단 API는 유지한다.
  • 전체 빌드·타입 검사와 API 테스트 80개 통과. 계정 보관함·반응형 레이아웃·익명 파일/링크 전송·클립보드 텍스트·위치 자동 발견 브라우저 검증 5종을 통과했다. 실제 계정 메일은 테스트 메일러로 검증하며 외부 Resend 발송은 수행하지 않았다.
  • 파일 원본·조각·DB의 영구 볼륨 위치, 다운로드 실패·사이트 이탈, 마지막 유효 참조가 끝난 뒤 원본 정리와 관리자 접근 범위를 구현 코드로 확인해 deploy.md에 기록했다. 파일 보관 정책·DB 구조·YAML·환경변수는 변경하지 않았다. NAS 원격 배포는 수행하지 않았다.

2026-10-13 공유 폴더 저장·수동 삭제 대비와 안내 정리

  • 파일을 프로젝트의 uploads 바인드 마운트에 저장하며 Git·Docker 빌드에서 제외한다. NAS 로그인 사용자의 UID/GID로 앱을 실행하고 소유자 전용 저장 권한을 준비한다. DB 볼륨에는 Compose 라벨과 nocopy를 적용해 처음 만든 빈 볼륨의 소유권을 유지한다. 실행 중인 프로젝트의 권한 변경과 이전 업로드 볼륨을 연결한 상태의 전환은 설정 스크립트에서 거절한다.
  • 사용자 요청대로 기존 NAS 테스트 자료를 복사하지 않는 최초 초기화 절차를 deploy.md 7-1에 기록했다. .env는 유지하며 설정 스크립트 자체는 데이터를 삭제하지 않는다. 초기화 명령은 NAS에서 사용자가 실행해야 하고 이후 코드 업데이트에서는 반복하지 않는다.
  • 수동 삭제 검증 8개를 추가해 API 총 88개를 통과했다. 조회·개인 용량·다운로드·1분 정리 작업으로 사라진 원본을 감지하며 공유된 모든 항목의 만료·용량 회수·정상 파일/링크 및 페이지 유지·소켓 알림·수락 대기 취소를 확인했다. 멱등 트랜잭션 실패/롤백 후에도 정리를 유지하고 다운로드 직전 삭제는 404, 권한 오류는 기록을 유지한 503으로 처리한다.
  • 계정 브라우저 검증에서 NAS 저장소에 해당하는 실제 서버 원본을 삭제한 뒤 다운로드 전 안내·양쪽 보관함과 사용량 정리·다른 기기의 열린 전송 선택 해제·전송 버튼 비활성화를 확인했다. 기존 저장·메모·삭제/복원·수락 후 자동 열기/다운로드·로그아웃 권한 격리는 유지한다.
  • 오류 토스트의 좌우 여백·텍스트/아이콘 중앙 정렬·44px 닫기 버튼·5초 자동 닫힘, 모바일 네트워크 실패의 한국어 안내와 수동 닫힘을 실제 Chromium에서 확인했다. 링크 수신 안내도 5초 뒤 닫히고 새 전송 모달을 가리지 않는다. 이메일 변경 버튼은 숨기고 받은 항목/임시 저장 탭 순서와 보관 만료 날짜 문구를 정리했다.
  • 전체 빌드·타입 검사, 계정·반응형 레이아웃·익명 파일/링크·클립보드 텍스트 브라우저 검증을 통과했다. 운영 Docker 이미지 빌드, 기본 UID와 다른 NAS UID/GID를 사용하는 실제 격리 Compose 시작/health·영구 DB·호스트 바인드 마운트·공개 호스트 포트 없음, 재시작 뒤 파일/텍스트/세션 보존과 8MiB 미완료 조각 이어 보내기·SQLite integrity·호스트 파일 삭제를 확인했다. 실제 NAS·파일 관리자·실물 Safari의 확인과 재배포는 수행하지 않았다.

2026-10-13 가입 8자 기준과 인증 자동 로그인

  • 새 비밀번호 최소 길이는 공유 상수 8자로 통일했다. 가입·재설정·변경의 서버 검사와 화면 안내에 같은 기준을 적용하고 기존 짧은 비밀번호 로그인은 유지한다. 개발 시드와 테스트 가입 데이터도 8자로 맞췄으며 실제 기존 개발 DB를 변경하거나 메일을 보내지는 않았다.
  • 인증 토큰 소비·계정 활성화·새 세션 발급·현재 브라우저의 이전 세션 취소를 같은 트랜잭션으로 처리한다. 성공 후 이전 세션의 업로드·소켓 구독을 정리하고 보호된 계정 쿠키를 설정한다. 다른 기기의 이전 계정 세션은 유지한다. 인증 화면에서는 개인 초안을 지우고 해당 계정으로 접속해 받은 항목을 표시한다.
  • 새 인증 테스트 10개를 포함한 API 총 98개 통과. 7자 거절/8자 허용, 자동 로그인·HttpOnly/Secure/SameSite 쿠키, 게스트 기기 유지, 이전 쿠키·소켓 무효화와 보관함 격리, 다른 기기 세션 유지, 만료·미등록·정지·삭제 계정·동시/재사용 토큰 거절, 세션 발급 실패 시 전체 롤백과 재시도를 확인했다. 기존 오프라인 검사는 35ms 대기 전에 실제 서버의 소켓 종료를 기다리도록 안정화했다.
  • PC/모바일 실제 Chromium에서 7자 가입 차단·8자 가입·인증 후 추가 로그인 없이 보관함 진입을 확인했다. 다른 계정의 인증 링크를 같은 브라우저에서 열고 인증한 계정으로 전환·이전 쿠키 401·기존 자료 미노출·인증 토큰의 주소창 제거를 확인했다. 지연된 이전 계정 조회를 재현하고 순차 조회 큐가 최종 계정을 유지하는지 검사했다. 기존 보관함·수동 파일 삭제·익명 파일/링크 전송도 통과했다.
  • 전체 빌드·타입 검사와 운영 Docker 빌드를 통과했다. 격리한 운영 컨테이너에서도 보호된 인증 쿠키·자동 로그인·이전 세션 무효화·토큰 재사용 거절·재시작 후 로그인 유지, 기존 파일/텍스트 보존·조각 이어 보내기·SQLite integrity를 확인했다. Docker 인증 토큰은 테스트 DB에 생성한 것으로 실제 Resend 발송과 NAS 배포는 수행하지 않았다. 코드 업데이트에 DB 초기화·YAML 재생성은 필요 없다.

2026-10-14 운영 Compose 파일 통합

  • Git에서 관리하는 docker-compose.yaml 하나로 통합했다. 중복 설정 파일을 제거하고 설정·자동 발견 스크립트와 배포 문서에서 같은 파일을 사용한다. 초기 설정은 .env와 저장 권한만 준비하며 Compose 파일의 내용을 변경하지 않는다.
  • 현재 NAS 값으로 이전 설정과 새 파일을 실제 Docker Compose로 해석해 전체 설정이 동일한지 비교했다. 프로젝트 hop, 컨테이너 hop, 네트워크 hop_hop_network, DB hop_hop_database, 사용자 1000:10, 포트 192.168.50.146:50189:50189, 빌드 정책, 소스·환경파일·업로드 경로와 재시작·로그 설정이 동일했다. 새 파일은 name: hop으로 별도 -p 없이 기존 프로젝트를 지정한다.
  • NAS 설정 검증에서 Compose 파일 미변경, 비밀값 유지, 환경파일 권한, 기존 저장소 식별자, nocopy, 실행 중 권한 변경 거절을 확인했다. 기존 운영 이미지로 격리한 실제 Compose 컨테이너를 시작해 health, UID/GID, 임시 DB 볼륨과 업로드 바인드 연결을 확인하고 테스트 자원을 정리했다. 셸 문법·포맷 검사도 통과했다. 운영 NAS의 컨테이너·볼륨·자료에는 접근하거나 재배포하지 않았다.

2026-10-14 전송 제한 안내와 수신 화면

  • 기본 전송 한도를 상대 10회·기기 세션 30회·IP 120회/분으로 확대했다. 거절 후 300초 대기는 유지한다. 제한 응답에 Retry-After와 남은 시간을 제공하고 전송 버튼에 카운트를 표시하며 대기 중 입력·파일 선택을 유지한다. 여러 제한을 함께 확인하여 제한된 재시도가 다른 한도를 소모하거나 기존 창의 종료 시간을 연장하지 않도록 했다. 기존 NAS의 명시적인 .env 값은 유지하므로 이전 기본값만 변경하는 명령을 deploy.md에 기록했다.
  • 수신 카드에 유형별 아이콘·제목, 수락/거절 2:1 버튼, 오른쪽 하단 차단 확인을 적용했다. 현재 기기만 자신의 차단 목록을 조회·해제할 수 있으며 해제해도 이전 요청은 되살리지 않는다. 수신 파일 목록의 기본 들여쓰기를 제거하고 0.1MB 이상은 MB·1GB 이상은 GB로 표시하며 한 파일의 용량을 중복 표시하지 않는다. 기기 이름 관련 안내 문구는 제거했다.
  • API 102개 통과. 새 검증에서 실제 제한 응답의 종료 시간·헤더, 반복 재시도의 다른 한도 보존, 거절 대기, 차단 목록 비공개·다른 기기의 해제 불가·해제 후 재전송과 기존 요청 재수락 불가를 확인했다. 전체 빌드·타입 검사와 기존 파일/링크·클립보드·반응형 레이아웃 브라우저 검증도 통과했다.
  • 새 실제 Chromium 검증에서 모바일/PC 버튼 비율, 파일 용량 0.1/1.3MB·1.7GB, 파일 목록 여백·가로 넘침 없음, 초안 유지·카운트 종료 후 재활성화, 차단 확인 취소·실행·관리 화면 해제를 확인하고 스크린샷을 확인했다. 브라우저 카운트 검사는 3초 제한 응답을 주입했고 실제 60초 제한·서버 권한은 API 테스트로 검증했다. NAS 재배포와 실물 Safari 검증은 수행하지 않았다.

2026-10-14 완료 파일 분류와 원래 확장자

  • 사용자가 선택한 대로 보관함에 연결되지 않은 파일은 수신자에게 다운로드 응답을 끝낸 뒤 uploads/completed로 옮기고 기존 7일 만료일을 유지한다. 보관함·실행 취소 가능한 계정 참조가 있으면 originals에 유지하며 복원된 참조는 정리 시 원래 폴더로 돌린다. 파일 ID·접근권·원래 다운로드 이름·개인 및 익명 용량 계산은 그대로 사용한다.
  • 물리 파일명에 안전한 원래 확장자를 붙이며 확장자 없는 기존 파일은 앱 시작 시 DB와 함께 변경한다. 이동은 진행 중 다운로드·이미지 미리보기가 종료될 때까지 미룬다. DB 변경 실패 시 파일을 원래 경로로 돌리고, 이동 기록으로 재시작 중 경로 불일치를 복구한다. 기존 다운로드 완료 여부는 소급 추정하지 않는다. 두 폴더에 수동 삭제 감지·기존 만료 및 고아 파일 정리를 적용했다.
  • API 총 112개 통과. 새 실제 파일 검사 10개로 로그인 발신→익명 수신 완료 분류·익명 발신→로그인 수신 보관함 유지·재다운로드·만료일과 체크섬 보존·권한 없는 읽기 및 발신자 읽기의 분류 제외·동시 읽기·HTTP 중도 종료·기존 확장자 이전·DB 실패 롤백·계정 삭제 실행 취소와 복원·재시작 복구·수동 삭제·자연 만료를 확인했다. 전체 빌드·타입 검사·포맷 및 셸 문법 검사도 통과했다.
  • 기존 익명 파일/링크 전송 및 PC/모바일 보관함·파일 재전송·수동 원본 삭제 브라우저 검증을 통과했다. 새 운영 Docker 이미지와 격리한 임시 DB 볼륨·바인드 업로드에서 완료 폴더와 .txt 확장자, 재시작 후 기존 주소 다운로드, 8MiB 조각 이어 보내기, Unicode 텍스트·세션 보존, SQLite integrity, 완료 폴더의 호스트 수동 삭제를 확인했다. NAS 설정 검사도 통과했고 docker-compose.yaml은 변경하지 않았다. 실제 NAS 재배포는 수행하지 않았다.