Files
story/internal/onboarding/voice_runtime.go
T

60 lines
1.7 KiB
Go
Raw Normal View History

package onboarding
import (
"context"
)
type VoiceRuntimeInput struct {
BootID string `json:"boot_id"`
}
// VoiceRuntime is independent of the short-lived provisioning screen. It
// exposes only this authenticated device's current, bound activation command.
// Registration is owned by the server; the device only acknowledges SDK initialization.
func (s *Service) VoiceRuntime(ctx context.Context, d Device, in VoiceRuntimeInput) (map[string]any, error) {
if !uuidV4(in.BootID) {
return nil, fail(400, "VALIDATION_FAILED", "启动编号不正确")
}
tx, e := s.pool.Begin(ctx)
if e != nil {
return nil, e
}
defer tx.Rollback(ctx)
current, e := readDevice(ctx, tx, d.ID, true)
if e != nil {
return nil, e
}
if !deviceAllowed(current) || current.BootID != in.BootID {
return nil, errState
}
var bound bool
if e = tx.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM device_binding WHERE device_id=$1::uuid AND generation=$2 AND unbound_at IS NULL) OR EXISTS(SELECT 1 FROM device_account_binding WHERE device_id=$1::uuid AND generation=$2 AND released_at IS NULL)`, d.ID, current.Generation).Scan(&bound); e != nil {
return nil, e
}
if !bound {
return nil, fail(409, "DEVICE_UNBOUND", "请先绑定设备")
}
command, e := s.activationCommand(ctx, tx, current)
if e != nil {
return nil, e
}
st, e := s.state(ctx, tx, current)
if e != nil {
return nil, e
}
out := map[string]any{"state": st, "command": command, "call_contract": "CALL-MEMORY-1.1"}
if !s.options.LegacyDeviceRegistration {
fields, err := s.voiceFields(ctx, tx, current)
if err != nil {
return nil, err
}
for k, v := range fields {
out[k] = v
}
}
if e = tx.Commit(ctx); e != nil {
return nil, e
}
return out, nil
}