1. 22 Feb, 2026 9 commits
    • refactor(task): enhance UpdateWithStatus for CAS updates and add integration tests · 374aabf3
      - Updated UpdateWithStatus method to use Model().Select("*").Updates() for conditional updates, preventing GORM's INSERT fallback.
      - Introduced comprehensive integration tests for UpdateWithStatus, covering scenarios for winning and losing CAS updates, as well as concurrent updates.
      - Added task_cas_test.go to validate the new behavior and ensure data integrity during concurrent state transitions.
      CaIon committed
    • refactor(task): add CAS-guarded updates to prevent concurrent billing conflicts · b386490d
      Replace all bare task.Update() (DB.Save) calls with UpdateWithStatus(),
      which adds a WHERE status = ? guard to prevent concurrent processes from
      overwriting each other's state transitions.
      
      Key changes:
      
      model/task.go:
      - Add taskSnapshot struct with Equal() method for change detection
      - Add Snapshot() method to capture pre-update state
      - Add UpdateWithStatus(fromStatus) using DB.Where().Save() for CAS
        semantics with full-struct save (no explicit field listing needed)
      
      model/midjourney.go:
      - Add UpdateWithStatus(fromStatus string) with same CAS pattern
      
      service/task_polling.go (updateVideoSingleTask):
      - Snapshot before processing upstream response; skip DB write if unchanged
      - Terminal transitions (SUCCESS/FAILURE) use UpdateWithStatus CAS:
        billing/refund only executes if this process wins the transition
      - Non-terminal updates also use UpdateWithStatus to prevent overwriting
        a concurrent terminal transition back to IN_PROGRESS
      - Defer settleTaskBillingOnComplete to after CAS check (shouldSettle flag)
      
      relay/relay_task.go (tryRealtimeFetch):
      - Add snapshot + change detection; use UpdateWithStatus for CAS safety
      
      controller/midjourney.go (UpdateMidjourneyTaskBulk):
      - Capture preStatus before mutations; use UpdateWithStatus CAS
      - Gate refund (IncreaseUserQuota) on CAS success (won && shouldReturnQuota)
      
      This prevents the multi-instance race condition where:
      1. Instance A reads task (IN_PROGRESS), fetches upstream (still IN_PROGRESS)
      2. Instance B reads same task, fetches upstream (now SUCCESS), writes SUCCESS
      3. Instance A's bare Save() overwrites SUCCESS back to IN_PROGRESS
      CaIon committed
    • refactor(relay): improve channel locking and retry logic in RelayTask · 6f39c028
      - Enhanced the RelayTask function to utilize a locked channel when available, allowing for better reuse during retries.
      - Updated error handling to ensure proper context setup for the selected channel.
      - Clarified comments in ResolveOriginTask regarding channel locking and retry behavior.
      - Introduced a new field in TaskRelayInfo to store the locked channel object, improving type safety and reducing import cycles.
      CaIon committed
    • refactor(relay): enhance remix logic for billing context extraction · 143b4535
      - Updated the remix handling in ResolveOriginTask to prioritize extracting OtherRatios from the BillingContext of the original task if available.
      - Retained the previous logic for extracting seconds and size from task data as a fallback.
      - Improved clarity and maintainability of the remix logic by separating the new and old approaches.
      CaIon committed
    • refactor(relay): rename RelayTask to RelayTaskFetch and update routing · 7d5fc3ff
      - Renamed RelayTask function to RelayTaskFetch for clarity.
      - Updated routing in relay-router.go and video-router.go to use RelayTaskFetch for fetch operations.
      - Enhanced error handling in RelayTaskFetch function.
      - Adjusted task data conversion in TaskAdaptor to include task ID.
      CaIon committed
    • feat(task): add adaptor billing interface and async settlement framework · 8374a830
      Add three billing lifecycle methods to the TaskAdaptor interface:
      - EstimateBilling: compute OtherRatios from user request before pricing
      - AdjustBillingOnSubmit: adjust ratios from upstream submit response
      - AdjustBillingOnComplete: determine final quota at task terminal state
      
      Introduce BaseBilling as embeddable no-op default for adaptors without
      custom billing. Move Sora/Ali OtherRatios logic from shared validation
      into per-adaptor EstimateBilling implementations.
      
      Add TaskBillingContext to persist pricing params (model_price, group_ratio,
      other_ratios) in task private data for async polling settlement.
      
      Extract RecalculateTaskQuota as a general-purpose delta settlement
      function and unify polling billing via settleTaskBillingOnComplete
      (adaptor-first, then token-based fallback).
      CaIon committed
    • refactor(task): extract billing and polling logic from controller to service layer · ba25ba88
      Restructure the task relay system for better separation of concerns:
      - Extract task billing into service/task_billing.go with unified settlement flow
      - Move task polling loop from controller to service/task_polling.go (supports Suno + video platforms)
      - Split RelayTask into fetch/submit paths with dedicated retry logic (taskSubmitWithRetry)
      - Add TaskDto, TaskResponse generics, and FetchReq to dto/task.go
      - Add taskcommon/helpers.go for shared task adaptor utilities
      - Remove controller/task_video.go (logic consolidated into service layer)
      - Update all task adaptors (ali, doubao, gemini, hailuo, jimeng, kling, sora, suno, vertex, vidu)
      - Simplify frontend task logs to use new TaskDto response format
      CaIon committed
    • imporve oauth provider UI/UX (#2983) · 29c2c895
      * feat: imporve UI/UX
      
      * fix: stabilize provider enabled toggle and polish custom OAuth settings UX
      
      * fix: add access policy/message templates and persist advanced fields reliably
      
      * fix: move template fill actions below fields and keep advanced form flow cleaner
      Seefs committed
  2. 21 Feb, 2026 4 commits
  3. 20 Feb, 2026 3 commits
  4. 19 Feb, 2026 1 commit
  5. 12 Feb, 2026 12 commits
  6. 11 Feb, 2026 11 commits