Add WEHAGO account ledger snapshot
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
# WEHAGO 계정별 원장 스냅샷
|
||||||
|
|
||||||
|
이 저장소에는 한맥기술 WEHAGO 계정별 원장 정보를 공유하기 위한 압축 SQLite 스냅샷이 포함되어 있습니다.
|
||||||
|
|
||||||
|
## 포함 파일
|
||||||
|
|
||||||
|
```text
|
||||||
|
snapshots/wehago_account_ledger_snapshot_20260605.sqlite3.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
## 포함 데이터
|
||||||
|
|
||||||
|
- `ledger_rows`: WEHAGO 계정별 원장 행 47,777건
|
||||||
|
- `source_files`: 원장 생성에 사용된 원본 파일 메타 136건
|
||||||
|
- `snapshot_manifest`: 스냅샷 생성일과 행 수 정보
|
||||||
|
|
||||||
|
전표 행(`voucher_rows`)과 비교 결과(`comparison_results`)는 이 스냅샷에 포함하지 않았습니다. 계정별 원장 공유 목적에 맞춰 파일 크기와 노출 범위를 줄이기 위해서입니다.
|
||||||
|
|
||||||
|
## 복원 방법
|
||||||
|
|
||||||
|
저장소를 받은 뒤 아래 명령을 실행합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd WEHAGO_DB
|
||||||
|
python3 scripts/restore_account_ledger_snapshot.py
|
||||||
|
```
|
||||||
|
|
||||||
|
복원 결과:
|
||||||
|
|
||||||
|
```text
|
||||||
|
data/wehago_account_ledger.sqlite3
|
||||||
|
```
|
||||||
|
|
||||||
|
다른 경로로 복원하려면:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/restore_account_ledger_snapshot.py --output /desired/path/wehago_account_ledger.sqlite3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 무결성
|
||||||
|
|
||||||
|
압축 스냅샷 SHA-256:
|
||||||
|
|
||||||
|
```text
|
||||||
|
dd1e8792d277427f1c95aa95f8eeefe92b208adc51168161ec3ec5b16f0b526f
|
||||||
|
```
|
||||||
|
|
||||||
|
복원 스크립트는 기본적으로 이 체크섬을 검증합니다.
|
||||||
|
|
||||||
|
## 주의
|
||||||
|
|
||||||
|
이 데이터에는 원장, 거래처, 금액 등 업무 정보가 포함될 수 있습니다. Gitea 저장소 접근 권한은 내부 공유 대상자로 제한해야 합니다.
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import gzip
|
||||||
|
import hashlib
|
||||||
|
import shutil
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_SNAPSHOT = Path(__file__).resolve().parents[1] / "snapshots" / "wehago_account_ledger_snapshot_20260605.sqlite3.gz"
|
||||||
|
DEFAULT_OUTPUT = Path(__file__).resolve().parents[1] / "data" / "wehago_account_ledger.sqlite3"
|
||||||
|
EXPECTED_SHA256 = "dd1e8792d277427f1c95aa95f8eeefe92b208adc51168161ec3ec5b16f0b526f"
|
||||||
|
|
||||||
|
|
||||||
|
def sha256(path: Path) -> str:
|
||||||
|
digest = hashlib.sha256()
|
||||||
|
with path.open("rb") as handle:
|
||||||
|
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
||||||
|
digest.update(chunk)
|
||||||
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(description="Restore the shared WEHAGO account ledger SQLite snapshot.")
|
||||||
|
parser.add_argument("--snapshot", type=Path, default=DEFAULT_SNAPSHOT, help="Path to the .sqlite3.gz snapshot.")
|
||||||
|
parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT, help="Output SQLite DB path.")
|
||||||
|
parser.add_argument("--skip-checksum", action="store_true", help="Skip snapshot checksum verification.")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
snapshot = args.snapshot.expanduser().resolve()
|
||||||
|
output = args.output.expanduser().resolve()
|
||||||
|
if not snapshot.exists():
|
||||||
|
raise SystemExit(f"Snapshot not found: {snapshot}")
|
||||||
|
if not args.skip_checksum:
|
||||||
|
actual = sha256(snapshot)
|
||||||
|
if actual != EXPECTED_SHA256:
|
||||||
|
raise SystemExit(f"Checksum mismatch: {actual} != {EXPECTED_SHA256}")
|
||||||
|
|
||||||
|
output.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
temp_output = output.with_suffix(output.suffix + ".tmp")
|
||||||
|
with gzip.open(snapshot, "rb") as source, temp_output.open("wb") as dest:
|
||||||
|
shutil.copyfileobj(source, dest)
|
||||||
|
temp_output.replace(output)
|
||||||
|
print(f"Restored: {output}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Binary file not shown.
Reference in New Issue
Block a user