업데이트 기록

# 린클로그 업데이트 기록

날짜는 한국 시간 기준이다. 이후 수정·배포마다 새 항목을 추가한다.

## 2026-09-17 — 업데이트 기록 관리 시작
- 사용자 요청에 따라 AGENTS.md에 매 업데이트 기록 의무와 NAS 배포 주의를 저장.
- 변경 파일: AGENTS.md, CHANGELOG.md.
- 상태: 로컬 작업 지침 작성 완료. 서비스 코드 변경 및 재시작 없음.

## 2026-09-17 — 전체 점검 및 안정성 수정
- DB 연결 명시적 종료, 최근 기록 조회용 복합 인덱스 추가.
- 텔레그램 커서 경계의 날빠 중복 집계 방지.
- 구간 화면의 레벨업 전후 %p 계산 수정.
- 일일 보고 완료 후 불필요한 통계 조회 방지, 폐기되던 중복 계산 제거.
- 변경 파일: work/source/app.py, work/audit/digest.py 및 관련 테스트.
- 검증: 테스트 스크립트 11개, 운영 데이터 기반 화면/API 10개 성공. 운영 DB quick_check와 백업 임시 복원 integrity_check 정상.
- 배포: NAS app.py 및 telegram-capture/digest.py 반영 완료. 대시보드만 재시작.
- 반영 후 측정: 지 현황 1.43초, 구간 0.92초. 측정 시점과 부하에 따라 달라질 수 있음.
- 남은 제한: 브라우저만 교체하는 프로젝트 업데이트 후에는 해당 수집기를 재생성해야 함.
- 상세: work/audit/REVIEW-2026-09-17.md.

## 2026-09-17 — 화면 계산 성능 개선
- 아이템 기록 해석 결과를 용량 제한 캐시에 저장하고 요청 안에서 중복 계산을 공유.
- 변경 파일: work/source/app.py 및 캐시 검증 테스트.
- 검증: 변경 전후 출력 일치, 변경 데이터 반영, 동시 요청 격리 확인.
- 배포: NAS 반영 완료. 대시보드만 재시작, 브라우저·수집기 유지.

## 2026-09-17 — 프로젝트 업데이트 후 수집기 복구
- 브라우저 2·3 교체 후 수집기가 이전 네트워크에 남아 연결에 실패하는 원인 확인.
- 조치: 기존 linclog-standalone 프로젝트의 collector2·collector3만 재생성.
- 검증: 륻·지 스냅샷 저장 성공, 용 정상 수집 유지, 중복 없이 총 8개 컨테이너 실행.


## 2026-09-17 — 운영 편의 기능 3종
- `/updates` 업데이트 기록, `/collection-check` 수집 상태 점검 버튼, NAS `recover-collectors.py` 추가.
- 복구 명령은 브라우저 ID와 수집기 네트워크를 비교해 문제 있는 수집기만 재생성하고 새 스냅샷 저장을 확인한다. --check는 읽기 전용.
- 변경 파일: work/source/app.py, work/source/recover-collectors.py, AGENTS.md, CHANGELOG.md.
- 검증: 신규 3개 경로 응답, HTML 안전 표시, 미연결 표시, 네트워크 불일치 감지, 점검 모드 비변경, 정상 상태 무변경 테스트 통과.
- 배포 상태: 로컬 구현 및 검증 완료. NAS 최종 검증 대기.
- 제한: 사이트 상태는 수집기의 최근 보고 기준. 로그인 만료는 직접 로그인이 필요하며 정지한 브라우저는 자동으로 시작하지 않는다.
- 배포 완료: NAS app.py·복구 명령·사이트 기록 반영. 대시보드만 재시작. 신규 화면/API 3개 HTTP 200, 세 캐릭터 수집 정상, NAS --check에서 네트워크 3개 정상 확인. 실제 장애를 만들거나 정상 수집기를 재생성하지 않음.

## 2026-09-17 — 소모품 영역 통합
- 소모품 잔량 영역과 개별 보충 기준 UI를 삭제하고 사용 기록에 잔량·창고·일일 시간당 평균·예상 소진·목표 시간 유지 수량 정보를 통합.
- 사용량 내림차순, 0개 아이템/시간대 숨김, 작은 아이콘 유지. 관측 부족 시 계산 대기 표시.
- 변경: work/source/app.py, 관련 테스트. 통합 수량/평균/유지 수량 및 렌더링 테스트 통과.
- 배포: 로컬 검증 완료, NAS 반영 대기. 판매·버림 구별 불가 등 기존 계산 제한 유지.
- NAS 반영 완료: 대시보드만 재시작. 실제 현황에서 기존 잔량 영역·보충 기준 제거 및 통합 정보 표시 확인. 수집기·브라우저 변경 없음.

## 2026-09-17 — 소모품 요약 시각적 구분
- 가운데 점으로 이어진 정보를 잔량/창고/시간당 평균 사용/예상 소진 4개 작은 칸으로 변경. 모바일은 2열, 유지 수량은 별도 안내 줄.
- 변경: work/source/app.py, work/test-merged-supplies.py. 통합 수량 표시 테스트 통과. 계산 로직 변경 없음.
- 상태: 로컬 검증 완료, NAS 반영 대기.
- NAS 배포 완료: 대시보드만 재시작, 실제 응답 HTTP 200 및 항목별 칸/유지 안내 HTML 확인. 수집기·브라우저 변경 없음. 모바일 2열 CSS 적용(기기별 시각 검증은 미실시).

## 2026-09-17 — 소모품 예상 소진 시간순 정렬
- 사용 기록을 예상 소진 시간이 짧은 순으로 정렬하고 계산 대기는 마지막에 표시. 같은 시간은 사용량순으로 정렬. 라벨을 예상 소진 시간으로 변경.
- 변경 파일: work/source/app.py, work/test-supply-order.py. 오름차순/계산 대기 후순위 테스트 통과.
- 상태: 로컬 검증 완료, NAS 배포 대기. 사용량 0개 숨김 유지.
- NAS 배포 완료: 대시보드만 재시작, 실제 페이지 정렬 안내·라벨 반영 확인. 브라우저·수집기 변경 없음.

## 2026-09-17 — 유지 수량 안내 위치 축소
- 유지 수량 안내를 오늘 사용 개수 옆 작은 배지로 이동. 별도 아래 안내 줄과 중복 제목 제거.
- 변경: work/source/app.py. 수량 표시 테스트 통과. 계산 변경 없음.
- 배포: 로컬 완료, NAS 반영 대기. 좁은 화면에서 긴 안내는 줄바꿈 가능.
- NAS 반영 완료: 대시보드만 재시작. 실제 페이지에서 사용 개수 옆 배지와 아래 안내 줄 제거 확인. 수집기·브라우저 변경 없음.

## 2026-09-17 — 최근 효율 칸 정리 및 아이콘 확대
- 최근 1시간 효율에서 관측 시간 칸 제거, 경험치/아데나 2칸 배치. 사용 기록 아이콘 18px → 24px.
- 변경 파일: work/source/app.py. 파이썬 문법 검사 통과. 계산 로직 변경 없음.
- 상태: 로컬 완료, NAS 반영 대기.
- NAS 반영 완료: 대시보드만 재시작. 배포된 함수에서 관측 시간 칸 제거·2칸 구성 및 24px CSS 확인. 페이지 응답 확인 중 검증 스크립트 제목 분리 조건 오류가 있어 소스 확인으로 대체. 수집기·브라우저 변경 없음.

## 2026-09-17 — 최근 1시간 소모 아이템 추가
- 최근 1시간 효율에 소모 아이템 종류/개수 칸 추가. 물약·주문서 감소를 많은 순으로 표시, 창고 이동·장시간 공백·일시 누락 제외 규칙 유지.
- 사용 기록 아이콘 24px → 30px. 변경: work/source/app.py.
- 검증: 최근 1시간 수량/시간 필터와 페이지 렌더링 테스트 통과. 로컬 완료, NAS 배포 대기.
- 제한: 판매·버림과 실제 사용은 기존처럼 구별 불가. 긴 소모 목록은 칸 안에서 스크롤.
- NAS 반영 완료: 대시보드만 재시작. 실제 현황의 소모 아이템 칸 및 30px CSS 확인. 수집기·브라우저 변경 없음.

## 2026-09-17 — 아데나 사용 기록 추가
- 소모품 사용 기록에 아데나 지출 추가. 소지+창고 합계의 관측 감소만 집계하며 창고 이동·15분 초과 공백·알 수 없는 창고 잔고는 제외.
- 소지/창고 잔고, 일일 시간당 평균 지출, 소지 잔고 예상 소진 시간, 시간대/수집별 지출 표시. 지출 0은 숨김, 예상 소진 시간순 정렬 유지.
- 손익 계산은 변경하지 않으며 아데나 지출을 소모품 비용에 더하지 않음.
- 변경: work/source/app.py, work/test-adena-usage.py. 이동/수입 분리/공백/잔고 누락/손익 불변 테스트 통과.
- 제한: 관측 사이 수입과 지출이 함께 있으면 상계되어 실제 총지출보다 적을 수 있음. 예상 소진은 향후 수입을 가정하지 않음. 로컬 검증 완료, NAS 배포 대기.
- NAS 반영 완료: 대시보드만 재시작. 실제 현황의 아데나 평균 지출과 손익 제외 안내 확인. 브라우저·수집기 변경 없음.

## 2026-09-17 — 아데나 아이콘 적용
- 사용자 제공 PNG 원본을 아데나 사용 기록 아이콘으로 적용. 30px 영역 안에서 비율 유지. 외부 이미지 요청 없이 표시.
- 변경: work/source/app.py, work/source/adena-icon.png. PNG 형식 및 기존 아데나 집계 테스트 통과. 로컬 완료, NAS 반영 대기.
- NAS 반영 완료: 대시보드만 재시작. 실제 페이지 PNG 아이콘 포함 확인. 계산·수집기·브라우저 변경 없음.

## 2026-09-17 — 용 캐릭터 일일 경험치 기준
- 용의 다음 레벨/목표 레벨/레벨별 예상은 오늘 제외 최근 7일 중 유효 관측 20시간 이상인 날의 일평균 EXP를 사용. 증가 없는 휴식일 포함, 15분 초과 공백 제외. 시간당 환산은 일평균/24로 달력 소요일 계산.
- 용의 경험치 정체 경고는 화면/API/텔레그램에서 제외하고 이전 정체 알림 상태도 정리. 로그인·수집 오류 및 소모품 경고 유지. 다른 캐릭터 방식 유지.
- 변경: work/source/app.py, work/audit/alert_state.py, work/test-yong-daily.py.
- 검증: 휴식일 포함/오늘 제외/일평균/다른 캐릭터/정체 억제/수집 오류 유지 테스트와 기존 예상 옵션 테스트 통과.
- 로컬 완료, NAS 반영 대기. 완료된 유효 날짜가 없거나 일평균 증가가 0 이하면 예상 계산 대기.
- NAS 배포 완료: 대시보드만 재시작. 실제 용 현황의 일일 예상 안내 및 모니터링 API 정체 경고 제외 확인. 알림 모듈은 다음 실행부터 적용. 브라우저·수집기 변경 없음.

## 2026-09-17 — 텔레그램 캐릭터 카드 텍스트 요약
- 매시간 전체 화면 캡처 대신 용/지/륻 순서로 캐릭터별 읽기 쉬운 텍스트 전송. 레벨·경험치 속도·레벨업 예상·수익/비용/손익·보충·수집 시각 포함.
- 기존 방해 금지/캐릭터별 설정 유지, 전송 성공 후 중복 방지 상태 저장. 정기 전송에서 브라우저 캡처·변화량 API 호출 제거.
- 변경: work/report-current.py, work/source/app.py, work/test-telegram-cards.py. 모의 전송/필드/문자 이스케이프/중복 방지/전송 실패 테스트 통과.
- 상태: 로컬 완료, NAS 배포 대기.
- NAS 반영 완료: 대시보드만 재시작. 새 형식으로 용·지·륻 각 1건 실제 텔레그램 전송 성공. 이후 매시간 같은 형식 사용. 브라우저·수집기 변경 없음.

## 2026-09-19 — 현황 조회 기간 선택
- 현황의 수집 상태 점검·업데이트 기록 아래에 오늘/어제/최근 12시간/최근 24시간/이번 주/이번 달 선택을 추가. 한국 시간 월요일·월초 기준이며 캐릭터 전환 및 설정 저장 시 기간을 유지.
- 캐릭터 카드 손익, 누적 경험치·아데나, 상세 손익, 소모품·아데나 사용 기록, 추이·아이템 증감을 선택 기간으로 집계. 사용 기록은 날짜+시간별로 구분. 현재 레벨·잔량·수집 상태와 최근 지표·소진 예상은 최신 기준임을 표시.
- 기간 경계 EXP·아데나는 관측 시간에 비례, 15분 초과 공백 제외. 아이템은 증감 확인 시각으로 집계하고 가격 미설정 비용은 잠정 손익 안내 유지.
- 수정 파일: work/source/app.py. 검증 추가: work/test-dashboard-period.py.
- 로컬 검증: 여섯 기간 렌더링, 한국 시간 주/월/자정 경계, 경계 시간 비례 및 공백 제외, 날짜별 사용량, 캐릭터 링크 유지 성공. 기존 손익·일시 누락·아데나 사용·실제 HTTP 단가 저장·세 화면 렌더링 성공.
- 배포 상태: 로컬 검증 완료, NAS 반영 및 운영 검증 진행 예정. 수집기·브라우저 변경 없음.
- NAS 반영 완료: app.py 업로드 후 대시보드만 재시작(최종 최적화 포함 총 2회). 수집기·브라우저 재시작/재생성 없음.
- 운영 검증: 6개 기간 HTTP 200, 캐릭터 전환 링크의 기간 유지, 어제 손익·사용량 반영 및 데스크톱 버튼 위치 실제 화면 확인. /updates, /api/collection-check, /api/monitoring 정상 응답.
- 긴 기간 사용 기록의 시간대별 반복 검색을 한 번의 그룹화로 변경. 최종 월간 조회 7.76초(운영 데이터, 캐시 초기 상태). 기록량이 많은 주/월 조회는 일간보다 느릴 수 있으며 월간 조회 지연을 완전히 제거한 것은 아님. 모바일은 반응형 CSS 적용, 실기기 시각 검증은 미실시.

## 2026-09-19 — NAS 내부 IP 변경에 따른 Linclog 연결 수정
- NAS가 공유기에서 192.168.45.106 대신 192.168.0.107을 받으면서 Docker 포트 바인딩 및 브라우저 링크가 이전 주소에 남아 웹사이트에 연결할 수 없었음. collector SERVER_URL도 이전 호스트 주소를 사용.
- Compose 포트 바인딩을 현재 LAN IP로 제한해 갱신하고, collector는 Docker 내부의 dashboard 서비스 주소로 통신하도록 변경. 브라우저 링크도 새 LAN IP로 갱신.
- 수정 파일: work/source/docker-compose.yaml. 브라우저 프로필 볼륨은 유지.
- 상태: 원인 확인 완료, Compose 화면 반영 및 재배포 진행 중. 수집 결과·포트 접근 검증 예정.
- 배포 확인: NAS Docker 관리자에서 Compose 재배포 성공, 프로젝트 컨테이너 7개 모두 실행 중. LAN 포트 8089/3001/3002/3003 연결 가능, `/api/collection-check` HTTP 200 및 컨테이너 내부 `dashboard:8088` DNS/HTTP 연결 성공.
- 남은 문제: collector3 로그아웃/계정발견이 완료되지 않아 최신 스냅샷은 아직 없음. 해당 브라우저 Chromium의 CDP 9334 요청은 연결 실패. 브라우저3 프로필의 SingletonLock이 이전 컨테이너 ID(`f93d2f5ec683`)를 가리키고, 현재 Chromium은 “다른 프로세스가 프로필을 사용 중” 경고 대기 상태로 확인됨. 다른 프로젝트 컨테이너 7개는 실행 중이나 이 프로필 잠금 해제와 새 수집 스냅샷은 미완료.
- SSH: NAS 관리자 웹 로그인과 별개로 SSH 공개키 인증은 계속 거부됨. NAS 웹 관리자 세션으로 Docker 점검을 진행했으며, update-history.md NAS 동기화는 SSH 접근 복구 전까지 보류.
- 재생성/재시작: 주소·네트워크 구성 반영을 위해 Linclog 프로젝트의 dashboard, browser 3개, collector 3개를 Compose에서 모두 재생성. 브라우저 프로필 명명 볼륨은 유지됐고 수집기 이미지 코드는 바꾸지 않아 수집기 이미지 재빌드는 없음.
- 상태 정정: Compose 배포는 완료됐고 웹/API 연결은 복구됐으나, collector3 Chromium의 과거 컨테이너 프로필 잠금 때문에 수집 정상화는 미완료. NAS update-history.md 동기화도 SSH 키 인증 복구 후 진행 예정.
- 추가 운영 확인(2026-09-19): `http://192.168.0.107:8089/` 실제 Chrome 페이지 렌더링 확인(HTTP 200, 153,314바이트, 첫 서버 요청 2.88초). `/api/collection-check`, `/api/monitoring`, `/updates`도 HTTP 200. 화면은 열리지만 최근 수집 시각이 09:55~09:59로 오래되어 캐릭터 카드에 수집 지연 표시가 남음. 웹 접속 정상과 최신 데이터 수집 정상은 별도 상태.

## 2026-09-19 — NAS SSH 공개키 및 수집기 연결 복구 상태
- NAS 재부팅 후 `/home` immutable 속성 때문에 SSH 키 등록이 막히고, 공개키 인증이 거부되던 문제를 복구. NAS에 등록된 키 지문과 로컬 키 지문이 `SHA256:3ReneRu6QL//ctSvQwNV6vws9K0YUaDXWdNUQKGheCw`로 일치하며 `youtack@192.168.0.107` 공개키 로그인을 확인.
- 이전 컨테이너 ID를 가리키던 3개 브라우저의 오래된 Chromium SingletonLock을 제거하고 브라우저를 재시작한 뒤 collector 3개를 강제 재생성하여 각 브라우저 네트워크 네임스페이스에 다시 연결. 복구 스크립트에서 collector 3개 모두 network OK, 컨테이너 실행 상태 확인.
- 운영 결과: Chromium/CDP 프로세스는 실행 중이나 세 브라우저 모두 PLAYNC 로그인 페이지로 이동되어 있음. collector 로그에 `SESSION_EXPIRED:login_page`가 확인되어 현재 새 스냅샷 수집은 사용자 PLAYNC 로그인 전까지 대기. NAS 브라우저에서 각 계정 로그인을 마치면 collector가 다음 재시도에서 수집을 이어감.
- 수정 파일: CHANGELOG.md. NAS에 update-history.md 동기화.
- 배포/재시작: browser 3개 재시작, collector 3개 재생성. 대시보드 및 collector 이미지 코드는 변경하지 않았고 재빌드 없음. SSH 및 Docker 운영 접속 성공.
- 남은 작업: NAS Chromium 세션별 PLAYNC 로그인 후 새 스냅샷 시각과 수집 성공 로그 확인.

## 2026-09-19 — NAS 브라우저 접속 비밀번호 변경
- 사용자가 지정한 값으로 브라우저 웹 접속 인증 비밀번호를 변경. 인증정보는 기록에 남기지 않음.
- 변경: work/source/.env 및 NAS `/volume1/lineage/linclog-nas/.env`의 BROWSER_PASSWORD 설정.
- 검증: 무인증 접속은 3001/3002/3003에서 HTTP 401, 새 인증은 3개 모두 HTTP 200. 브라우저·수집기 총 6개 실행 중이며 복구 점검에서 수집기 네트워크 3개 모두 정상.
- 배포: 브라우저 3개 재생성 후 네트워크 네임스페이스 연결을 위해 수집기 3개 재생성. 대시보드는 재시작하지 않았고 이미지 빌드 변경 없음.
- 남은 제한: 수집기 네트워크는 정상이나 최근 수집 재시도에서 PLAYNC 계정 발견이 실패함. 브라우저 인증과 PLAYNC 로그인 세션은 별개임.

## 2026-09-19 — 브라우저 3개 프로필 잠금 경고 정리
- 3001/3002/3003 화면이 깨져 보이고 수집기가 브라우저에 연결하지 못하던 원인은 이전 컨테이너 ID를 가리키는 Chromium `SingletonLock` 링크였음. Chromium이 프로필 손상 방지 경고창에 멈춰 있었음.
- 세 브라우저의 오래된 잠금 링크만 제거하고 브라우저 3개를 재시작한 뒤, 브라우저 네트워크를 공유하는 수집기 3개를 재생성.
- 검증: 세 포트 인증 접속 HTTP 200, CDP 9334 세 곳 HTTP 200, 복구 점검 collector 3개 network OK. 모든 컨테이너 실행 확인.
- 변경 파일: CHANGELOG.md. NAS 이미지 빌드 및 대시보드 재시작 없음. NAS update-history.md 동기화.
- 남은 제한: 세 PlayNC 프로필이 로그인 화면으로 이동되어 있어 collector 로그에 SESSION_EXPIRED가 남음. 각 브라우저에서 PlayNC 계정 로그인이 필요.

## 2026-09-20 — Linclog 외부 포트 28091 준비
- 요청한 공개 접속 포트 사용을 위해 dashboard에 NAS 호스트 포트 28091을 추가하고 기존 8089 주소도 유지. 두 포트 모두 컨테이너 8088에 연결.
- 변경 파일: work/source/docker-compose.yaml, CHANGELOG.md. Compose 설정 검증 성공.
- 검증: 이 PC에서 내부 주소 `http://192.168.0.107:28091/` 및 기존 8089 모두 HTTP 200. 컨테이너 bind 데이터(`/data`)와 app.py 마운트 유지.
- 배포: dashboard만 재생성, 다른 6개 Linclog 컨테이너는 변경 없음. NAS update-history.md 동기화.
- 외부 공개 대기: 공유기 화면의 lineage 규칙은 현재 192.168.0.6:28091을 대상으로 하며 외부 IP 접속은 타임아웃. 현재 NAS는 192.168.0.107이므로 공유기 내부 대상 변경이 필요.

## 2026-09-20 — Linclog 공인 포트 28091 연결 완료
- ipTIME `lineage` 포트포워드의 내부 대상을 이전 주소 `192.168.0.6:28091`에서 현재 NAS `192.168.0.107:28091`로 수정·저장. 외부 TCP 포트 28091 유지.
- 대시보드 컨테이너 포트 28091 → 8088 게시를 추가했으며 기존 내부 포트 8089도 유지.
- 검증: `http://1.244.213.116:28091/`, `/updates`, `/api/collection-check` 모두 HTTP 200. 내부 NAS 주소 28091도 HTTP 200.
- 변경: work/source/docker-compose.yaml 및 공유기 `lineage` 규칙. dashboard만 재생성, 기존 데이터/볼륨과 나머지 6개 Linclog 컨테이너 유지. NAS update-history.md 동기화.
- 제한: 요청한 HTTP 연결은 암호화되지 않으며 dashboard 경로에 별도 로그인 인증이 없음.

## 2026-09-23 — 현황 성능·모바일 구성 개선 (검증 완료, 배포 준비)
- 이유: 내부망 현황 5.5~8.4초, 월간 14.5초 및 중복 안내·모바일 상단 과밀 개선.
- 변경: 읽기용 아이템 합계 재사용, 변화 없는 아이템 이벤트 생략, 선택 캐릭터/기간 중심 조회, 중복 개요 계산 제거. 아이템→시간대→수집별 상세 단계별 조회. 긴 그래프는 극값·공백 경계를 유지해 표시점 축약.
- 화면: 전체 새로고침 대신 화면 내용 갱신, 상세 열람·설정 입력 중 갱신 보류. 모바일 헤더/관리 메뉴 압축, 최신/선택 기간 구분, 소모품 중복 목록 제거, 작은 비율 표시 개선. 사용자 요청에 따라 별도 설정 비밀번호는 추가하지 않음.
- 파일: work/source/app.py, dashboard-ui.js, dashboard-ui.css, Dockerfile, docker-compose.yaml; work/test-lazy-dashboard.py 및 감사·검증 스크립트.
- 검증: 캐시/창고 이동/일시 누락/손익/용 일일 기준/예상 속도/아데나/기간/HTTP 단가 저장/그래프 공백 테스트 통과. NAS 실제 세 캐릭터 소모품 추정·손익 결과가 기존과 일치. 가상 기록 브라우저에서 아이템·시간대 상세 및 모바일 화면 확인.
- 상태: 이 항목 작성 시 NAS 본 배포 전. 재시작·재생성 없음. 별도 검증 프로세스만 사용. 배포와 최종 속도 결과는 다음 항목에 기록.
- 제한: 월간 데이터와 접힌 상세는 요청 시 계산. 수집 사이 획득/사용·판매/버리기 구별 한계 유지. 외부 조회/설정 접근 방식 변경 없음.

## 2026-09-23 20:32 KST — 현황 성능·모바일 개선 NAS 배포 완료
- 배포: dashboard 이미지 재빌드 및 dashboard만 재생성. 새 CSS/JS 파일의 읽기 전용 연결을 추가했으며 기존 포트·데이터 연결 유지. browser/collector 6개는 재시작·재생성하지 않았음.
- 기존 파일 백업: NAS /volume1/lineage/linclog-nas/deploy-backups/20260923-203022. 배포 전 Compose 차이는 끝의 빈 줄뿐이었으며 운영 설정은 보존.
- 실제 검증: 내부 HTTP 200 (세 캐릭터 현황·월간·수집 점검·JS), 외부 DDNS HTTP 200. collector 3개 네트워크 점검 OK, 상태 API 세 캐릭터 최근 수집 정상, 나머지 6개 컨테이너 가동 시간 4일 유지.
- 내부망 각 1회 측정: 용 8.408→4.074초, 지 7.703→3.015초, 륻 5.545→1.341초, 지 월간 14.477→7.383초. 서로 다른 시점의 단회 측정이며 서버 부하·캐시 영향이 있음. 월간 HTML 1,604,916→190,794바이트.
- 검증: 관련 회귀 스크립트 10개 통과 및 JS 구문 검사. 실제 NAS 세 캐릭터 소모품 추정/손익이 변경 전과 일치. 브라우저 가상 기록에서 아이템→시간대→수집별 조회, 모바일 390×844, 상세 확인 중 갱신 보류 및 닫은 후 부분 갱신 완료 확인(콘솔 오류 없음). 운영 사이트 새 화면 반영 확인.
- 남은 제한: 월간 첫 조회는 여전히 수초가 걸림. 현재는 계산 규칙을 유지하면서 조회 범위·객체 재사용·표시량을 줄였으며 영구 사전집계는 도입하지 않음. 외부 설정 보호는 사용자가 비밀번호를 원하지 않아 변경하지 않음. 이번 변경은 app.py 외 dashboard-ui.css/js도 함께 배포해야 함.

## 2026-09-23 — 시간대별 효율 비교 24시간 표 (배포 준비)
- 요청: 현황에서 오늘 00~24시를 시간 단위로 조회하고 표 내부를 위아래로 스크롤.
- 변경: 24개 행, 현재 시간대 강조, 미래 시간 집계 전 표시, 고정 열 제목/시간 열, 높이 제한(데스크톱 360px·모바일 320px), 자동 갱신 후 표 스크롤 위치 복원. 다른 날짜·기간 분석은 기존 구간 화면으로 연결해 용도 구분.
- 파일: work/source/app.py, dashboard-ui.css, dashboard-ui.js, work/test-hourly-day.py.
- 검증: 24시간/자정·시간 경계 배분/공백 제외/미래 시간 테스트, 기존 모니터링·6개 기간 렌더 테스트, JS 구문 검사 통과.
- 상태: 작성 시 배포 전. 소모·손익 계산 규칙 및 구간 화면 변경 없음. 이 표는 현황의 기간 선택과 별개로 오늘 기준임을 화면에 표시.

## 2026-09-23 22:18 KST — 시간대별 효율 24시간 표 NAS 반영 완료
- app.py·dashboard-ui.css·dashboard-ui.js 배포, dashboard만 재시작(표 반영과 화면 버전 감지 보완). 브라우저·수집기 재시작/재생성 없음.
- 검증: 운영 현황 HTTP 200, 24개 행과 23~24시까지 스크롤·고정 제목 확인. 데스크톱 표 높이 360px, 모바일 390px 폭에서 제한 높이와 가로/세로 스크롤 확인. 세 캐릭터 수집 상태 정상.
- 자동 갱신 시 표 내부 위치 복원 추가. CSS/JS 변경도 새 버전으로 감지해 기존 열린 화면에 다시 읽기 안내하도록 보완.
- 백업: /volume1/lineage/linclog-nas/deploy-backups/hourly-20260923-221437.
- 제한: 오늘 요약은 현황, 다른 날짜/기간 분석은 구간에서 확인. 15분 미만 관측은 효율 계산 대기, 15분 초과 공백 제외 규칙 유지. 스크롤 위치 보존은 코드 반영/JS 구문 검증했으며 실제 1분 갱신 후 위치 비교는 별도 수행하지 않음.

## 2026-09-23 22:31 KST — 시간대별 내역 통합 (배포 준비)
- 이유/내용: 중복 시간별 변화 표를 현황의 시간대별 효율로 통합. 오늘·어제·날짜 선택, 날빠 옆 소모품 및 득템 칸, 시간 행 바로 아래 7열 너비의 아이콘/수량 상세 추가. 득템에서 날빠 중복 제외. 구간의 기간 합계·그래프·사냥 분석 유지, 삭제한 표 대신 날짜를 전달하는 이동 링크 제공.
- 파일: work/source/app.py, dashboard-ui.css, dashboard-ui.js; work/test-hourly-items.py.
- 검증: 24시간 경계/공백 테스트, 창고 이동·소모·득템·날빠 중복 제외 테스트, 기간별 전체 페이지 회귀, 지연 상세/캐시 격리 테스트 통과. JS 구문 검사 통과. 가상 데이터 브라우저에서 클릭한 행 바로 아래 상세 및 colspan 7 확인, 구간 HTTP 200 확인.
- 상태: 배포 전. 설정/손익 계산 규칙 변경 없음. 상세 펼침 중 자동 갱신 보류.
- 제한: 사용·판매·버리기는 관측 감소만으로 구분하지 못함. 과거 날짜 표만 별도 조회하며 현황의 다른 누적 지표 기간은 상단 기간 선택을 따름.

## 2026-09-23 22:34 KST — 시간대별 내역 통합 NAS 배포 완료
- app.py·dashboard-ui.css·dashboard-ui.js 배포, dashboard만 재시작. 브라우저·수집기 재시작/재생성 없음.
- 검증: 운영 지 오늘·륻 어제·구간 페이지 HTTP 200. 실제 지 00~01시 소모품 상세(빨간 물약 16개, 파란 물약 5개), 득템 상세(파란 물약 +80개)와 아이콘 로딩 확인. 어제 선택 시 09.22의 24개 시간 행 전환 확인.
- 모바일 390×844에서 가로 스크롤 이후에도 펼친 상세가 화면 안에 표시됨(상세 폭 약 290px). 7열 전체를 차지하는 바로 아래 행, 열 제목/시간 고정 및 표 내부 스크롤 확인.
- collector/collector2/collector3 네트워크 점검 모두 OK. 백업: /volume1/lineage/linclog-nas/deploy-backups/hourly-unify-20260923-223125.
- 제한: 득템은 관측 증가로 구매/획득을 구분하지 않음. 시간대별 날짜 선택은 해당 표에만 적용. 자동 갱신 상세 펼침 보류는 코드/구문 검증, 실제 1분 대기는 별도 수행하지 않음.

## 2026-09-23 22:55 KST — 현황·구간 화면 통합 (배포 준비)
- 이유/내용: 조회 기간을 현황 한곳으로 통합. 직접 선택(한국 시간, 최대 31일)과 지금까지 옵션 추가. 누적/손익/사용 내역/시간대별 표에 같은 기간 적용; 최신 상태·소진 예상은 최신 기준 유지. 여러 날은 선택 기간 안에서 표 날짜만 나눠 조회.
- 분석: 경험치 증가가 관측된 15분 이내 간격을 사냥으로 추정. 사냥 시간·전체 대비 비율, 관측 순증가/전체 시간 및 증가 구간 경험치/사냥 추정 시간 구분. 미관측은 별도 표시. 시간대 클릭 시 사냥·공백·아이템 상세를 바로 아래에 펼침.
- 화면: 긴 추이 그래프·날짜별 기록·사냥 구간 비교·기간 아이템을 접음. 구간 메뉴 제거 및 기존 /range 링크는 기간을 유지한 현황으로 연결. 다른 캐릭터/소모품 지연 상세/설정 저장 이후에도 직접 선택한 기간 유지.
- 파일: work/source/app.py, dashboard-ui.css, dashboard-ui.js, work/test-single-dashboard.py, work/test-hourly-day.py, work/test-gap-render.py.
- 검증: 직접 기간 유효성·경계 배분·공백/미관측 분리·캐릭터 전환 링크·지연 상세·이전 주소 연결 테스트, 6개 기본 기간 전체 렌더, 아이템 사용/창고 이동, 요청 캐시, 그래프 공백, 단가 HTTP 저장 테스트 통과. JS 구문 검사 통과. 가상 데이터 16~18시 조회 사냥 2시간/100% 확인, 모바일 390px 입력란 넘침 없음, 시간대 바로 아래 펼침 및 콘솔 오류 없음.
- 상태: 배포 전. 장기 과거 조회 시 선택 구간과 최근 상태용 기록만 읽도록 조회 범위 제한. 손익 계산 규칙 변경 없음.
- 제한: 경험치 증가 기반 사냥 추정으로 실제 사냥 시간을 확정하지 않음. 수집 공백에서 얻은 경험치는 알 수 없음. 기존 독립 구간 화면은 현황으로 대체하며 30분/10분/1일 단위 표는 유지하지 않고 1시간 표와 날짜별 기록 제공.

## 2026-09-23 22:57 KST — 통합 현황 NAS 배포 완료
- app.py·dashboard-ui.css·dashboard-ui.js 배포 후 dashboard만 재시작. 브라우저/수집기 6개 가동 시간 4일 유지, 재생성 없음.
- 운영 검증: 지 오늘/륻 직접 지정 08~12시/용 월간 HTTP 200, 이전 /range의 기간 유지 이동 200. 실제 륻 08~12시 전체 4시간·증가 관측 사냥 0분·미관측 0분 표시 확인. 수집 점검 세 캐릭터 정상 및 collector 3개 네트워크 OK.
- 응답 단회 측정: 지 오늘 4.735초/249279바이트, 륻 직접 기간 2.234초/107601바이트, 용 월간 13.593초/274007바이트. 캐릭터·기간이 달라 이전 측정과 직접 성능 비교 불가; 캐시/동시 요청 영향 포함.
- 백업: /volume1/lineage/linclog-nas/deploy-backups/single-dashboard-20260923-225525.
- 남은 제한: 월간 첫 조회는 여전히 수초~십여 초가 걸릴 수 있음. 긴 내역은 화면에서 접었지만 서버 계산/HTML은 생성함. 사냥은 경험치 증가 관측 기반 추정이며 전체 시간당에는 미관측 시간도 분모에 포함함. 자동 갱신/지금까지 장시간 유지 동작은 별도 장시간 관찰하지 않음.

## 2026-09-23 23:13 KST — 현황 4개 배치 개선 (배포 준비)
- 시간대별 표: 기본 10행 높이, 현재 시간대를 하단으로 초기 스크롤. 선택 기간이 과거이면 그 기간 마지막 해당 시간 기준. 사용자가 움직인 위치는 자동 갱신 때 보존.
- 소모품 사용 기록: 아이콘·이름·사용량·유지 수량 옆에 잔량/창고/시간당 평균 사용/예상 소진 시간을 한 줄 배치. 좁은 화면에서는 행 내부 가로 스크롤.
- 기간 추이: 접기 제거, 항상 펼친 그래프를 시간대별 효율 비교 바로 위로 이동.
- 날짜별 기록/사냥 비교: 정각 기준 1시간 행, 사냥/휴식 시간 표기, 사냥 시간당 열 제거. 사냥(초록)/휴식(파랑)/미관측(빗금) 누적 막대 및 범례 추가. 경계·진행 중인 시간은 선택 구간 안의 관측만 계산.
- 파일: work/source/app.py, dashboard-ui.css, dashboard-ui.js; work/test-layout-four.py.
- 검증: 시간 경계 배분·사냥/휴식/공백·23:05 기준·24:00 라벨 테스트, 직접 기간/기본 기간 전체 렌더, 지연 사용 기록/캐시 격리 테스트 및 JS 구문 검사 통과. 브라우저 데스크톱/390px 모바일에서 14~24시 정확히 10행, 23~24시 하단 확인. 그래프 순서와 한 줄 사용 기록 확인.
- 상태: 배포 전. 사냥·휴식은 경험치 변화 기반 추정이며 공백을 휴식으로 계산하지 않음. 하루 초반처럼 앞선 시간 행이 10개 미만이면 0시부터 표시 가능한 범위 내에서 위치 조정.

## 2026-09-23 23:14 KST — 4개 배치 개선 NAS 반영 완료
- app.py·dashboard-ui.css·dashboard-ui.js 배포, dashboard만 재시작. 브라우저·수집기 재시작/재생성 없음.
- 운영 브라우저 검증: 14~15시부터 23~24시까지 정확히 10행, 현재 23시 행이 하단. 추이 그래프가 접힘 없이 표 위에 표시됨. 실제 소모품 행 높이 48px, 데스크톱 1074px 안에 한 줄 정보 표시.
- 실제 날짜/시간별 사냥·휴식 막대와 1시간 라벨 확인(예: 22~23시 사냥 57분/휴식 3분). 수집기 3개 네트워크 점검 OK.
- 백업: /volume1/lineage/linclog-nas/deploy-backups/layout-four-20260923-231316.
- 한계: 시간은 분 단위 반올림 표시. 좁은 화면의 소모품 한 줄은 가로 스크롤 필요. 사냥/휴식은 경험치 증가 기반 추정이며 미관측은 별도 표시.

## 2026-09-23 23:27 KST — 시간 비율 가독성 및 무변화 시간대 숨김 (NAS 배포 완료)
- 눈부심과 유사색 문제를 줄이기 위해 사냥은 차분한 금색, 휴식은 회색, 미관측은 어두운 테두리로 구분. 미관측 빗금 제거.
- 1시간 기록은 날짜별 제목 아래 23:00 → 24:00처럼 시간만 표시하여 날짜 반복 제거.
- 시간대별 효율 비교는 경험치/아데나/날빠/소모품/득템 모두 변화 없는 행을 숨김. 작은 변화 및 증가·감소가 상쇄된 시간은 유지. 비어 있으면 간단한 안내 표시, 현재 시간 행이 없으면 가장 가까운 이전 표시 행으로 위치 설정.
- 파일: work/source/app.py, dashboard-ui.css, dashboard-ui.js; work/test-hourly-clean.py 및 기존 시간대/기간 테스트 갱신.
- 검증: 다섯 항목 각각의 변화, 무변화, 미세 변화, 상쇄 변화, 날짜 묶음 테스트 통과. 시간 경계/창고 이동/수집 공백/사용 상세/직접 기간/6개 기간 렌더 테스트 통과. Python 및 JavaScript 구문 검사 통과. 운영 용 캐릭터에서 무변화 행 제외, 날짜 묶음, 그래프 색상 실제 화면 확인.
- 배포: app.py/CSS/JS 반영 후 dashboard만 재시작. 브라우저·수집기 재시작/재생성 없음. 수집기 3개 네트워크 점검 OK.
- 백업: /volume1/lineage/linclog-nas/deploy-backups/hourly-clean-20260923-232558.
- 한계: 사냥/휴식은 경험치 변화 기반 추정, 시간 표시는 분 반올림. 화면에 반올림되어 0으로 보이더라도 실제 변화가 있으면 해당 시간대는 유지. 날짜별 사냥/휴식 기록의 0변화 행은 비교를 위해 유지.

## 2026-09-23 23:36 KST — 상단 정보 고정 및 날짜별 기록 상시 펼침 (NAS 배포 완료)
- 요청: 캐릭터 정보/조회 기간을 스크롤 중에도 유지하고 날짜별 기록·사냥 구간 비교는 항상 펼쳐 표시.
- 변경: 대시보드 상단만 sticky로 고정, 캐릭터 비교 카드는 본문으로 이동. 기록 영역의 접기 제거. 고정 높이를 관찰하여 구간 바로가기 가림 방지, 자동 갱신 시 높이 관찰 재연결. 모바일 최대 42vh로 제한하며 긴 설정은 상단 내부에서 스크롤 가능.
- 파일: work/source/app.py, work/source/dashboard-ui.css, work/source/dashboard-ui.js.
- 검증: 직접 기간 전체 렌더/캐릭터 전환 링크/지연 사용 내역 테스트 및 JS 구문 검사 통과. 운영 륻 화면에서 스크롤 후 상단 top=0, 기록 SECTION 상시 표시, 카드가 고정 영역 밖에 있음을 확인. 390x844 모바일에서도 top=0, 페이지 가로 넘침 없음 확인.
- 배포: app.py/CSS/JS 반영, dashboard만 재시작. 브라우저·수집기 재시작/재생성 없음.
- 백업: /volume1/lineage/linclog-nas/deploy-backups/sticky-header-20260923-233432.
- 제한: 작은 화면에서 관리/기간 입력을 펼치면 고정 상단 내부 스크롤이 필요할 수 있음. 날짜별 기록은 항상 펼치되 기존 표 내부 스크롤 유지.

## 2026-09-23 23:47 KST — 고정 상단과 기간 선택 압축 (NAS 배포 완료)
- 사진의 캐릭터 정보/메뉴만 상단 고정. 기간 선택은 본문 맨 위로 이동하고 최근 12시간/24시간 버튼 제거, 오늘/어제/이번 주/이번 달/직접 선택을 한 줄로 배치. 기존 12h/24h 링크 해석은 호환 유지.
- 갱신 시각을 관리·알림·업데이트 옆으로 이동, 긴 갱신 안내를 짧게 표시. 직접 선택 폼과 관리 메뉴는 펼칠 때만 표시. 카드/구역/상단 여백 축소.
- 파일: work/source/app.py, work/source/dashboard-ui.js, work/source/dashboard-ui.css.
- 검증: 직접 기간 전체 렌더/범위 링크/사용 내역 테스트, JS 구문 검사 통과. 운영 화면 PC 고정 높이 약 286→133px, 390x844 모바일 302→156px 확인. 모바일 직접 선택 입력창 열림 및 가로 넘침 없음 확인.
- 배포: 세 파일 반영 후 dashboard만 재시작. 수집기와 브라우저 재시작/재생성 없음. 백업 /volume1/lineage/linclog-nas/deploy-backups/compact-top-20260923-234607.
- 한계: 직접 선택 입력창은 펼쳤을 때 아래 내용을 일시적으로 덮으며 닫으면 원래 화면 유지. 기존 데이터 계산 변경 없음.

## 2026-09-23 23:49 KST — 현황 메뉴 상단 이동 수정 (NAS 배포 완료)
- 원인: 현황 메뉴가 링크가 아닌 span 텍스트여서 클릭 동작이 없었음.
- 변경: work/source/app.py에서 현황을 #top 링크로 변경. 캐릭터·조회 기간은 유지하면서 화면 맨 위로 이동.
- 검증: Python 구문 검사 통과. 운영 브라우저 사냥 분석 위치 scrollY=1405.6에서 현황 클릭 후 scrollY=0, #top 확인.
- 배포: app.py만 반영하고 dashboard만 재시작. 수집기/브라우저 변경 없음. 백업 /volume1/lineage/linclog-nas/deploy-backups/overview-link-20260923-234903.
- 제한: 이미 열린 이전 화면은 새로고침 필요.

## 2026-09-24 00:19 KST — linclassic.duckdns.org HTTPS 연결 (NAS 배포 완료)
- 주소: https://linclassic.duckdns.org . 기존 공용 Caddy에 리니지 도메인만 추가, 내부 192.168.0.107:28091로 연결. 기존 Tesla View 도메인과 공유기 80/443 전달 규칙 활용.
- 변경 파일: NAS /volume1/0.docker/tesla-view-https/Caddyfile, update_dns.py. 로컬 실행 도구 work/enable-linclog-https.py. 대시보드/수집기 소스 변경 없음.
- 인증서 자동 발급/갱신은 기존 Caddy의 영속 볼륨 사용. IP 자동 갱신 대상은 teslaview,linclassic 두 도메인. 토큰은 기존 환경 파일 사용하며 기록하지 않음.
- 검증: Caddy 설정 검증 및 무중단 reload 성공. 인증서 검증을 끄지 않은 HTTPS 요청에서 리니지/Tesla View 모두 200. HTTP에서 HTTPS로 308 이동 확인. 운영 브라우저 HTTPS 주소에서 캐릭터/최근 수집 상태/시간대별 효율 표시 확인. DDNS update OK, 수집기 3개 network OK.
- 배포/서비스: Caddy는 설정 reload만 수행, tesla-view-ddns만 재빌드·재생성. Tesla View 앱 및 리니지 대시보드·브라우저·수집기 재시작 없음.
- 백업: /volume1/0.docker/tesla-view-https/backups/linclog-20260924-001759.
- 한계: 기존 HTTP IP:28091 접속은 유지. 향후 인증서 갱신은 공유기 80/443 연결과 Caddy 실행이 유지되어야 함. 미래 실제 갱신 시점의 동작까지 검증한 것은 아님.

## 2026-09-24 00:27 KST — 사이트 제목 변경 (NAS 배포 완료)
- work/source/app.py: 현황 탭 제목을 캐릭터명 · 리니지 사냥 일지로 변경, NAS 수집기 제목도 동일 명칭 적용.
- 검증: Python 구문 검사 통과. HTTPS 현황 응답의 title이 륻 · 리니지 사냥 일지임을 확인. 재시작 중 잠시 502 응답 후 정상 복구.
- 배포: app.py 반영, dashboard만 재시작. 수집기/브라우저 변경 없음. 백업 /volume1/lineage/linclog-nas/deploy-backups/site-title-20260924-002635.
- 제한: 이미 열린 탭은 새로고침 필요.

## 2026-09-24 01:07 KST — 시간대 상세 잘림 및 아데나 천 단위 (NAS 배포 완료)
- 시간대별 효율 비교에서 한 행만 있으면 상세 높이가 반영되지 않아 소모품/득템 목록이 잘리던 문제 수정. 펼친 상세 높이만큼 표 확장(추가 최대 320px), 닫으면 복원, 긴 상세는 표 내부 스크롤 유지.
- 소모품 사용 기록의 사용량 0개 제외 조건 유지. 앞서 준비했던 잔량 기준 표시 변경은 사용자 정정에 따라 배포 전에 취소.
- 소모품 사용 기록의 아데나 잔량/창고/지출/평균/보충/시간별 상세와 시간대별 효율 아데나를 천 단위로 표시. 예: 49,785→49.8천, 시간당 -4,000→−4천/h. 100 미만의 양수는 0.1천 미만으로 표시. 원본 집계/손익 계산 변경 없음.
- 파일: work/source/app.py, dashboard-ui.js; work/test-lazy-dashboard.py 표시 기대값 변경.
- 검증: 지연 상세/집계 일치/시간 범위/캐시 격리, 소모품·득템/창고 이동/공백 제외 테스트 및 JS 구문 검사 통과. 운영 HTTPS에서 00~01시 한 행 조건의 소모품 3종 전부 표시 확인(펼침 높이 287px, 닫힘 93px), 득템 3종 전환 및 아데나 천 단위 확인.
- 배포: app.py/JS/CSS 동기화, dashboard만 재시작. 수집기/브라우저 변경 없음. 백업 /volume1/lineage/linclog-nas/deploy-backups/hour-detail-height-20260924-010609.
- 한계: 천 단위는 소수 첫째 자리 반올림. 상세가 긴 경우에는 표 내부 스크롤 필요.