Skip to content

feat(channel): add channel management with custom model pricing#1448

Closed
touwaeriol wants to merge 8 commits intoWei-Shaw:mainfrom
touwaeriol:feat/channel-management
Closed

feat(channel): add channel management with custom model pricing#1448
touwaeriol wants to merge 8 commits intoWei-Shaw:mainfrom
touwaeriol:feat/channel-management

Conversation

@touwaeriol
Copy link
Copy Markdown
Contributor

背景 / Background

目前系统缺乏对不同用户分组进行差异化定价的能力。管理员无法为不同分组配置独立的模型定价、计费模式或模型访问限制,所有分组共享相同的全局定价策略。

Currently the system lacks the ability to apply differentiated pricing to different user groups. Administrators cannot configure independent model pricing, billing modes, or model access restrictions per group — all groups share the same global pricing strategy.


目的 / Purpose

引入「渠道(Channel)」管理功能,允许管理员创建渠道并关联分组,为每个渠道独立配置模型定价规则、模型映射和访问限制,实现灵活的分组级计费管理。

Introduce a "Channel" management feature that allows administrators to create channels associated with groups, independently configure model pricing rules, model mappings, and access restrictions per channel — enabling flexible group-level billing management.


改动内容 / Changes

后端 / Backend

  • 渠道 CRUD:完整的 Handler → Service → Repository 三层架构,支持创建、查询、更新、删除渠道
  • 数据库迁移:7 个 migration 文件(channels 主表、channel_groups 关联表、channel_model_pricing 定价表、channel_pricing_intervals 分层定价子表)
  • 三种计费模式:Token 计费、按次计费(Per Request)、图片计费(Image)
  • 平台级配置:每个渠道可按平台(Anthropic/OpenAI/Gemini 等)独立配置定价和映射
  • 模型映射:渠道级模型名称转换(请求模型 → 上游模型),在账号级映射之前执行
  • 计费基准控制:billing_model_source 支持 requested / upstream / channel_mapped 三种模式
  • 模型限制:restrict_models 开关,限制分组只能访问渠道定义的模型列表
  • 分组隔离:每个分组最多属于一个渠道,防止定价冲突
  • 通配符匹配:模型名称支持通配符前缀匹配
  • 上下文区间定价:基于 input token 数量分层定价
  • ImageOutputPricePerToken:ModelPricing 新增图片输出 token 定价字段

  • Channel CRUD: Complete Handler → Service → Repository layers with full create, read, update, delete support
  • Database migrations: 7 migration files (channels, channel_groups, channel_model_pricing, channel_pricing_intervals)
  • Three billing modes: Token billing, per-request billing, and image billing
  • Platform-level config: Per-platform (Anthropic/OpenAI/Gemini etc.) pricing and mapping within each channel
  • Model mapping: Channel-level model name translation (request → upstream), runs before account-level mapping
  • Billing model source: Supports requested / upstream / channel_mapped modes
  • Model restriction: restrict_models toggle to limit groups to channel-defined models only
  • Group isolation: Each group belongs to at most one channel to prevent pricing conflicts
  • Wildcard matching: Model names support wildcard prefix matching
  • Context interval pricing: Tiered pricing based on input token count
  • ImageOutputPricePerToken: New field in ModelPricing for image output token pricing

前端 / Frontend

  • 渠道管理页面(ChannelsView.vue, 1065 行):表格列表、搜索、状态切换、创建/编辑对话框
  • 定价卡片组件(PricingEntryCard.vue):支持 Token/按次/图片三种模式切换、区间配置
  • 模型标签输入(ModelTagInput.vue):支持回车添加、粘贴批量导入
  • 区间行组件(IntervalRow.vue):上下文区间定价配置
  • 侧边栏导航:新增渠道管理入口
  • 路由注册:/admin/channels 路由
  • 完整 i18n:中英文翻译(102 行/语言)

  • Channel management page (ChannelsView.vue, 1065 lines): table list, search, status toggle, create/edit dialogs
  • Pricing entry card (PricingEntryCard.vue): Token/per-request/image mode switching with interval config
  • Model tag input (ModelTagInput.vue): Enter to add, paste for batch import
  • Interval row (IntervalRow.vue): Context interval pricing configuration
  • Sidebar navigation: New channel management entry
  • Route registration: /admin/channels route
  • Full i18n: English and Chinese translations (102 lines/language)

测试 / Tests

  • Channel service unit tests (2187 lines)
  • Channel handler unit tests (502 lines)
  • Channel model unit tests (435 lines)
  • Channel repository unit tests (227 lines)
  • Account handler mixed-channel test

Add a complete channel management system that enables administrators to
define custom pricing rules per model, per platform, with multiple
billing modes.

Backend:
- Channel CRUD handler, service, and repository layers
- 7 database migrations (channels, pricing, intervals, model mapping)
- Three billing modes: token, per-request, and image
- Platform-specific pricing configuration
- Wildcard model matching and context interval pricing
- Model mapping (request model → upstream model)
- Billing model source control (requested/upstream/channel-mapped)
- Model restriction (limit groups to channel-defined models)
- Group isolation (each group belongs to at most one channel)
- ImageOutputPricePerToken field in ModelPricing for image billing
- Wire dependency injection for ChannelHandler and ChannelRepository

Frontend:
- Full channel management page (ChannelsView.vue)
- Pricing entry card with interval configuration
- Model tag input component with paste/batch support
- Platform tab layout for per-platform configuration
- Sidebar navigation entry and route registration
- Complete i18n translations (en + zh)

Tests:
- Channel service unit tests (2187 lines)
- Channel handler unit tests (502 lines)
- Channel model unit tests (435 lines)
- Channel repository unit tests (227 lines)
- Account handler mixed-channel test
lodash/lodash-es template injection vulnerability is not exploitable
in our codebase as we never pass user-controlled strings to _.template.
- Fix channel_service.go gofmt alignment to match release
- Move channels nav item after groups with hideInSimpleMode: true
- Move channels route after groups in router
- Move registerChannelRoutes after ScheduledTest in admin routes
…ranch

Integrate channel management associated changes from release/custom-0.1.106
that were missing from the initial channel CRUD PR:

Backend:
- ModelPricingResolver: unified pricing chain (Channel → LiteLLM → Fallback)
- CalculateCostUnified: three billing modes (token/per-request/image)
- recordUsageCore: merge RecordUsage + RecordUsageWithLongContext
- Gateway handlers: channel mapping + restriction at all 6 entry points
- Channel model restriction moved to scheduling phase
- Usage log: channel_id, model_mapping_chain, billing_tier, billing_mode fields
- Credits precheck with fail-open degradation
- Sticky session upstream restriction bypass fix
- Wire DI: inject ChannelService + ModelPricingResolver into gateway services
- DB migrations: 087 (billing_mode), 089 (image_output_tokens)

Frontend:
- Usage views: billing mode column, three-level mapping chain display
- formatters.ts: shared formatCacheTokens/formatMultiplier utilities
- Chart components: filters prop passthrough
- i18n: billingMode keys (en + zh)

Excluded: affinity scheduling, ClaudeMax simulation (to be removed)
Channel-related fixes:
- Add BillingMode to UsageLog DTO for frontend display
- Add ChannelID/ModelMappingChain/BillingTier to AdminUsageLog DTO
- Add billing_type and drill-down filters to dashboard handler/API

Independent improvements:
- Gemini image output token extraction (CandidatesTokensDetails support)
- OpenAI Instructions field for GPT-5/Codex compatibility
- Sonnet 4.5 → 4.6 model mapping in constants and frontend presets
- Fix user_group_rate_repo JOIN to filter deleted users
- Fix concurrency service using detached context to prevent HTTP cancellation
- Sidebar channel icon update and i18n fallback
@touwaeriol touwaeriol closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant