Skip to content

Operation Settings ​

Site-wide operational knobs: registration / invitation / new-user quota, monitoring thresholds, channel routing and error strategy. UI: web/default-pro/src/views/setting/OperationSetting.vue.

Endpoints ​

EndpointMethodAuthDescription
/api/option/GETRootAll OptionMap entries except those whose key ends with Token or Secret
/api/option/PUTRootSingle { key, value } save with per-key validation

Implementation: controller/option.go. Persisted in the options table and mirrored into the in-memory config.OptionMap.

options is a parallel mechanism to system_settings: options is a generic key/value table loaded into OptionMap at startup; toggles whose key ends with Enabled also flip the corresponding config.* runtime variable. system_settings is the newer category-grouped store maintained by model.UpsertSystemSetting. This page covers options only.

Sections ​

The UI splits settings by purpose; switches usually save on @change, while numeric fields share a section-level Save button.

SectionFields
Quota policyQuotaForNewUser / PreConsumedQuota / QuotaForInviter / QuotaForInvitee
MonitorChannelDisableThreshold / QuotaRemindThreshold + AutomaticDisableChannelEnabled / AutomaticEnableChannelEnabled / LogConsumeEnabled
Log pruningDate picker + Clean logs button → DELETE /api/log/?target_timestamp=…
GeneralTopUpLink / ChatLink / QuotaPerUnit / RetryTimes + DisplayInCurrencyEnabled / DisplayTokenStatEnabled / ApproximateTokenEnabled
Channel routingChannelDefaultCooldownSeconds / ChannelMaxCooldownSeconds + ChannelConcurrencyEnabled / ChannelStickySessionEnabled
Error strategyErrorNext JSON: { passthrough, retry, disable, cooldown }
Planplan.upgrade_mode (see plan-setting)

Field Semantics ​

FieldDefaultNotes
QuotaForNewUserenvNew-user signup bonus (quota)
PreConsumedQuota0Pre-deducted per request; refunded on failure
QuotaForInviter0Bonus to the inviter when an invitee signs up
QuotaForInvitee0Bonus to the invitee when signing up
ChannelDisableThreshold0Auto-disable channel after N consecutive failures (requires AutomaticDisableChannelEnabled=true)
QuotaRemindThreshold0UI low-balance alert
QuotaPerUnitenvCurrency conversion: QuotaPerUnit quota = 1 CNY
RetryTimesenvPer-channel retry attempts
ChannelDefaultCooldownSeconds / ChannelMaxCooldownSecondsenvChannel cooldown window
ErrorNext{passthrough:true,retry:true,disable:true,cooldown:true}Relay error-chain strategy (see below)

TopUpLink / ChatLink are the landing-page CTA buttons.

ErrorNext Strategy ​

Stored as {"errived": bool, "retry": bool, "disable": bool, "cooldown": bool}:

  • passthrough — surface the error to the client without retries.
  • retry — retry up to RetryTimes within the same channel.
  • disable — disable the channel after hitting the failure threshold.
  • cooldown — apply ChannelDefaultCooldownSeconds after a failure.

The relay engine reads the JSON; the UI just persists the four booleans.

Toggle Precondition Checks ​

PUT /api/option/ rejects enabling the following keys until their preconditions are met (controller/option.go):

KeyPrerequisite
ThemeValue must be in config.ValidThemes
GitHubOAuthEnabledGitHubClientId and GitHubClientSecret both non-empty
EmailDomainRestrictionEnabledEmailDomainWhitelist non-empty
WeChatAuthEnabledWeChatServerAddress non-empty
TurnstileCheckEnabledTurnstileSiteKey non-empty

Failures return actionable error messages.

Frontend Guide ​

  • Welcome bar + loading spinner; the page loads via GET /api/option/ on mount.
  • Numeric fields use <a-input-number size="large">; each section has its own Save button that PUTs all the section's keys.
  • Most toggles call saveSwitch(key) immediately on @change.
  • Log pruning sends DELETE /api/log/?target_timestamp=<unix-seconds>; target=0 is rejected by the backend.
  • Error strategy is saved as a single JSON string with the four booleans.

Implementation Pointers ​

ConcernLocation
Handler + validationcontroller/option.go
OptionMap bootstrapmodel/option.go::InitOptionMap / SyncOptions
Runtime syncmodel/option.go::UpdateOption → updateOptionMap
Relation with system_settingsSee header comment in model/system_setting.go
Routesrouter/api.go