docs(05): create phase plan
Phase 05: Polish & Deploy - 3 plans in 3 waves - 1 parallel (Wave 1), 2 sequential (Waves 2-3) - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,13 @@ Plans:
|
|||||||
|
|
||||||
**Delivers:** Production readiness
|
**Delivers:** Production readiness
|
||||||
|
|
||||||
|
**Plans:** 3 plans
|
||||||
|
|
||||||
|
Plans:
|
||||||
|
- [ ] 05-01-PLAN.md — Remove NLU nodes and add keyword routing with persistent menu
|
||||||
|
- [ ] 05-02-PLAN.md — Standardize error messages and migrate credentials
|
||||||
|
- [ ] 05-03-PLAN.md — Write deployment README and end-to-end testing
|
||||||
|
|
||||||
**Status:** 🔲 Not started
|
**Status:** 🔲 Not started
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
---
|
||||||
|
phase: 05-polish-deploy
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified: [n8n-workflow.json]
|
||||||
|
autonomous: true
|
||||||
|
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "User sees persistent menu buttons in Telegram"
|
||||||
|
- "Typing 'status' triggers container list (no Claude API call)"
|
||||||
|
- "Typing 'start plex' triggers start flow (no Claude API call)"
|
||||||
|
- "Unknown commands show menu instead of error"
|
||||||
|
artifacts:
|
||||||
|
- path: "n8n-workflow.json"
|
||||||
|
provides: "Keyword Router Switch node"
|
||||||
|
contains: "Keyword Router"
|
||||||
|
- path: "n8n-workflow.json"
|
||||||
|
provides: "Persistent menu reply markup"
|
||||||
|
contains: "is_persistent"
|
||||||
|
key_links:
|
||||||
|
- from: "Telegram Trigger"
|
||||||
|
to: "Keyword Router"
|
||||||
|
via: "Route Message path"
|
||||||
|
pattern: "Keyword Router"
|
||||||
|
- from: "Keyword Router"
|
||||||
|
to: "Docker List Containers"
|
||||||
|
via: "status output"
|
||||||
|
pattern: "status.*Docker List"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Replace Claude/NLU nodes with keyword-based routing and add persistent Telegram menu buttons.
|
||||||
|
|
||||||
|
Purpose: Remove external Claude API dependency, enable offline-first operation with simple keyword matching.
|
||||||
|
Output: Working keyword routing with persistent menu, no Claude API calls in workflow.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-CONTEXT.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-RESEARCH.md
|
||||||
|
@n8n-workflow.json
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Remove NLU/Claude nodes and add Keyword Router</name>
|
||||||
|
<files>n8n-workflow.json</files>
|
||||||
|
<action>
|
||||||
|
Remove these nodes from the workflow:
|
||||||
|
- Prepare Claude Request
|
||||||
|
- Claude Intent Parser (HTTP Request node calling api.anthropic.com)
|
||||||
|
- Parse Intent (Code node)
|
||||||
|
- Intent Router (old Switch node routing on parsed intent)
|
||||||
|
- Send Unknown Intent
|
||||||
|
- Send Intent Error
|
||||||
|
- Remove Anthropic API Key credential reference
|
||||||
|
|
||||||
|
Replace with a single Switch node called "Keyword Router" with these rules (case-insensitive matching on message.text):
|
||||||
|
- Contains "status" -> output "status" -> connect to Docker List Containers
|
||||||
|
- Contains "start" -> output "start" -> connect to Parse Action Command (with action set to start)
|
||||||
|
- Contains "stop" -> output "stop" -> connect to Parse Action Command (with action set to stop)
|
||||||
|
- Contains "restart" -> output "restart" -> connect to Parse Action Command (with action set to restart)
|
||||||
|
- Contains "update" -> output "update" -> connect to existing update flow entry point
|
||||||
|
- Contains "logs" -> output "logs" -> connect to existing logs flow entry point
|
||||||
|
- Fallback (extra) -> connect to new "Show Menu" node
|
||||||
|
|
||||||
|
Use the Switch node pattern from RESEARCH.md:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"conditions": {
|
||||||
|
"options": { "caseSensitive": false },
|
||||||
|
"conditions": [{
|
||||||
|
"leftValue": "={{ $json.message.text }}",
|
||||||
|
"rightValue": "status",
|
||||||
|
"operator": { "type": "string", "operation": "contains" }
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Update "Route Message" node to connect directly to "Keyword Router" instead of the old Claude flow.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Open workflow in n8n UI. Send "status" - should trigger Docker List Containers path.
|
||||||
|
Check that no nodes reference api.anthropic.com or Anthropic API Key credential.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
Keyword Router handles all 6 commands (status, start, stop, restart, update, logs) plus fallback.
|
||||||
|
No Claude/NLU nodes remain in workflow.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Add persistent Telegram menu</name>
|
||||||
|
<files>n8n-workflow.json</files>
|
||||||
|
<action>
|
||||||
|
Create a new "Show Menu" node (HTTP Request type, not native Telegram node - per project pattern for keyboards).
|
||||||
|
|
||||||
|
Configure HTTP Request:
|
||||||
|
- URL: `https://api.telegram.org/bot{{ $credentials.telegramApi.token }}/sendMessage`
|
||||||
|
- Method: POST
|
||||||
|
- Body (JSON):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"chat_id": "={{ $json.message.chat.id }}",
|
||||||
|
"text": "Use buttons below or type commands:",
|
||||||
|
"parse_mode": "HTML",
|
||||||
|
"reply_markup": {
|
||||||
|
"keyboard": [
|
||||||
|
[{"text": "Status"}],
|
||||||
|
[{"text": "Start"}, {"text": "Stop"}],
|
||||||
|
[{"text": "Restart"}, {"text": "Update"}],
|
||||||
|
[{"text": "Logs"}]
|
||||||
|
],
|
||||||
|
"is_persistent": true,
|
||||||
|
"resize_keyboard": true,
|
||||||
|
"one_time_keyboard": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect Keyword Router fallback output to Show Menu node.
|
||||||
|
|
||||||
|
NOTE: Research suggests emojis optional (Claude's discretion from CONTEXT.md). Start without emojis for cleaner keyword matching - button text "Status" matches "status" keyword.
|
||||||
|
|
||||||
|
Also wire /start command to Show Menu:
|
||||||
|
- In Keyword Router, add rule: Contains "/start" -> output "menu" -> connect to Show Menu
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Send any unknown command (e.g., "hello") - should receive menu with persistent keyboard.
|
||||||
|
Send "/start" - should receive same menu.
|
||||||
|
Keyboard should persist after sending other messages.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
Persistent menu visible in Telegram chat.
|
||||||
|
Menu buttons trigger corresponding actions when tapped.
|
||||||
|
/start and unknown commands show menu.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
1. All Claude/NLU nodes removed (grep for "anthropic", "Claude", "Intent" in workflow JSON)
|
||||||
|
2. Keyword Router handles: status, start, stop, restart, update, logs, /start, fallback
|
||||||
|
3. Persistent menu shows 6 buttons in grouped layout
|
||||||
|
4. Button taps trigger corresponding keyword routes
|
||||||
|
5. No errors in n8n execution logs for any command
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Zero references to Anthropic API or Claude in workflow
|
||||||
|
- All 6 container commands work via typed keywords
|
||||||
|
- Persistent menu visible and functional
|
||||||
|
- Unknown input shows menu (not error)
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-polish-deploy/05-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
---
|
||||||
|
phase: 05-polish-deploy
|
||||||
|
plan: 02
|
||||||
|
type: execute
|
||||||
|
wave: 2
|
||||||
|
depends_on: [05-01]
|
||||||
|
files_modified: [n8n-workflow.json]
|
||||||
|
autonomous: true
|
||||||
|
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "Docker socket errors show 'Cannot connect to Docker' (not stack trace)"
|
||||||
|
- "Failed actions show 'Failed to X' format (not verbose details)"
|
||||||
|
- "User ID stored in n8n credentials (not hardcoded in workflow JSON)"
|
||||||
|
artifacts:
|
||||||
|
- path: "n8n-workflow.json"
|
||||||
|
provides: "Terse error messages in response nodes"
|
||||||
|
contains: "Cannot connect to Docker"
|
||||||
|
- path: "n8n-workflow.json"
|
||||||
|
provides: "Credential reference for user auth"
|
||||||
|
contains: "$credentials"
|
||||||
|
key_links:
|
||||||
|
- from: "IF User Authenticated"
|
||||||
|
to: "n8n credentials"
|
||||||
|
via: "credential reference expression"
|
||||||
|
pattern: "\\$credentials"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Harden error handling with minimal user-facing messages and migrate user ID to n8n credentials system.
|
||||||
|
|
||||||
|
Purpose: Production-ready error UX and secure credential storage for workflow sharing.
|
||||||
|
Output: Terse error messages, credential-based auth, exportable workflow without sensitive data.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-CONTEXT.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-RESEARCH.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-01-SUMMARY.md
|
||||||
|
@n8n-workflow.json
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Standardize error messages</name>
|
||||||
|
<files>n8n-workflow.json</files>
|
||||||
|
<action>
|
||||||
|
Find all error response nodes and update their message text to follow minimal format:
|
||||||
|
|
||||||
|
**Docker/infrastructure errors (detect "docker.sock" or "ECONNREFUSED" in error):**
|
||||||
|
- Message: "Cannot connect to Docker"
|
||||||
|
|
||||||
|
**Action failures:**
|
||||||
|
- Pattern: "Failed to {action} {container}"
|
||||||
|
- Examples: "Failed to start plex", "Failed to stop nginx"
|
||||||
|
|
||||||
|
**No match errors:**
|
||||||
|
- Keep existing "No container matching 'X'" format (already terse)
|
||||||
|
|
||||||
|
Update these nodes to use terse format:
|
||||||
|
- Send Docker Error -> "Cannot connect to Docker"
|
||||||
|
- Send Action Result (error case) -> "Failed to {action} {container}"
|
||||||
|
- Send Update Error -> "Failed to update {container}"
|
||||||
|
- Send Logs Error -> "Failed to get logs for {container}"
|
||||||
|
|
||||||
|
Do NOT include:
|
||||||
|
- Stack traces
|
||||||
|
- HTTP status codes
|
||||||
|
- Docker API error details
|
||||||
|
- Technical debugging info
|
||||||
|
|
||||||
|
Per CONTEXT.md: "Minimal error messages - 'Failed to start plex' without verbose details"
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Grep workflow JSON for error messages - should be terse, no technical details.
|
||||||
|
Manually test by stopping n8n's Docker socket access and sending command - should see "Cannot connect to Docker".
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
All user-facing error messages follow terse format.
|
||||||
|
Infrastructure errors show "Cannot connect to Docker".
|
||||||
|
Action errors show "Failed to X Y" pattern.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Migrate user ID to n8n credentials</name>
|
||||||
|
<files>n8n-workflow.json</files>
|
||||||
|
<action>
|
||||||
|
Currently the workflow has hardcoded user ID in IF nodes for auth check. Per CONTEXT.md and RESEARCH.md, migrate to n8n credentials system.
|
||||||
|
|
||||||
|
**Step 1: Create credential type reference in workflow**
|
||||||
|
|
||||||
|
n8n credentials will be created manually by user during deployment, but workflow must reference them.
|
||||||
|
|
||||||
|
**Step 2: Update auth check nodes**
|
||||||
|
|
||||||
|
Find "IF User Authenticated" and "IF Callback Authenticated" nodes.
|
||||||
|
|
||||||
|
Change the condition from hardcoded ID comparison to credential reference:
|
||||||
|
```
|
||||||
|
// Old (hardcoded):
|
||||||
|
$json.message.from.id === 123456789
|
||||||
|
|
||||||
|
// New (credential reference):
|
||||||
|
$json.message.from.id === parseInt($credentials.telegramAuth.userId)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: The credential name "telegramAuth" with field "userId" follows RESEARCH.md pattern.
|
||||||
|
User will create this credential during deployment (documented in README from Plan 03).
|
||||||
|
|
||||||
|
**Step 3: Clean up sensitive data**
|
||||||
|
|
||||||
|
Search workflow JSON for any hardcoded numeric IDs that look like Telegram user IDs (8+ digit numbers).
|
||||||
|
Remove or replace with credential references.
|
||||||
|
|
||||||
|
Per CONTEXT.md: "Sensitive values (Telegram user ID) moved to n8n credentials system - not hardcoded in workflow JSON"
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Grep workflow JSON for 8+ digit numbers - should find none (except node position coordinates).
|
||||||
|
Auth check nodes should reference $credentials.telegramAuth.userId.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
No hardcoded user ID in workflow JSON.
|
||||||
|
Auth nodes use credential reference.
|
||||||
|
Workflow can be safely exported/shared.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
1. All error messages terse (no stack traces, no verbose details)
|
||||||
|
2. Docker socket errors produce "Cannot connect to Docker"
|
||||||
|
3. Action failures produce "Failed to X Y" format
|
||||||
|
4. No hardcoded Telegram user ID in workflow JSON
|
||||||
|
5. Auth nodes reference $credentials.telegramAuth.userId
|
||||||
|
6. Workflow exports cleanly without embedded secrets
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Error messages fit in single Telegram line (no scrolling needed)
|
||||||
|
- Zero hardcoded sensitive values in workflow JSON
|
||||||
|
- grep -E '[0-9]{9,}' workflow.json returns only position coordinates
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-polish-deploy/05-02-SUMMARY.md`
|
||||||
|
</output>
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
---
|
||||||
|
phase: 05-polish-deploy
|
||||||
|
plan: 03
|
||||||
|
type: execute
|
||||||
|
wave: 3
|
||||||
|
depends_on: [05-02]
|
||||||
|
files_modified: [README.md, n8n-workflow.json]
|
||||||
|
autonomous: false
|
||||||
|
|
||||||
|
must_haves:
|
||||||
|
truths:
|
||||||
|
- "README has step-by-step deployment instructions"
|
||||||
|
- "README documents credential creation in n8n"
|
||||||
|
- "README documents Docker socket setup for n8n container"
|
||||||
|
- "All 6 commands tested end-to-end via Telegram"
|
||||||
|
artifacts:
|
||||||
|
- path: "README.md"
|
||||||
|
provides: "Deployment guide"
|
||||||
|
min_lines: 50
|
||||||
|
contains: "Installation"
|
||||||
|
- path: "n8n-workflow.json"
|
||||||
|
provides: "Production-ready workflow"
|
||||||
|
key_links:
|
||||||
|
- from: "README.md"
|
||||||
|
to: "n8n credentials"
|
||||||
|
via: "documentation"
|
||||||
|
pattern: "telegramAuth"
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Write deployment README and perform end-to-end testing of complete bot functionality.
|
||||||
|
|
||||||
|
Purpose: Enable users to deploy the bot on their own Unraid servers with clear instructions.
|
||||||
|
Output: Complete README, verified workflow, production-ready deployment package.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-CONTEXT.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-RESEARCH.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-01-SUMMARY.md
|
||||||
|
@.planning/phases/05-polish-deploy/05-02-SUMMARY.md
|
||||||
|
@n8n-workflow.json
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Write deployment README</name>
|
||||||
|
<files>README.md</files>
|
||||||
|
<action>
|
||||||
|
Replace the stub README with a complete deployment guide. Per CONTEXT.md: "README only - step-by-step instructions in markdown" and "No troubleshooting section - focused on initial setup only".
|
||||||
|
|
||||||
|
Structure (following RESEARCH.md template):
|
||||||
|
|
||||||
|
# Docker Manager Bot
|
||||||
|
|
||||||
|
One-line description: Telegram bot for managing Docker containers on Unraid.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Unraid server with Docker enabled
|
||||||
|
- n8n container running on Unraid
|
||||||
|
- Telegram Bot Token (from @BotFather)
|
||||||
|
- Your Telegram User ID (from @userinfobot)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Configure n8n Container
|
||||||
|
|
||||||
|
Document the Docker run flags needed:
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name n8n \
|
||||||
|
--group-add 281 \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-v /path/to/curl:/usr/bin/curl:ro \
|
||||||
|
n8nio/n8n
|
||||||
|
```
|
||||||
|
|
||||||
|
Explain:
|
||||||
|
- `--group-add 281` for Docker socket access
|
||||||
|
- Socket mount requirement
|
||||||
|
- Static curl binary mount (hardened n8n image)
|
||||||
|
|
||||||
|
### 2. Create n8n Credentials
|
||||||
|
|
||||||
|
**Telegram API credential:**
|
||||||
|
- Type: Telegram API
|
||||||
|
- Access Token: your bot token from @BotFather
|
||||||
|
|
||||||
|
**Telegram Auth credential:**
|
||||||
|
- Type: Header Auth (or custom)
|
||||||
|
- Field: userId = your Telegram user ID
|
||||||
|
|
||||||
|
### 3. Import Workflow
|
||||||
|
|
||||||
|
- Copy n8n-workflow.json to server
|
||||||
|
- In n8n: Workflows -> Import from File
|
||||||
|
- Map credentials when prompted
|
||||||
|
|
||||||
|
### 4. Activate Workflow
|
||||||
|
|
||||||
|
- Open workflow
|
||||||
|
- Click Active toggle
|
||||||
|
- Test with "status" message
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
List the 6 commands:
|
||||||
|
- status - View all containers
|
||||||
|
- start <name> - Start container
|
||||||
|
- stop <name> - Stop container
|
||||||
|
- restart <name> - Restart container
|
||||||
|
- update <name> - Pull and recreate container
|
||||||
|
- logs <name> [lines] - View container logs
|
||||||
|
|
||||||
|
Mention persistent menu buttons available.
|
||||||
|
|
||||||
|
Per CONTEXT.md: No troubleshooting section.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
README exists at root.
|
||||||
|
Contains all 4 installation sections.
|
||||||
|
No troubleshooting section.
|
||||||
|
Markdown renders correctly.
|
||||||
|
</verify>
|
||||||
|
<done>
|
||||||
|
Complete deployment guide in README.md.
|
||||||
|
Step-by-step instructions for fresh Unraid installation.
|
||||||
|
</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="checkpoint:human-verify" gate="blocking">
|
||||||
|
<name>Task 2: End-to-end testing</name>
|
||||||
|
<what-built>
|
||||||
|
Complete Docker Manager Bot:
|
||||||
|
- Keyword routing (no Claude dependency)
|
||||||
|
- Persistent Telegram menu
|
||||||
|
- All 6 container commands
|
||||||
|
- Terse error messages
|
||||||
|
- Credential-based auth
|
||||||
|
</what-built>
|
||||||
|
<how-to-verify>
|
||||||
|
Test each command via Telegram bot:
|
||||||
|
|
||||||
|
1. **Menu:** Send /start or any unknown text
|
||||||
|
- Expected: Persistent keyboard appears with 6 buttons
|
||||||
|
|
||||||
|
2. **Status:** Tap Status button or type "status"
|
||||||
|
- Expected: List of containers with status indicators
|
||||||
|
|
||||||
|
3. **Start:** Type "start <stopped-container-name>"
|
||||||
|
- Expected: Container starts, confirmation message
|
||||||
|
|
||||||
|
4. **Stop:** Type "stop <running-container-name>"
|
||||||
|
- Expected: Container stops, confirmation message
|
||||||
|
|
||||||
|
5. **Restart:** Type "restart <container-name>"
|
||||||
|
- Expected: Container restarts, confirmation message
|
||||||
|
|
||||||
|
6. **Update:** Type "update <container-name>"
|
||||||
|
- Expected: Image pulled, container recreated (or silent if no update)
|
||||||
|
|
||||||
|
7. **Logs:** Type "logs <container-name>"
|
||||||
|
- Expected: Last 50 log lines displayed
|
||||||
|
|
||||||
|
8. **Error handling:** Stop n8n's Docker socket access briefly
|
||||||
|
- Expected: "Cannot connect to Docker" (not stack trace)
|
||||||
|
|
||||||
|
9. **Auth:** Message bot from different Telegram account
|
||||||
|
- Expected: No response (silent ignore per Phase 1 decision)
|
||||||
|
</how-to-verify>
|
||||||
|
<resume-signal>Type "approved" if all tests pass, or describe which tests failed</resume-signal>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
1. README exists and has all required sections
|
||||||
|
2. All 6 commands work end-to-end
|
||||||
|
3. Persistent menu functions correctly
|
||||||
|
4. Error messages are terse
|
||||||
|
5. Unauthorized users get no response
|
||||||
|
6. Workflow exports without sensitive data
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Fresh user can follow README to deploy bot
|
||||||
|
- All container management commands functional
|
||||||
|
- Bot ready for production use on Unraid
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-polish-deploy/05-03-SUMMARY.md`
|
||||||
|
</output>
|
||||||
Reference in New Issue
Block a user