Files
Lucas Berger b7cefd931e 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>
2026-01-31 21:00:51 -05:00

173 lines
5.6 KiB
Markdown

---
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>