- Remove unused imports from nodes (time, torch, requests, itertools) - Move uuid import to top-level in bot/bot.py - Add 4 new test files with 86 tests for shared utilities - Update CHANGELOG.md with version 2.0.0 refactoring summary - Update REFACTOR_PRD.md to mark Phase 5 complete Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
332 lines
14 KiB
Markdown
332 lines
14 KiB
Markdown
# ComfyUI-DiscordSend Refactoring PRD
|
|
|
|
**Document Type:** Product Requirements Document
|
|
**Project:** ComfyUI-DiscordSend Separation of Concerns Refactor
|
|
**Version:** 1.0
|
|
**Date:** 2026-01-19
|
|
**Author:** Claude Opus 4.5 + Human Review
|
|
**Status:** In Progress (Phases 0-5 Complete)
|
|
|
|
---
|
|
|
|
## 1. Overview
|
|
|
|
### 1.1 Purpose
|
|
This PRD defines the requirements and scope for a comprehensive refactoring of the ComfyUI-DiscordSend project to improve code organization, reduce duplication, and complete missing features.
|
|
|
|
### 1.2 Background
|
|
The project currently consists of two main components:
|
|
- **ComfyUI Nodes**: Production-ready custom nodes for sending images/videos to Discord
|
|
- **Discord Bot**: A companion bot for triggering generations from Discord (functional but incomplete)
|
|
|
|
### 1.3 Problem Statement
|
|
| Issue | Impact | Severity |
|
|
|-------|--------|----------|
|
|
| 4 critical bugs preventing bot startup | Bot unusable | Critical |
|
|
| 1562-line monolithic video node | Hard to maintain/debug | High |
|
|
| ~400 lines of duplicated code | Bug fixes needed in multiple places | High |
|
|
| Wrong coupling (video imports from image node) | Fragile dependencies | Medium |
|
|
| No directory structure for separation | Confusing organization | Medium |
|
|
| Incomplete bot features | Missing user functionality | Medium |
|
|
|
|
---
|
|
|
|
## 2. Goals & Non-Goals
|
|
|
|
### 2.1 Goals
|
|
1. **Fix all critical bugs** that prevent the bot from running
|
|
2. **Restructure directory layout** with clear separation: `nodes/`, `shared/`, `bot/`
|
|
3. **Eliminate code duplication** between image and video nodes
|
|
4. **Extract video encoding logic** to reduce video node from 1562 to ~400 lines
|
|
5. **Create base node class** for shared functionality
|
|
6. **Complete missing bot features**: templates, history, error delivery, WebSocket reconnection
|
|
7. **Improve maintainability** through modular design
|
|
|
|
### 2.2 Non-Goals
|
|
- Adding new node features (beyond bug fixes)
|
|
- Changing the Discord webhook API integration
|
|
- Modifying ComfyUI compatibility requirements
|
|
- Database schema changes (bot uses existing models)
|
|
- UI/UX changes to ComfyUI node interface
|
|
|
|
---
|
|
|
|
## 3. Requirements
|
|
|
|
### 3.1 Functional Requirements
|
|
|
|
#### FR-1: Bug Fixes (Phase 0)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-1.1 | Fix `BotConfig` class name mismatch in `bot/__main__.py` | P0 |
|
|
| FR-1.2 | Add missing `json` import to `bot/services/delivery.py` | P0 |
|
|
| FR-1.3 | Fix `PermissionLevel` import in `bot/cogs/admin.py` | P0 |
|
|
| FR-1.4 | Fix `config.comfyui.url` attribute path in admin cog | P0 |
|
|
|
|
#### FR-2: Directory Structure (Phase 1)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-2.1 | Create `nodes/` directory for node implementations | P1 |
|
|
| FR-2.2 | Create `shared/` directory for utilities | P1 |
|
|
| FR-2.3 | Create `shared/discord/`, `shared/media/`, `shared/workflow/` subdirectories | P1 |
|
|
| FR-2.4 | Move utility files to appropriate locations | P1 |
|
|
| FR-2.5 | Update all imports throughout codebase | P1 |
|
|
| FR-2.6 | Maintain backward compatibility for ComfyUI node loading | P1 |
|
|
|
|
#### FR-3: Shared Utilities (Phase 2)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-3.1 | Extract filename/timestamp utilities to `shared/filename_utils.py` | P1 |
|
|
| FR-3.2 | Extract output directory logic to `shared/path_utils.py` | P1 |
|
|
| FR-3.3 | Extract Discord message building to `shared/discord/message_builder.py` | P1 |
|
|
| FR-3.4 | Extract CDN URL handling to `shared/discord/cdn_extractor.py` | P1 |
|
|
|
|
#### FR-4: Video Encoder Extraction (Phase 3)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-4.1 | Create `FFmpegEncoder` class in `shared/media/video_encoder.py` | P1 |
|
|
| FR-4.2 | Create `PILGifEncoder` fallback class | P1 |
|
|
| FR-4.3 | Extract format detection to `shared/media/format_utils.py` | P1 |
|
|
| FR-4.4 | Reduce video node to orchestration layer (~400 lines) | P1 |
|
|
|
|
#### FR-5: Base Node Class (Phase 4)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-5.1 | Create `BaseDiscordNode` class in `nodes/base_node.py` | P2 |
|
|
| FR-5.2 | Extract common `INPUT_TYPES` definitions | P2 |
|
|
| FR-5.3 | Extract shared methods (sanitize, send, etc.) | P2 |
|
|
| FR-5.4 | Refactor image and video nodes to inherit from base | P2 |
|
|
|
|
#### FR-6: Bot Features (Phase 5)
|
|
| ID | Requirement | Priority |
|
|
|----|-------------|----------|
|
|
| FR-6.1 | Implement WebSocket reconnection with exponential backoff | P1 |
|
|
| FR-6.2 | Implement error delivery to Discord users | P1 |
|
|
| FR-6.3 | Implement `/template` commands (save, load, list, delete) | P2 |
|
|
| FR-6.4 | Implement `/history` and `/rerun` commands | P2 |
|
|
| FR-6.5 | Create `config.yaml.example` template | P1 |
|
|
| FR-6.6 | Create `.env.example` template | P1 |
|
|
|
|
### 3.2 Non-Functional Requirements
|
|
|
|
| ID | Requirement | Metric |
|
|
|----|-------------|--------|
|
|
| NFR-1 | Reduce total node code by >50% | 2548 → <1200 lines |
|
|
| NFR-2 | Eliminate code duplication | ~400 lines → 0 |
|
|
| NFR-3 | Maintain test pass rate | All existing tests pass |
|
|
| NFR-4 | No breaking changes to ComfyUI | Nodes load and function identically |
|
|
| NFR-5 | Improve modularity | 12+ separate utility modules |
|
|
|
|
---
|
|
|
|
## 4. Architecture
|
|
|
|
### 4.1 Current State
|
|
```
|
|
comfyui-discordsend/
|
|
├── discord_image_node.py (986 lines)
|
|
├── discord_video_node.py (1562 lines)
|
|
├── discordsend_utils/ (6 files, tightly coupled)
|
|
└── bot/ (incomplete, 4 bugs)
|
|
```
|
|
|
|
### 4.2 Target State
|
|
```
|
|
comfyui-discordsend/
|
|
├── __init__.py # ComfyUI entry point
|
|
├── nodes/ # Node implementations (~950 lines total)
|
|
│ ├── __init__.py
|
|
│ ├── base_node.py # Shared base class
|
|
│ ├── image_node.py # Image-specific logic
|
|
│ └── video_node.py # Video-specific logic
|
|
├── shared/ # Shared utilities (12 modules)
|
|
│ ├── discord/ # Discord integration
|
|
│ │ ├── webhook_client.py
|
|
│ │ ├── message_builder.py
|
|
│ │ └── cdn_extractor.py
|
|
│ ├── media/ # Media processing
|
|
│ │ ├── image_processing.py
|
|
│ │ ├── video_encoder.py
|
|
│ │ └── format_utils.py
|
|
│ ├── workflow/ # Workflow utilities
|
|
│ │ ├── sanitizer.py
|
|
│ │ ├── prompt_extractor.py
|
|
│ │ └── workflow_builder.py
|
|
│ ├── github_integration.py
|
|
│ ├── filename_utils.py
|
|
│ ├── path_utils.py
|
|
│ └── logging_config.py
|
|
└── bot/ # Fully functional bot
|
|
├── cogs/
|
|
│ ├── generate.py
|
|
│ ├── queue.py
|
|
│ ├── admin.py
|
|
│ ├── templates.py # NEW
|
|
│ └── history.py # NEW
|
|
└── ...
|
|
```
|
|
|
|
### 4.3 Component Dependencies
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ ComfyUI Runtime │
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ ImageNode │ │ VideoNode │ │
|
|
│ └──────┬───────┘ └──────┬───────┘ │
|
|
│ │ │ │
|
|
│ └────────┬───────────┘ │
|
|
│ ▼ │
|
|
│ ┌──────────────┐ │
|
|
│ │ BaseNode │ │
|
|
│ └──────┬───────┘ │
|
|
└────────────────┼────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ shared/ │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │ discord │ │ media │ │workflow │ │ utils │ │
|
|
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼ (logging_config only)
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ bot/ │
|
|
│ (Minimal shared dependency - mostly independent) │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Phased Implementation
|
|
|
|
### Phase 0: Critical Bug Fixes ✅ COMPLETE
|
|
- Fix 4 bugs preventing bot startup
|
|
- Verify all existing tests pass
|
|
- **Status:** Complete (2026-01-19)
|
|
|
|
### Phase 1: Directory Restructure ✅ COMPLETE
|
|
- Create new directory structure (`nodes/`, `shared/`)
|
|
- Move files to new locations
|
|
- Update all imports
|
|
- Remove deprecated `discordsend_utils/`
|
|
- **Status:** Complete (2026-01-20)
|
|
- **Commit:** 852840d
|
|
|
|
### Phase 2: Extract Shared Utilities ✅ COMPLETE
|
|
- Create `filename_utils.py` - filename with date/time/dimensions
|
|
- Create `path_utils.py` - output directory handling
|
|
- Create `message_builder.py` - Discord message construction
|
|
- Create `cdn_extractor.py` - CDN URL extraction and file sending
|
|
- **Status:** Complete (2026-01-20)
|
|
- **Commit:** a208cd4
|
|
- **Result:** 522 lines removed from nodes (image: -161, video: -361)
|
|
|
|
### Phase 3: Extract Video Encoder ✅ COMPLETE
|
|
- Create `FFmpegEncoder` class with format-specific encoding
|
|
- Create `PILEncoder` class for GIF/WebP fallback
|
|
- Create `format_utils.py` - format detection, validation, Discord compatibility
|
|
- Refactor video node to use shared encoders
|
|
- **Status:** Complete (2026-01-20)
|
|
- **Commit:** 76da850
|
|
- **Result:** Video node reduced from 1562 to 1092 lines (-470 lines, 30% reduction)
|
|
|
|
### Phase 4: Create Base Node Class ✅ COMPLETE
|
|
- Create `BaseDiscordNode` (343 lines) in `nodes/base_node.py`
|
|
- Extract common `INPUT_TYPES` generators (Discord, CDN, filename metadata)
|
|
- Extract shared methods (sanitize, send, GitHub update, etc.)
|
|
- **Status:** Complete (2026-01-20)
|
|
- **Commit:** 87c97e0
|
|
- **Note:** Nodes not yet refactored to inherit from base (deferred to reduce risk)
|
|
|
|
### Phase 4.1: PR Review Bug Fixes ✅ COMPLETE
|
|
- Fix else block indentation in batch Discord send (1e94a69)
|
|
- Add section header when only dimensions displayed (b8aadd7)
|
|
- Restore SDXL workflow prompt extraction support (36c5d06)
|
|
- Prevent redundant CDN URL sends on 204 responses (cc07d20)
|
|
- Add trailing newline to metadata section formatting (0d6ed9d)
|
|
- **Status:** Complete (2026-01-20)
|
|
|
|
### Phase 5: Complete Bot Features ✅ COMPLETE
|
|
- WebSocket reconnection with exponential backoff
|
|
- Error delivery to Discord users
|
|
- Templates cog (`/template save/load/list/delete`)
|
|
- History cog (`/history`, `/rerun`)
|
|
- Config templates (already existed)
|
|
- Fixed BotConfig import bug
|
|
- **Status:** Complete (2026-01-20)
|
|
- **Commit:** b083702
|
|
|
|
### Phase 6: Final Cleanup
|
|
- Update documentation
|
|
- Add new tests
|
|
- Remove dead code
|
|
- **Deliverable:** Production-ready codebase
|
|
|
|
---
|
|
|
|
## 6. Success Metrics
|
|
|
|
| Metric | Original | Current | Target | Status |
|
|
|--------|----------|---------|--------|--------|
|
|
| Image node lines | 986 | 836 | ~350 | 🟡 -150 lines (15%) |
|
|
| Video node lines | 1562 | 1092 | ~400 | 🟡 -470 lines (30%) |
|
|
| Total node lines | 2548 | 1928 | ~750 | 🟡 -620 lines (24%) |
|
|
| Base node class | 0 | 343 | ~200 | ✅ Created |
|
|
| Utility modules | 6 | 17 | 12+ | ✅ Exceeded |
|
|
| Code duplication | ~400 lines | ~200 | 0 | 🟡 In progress |
|
|
| Test pass rate | 46/52 | 46/52 | 52/52 | 🟡 Maintained |
|
|
| Bot features | 60% | 100% | 100% | ✅ Phase 5 Complete |
|
|
|
|
**Notes:**
|
|
- Node line counts don't include base_node.py (343 lines of reusable code)
|
|
- 6 test failures are pre-existing numpy mocking issues, not refactoring-related
|
|
- Nodes have not yet been refactored to inherit from BaseDiscordNode
|
|
|
|
---
|
|
|
|
## 7. Risks & Mitigations
|
|
|
|
| Risk | Likelihood | Impact | Mitigation |
|
|
|------|------------|--------|------------|
|
|
| Breaking ComfyUI node loading | Medium | High | Test after each phase; maintain `__init__.py` |
|
|
| Breaking existing workflows | Low | High | Preserve node class names exactly |
|
|
| Introducing new bugs | Medium | Medium | Comprehensive tests; review after each phase |
|
|
| Merge conflicts | Low | Low | Work on feature branch; small commits |
|
|
| Scope creep | Medium | Medium | Strict adherence to PRD; defer new features |
|
|
|
|
---
|
|
|
|
## 8. Out of Scope (Future Work)
|
|
|
|
- New node types (audio, 3D, etc.)
|
|
- Multi-webhook support per node
|
|
- Cloud storage integration (S3, GCS)
|
|
- Web dashboard for bot
|
|
- Rate limiting per user in nodes
|
|
- Encrypted webhook storage
|
|
|
|
---
|
|
|
|
## 9. Approval & Sign-off
|
|
|
|
| Role | Name | Date | Status |
|
|
|------|------|------|--------|
|
|
| Developer | Claude Opus 4.5 | 2026-01-19 | Approved |
|
|
| Reviewer | Human | 2026-01-19 | Approved |
|
|
|
|
---
|
|
|
|
## 10. Change Log
|
|
|
|
| Version | Date | Author | Changes |
|
|
|---------|------|--------|---------|
|
|
| 1.0 | 2026-01-19 | Claude | Initial PRD created |
|
|
| 1.0.1 | 2026-01-19 | Claude | Phase 0 marked complete |
|
|
| 1.1 | 2026-01-20 | Claude | Phase 1 complete - directory restructure |
|
|
| 1.2 | 2026-01-20 | Claude | Phase 2 complete - shared utilities extracted |
|
|
| 1.3 | 2026-01-20 | Claude | Phase 3 complete - video encoder extraction |
|
|
| 1.4 | 2026-01-20 | Claude | Phase 4 complete - BaseDiscordNode created |
|
|
| 1.4.1 | 2026-01-20 | Claude | Phase 4.1 - PR review bug fixes (5 issues resolved) |
|