chore: update plan docs, add optimize-update-sh plan
This commit is contained in:
@@ -87,19 +87,19 @@ Make the NexusGuard WG dashboard feature-complete with wg-dashboard-style key vi
|
||||
- Debug panel read-only section in DeviceDetail
|
||||
|
||||
### Definition of Done
|
||||
- [ ] `curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID -d '{"dns":"1.1.1.1"}'` → 200, DNS updated
|
||||
- [ ] `curl -X PUT -H "Authorization: Bearer $NON_ADMIN_TOKEN" /api/v1/devices/$OTHER_USER_DEVICE_ID` → 404 (not found)
|
||||
- [ ] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID` → JSON includes `private_key` and `preshared_key`
|
||||
- [ ] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices` → Array items DO NOT contain `private_key` or `preshared_key`
|
||||
- [ ] `curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID/regenerate-keys` → 200, new private_key + preshared_key (≠ old)
|
||||
- [ ] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID/status` → 200, JSON with is_active, last_handshake, rx_bytes, tx_bytes
|
||||
- [ ] `curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/servers/$ID -d '{"public_key":"newpub..."}'` → 200, server.public_key updated
|
||||
- [ ] `npm run build` passing (vue-tsc + vite build)
|
||||
- [ ] `go build -tags dev ./...` passing
|
||||
- [ ] DeviceDetail.vue shows PrivateKey/PresharedKey with eye-toggle (admin only)
|
||||
- [ ] DeviceDetail.vue has "Regenerate Keys" button → calls POST → shows new keys
|
||||
- [ ] DeviceDetail.vue has debug panel showing status data
|
||||
- [ ] Servers.vue edit modal has PublicKey input field
|
||||
- [x] `curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID -d '{"dns":"1.1.1.1"}'` → 200, DNS updated
|
||||
- [x] `curl -X PUT -H "Authorization: Bearer $NON_ADMIN_TOKEN" /api/v1/devices/$OTHER_USER_DEVICE_ID` → 404 (not found)
|
||||
- [x] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID` → JSON includes `private_key` and `preshared_key`
|
||||
- [x] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices` → Array items DO NOT contain `private_key` or `preshared_key`
|
||||
- [x] `curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID/regenerate-keys` → 200, new private_key + preshared_key (≠ old)
|
||||
- [x] `curl -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/devices/$ID/status` → 200, JSON with is_active, last_handshake, rx_bytes, tx_bytes
|
||||
- [x] `curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" /api/v1/servers/$ID -d '{"public_key":"newpub..."}'` → 200, server.public_key updated
|
||||
- [x] `npm run build` passing (vue-tsc + vite build)
|
||||
- [x] `go build -tags dev ./...` passing
|
||||
- [x] DeviceDetail.vue shows PrivateKey/PresharedKey with eye-toggle (admin only)
|
||||
- [x] DeviceDetail.vue has "Regenerate Keys" button → calls POST → shows new keys
|
||||
- [x] DeviceDetail.vue has debug panel showing status data
|
||||
- [x] Servers.vue edit modal has PublicKey input field
|
||||
|
||||
### Must Have
|
||||
- Admin bypass in all 6 devices.go handlers (Get, Update, Delete, RegenerateToken, Suspend, Unsuspend)
|
||||
@@ -169,7 +169,7 @@ Wave FINAL (Verification):
|
||||
|
||||
## TODOs
|
||||
|
||||
- [ ] 1. **Add json tags to Device.PrivateKey/PresharedKey + strip from List**
|
||||
- [x] 1. **Add json tags to Device.PrivateKey/PresharedKey + strip from List**
|
||||
|
||||
**What to do**:
|
||||
- In `models/models.go`, add `json:"private_key"` and `json:"preshared_key"` tags to `Device.PrivateKey` and `Device.PresharedKey`
|
||||
@@ -236,7 +236,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): expose Device private/preshared keys for admin on individual GET, strip from List`
|
||||
- Files: `apps/server-core/internal/models/models.go`, `apps/server-core/api/devices.go`
|
||||
|
||||
- [ ] 2. **Admin bypass in devices.go handlers**
|
||||
- [x] 2. **Admin bypass in devices.go handlers**
|
||||
|
||||
**What to do**:
|
||||
- In `devices.go`, add `isAdmin(c)` checks to `Get`, `Update`, `Delete`, `RegenerateToken`, `Suspend`, `Unsuspend` handlers
|
||||
@@ -303,7 +303,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): admin bypass in devices.go Get/Update/Delete/RegenerateToken/Suspend/Unsuspend`
|
||||
- Files: `apps/server-core/api/devices.go`
|
||||
|
||||
- [ ] 3. **Add private_key/preshared_key to UpdateDeviceRequest + ParseKey validation**
|
||||
- [x] 3. **Add private_key/preshared_key to UpdateDeviceRequest + ParseKey validation**
|
||||
|
||||
**What to do**:
|
||||
- In `devices.go`, add `PrivateKey *string \`json:"private_key"\`` and `PresharedKey *string \`json:"preshared_key"\`` to `UpdateDeviceRequest` struct
|
||||
@@ -366,7 +366,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): add private_key/preshared_key to UpdateDeviceRequest with ParseKey validation`
|
||||
- Files: `apps/server-core/api/devices.go`
|
||||
|
||||
- [ ] 4. **POST /devices/:id/regenerate-keys endpoint**
|
||||
- [x] 4. **POST /devices/:id/regenerate-keys endpoint**
|
||||
|
||||
**What to do**:
|
||||
- In `devices.go`, add a new `RegenerateKeys` handler method on `DevicesHandler`
|
||||
@@ -437,7 +437,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): add POST /devices/:id/regenerate-keys endpoint`
|
||||
- Files: `apps/server-core/api/devices.go`, `apps/server-core/main.go`
|
||||
|
||||
- [ ] 5. **GET /devices/:id/status endpoint (admin-only, real-time WG data)**
|
||||
- [x] 5. **GET /devices/:id/status endpoint (admin-only, real-time WG data)**
|
||||
|
||||
**What to do**:
|
||||
- In a new file or existing `devices.go`, add a `GetDeviceStatus` handler on `DevicesHandler`
|
||||
@@ -507,7 +507,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): add GET /devices/:id/status endpoint for real-time WG data`
|
||||
- Files: `apps/server-core/api/devices.go`, `apps/server-core/main.go`
|
||||
|
||||
- [ ] 6. **UpdateServerRequest: add public_key field + Servers.vue edit modal wiring**
|
||||
- [x] 6. **UpdateServerRequest: add public_key field + Servers.vue edit modal wiring**
|
||||
|
||||
**What to do**:
|
||||
**Backend**:
|
||||
@@ -560,7 +560,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(api): add public_key to UpdateServerRequest for node key editing`
|
||||
- Files: `apps/server-core/api/servers.go`, `apps/dashboard-ui/src/api/servers.ts`
|
||||
|
||||
- [ ] 7. **Update Device interface + mapDevice in devices.ts**
|
||||
- [x] 7. **Update Device interface + mapDevice in devices.ts**
|
||||
|
||||
**What to do**:
|
||||
- In `devices.ts`, add `PrivateKey?: string` and `PresharedKey?: string` to the `Device` TypeScript interface
|
||||
@@ -610,7 +610,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(ui): add PrivateKey/PresharedKey to Device TypeScript interface and mapDevice`
|
||||
- Files: `apps/dashboard-ui/src/api/devices.ts`
|
||||
|
||||
- [ ] 8. **DeviceDetail.vue: PrivateKey/PresharedKey display with eye toggle (admin only)**
|
||||
- [x] 8. **DeviceDetail.vue: PrivateKey/PresharedKey display with eye toggle (admin only)**
|
||||
|
||||
**What to do**:
|
||||
- In the DeviceDetail template, add a new section (below Allow Internet Access, inside the left column) showing:
|
||||
@@ -681,7 +681,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(ui): add PrivateKey/PresharedKey display with eye toggle in DeviceDetail (admin only)`
|
||||
- Files: `apps/dashboard-ui/src/views/DeviceDetail.vue`
|
||||
|
||||
- [ ] 9. **DeviceDetail.vue: Regenerate Keys button**
|
||||
- [x] 9. **DeviceDetail.vue: Regenerate Keys button**
|
||||
|
||||
**What to do**:
|
||||
- Add a new function `handleRegenerateKeys()` that calls a new API function `regenerateDeviceKeys(id)`
|
||||
@@ -748,7 +748,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(ui): add Regenerate Keys button and API in DeviceDetail`
|
||||
- Files: `apps/dashboard-ui/src/views/DeviceDetail.vue`, `apps/dashboard-ui/src/api/devices.ts`
|
||||
|
||||
- [ ] 10. **DeviceDetail.vue: Debug panel (status data section)**
|
||||
- [x] 10. **DeviceDetail.vue: Debug panel (status data section)**
|
||||
|
||||
**What to do**:
|
||||
- Add a "🔍 Connection Status" section in DeviceDetail.vue (below Advanced Settings if admin)
|
||||
@@ -828,7 +828,7 @@ Wave FINAL (Verification):
|
||||
- Message: `feat(ui): add Connection Status debug panel and getDeviceStatus API`
|
||||
- Files: `apps/dashboard-ui/src/views/DeviceDetail.vue`, `apps/dashboard-ui/src/api/devices.ts`
|
||||
|
||||
- [ ] 11. **Servers.vue: Add PublicKey field to edit modal**
|
||||
- [x] 11. **Servers.vue: Add PublicKey field to edit modal**
|
||||
|
||||
**What to do**:
|
||||
- In `Servers.vue` edit modal (lines 162-262), add a Public Key input field in the "Network" section
|
||||
@@ -887,19 +887,19 @@ Wave FINAL (Verification):
|
||||
|
||||
## Final Verification Wave (MANDATORY — after ALL implementation tasks)
|
||||
|
||||
- [ ] F1. **Plan Compliance Audit** — `oracle`
|
||||
- [x] F1. **Plan Compliance Audit** — `oracle`
|
||||
Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, curl endpoint, run command). For each "Must NOT Have": search codebase for forbidden patterns — reject with file:line if found. Check evidence files exist in .sisyphus/evidence/. Compare deliverables against plan.
|
||||
Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`
|
||||
|
||||
- [ ] F2. **Code Quality Review** — `unspecified-high`
|
||||
- [x] F2. **Code Quality Review** — `unspecified-high`
|
||||
Run `tsc --noEmit` + `go build -tags dev ./...` + `go vet ./...`. Review all changed files for: `as any`/`@ts-ignore`, empty catches, console.log in prod, commented-out code, unused imports. Check AI slop: excessive comments, over-abstraction, generic names. Check no PrivateKey is logged anywhere (grep for `log.*PrivateKey`, `fmt.Print.*PrivateKey`).
|
||||
Output: `Build [PASS/FAIL] | Vet [PASS/FAIL] | TSC [PASS/FAIL] | Files [N clean/N issues] | VERDICT`
|
||||
|
||||
- [ ] F3. **Real Manual QA** — `unspecified-high` (+ `playwright` skill)
|
||||
- [x] F3. **Real Manual QA** — `unspecified-high` (+ `playwright` skill)
|
||||
Start from clean state. Execute EVERY QA scenario from EVERY task — follow exact steps, capture evidence. Test cross-task integration (admin bypass + key display working together). Test edge cases: non-admin attempts, invalid keys, regenerate on unprovisioned device. Save to `.sisyphus/evidence/final-qa/`.
|
||||
Output: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT`
|
||||
|
||||
- [ ] F4. **Scope Fidelity Check** — `deep`
|
||||
- [x] F4. **Scope Fidelity Check** — `deep`
|
||||
For each task: read "What to do", read actual diff (git log/diff). Verify 1:1 — everything in spec was built (no missing), nothing beyond spec was built (no creep). Check "Must NOT do" compliance. Detect cross-task contamination: Task N touching Task M's files. Flag unaccounted changes.
|
||||
Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | Unaccounted [CLEAN/N files] | VERDICT`
|
||||
|
||||
@@ -930,12 +930,12 @@ cd apps/server-core && go test ./... -tags dev
|
||||
```
|
||||
|
||||
### Final Checklist
|
||||
- [ ] Admin can see/edit keys on individual device GET
|
||||
- [ ] Non-admin cannot see any keys
|
||||
- [ ] Keys not exposed in List responses
|
||||
- [ ] `POST /devices/:id/regenerate-keys` works and calls SyncLocalPeers
|
||||
- [ ] `GET /devices/:id/status` returns real-time data
|
||||
- [ ] Server PublicKey editable in edit modal
|
||||
- [ ] Admin bypass works for all 6 handlers
|
||||
- [ ] No security regressions (keys not logged, not in lists)
|
||||
- [ ] `json:"-"` on WgServer.PrivateKey preserved
|
||||
- [x] Admin can see/edit keys on individual device GET
|
||||
- [x] Non-admin cannot see any keys
|
||||
- [x] Keys not exposed in List responses
|
||||
- [x] `POST /devices/:id/regenerate-keys` works and calls SyncLocalPeers
|
||||
- [x] `GET /devices/:id/status` returns real-time data
|
||||
- [x] Server PublicKey editable in edit modal
|
||||
- [x] Admin bypass works for all 6 handlers
|
||||
- [x] No security regressions (keys not logged, not in lists)
|
||||
- [x] `json:"-"` on WgServer.PrivateKey preserved
|
||||
|
||||
Reference in New Issue
Block a user