feat: initialize managed portal

This commit is contained in:
Yoilun
2026-04-27 10:04:36 +08:00
commit d4e351df71
145 changed files with 13425 additions and 0 deletions

View File

@@ -0,0 +1,240 @@
# Offline Bundle Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Build a self-contained offline delivery bundle for `store_dwell_alert_108` that can be unpacked on a `.108`-class machine, installed without internet, and run after the operator edits `scripts/run.sh`.
**Architecture:** Add a delivery layer around the existing runtime by introducing a bundle staging pipeline, a locked requirements file, an offline wheelhouse, portable install/run scripts, and a relocatable service template. Keep the application logic unchanged and isolate all new behavior to packaging, deployment, and documentation.
**Tech Stack:** Bash, Python virtual environments, pip wheelhouse installs, tar.gz packaging, systemd, existing `ultralytics` runtime.
---
### Task 1: Audit runtime inputs and delivery assets
**Files:**
- Modify: `README.md`
- Create: `docs/plans/2026-04-16-offline-bundle-design.md`
- Create: `docs/plans/2026-04-16-offline-bundle.md`
**Step 1: Verify the current runtime entrypoints and required assets**
Check `app/main.py`, `requirements.txt`, `config/config.example.yaml`, `scripts/run_local.sh`, and `deploy/store-dwell-alert.service` to identify everything the bundle must include.
**Step 2: Update the top-level README scope if needed**
Add a short note that the project now supports building an offline delivery bundle for compatible hosts.
**Step 3: Commit**
```bash
git add README.md docs/plans/2026-04-16-offline-bundle-design.md docs/plans/2026-04-16-offline-bundle.md
git commit -m "docs: add offline bundle design and plan"
```
### Task 2: Add bundle-facing deployment files
**Files:**
- Create: `deploy/store-dwell-alert.service.tpl`
- Create: `scripts/install.sh`
- Create: `scripts/run.sh`
- Create: `scripts/install_service.sh`
- Test: `tests/test_bundle_layout.py`
**Step 1: Write the failing tests**
Add tests that assert:
- the new scripts exist
- `run.sh` contains a placeholder `RTSP_URL`
- the service template contains placeholder tokens rather than a host-pinned path
**Step 2: Run the tests to verify they fail**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 3: Write the minimal implementation**
Create the installer, runner, and service template files with portable placeholders and safe shell behavior.
**Step 4: Run the tests to verify they pass**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 5: Commit**
```bash
git add deploy/store-dwell-alert.service.tpl scripts/install.sh scripts/run.sh scripts/install_service.sh tests/test_bundle_layout.py
git commit -m "feat: add offline bundle deployment scripts"
```
### Task 3: Lock Python dependencies for offline delivery
**Files:**
- Create: `requirements.lock.txt`
- Modify: `requirements.txt`
- Test: `tests/test_bundle_layout.py`
**Step 1: Write the failing tests**
Extend bundle layout tests to assert:
- `requirements.lock.txt` exists
- it pins exact versions for the runtime packages needed by the bundle
**Step 2: Run the tests to verify they fail**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 3: Write the minimal implementation**
Add a checked-in `requirements.lock.txt` aligned with the known-good runtime stack and keep `requirements.txt` as the human-edited high-level list if needed.
**Step 4: Run the tests to verify they pass**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 5: Commit**
```bash
git add requirements.txt requirements.lock.txt tests/test_bundle_layout.py
git commit -m "build: lock offline bundle dependencies"
```
### Task 4: Add bundle staging and archive generation
**Files:**
- Create: `scripts/package_bundle.sh`
- Modify: `README.md`
- Test: `tests/test_bundle_layout.py`
**Step 1: Write the failing tests**
Add tests that assert:
- `scripts/package_bundle.sh` exists
- it references the expected bundle contents
- it excludes host-specific config such as `config/108.local.yaml`
**Step 2: Run the tests to verify they fail**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 3: Write the minimal implementation**
Create `scripts/package_bundle.sh` to stage the bundle into `dist/store_dwell_alert_bundle/` and archive it as `dist/store_dwell_alert_bundle_<date>.tar.gz`.
**Step 4: Run the tests to verify they pass**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 5: Commit**
```bash
git add scripts/package_bundle.sh README.md tests/test_bundle_layout.py
git commit -m "build: add offline bundle packaging script"
```
### Task 5: Vendor weights and prepare runtime directories
**Files:**
- Create: `weights/.gitkeep`
- Create: `data/staff_gallery/.gitkeep`
- Create: `data/runtime/.gitkeep`
- Modify: `README.md`
- Test: `tests/test_bundle_layout.py`
**Step 1: Write the failing tests**
Add tests that assert the bundle pipeline expects:
- `weights/`
- `data/staff_gallery/`
- `data/runtime/`
**Step 2: Run the tests to verify they fail**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 3: Write the minimal implementation**
Create the tracked directories and document that `weights/yolo11n.pt` must exist before packaging.
**Step 4: Run the tests to verify they pass**
Run: `pytest tests/test_bundle_layout.py -v`
**Step 5: Commit**
```bash
git add weights/.gitkeep data/staff_gallery/.gitkeep data/runtime/.gitkeep README.md tests/test_bundle_layout.py
git commit -m "chore: track offline bundle asset directories"
```
### Task 6: Document operator workflow
**Files:**
- Modify: `README.md`
- Test: `tests/test_main_smoke.py`
**Step 1: Write the failing test**
If practical, add a smoke-level documentation assertion or adjust an existing smoke test so the offline scripts are covered by a simple presence/usage check.
**Step 2: Run the test to verify it fails**
Run: `pytest tests/test_main_smoke.py -v`
**Step 3: Write the minimal implementation**
Document:
- how to build the bundle
- how to transfer it
- how to run `scripts/install.sh`
- how to edit `scripts/run.sh`
- how to optionally install the service
**Step 4: Run the tests to verify they pass**
Run: `pytest tests/test_main_smoke.py -v`
**Step 5: Commit**
```bash
git add README.md tests/test_main_smoke.py
git commit -m "docs: add offline bundle operator workflow"
```
### Task 7: Produce and verify a real bundle locally
**Files:**
- Modify: `scripts/package_bundle.sh`
- Modify: `README.md`
**Step 1: Run the packaging script**
Run: `bash scripts/package_bundle.sh`
Expected:
- `dist/store_dwell_alert_bundle/` is created
- `dist/store_dwell_alert_bundle_<date>.tar.gz` is created
**Step 2: Inspect the archive contents**
Run: `tar -tzf dist/store_dwell_alert_bundle_<date>.tar.gz`
Expected:
- bundled scripts, config template, service template, app code, `requirements.lock.txt`, and tracked runtime directories are present
**Step 3: Fix any path or omission bugs**
Adjust the packaging script until the archive layout matches the design.
**Step 4: Run the full test suite**
Run: `pytest -q`
Expected: PASS
**Step 5: Commit**
```bash
git add scripts/package_bundle.sh README.md
git commit -m "build: verify offline bundle artifact generation"
```