- Migrations 026-028: qt_partnumber_books + qt_partnumber_book_items tables; is_primary_pn on lot_partnumbers; version VARCHAR(30); description VARCHAR(10000) on items (required by QuoteForge sync) - Service: CreateSnapshot expands bundles, filters empty lot_name and ignored PNs, copies description, activates new book atomically, applies GFS retention (7d/5w/12m/10y) with explicit item deletion - Task type TaskTypePartnumberBookCreate; handlers ListPartnumberBooks and CreatePartnumberBook; routes GET/POST /api/admin/pricing/partnumber-books - UI: snapshot list + "Создать снапшот сопоставлений" button with progress polling on /vendor-mappings page - Bible: history, api, background-tasks, vendor-mapping updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.0 KiB
2.0 KiB
Background Tasks (Task Manager)
Principle
All long-running operations use the Task Manager. SSE (Server-Sent Events) must not be used.
Flow
1. Client sends POST request
│
▼
2. Handler creates task: taskManager.Submit(...)
│
▼
3. Handler returns { "task_id": "uuid" }
│
▼
4. Client polls GET /api/tasks/:id every 500ms
│
▼
5. On completed/error — show toast notification
Task Types
| Constant | Purpose |
|---|---|
TaskTypeRecalculate |
Recalculate all component prices |
TaskTypeStockImport |
Import stock file (.mxl/.xlsx) |
TaskTypePricelistCreate |
Create pricelist (estimate/warehouse/competitor) |
TaskTypePartnumberBookCreate |
Create partnumber book snapshot for QuoteForge |
Task Structure
type Task struct {
ID string // Task UUID
Type TaskType // Task type
Status TaskStatus // running | completed | error
Progress int // 0-100
Message string // Current UI message
Result map[string]interface{} // Result when completed
Error string // Error text when error
CreatedAt time.Time
DoneAt *time.Time
}
Usage Example (Backend)
taskID := h.taskManager.Submit(tasks.TaskTypeStockImport,
func(ctx context.Context, progressCb func(int, string)) (map[string]interface{}, error) {
progressCb(25, "Reading file")
// ... work ...
progressCb(75, "Saving to DB")
return map[string]interface{}{
"rows_total": 100,
"inserted": 95,
}, nil
},
)
c.JSON(http.StatusOK, gin.H{"task_id": taskID})
API
| Method | URL | Description |
|---|---|---|
| GET | /api/tasks/:id |
Task status and result |
Implementation
internal/tasks/ — Task Manager: Submit, track, poll.