# sort 현재 기준서 — 패키지 v227

전체 진행률: 65% (`test_list.md` 완료 17 / 전체 26)
문서 체계: 100%
마우스 제어 폐기: 100%
공통 MEDIA_SAVED 로컬 처리: 100%
SQLite 기본·다운로드 구조: 100%
1단계-A 로컬 분석 기반: 100%
IG 실시간 observation 연결: 0%
PHP/MySQL 10분 중앙 집계: 0%
수집자·그룹·연구 기능: 0%
P2P·포인트: 0%

## 1. 절대 원칙

- 자동·수동 다운로드는 OS 마우스, 원점, hover 검증, Heart8772를 사용하지 않는다.
- 다운로드 시작 방식은 유지하되 파일 저장 완료 이후에는 공통 `MEDIA_SAVED` 흐름을 사용한다.
- 통계 수집은 다운로드 여부와 분리한다. 파일을 받지 않은 게시물도 계정·게시물·통계 저장 대상이다.
- 버전은 실제 수정된 모듈만 변경한다. 관련 없는 파일과 테스트의 버전 문자열만 바꾸지 않는다.
- 완료된 일회성 테스트는 누적하지 않고 현재 기능을 보호하는 고정 이름 최소 회귀 테스트만 유지한다.
- 실제 Windows·Chrome·운영 MySQL 로그가 없는 항목은 `[검증대기]` 또는 `[예정]`으로 둔다.
- 삭제는 우선 soft-delete로 처리한다. 계정·게시물을 분석과 수집 목록에서 제외하지만 MP4/JPG 실제 파일은 자동 삭제하지 않는다.
- 서버에는 MP4/JPG 원본과 사용자 로컬 절대경로·상대경로를 저장하지 않는다.
- 실패·불확실 상태를 성공으로 기록하지 않는다.

## 2. 현재 실행 구조

- `Auto8700`: 실행 버전 `2.3.8.223`; Chrome·CDP·WS·RTC 서비스 관리
- `IG_StYellow`: 실행 버전 `2.3.8.227`; Instagram DOM 분석, 메인·Side 계정 표시, 직접 URL 다운로드, 삭제 계정 표시·제외
- `WS8771`: 실행 버전 `2.3.8.225`; 파일 확인·해시·JSON·ECharts·Shared `MEDIA_SAVED`
- `Analyze8780`: 실행 버전 `2.3.8.227`; 로컬 SQLite 계정·게시물·10분 통계 조회와 삭제 API, 분석 화면
- `Shared/storage`: SQLite 스키마 v3, 공통 저장·repository·soft-delete 함수
- `RTC8790_8791`: 기존 v141 유지
- `Heart8772`: 폐기 및 ZIP 제외

실행 주소:

```text
http://127.0.0.1:8780/
```

실행 파일:

```text
_St/Analyze8780/run_Analyze8780.bat
```

## 3. IG 표시 기준

### 메인 주입 화면

```text
IG double_king0.1
```

- 계정명이 없으면 `IG`만 표시한다.
- 메인 Top 순위 라벨은 기존 스냅샷 표시를 유지한다.
- 실시간으로 계속 변하는 순위를 메인 화면에서 재계산하지 않는다.

### Side 게시물 카드

```text
IG double_king0.1
No003
```

- `IG account`는 항상 별도 줄이다.
- `No000`은 Top 조건이 활성화되고 해당 게시물이 조건에 포함될 때만 별도 줄로 표시한다.
- 계정명과 `No000`을 하나의 박스로 묶지 않는다.
- 순위는 Side 정렬 시점의 스냅샷이며 실시간 재계산 대상이 아니다.

## 4. 저장 폴더 기준

```text
상위폴더/
├─ _St/
│  ├─ Analyze8780/
│  ├─ Auto8700/
│  ├─ IG_StYellow/
│  ├─ WS8771/
│  ├─ RTC8790_8791/
│  └─ Shared/
└─ _StDown/
   └─ instagram/
      ├─ account_a/
      │  ├─ 원래파일명.mp4
      │  └─ 원래파일명.jpg
      ├─ account_a.html
      └─ 사용자집계명.html
```

- 기존 `index.htm`·계정별 HTML·JSON 표시 기능은 유지한다.
- Analyze8780은 기존 정적 HTML을 삭제하지 않고 SQLite 조회용 새 로컬 화면을 제공한다.
- 실제 파일 정체성은 `platform + shortcode + asset_kind + media_index`와 해시로 판단한다.

## 5. 다운로드와 observation 분리

다운로드 source mode:

```text
MANUAL_SINGLE
BULK_ALL
BULK_FILTERED
TOP_SORTED
TRANSCRIPT_REQUEST
```

다운로드 완료 흐름:

```text
IG 다운로드 시작
→ Chrome 다운로드
→ WS 파일·해시 확인
→ JSON·ECharts 갱신
→ Shared MEDIA_SAVED
→ sync_queue
```

통계 observation 목표 흐름:

```text
Instagram 주입 통계
→ Analyze8780/Python 수신
→ SQLite 계정·게시물 upsert
→ 10분 bucket upsert
→ sync_queue
→ PHP 호출
→ MySQL 동일 bucket upsert
```

현재 v227에서는 로컬 repository와 8780 수신 API까지만 구현했다. IG 실시간 전송과 PHP/MySQL 중앙 저장은 다음 단계다.

## 6. SQLite v3 기준

### 기존 v1·v2

- 계정·수집 조건·게시물·최신 통계·통계 이력
- 미디어·대본·후킹·카테고리·평가·댓글
- 다운로드 batch/job·`MEDIA_SAVED`
- P2P 보유 캐시·sync_queue

### v3 추가

- `post_stat_10m`
  - 게시물별 10분 버킷 통계
  - `UNIQUE(post_id, bucket_at)`
  - 같은 10분 구간 재수집은 새 행이 아니라 UPSERT
  - `sample_count`로 같은 구간 수집 횟수 기록
- `deletion_events`
  - 계정·게시물 soft-delete tombstone
  - 서버 DELETE 동기화 대기 근거
- `social_accounts.deleted_at`
- `posts.deleted_at`

10분 버킷 예:

```text
14:02:37 → 14:00:00
14:09:59 → 14:00:00
14:10:01 → 14:10:00
14:27:20 → 14:20:00
14:59:59 → 14:50:00
```

한 게시물은 시간당 최대 6개 버킷을 가진다.

## 7. Analyze8780 API

```text
GET    /api/health
GET    /api/accounts?page=1&page_size=50
GET    /api/accounts/{id}/posts?page=1&page_size=50&sort_by=views
GET    /api/posts/{id}
GET    /api/posts/{id}/stats?limit=144
GET    /api/deleted/accounts
POST   /api/observations
DELETE /api/accounts/{id}
DELETE /api/posts/{id}
```

정렬 기준:

```text
views
likes
comments
reposts
views_delta
views_per_hour
published_at
```

기본 분석값:

- 현재 조회수·좋아요·댓글·리포스트
- 최근 10분 조회수 증가량
- 시간당 환산 증가량
- 좋아요율·댓글률
- 계정별 게시물 수·최고 조회수·합계 조회수

떡상 점수 공식은 아직 확정하지 않는다. 실제 10분 데이터가 누적된 뒤 가중치를 결정한다.

## 8. 삭제 기준

### 게시물 삭제

- Analyze8780 목록에서 숨김
- `posts.deleted_at` 기록
- `deletion_events`와 `sync_queue DELETE` 기록
- 실제 MP4/JPG 파일은 유지

### 계정 삭제

- `social_accounts.active=0`, `deleted_at` 기록
- 해당 계정 수집 규칙 `enabled=0`
- 해당 계정 게시물을 분석 목록에서 숨김
- Side 수집대상 목록의 해당 URL 앞에 `🗑️` 표시
- `🗑️` 항목은 수집 순회와 계정 카운팅에서 제외
- 실제 파일은 유지

Side 목록 예:

```text
https://www.instagram.com/account_a/
🗑️ https://www.instagram.com/account_b/
https://www.instagram.com/account_c/
```

표시 카운트는 2개이며 삭제 1개는 별도 안내한다. 단순 전체 줄 수에서 이모지 개수를 빼는 방식이 아니라 각 항목의 삭제 상태를 판별해 제외한다.

## 9. 기존 index.htm 유지와 향후 역할

현재 만족 확인된 기능:

- 개별 수동 다운로드
- JSON 연동 index.htm 표시
- 계정별 HTML·ECharts 보고서

유지 원칙:

- 기존 index.htm 생성·JSON 연동을 깨지 않는다.
- Analyze8780은 데이터가 많아질 때 페이지 조회·삭제·분석을 담당한다.
- 향후 index.htm 또는 8780 화면에서 대본 추출 버튼을 누르면 Python이 처리한다.
- 대본 완료 후 본문 표시와 `📋 복사` 버튼을 제공한다.

## 10. 단계별 우선순위

### 1단계-A — 이번 v227 완료

- Side `IG account`·`No000` 분리
- Analyze8780 서비스
- SQLite 계정·게시물 repository
- 10분 통계 UPSERT·조회
- 계정·게시물 soft-delete
- Side `🗑️` 삭제 계정 제외

### 1단계-B — 다음 우선순위

- Side 계정목록 `💾 저장` 명시 버튼
- 포커스 이탈 자동 저장 제거 또는 보조화
- IG 주입 통계를 다운로드와 무관하게 8780으로 실시간 전송
- observation 전송량 제어·중복 방지·재시도
- SQLite sync_queue observation 등록

### 2단계

- PHP/MySQL 10분 통계 중앙 저장
- 같은 게시물·같은 10분 버킷 UPSERT
- 중앙 계정별·게시물별 집계
- 서버 최신값·이력 조회

### 3단계

- 수집자 회원·컴퓨터·토큰

### 4단계

- 그룹·공개 범위·공동 수집

### 5단계

- 대본 추출·카테고리·평가·후킹·검색

### 6단계

- P2P·포인트 정산

## 11. 완료 선언 기준

- 코드만 반영된 상태는 완료가 아니다.
- 관련 고정 테스트가 존재하고 실행 결과가 `OK`여야 한다.
- 실제 Windows·Chrome·서버 동작은 실제 로그 확인 전 `[검증대기]`다.
- 다음 채팅에서도 `ai_read*`와 `test_list.md`만 읽으면 현재 기준과 다음 작업을 알 수 있어야 한다.
