feat(issues): type field + operator create (#31, #14)#145
Conversation
Backend: - Migration 075: add type column (TEXT, default 'task') to issues table - Issue model: Type field with validation (bug/feature/improvement/task) - Store: CreateIssue validates type, UpdateIssueFields accepts type, ListIssuesEx filters by type - MCP tool: type param in issues(action="create") - REST: type in POST/PATCH body, GET query param Dashboard: - "New Issue" button + creation modal (title, body, type, priority, target_project) - Type filter buttons (All/Bug/Feature/Improvement/Task) - Type badge in issue list (colored: red/blue/green/gray) - Type badge + edit in issue detail view Hooks: - formatIssuesBlock shows [TYPE] tag in session injection Plugin v3.7.8. Closes #31, #14.
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 7 minutes and 43 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
ПояснениеВ этот pull request добавлена поддержка типов проблем (bug, feature, improvement, task) во всех слоях системы: базе данных, API обработчиках, пользовательском интерфейсе и плагине. Реализована фильтрация проблем по типу, возможность создания и редактирования типа проблемы с валидацией против разрешённого списка. Изменения
Диаграмма последовательностиsequenceDiagram
participant UI as UI (IssuesView)
participant API as API Handler<br/>(handlers_issues)
participant Store as GORM Store<br/>(issue_store)
participant DB as Database
rect rgba(100, 150, 200, 0.5)
Note over UI,DB: Создание проблемы с типом
UI->>API: POST /issues (title, body, type, priority)
API->>Store: CreateIssue(ctx, issue{Type, ...})
Store->>Store: Валидация Type против<br/>allowlist
Store->>DB: INSERT INTO issues<br/>(type='feature', ...)
DB-->>Store: OK
Store-->>API: issue{id, Type, ...}
API-->>UI: {id, message}
UI->>UI: Обновить список
end
rect rgba(150, 100, 200, 0.5)
Note over UI,DB: Фильтрация проблем по типу
UI->>API: GET /issues?type=bug
API->>Store: ListIssuesEx(ctx,<br/>params{Type='bug'})
Store->>DB: SELECT * FROM issues<br/>WHERE type = 'bug'
DB-->>Store: [{id, type, ...}, ...]
Store-->>API: issues[]
API-->>UI: [{id, type, ...}, ...]
UI->>UI: Отобразить filtered<br/>список
end
rect rgba(200, 100, 100, 0.5)
Note over UI,DB: Редактирование типа проблемы
UI->>API: PATCH /issues/{id}<br/>(fields{type: 'improvement'})
API->>Store: UpdateIssueFields(ctx, id,<br/>..., issueType='improvement', ...)
Store->>Store: Валидация issueType
Store->>DB: UPDATE issues<br/>SET type='improvement'<br/>WHERE id=?
DB-->>Store: OK
Store-->>API: OK
API-->>UI: success
UI->>UI: Обновить деталь проблемы
end
Оценка сложности рецензирования🎯 4 (Complex) | ⏱️ ~45 минут Возможно связанные Pull Request'ы
Рекомендуемые метки
Стихотворение
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review focus:security |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 28856
🔒 Security Review — PR
|
| Severity | Finding | File |
|---|---|---|
| 🟡 Medium | Unvalidated type query param — no 400 for invalid input |
handlers_issues.go |
| 🟡 Medium | source_agent: "human" client-controlled — trust boundary |
api.ts |
| 🟡 Low | Auth errors silently swallowed in fetchTrackedProjects |
api.ts |
| 🟠 Low | GORM model tag missing not null vs migration |
models.go |
| 🔵 Info | Dead timeout destructure in createIssue |
api.ts |
There was a problem hiding this comment.
Code Review
This pull request introduces issue categorization by adding a type field (bug, feature, improvement, task) across the stack. Key changes include a database migration, updated GORM models and store logic for validation and filtering, and frontend enhancements for creating, editing, and filtering issues by type. Feedback suggests refactoring the new createIssue API function to utilize the existing postJson helper for better consistency and reduced boilerplate.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
internal/worker/handlers_issues.go (1)
22-22: Нормализуйтеtype(trim + lower) до передачи в store.Это снимет лишние 400/пустые выборки при вводе вроде
" Bug "или"FEATURE".♻️ Вариант правки
- typeParam := r.URL.Query().Get("type") + typeParam := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("type"))) ... - issue := &gormdb.Issue{ + req.Type = strings.ToLower(strings.TrimSpace(req.Type)) + issue := &gormdb.Issue{ ... - if req.Title != "" || req.Body != "" || req.Priority != "" || req.Type != "" || req.Labels != nil { + req.Type = strings.ToLower(strings.TrimSpace(req.Type)) + if req.Title != "" || req.Body != "" || req.Priority != "" || req.Type != "" || req.Labels != nil {Also applies to: 49-50, 106-107, 135-136, 181-182, 190-192
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/worker/handlers_issues.go` at line 22, Normalize the query parameter value before passing to the store by trimming whitespace and converting to lowercase: for the variable typeParam (from r.URL.Query().Get("type")) and the other similar variables used as filters (the occurrences around the other mentioned contexts), call strings.TrimSpace(...) and strings.ToLower(...) and then pass that normalized value into the store calls and validations (e.g., where typeParam is used to build the store filter or conditional logic). Ensure all places that read "type" from the request (the instances you flagged) apply the same normalization so inputs like " Bug " or "FEATURE" map consistently.internal/db/gorm/models.go (1)
434-434: Синхронизируйте тег модели с ограничениемNOT NULLиз миграции.Это улучшит консистентность model metadata и фактической схемы.
♻️ Минимальная правка
- Type string `gorm:"type:text;default:task" json:"type"` + Type string `gorm:"type:text;not null;default:task" json:"type"`🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/db/gorm/models.go` at line 434, The struct field Type currently has a GORM tag `gorm:"type:text;default:task"` but the migration enforces NOT NULL; update the Type field's GORM tag to include not null (e.g., change `gorm:"type:text;default:task"` to `gorm:"type:text;default:task;not null"`) so the model metadata matches the schema constraint.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/db/gorm/migrations.go`:
- Around line 2199-2208: Update migration "075_issues_type" to enforce allowed
values at the DB level: in the Migrate function, after adding the column `type`
to table `issues`, add a CHECK constraint (e.g., `chk_issues_type`) that
restricts `type` to the set ('bug','feature','improvement','task'); in the
Rollback function, first drop that constraint (`DROP CONSTRAINT IF EXISTS
chk_issues_type`) and then drop the `type` column. Ensure both SQL statements
use the existing `tx.Exec(...).Error` pattern in the `Migrate` and `Rollback`
functions so the constraint is created and removed reliably.
In `@ui/src/utils/api.ts`:
- Around line 1063-1088: In createIssue validate that data.target_project is
present and non-empty before making the fetch: if target_project is
missing/empty, throw a meaningful Error (or reject) so the helper fails fast
instead of sending source_project:'dashboard'; update the validation near the
start of the createIssue function to check data.target_project and return/throw
before constructing the request body and calling fetch.
---
Nitpick comments:
In `@internal/db/gorm/models.go`:
- Line 434: The struct field Type currently has a GORM tag
`gorm:"type:text;default:task"` but the migration enforces NOT NULL; update the
Type field's GORM tag to include not null (e.g., change
`gorm:"type:text;default:task"` to `gorm:"type:text;default:task;not null"`) so
the model metadata matches the schema constraint.
In `@internal/worker/handlers_issues.go`:
- Line 22: Normalize the query parameter value before passing to the store by
trimming whitespace and converting to lowercase: for the variable typeParam
(from r.URL.Query().Get("type")) and the other similar variables used as filters
(the occurrences around the other mentioned contexts), call
strings.TrimSpace(...) and strings.ToLower(...) and then pass that normalized
value into the store calls and validations (e.g., where typeParam is used to
build the store filter or conditional logic). Ensure all places that read "type"
from the request (the instances you flagged) apply the same normalization so
inputs like " Bug " or "FEATURE" map consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1759a90e-7888-46fe-8b7a-11cc7c044164
📒 Files selected for processing (11)
internal/db/gorm/issue_store.gointernal/db/gorm/migrations.gointernal/db/gorm/models.gointernal/mcp/tools_issues.gointernal/worker/handlers_issues.goplugin/engram/.claude-plugin/plugin.jsonplugin/engram/hooks/lib.jsui/src/composables/useIssues.tsui/src/utils/api.tsui/src/views/IssueDetailView.vueui/src/views/IssuesView.vue
- migrations.go: add DB-level CHECK constraint issues_type_check for
type IN ('bug','feature','improvement','task') with proper rollback
- models.go: add not null to GORM tag for Type field to match migration
- handlers_issues.go: normalize type param with TrimSpace+ToLower in
list, create, and update handlers
- api.ts: refactor createIssue to use postJson helper (removes
duplicated timeout/abort/retry logic); require non-empty target_project
and validate eagerly before HTTP call
- IssuesView.vue: pass target_project as string (not undefined) since
createIssue now validates it directly
Summary
Changes
Test plan
go build ./...cleango test ./... -count=1passesnpm run buildpassesissues(action="create", type="bug")creates bug-type issueSummary by CodeRabbit