Add comprehensive unit tests for CreateIssues (bd-241)
- Added 12 table-driven test cases covering all validation scenarios - Added 2 rollback tests (validation error + DB conflict) - Added nil item detection to prevent panic - Fixed nil pointer panic in CreateIssues - Tests verify ID uniqueness, timestamps, closed_at invariant - All tests pass Amp-Thread-ID: https://ampcode.com/threads/T-61c584cd-d873-4a1a-bfa6-d739b630b3e5 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -156,7 +156,7 @@
|
||||
{"id":"bd-239","title":"Fix import.go to normalize closed_at before creating issues","description":"Modify cmd/bd/import.go to enforce closed_at invariant before calling CreateIssue/CreateIssues.\n\nNormalize data: if status=closed, ensure closed_at is set; if status!=closed, ensure closed_at is nil.","design":"```go\nif _, ok := rawData[\"status\"]; ok {\n updates[\"status\"] = issue.Status\n\n // Enforce closed_at invariant\n if issue.Status == types.StatusClosed {\n // Status is closed: ensure closed_at is set\n if issue.ClosedAt == nil {\n now := time.Now()\n updates[\"closed_at\"] = now\n } else {\n updates[\"closed_at\"] = *issue.ClosedAt\n }\n } else {\n // Status is not closed: ensure closed_at is NULL\n updates[\"closed_at\"] = nil\n }\n}\n```","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-15T14:21:11.837762-07:00","updated_at":"2025-10-15T16:27:28.022212-07:00","closed_at":"2025-10-15T16:27:28.022212-07:00","dependencies":[{"issue_id":"bd-239","depends_on_id":"bd-224","type":"parent-child","created_at":"2025-10-15T14:21:11.838751-07:00","created_by":"stevey"},{"issue_id":"bd-239","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:22:36.49138-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-24","title":"Support ID space partitioning for parallel worker agents","description":"Enable external orchestrators (like AI worker swarms) to control issue ID assignment. Add --id flag to 'bd create' for explicit ID specification. Optionally support 'bd config set next_id N' to set the starting point for auto-increment. Storage layer already supports pre-assigned IDs (sqlite.go:52-71), just need CLI wiring. This keeps beads simple while letting orchestrators implement their own ID partitioning strategies to minimize merge conflicts. Complementary to bd-9's collision resolution.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-14T14:43:06.910467-07:00","updated_at":"2025-10-15T16:27:21.997209-07:00","closed_at":"2025-10-15T03:01:29.569795-07:00"}
|
||||
{"id":"bd-240","title":"Add CreateIssues interface method to Storage","description":"Add CreateIssues to the Storage interface in storage/storage.go\n\nNon-breaking addition to interface for batch issue creation.","design":"```go\n// storage/storage.go\ntype Storage interface {\n CreateIssue(ctx context.Context, issue *types.Issue, actor string) error\n CreateIssues(ctx context.Context, issues []*types.Issue, actor string) error // NEW\n // ... rest unchanged\n}\n```","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:21.252413-07:00","updated_at":"2025-10-15T18:30:09.264339-07:00","closed_at":"2025-10-15T18:30:09.264339-07:00","dependencies":[{"issue_id":"bd-240","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:21.253617-07:00","created_by":"stevey"},{"issue_id":"bd-240","depends_on_id":"bd-224","type":"blocks","created_at":"2025-10-15T14:21:21.254504-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-241","title":"Add comprehensive unit tests for CreateIssues","description":"Test coverage for CreateIssues:\n- Empty batch\n- Single issue\n- Multiple issues\n- Mixed ID assignment (explicit + auto-generated)\n- Validation errors\n- Duplicate ID errors\n- Rollback on error\n- Verify closed_at invariant enforced","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:47.237196-07:00","updated_at":"2025-10-15T16:27:21.998143-07:00","dependencies":[{"issue_id":"bd-241","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:47.246448-07:00","created_by":"stevey"},{"issue_id":"bd-241","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:21:47.247811-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-241","title":"Add comprehensive unit tests for CreateIssues","description":"Test coverage for CreateIssues:\n- Empty batch\n- Single issue\n- Multiple issues\n- Mixed ID assignment (explicit + auto-generated)\n- Validation errors\n- Duplicate ID errors\n- Rollback on error\n- Verify closed_at invariant enforced","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:47.237196-07:00","updated_at":"2025-10-15T19:16:35.461354-07:00","closed_at":"2025-10-15T19:16:35.461354-07:00","dependencies":[{"issue_id":"bd-241","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:47.246448-07:00","created_by":"stevey"},{"issue_id":"bd-241","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:21:47.247811-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-242","title":"Update import.go to use CreateIssues for bulk imports","description":"Modify cmd/bd/import.go to use CreateIssues instead of CreateIssue loop.\n\nAfter bd-224, import already normalizes closed_at, so this is straightforward:\n1. Normalize all issues in batch (closed_at handling)\n2. Call CreateIssues once with full batch\n3. Much simpler than current loop","design":"```go\n// After normalizing all issues\nfor _, issue := range issues {\n if issue.Status == types.StatusClosed {\n if issue.ClosedAt == nil {\n now := time.Now()\n issue.ClosedAt = \u0026now\n }\n } else {\n issue.ClosedAt = nil\n }\n}\n\n// Single batch call (5-15x faster!)\nreturn store.CreateIssues(ctx, issues, \"import\")\n```","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:47.258493-07:00","updated_at":"2025-10-15T16:27:21.998773-07:00","dependencies":[{"issue_id":"bd-242","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:47.259318-07:00","created_by":"stevey"},{"issue_id":"bd-242","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:21:47.25982-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-243","title":"Document CreateIssues API and update EXTENDING.md","description":"Documentation updates:\n- Godoc for CreateIssues with usage guidance\n- Add batch import examples\n- Update EXTENDING.md with batch usage patterns\n- Performance notes in README.md\n- When to use CreateIssue vs CreateIssues","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:47.398473-07:00","updated_at":"2025-10-15T16:27:21.99948-07:00","dependencies":[{"issue_id":"bd-243","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:47.398904-07:00","created_by":"stevey"},{"issue_id":"bd-243","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:21:47.399336-07:00","created_by":"stevey"}]}
|
||||
{"id":"bd-244","title":"Implement SQLiteStorage.CreateIssues with atomic ID range reservation","description":"Core implementation of CreateIssues in internal/storage/sqlite/sqlite.go\n\nKey optimizations:\n- Single connection + transaction\n- Atomic ID range reservation (generate N IDs in one counter update)\n- Prepared statement for bulk inserts\n- All-or-nothing atomicity\n\nExpected 5-10x speedup for N\u003e10 issues.","design":"Implementation phases per ULTRATHINK_BD222.md:\n\n1. **Validation**: Pre-validate all issues (calls Issue.Validate() which enforces closed_at invariant from bd-224)\n2. **Connection \u0026 Transaction**: BEGIN IMMEDIATE (same as CreateIssue)\n3. **Batch ID Generation**: Reserve range [nextID, nextID+N) in single counter update\n4. **Bulk Insert**: Prepared statement loop (defer multi-VALUE INSERT optimization)\n5. **Bulk Events**: Record creation events for all issues\n6. **Bulk Dirty**: Mark all issues dirty for export\n7. **Commit**: All-or-nothing transaction commit\n\nSee ULTRATHINK_BD222.md lines 344-541 for full implementation details.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-15T14:21:53.433641-07:00","updated_at":"2025-10-15T18:31:28.771539-07:00","closed_at":"2025-10-15T18:31:28.771539-07:00","dependencies":[{"issue_id":"bd-244","depends_on_id":"bd-222","type":"parent-child","created_at":"2025-10-15T14:21:53.435109-07:00","created_by":"stevey"},{"issue_id":"bd-244","depends_on_id":"bd-240","type":"blocks","created_at":"2025-10-15T14:21:53.43563-07:00","created_by":"stevey"},{"issue_id":"bd-244","depends_on_id":"bd-241","type":"blocks","created_at":"2025-10-15T14:22:17.181984-07:00","created_by":"stevey"},{"issue_id":"bd-244","depends_on_id":"bd-242","type":"blocks","created_at":"2025-10-15T14:22:17.195635-07:00","created_by":"stevey"}]}
|
||||
|
||||
Reference in New Issue
Block a user