Files
wangjia 40760aa884
ci / server (push) Failing after 14s
ci / design-tokens (push) Failing after 11s
dudu MVP:五端语音输入法初始提交
- server:Go 网关(WS 流式识别中继/计费配额/微信登录支付 mock/反馈/埋点),gummy provider 已真实联调
- desktop:Tauri 2(全局快捷键 push-to-talk/浮层/托盘/设置/登录购买/反馈/首启引导)
- android:Compose 主 App + IME(键盘内录音直传)
- ios:App + 键盘扩展(1A spike 实证键盘内不可录音,走 deep link 听写)
- design/design-pipeline:设计系统 + token 导出 iOS/Android 主题
- doc:前后端设计文档(HTML);web:官网宣传页;todo:任务看板

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 00:38:37 +08:00

140 lines
4.7 KiB
Go

package protocol
// ─── 认证 ────────────────────────────────────────────────────────────────────
type AuthQrResponse struct {
State string `json:"state"`
QrURL string `json:"qr_url"`
}
type AuthQrStatusResponse struct {
Status string `json:"status"` // pending | confirmed | expired
Token string `json:"token,omitempty"`
User *UserInfo `json:"user,omitempty"`
}
type AuthWechatRequest struct {
Code string `json:"code" binding:"required"`
}
type AuthTokenResponse struct {
Token string `json:"token"`
User UserInfo `json:"user"`
}
type UserInfo struct {
UserID string `json:"user_id"`
NicknameMasked string `json:"nickname_masked"`
}
// ─── 用户与余额 ───────────────────────────────────────────────────────────────
// 账户状态:余额 > 0 → ok;余额 = 0 且试用未尽 → trial;皆尽 → quota。
const (
AccountOK = "ok"
AccountTrial = "trial"
AccountQuota = "quota"
)
type MeResponse struct {
UserID string `json:"user_id"`
NicknameMasked string `json:"nickname_masked"`
BalanceSeconds int64 `json:"balance_seconds"`
TrialDailyLimit int `json:"trial_daily_limit"`
TrialUsedToday int `json:"trial_used_today"`
AccountState string `json:"account_state"` // ok | trial | quota
}
// ─── 时长包与订单 ─────────────────────────────────────────────────────────────
type Pack struct {
ID string `json:"id"`
Minutes int `json:"minutes"`
PriceCents int `json:"price_cents"`
UnitDesc string `json:"unit_desc"`
Tag string `json:"tag,omitempty"`
}
type PacksResponse struct {
Packs []Pack `json:"packs"`
}
const (
PayChannelNative = "native" // 桌面扫码
PayChannelApp = "app" // 移动收银台
)
type CreateOrderRequest struct {
PackID string `json:"pack_id" binding:"required"`
Channel string `json:"channel" binding:"required"` // native | app
}
type CreateOrderResponse struct {
OrderID string `json:"order_id"`
CodeURL string `json:"code_url,omitempty"` // native
PayParams map[string]any `json:"pay_params,omitempty"` // app
}
type OrderStatusResponse struct {
Status string `json:"status"` // pending | paid | closed
BalanceSeconds int64 `json:"balance_seconds,omitempty"`
}
// ─── 反馈(v1.1)──────────────────────────────────────────────────────────────
const (
FeedbackMaxImages = 3
FeedbackMaxImageBytes = 5 << 20 // 5MB
FeedbackMaxContentLen = 1000
FeedbackDailyLimit = 10
)
type FeedbackResponse struct {
FeedbackID string `json:"feedback_id"`
}
// ─── 打点(v1.1)──────────────────────────────────────────────────────────────
const (
MetricsMaxBatch = 100
MetricsMaxPropBytes = 2048
)
type MetricEvent struct {
Event string `json:"event"`
Props map[string]any `json:"props,omitempty"`
ClientTs int64 `json:"client_ts"`
}
type MetricsBatchRequest struct {
DeviceID string `json:"device_id" binding:"required"`
Platform string `json:"platform" binding:"required"` // mac | win | ios | android
AppVersion string `json:"app_version"`
OSVersion string `json:"os_version"`
Events []MetricEvent `json:"events" binding:"required"`
}
// MetricWhitelist 事件白名单:未知事件名直接丢弃(见前端文档 9.1 指标清单)。
var MetricWhitelist = map[string]bool{
"asr.first_partial_ms": true,
"asr.release_to_commit_ms": true,
"audio.start_ms": true,
"ws.connect_ms": true,
"ws.reconnect": true,
"asr.session": true,
"inject.fail": true,
"onboarding.step": true,
"login.success": true,
"purchase.success": true,
"kb.enabled": true,
}
// ─── 应用更新 ─────────────────────────────────────────────────────────────────
type AppLatestResponse struct {
Version string `json:"version"`
Notes string `json:"notes,omitempty"`
URL string `json:"url"`
Force bool `json:"force"`
}