From a49db192f48b0bf21bea4c3a840129a53446269c Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Fri, 14 Nov 2025 11:25:09 +0100 Subject: [PATCH] feat: complete Nextcloud Deck integration with English emoji stack names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Renamed all stacks to English with emojis (Backlog, Planning, In Progress, Complete) - Updated sync script to use new stack names - Created all 3 initiative cards (IDs 189-191) - Enhanced error handling with detailed debug output - Updated documentation with API limitations and troubleshooting - Fixed stack fallback from 'eingang' to '📥 Backlog' Changes: - scripts/sync-roadmap-to-deck.py: Updated STATUS_TO_STACK mapping, added verbose logging - docs/NEXTCLOUD_DECK_SYNC.md: Updated stack table, added Known Limitations section, enhanced troubleshooting Note: 6 duplicate/test cards (184-188, 192) must be deleted manually from Nextcloud UI due to API limitations (DELETE returns 405) --- docs/NEXTCLOUD_DECK_SYNC.md | 57 ++++++++++++++++++++++++++------- scripts/sync-roadmap-to-deck.py | 42 ++++++++++++++++-------- 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/docs/NEXTCLOUD_DECK_SYNC.md b/docs/NEXTCLOUD_DECK_SYNC.md index d710597..c1af941 100644 --- a/docs/NEXTCLOUD_DECK_SYNC.md +++ b/docs/NEXTCLOUD_DECK_SYNC.md @@ -32,10 +32,10 @@ This will: | Deck Stack | Roadmap Status | Purpose | |------------|----------------|---------| -| `eingang` (inbox) | FUTURE | Backlog items, ideas, future phases | -| `in planung` (planning) | PENDING | Ready to implement, needs detailed specs | -| `in arbeit` (in progress) | IN PROGRESS (🔄) | Currently working on | -| `erledigt` (done) | COMPLETE (✅) | Finished and verified | +| 📥 Backlog | FUTURE | Backlog items, ideas, future phases | +| 📋 Planning | PENDING | Ready to implement, needs detailed specs | +| 🚀 In Progress | IN PROGRESS (🔄) | Currently working on | +| ✅ Complete | COMPLETE (✅) | Finished and verified | ## Usage @@ -102,9 +102,34 @@ Nextcloud Deck API: `/index.php/apps/deck/api/v1.0` Key endpoints used: - `GET /boards` - List all boards -- `GET /boards/{boardId}` - Get board details -- `GET /boards/{boardId}/stacks` - Get stacks +- `GET /boards/{boardId}` - Get board details with stacks (no cards included) +- `GET /boards/{boardId}/stacks/{stackId}` - Get stack with cards (this works!) - `POST /boards/{boardId}/stacks/{stackId}/cards` - Create card +- `PUT /boards/{boardId}/stacks/{stackId}` - Rename stack + +**Note:** Many endpoints return 405 Method Not Allowed: +- `GET /boards/{boardId}/stacks/{stackId}/cards` - Not supported +- `DELETE /boards/{boardId}/cards/{cardId}` - Not supported +- `GET /boards/{boardId}/cards/{cardId}` - Not supported + +## Known Limitations + +1. **No Duplicate Detection**: The Deck API v1.0 doesn't support listing cards by stack, so: + - Running `--init` multiple times creates duplicate cards + - Delete duplicates manually from the Nextcloud Deck UI + - Always use `--dry-run` first to preview changes + +2. **No Card Deletion API**: The DELETE endpoint returns 405, so: + - Test cards must be deleted manually from the web UI + - No automated cleanup possible + +3. **Limited GET Support**: Most card-level GET endpoints return 405: + - Cannot verify card creation without checking full stack + - Use `GET /boards/{boardId}/stacks/{stackId}` to view cards + +4. **No Bidirectional Sync**: Card position changes in Deck don't update markdown files + +5. **Initiative-Level Only**: Currently only syncs high-level initiatives, not individual phases ## Troubleshooting @@ -114,15 +139,25 @@ Key endpoints used: - Verify name contains "trader" (case insensitive) **"405 Method Not Allowed"** -- Nextcloud Deck version may have different API -- Check Nextcloud Deck version in settings -- Some GET endpoints may not be available +- Normal for most GET/DELETE card endpoints +- Use stack endpoint instead: `GET /boards/{boardId}/stacks/{stackId}` +- Check Nextcloud Deck API documentation for your version + +**"Cards not showing in board"** +- Cards ARE created but not visible in `GET /boards/{boardId}` response +- Use `GET /boards/{boardId}/stacks/{stackId}` to view cards properly +- Or check the Nextcloud Deck web UI **"Cards not syncing"** - Check `/tmp/deck-config.json` exists - Verify credentials in config - Run with `--dry-run` first to test +**"Duplicate cards"** +- This is expected - API doesn't support duplicate checking +- Delete extras manually from Nextcloud Deck UI +- Always run `--dry-run` before `--init` + ## Development **Adding new roadmap files:** @@ -140,7 +175,7 @@ ROADMAP_FILES = [ Edit `STATUS_TO_STACK` dict: ```python STATUS_TO_STACK = { - 'IN PROGRESS': 'in arbeit', - 'YOUR_STATUS': 'your_stack', # Add here + 'IN PROGRESS': '🚀 In Progress', + 'YOUR_STATUS': '📋 Your Stack', # Add here (with emoji) } ``` diff --git a/scripts/sync-roadmap-to-deck.py b/scripts/sync-roadmap-to-deck.py index 1ffc181..6488653 100755 --- a/scripts/sync-roadmap-to-deck.py +++ b/scripts/sync-roadmap-to-deck.py @@ -32,14 +32,14 @@ STACKS = {stack['name']: stack['id'] for stack in DECK_CONFIG['stacks']} # Status to stack mapping STATUS_TO_STACK = { - 'IN PROGRESS': 'in arbeit', - '🔄 IN PROGRESS': 'in arbeit', - 'COMPLETE': 'erledigt', - '✅ COMPLETE': 'erledigt', - 'PENDING': 'in planung', - '🔜 NEXT': 'in planung', - 'FUTURE': 'eingang', - '🎯 FUTURE': 'eingang', + 'IN PROGRESS': '🚀 In Progress', + '🔄 IN PROGRESS': '🚀 In Progress', + 'COMPLETE': '✅ Complete', + '✅ COMPLETE': '✅ Complete', + 'PENDING': '📋 Planning', + '🔜 NEXT': '📋 Planning', + 'FUTURE': '📥 Backlog', + '🎯 FUTURE': '📥 Backlog', } # Roadmap files to parse @@ -133,8 +133,8 @@ class RoadmapParser: content = filepath.read_text() tasks = [] - # Parse initiatives (main sections) - initiative_pattern = r'## 🎯 Initiative (\d+): (.+?)(?=\n##|\Z)' + # Parse initiatives (main sections) - handle different emoji prefixes + initiative_pattern = r'## (?:🎯|📐|📊) Initiative (\d+): (.+?)(?=\n##|\Z)' initiatives = re.finditer(initiative_pattern, content, re.DOTALL) for initiative in initiatives: @@ -247,25 +247,39 @@ def sync_roadmap_to_deck(dry_run: bool = False): title = task['title'] # Create new card - stack_name = STATUS_TO_STACK.get(task['status'], 'eingang') - stack_id = STACKS[stack_name] + stack_name = STATUS_TO_STACK.get(task['status'], '📥 Backlog') + # Debug output print(f"✨ Create: {title}") - print(f" Stack: {stack_name}") + print(f" Status from roadmap: {task['status']!r}") + print(f" Mapped to stack: {stack_name!r}") + + if stack_name not in STACKS: + print(f" ❌ ERROR: Stack {stack_name!r} not found in STACKS") + print(f" Available stacks: {list(STACKS.keys())}") + skipped += 1 + continue + + stack_id = STACKS[stack_name] + print(f" Stack ID: {stack_id}") + if task['progress']: print(f" Progress: {task['progress']}") if not dry_run: try: - api.create_card( + result = api.create_card( stack_id=stack_id, title=title, description=task['description'], due_date=task['due_date'], ) + print(f" ✅ Created card ID: {result['id']}") created += 1 except Exception as e: print(f" ❌ Error: {e}") + import traceback + traceback.print_exc() skipped += 1 else: created += 1