# Synology Snapshot Admin Deployment Checklist

This checklist is the POC-ready version with concrete values.

## 1. Target paths

- Project root: `/volume1/projects/data_feed`
- Launch script: `/volume1/projects/data_feed/tools/run_snapshot_admin_synology.sh`
- Local DB: `/volume1/projects/data_feed/outputs/snapshot_admin/snapshot_admin.db`
- Local seed JSON: `/volume1/projects/data_feed/GatherTradingData.json`
- PID file: `/volume1/projects/data_feed/Temp/snapshot_admin.pid`
- Log file: `/volume1/projects/data_feed/Temp/snapshot_admin.log`

See also: [`docs/SYNOLOGY_SNAPSHOT_ADMIN_DEPLOYMENT_CHECKLIST_FILLED.md`](C:/Temp/data_feed/docs/SYNOLOGY_SNAPSHOT_ADMIN_DEPLOYMENT_CHECKLIST_FILLED.md)
and [`docs/SYNOLOGY_SNAPSHOT_ADMIN_FIREWALL_PROXY_TABLE.md`](C:/Temp/data_feed/docs/SYNOLOGY_SNAPSHOT_ADMIN_FIREWALL_PROXY_TABLE.md)

## 2. Service account

- Preferred: dedicated DSM local user `snapshot-admin`
- Fallback for first POC: `root`
- Required permission: read/write access to `/volume1/projects/data_feed`

## 3. Environment variables

Set these before the Task Scheduler task runs.

- `SNAPSHOT_ADMIN_AUTH_USER=snapshot-admin`
- `SNAPSHOT_ADMIN_AUTH_PASSWORD=<strong-password>`
- `SNAPSHOT_ADMIN_HOST=127.0.0.1`
- `SNAPSHOT_ADMIN_PORT=8787`
- `SNAPSHOT_ADMIN_ALLOW_REMOTE=0`
- `SNAPSHOT_ADMIN_PID_FILE=/volume1/projects/data_feed/Temp/snapshot_admin.pid`
- `SNAPSHOT_ADMIN_LOG_FILE=/volume1/projects/data_feed/Temp/snapshot_admin.log`
- `SNAPSHOT_ADMIN_STATE_URL=http://127.0.0.1:8787/api/state`
- `SNAPSHOT_ADMIN_PUBLIC_STATE_URL=https://admin.example.com/api/state`

## 4. Task Scheduler tasks

### Boot task

- Name: `snapshot-admin-start`
- Trigger: `Boot-up`
- User: `snapshot-admin` or `root`
- Command:

```bash
bash /volume1/projects/data_feed/tools/run_snapshot_admin_synology.sh start
```

### Healthcheck task

- Name: `snapshot-admin-healthcheck`
- Trigger: `Scheduled Task`
- Interval: every 5 minutes
- User: same as boot task
- Command:

```bash
bash /volume1/projects/data_feed/tools/run_snapshot_admin_synology.sh healthcheck
```

### Restart task

- Name: `snapshot-admin-restart`
- Trigger: manual only
- User: same as boot task
- Command:

```bash
bash /volume1/projects/data_feed/tools/run_snapshot_admin_synology.sh restart
```

## 4b. Gitea Actions runner label

Use a unique host label so the deployment job is not mixed with generic self-hosted work.

- Runner label: `snapshot-admin-host`
- Registration example:

```bash
REG_TOKEN="<runner-registration-token>" \
GITEA_URL="http://192.168.123.100:8418" \
RUNNER_LABEL="snapshot-admin-host" \
bash tools/re_register_act_runner_synology.sh
```

- Workflow selector:

```yaml
runs-on: [self-hosted, snapshot-admin-host]
```

## 4c. Queue handling

- If the deploy workflow stays queued, it usually means the host runner is busy.
- Check the job currently holding the runner before re-dispatching.
- Do not keep dispatching deploy runs back-to-back. The workflow already uses `concurrency` to cancel in-progress duplicates.

## 5. Reverse proxy

- DSM path: `Control Panel > Login Portal > Advanced > Reverse Proxy`
- Rule name: `snapshot-admin`
- Source:
  - Protocol: `HTTPS`
  - Hostname: `admin.example.com`
  - Port: `443`
  - Path: `/`
- Destination:
  - Protocol: `HTTP`
  - Hostname: `127.0.0.1`
  - Port: `8787`
- TLS certificate: certificate matching `admin.example.com`

## 6. Firewall

- Allow inbound `443/TCP`
- Block inbound `8787/TCP` from WAN
- If needed, allowlist office/VPN CIDRs only

## 7. Verification order

1. Start the service.
2. Confirm `bash /volume1/projects/data_feed/tools/run_snapshot_admin_synology.sh healthcheck` prints `healthcheck ok`.
3. Confirm local `curl -i http://127.0.0.1:8787/api/state`.
   - Expect `200 OK`.
   - Expect JSON with `version.app = snapshot-admin-web-v7`.
4. Confirm external `curl -i https://admin.example.com/api/state` returns `401`.
   - Expect `WWW-Authenticate: Basic`.
5. Confirm authenticated `curl -u 'snapshot-admin:<password>' https://admin.example.com/api/state` returns `200`.
   - Expect the same `version.app` value as the local endpoint.
6. Confirm `curl -i https://admin.example.com/tables` after Basic Auth.
   - Expect `200 OK` and the Tabler grid page.
7. Open browser `https://admin.example.com/`.
   - Expect Basic Auth prompt, then UI render.
8. Open browser `https://admin.example.com/tables`.
   - Expect Basic Auth prompt, then grid render.
9. Restart the task or NAS.
10. Repeat steps 2-8 and confirm the response pattern is unchanged.

## 7b. Evidence rule

- Do not mark `WBS-7.9` complete until the external `401`/`200` curl pair, both browser screenshots, and the reverse proxy rule screenshot are archived together.
- Loopback-only smoke tests are useful, but they do not replace the NAS-side live verification.

## 7c. One-page field run sheet

For a compact field execution order, use [`docs/SYNOLOGY_SNAPSHOT_ADMIN_FINAL_EXECUTION_ONE_PAGER.md`](C:/Temp/data_feed/docs/SYNOLOGY_SNAPSHOT_ADMIN_FINAL_EXECUTION_ONE_PAGER.md).

## 8. Completion wording

Use the following text only after evidence is collected:

> WBS-7.9 실배포 검증 완료: Synology NAS에서 `tools/run_snapshot_admin_synology.sh` 기반 서비스가 `127.0.0.1:8787`에 정상 기동되고, DSM Reverse Proxy `HTTPS:443 -> HTTP 127.0.0.1:8787` 경유 외부 접속이 Basic Auth와 함께 `200 OK`로 확인되었으며, 미인증 요청은 `401 Unauthorized`로 차단되었다. `/` 및 `/tables` 렌더링과 재시작 후 지속성도 확인되었고, 증빙은 `docs/SYNOLOGY_SNAPSHOT_ADMIN_EVIDENCE_TEMPLATE.md` 양식으로 보관되었다.
