feat(voice): per-account choice between Whisper and the browser; STT_ALLOW_BROWSER
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m40s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m40s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
55112b940c
commit
a927a94a95
21 files changed
+288
-15
No files matched your search
@@ -35,6 +35,7 @@ var migrations = []migration{
|
||||
{12, "Markierung für Einträge von KI-Agenten", (*Store).migrateAgentMark},
|
||||
{13, "Herkunft von Einträgen (API-Schlüssel)", (*Store).migrateOrigin},
|
||||
{14, "Erledigte Aufgaben aufräumen", (*Store).migrateDoneCleanup},
|
||||
{15, "Spracheingabe pro Person", (*Store).migrateVoiceInput},
|
||||
}
|
||||
|
||||
func (s *Store) migrate() error {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package storage
|
||||
|
||||
import "errors"
|
||||
|
||||
// Everyone picks how their voice input works: the server's Whisper ("", the default) or the browser's
|
||||
// recognition ("browser"). The server only offers the choice when it has a Whisper server and the
|
||||
// browser is allowed (STT_ALLOW_BROWSER); the app applies it (lib/voice.ts).
|
||||
|
||||
var ErrInvalidVoiceInput = errors.New("Ungültige Spracheingabe (erlaubt: Whisper-Server oder Browser)")
|
||||
|
||||
func (s *Store) migrateVoiceInput() error {
|
||||
return s.addColumnIfMissing("users", "voice_input", "TEXT NOT NULL DEFAULT ''")
|
||||
}
|
||||
|
||||
// VoiceInput returns the user's choice: "" or "browser".
|
||||
func (s *Store) VoiceInput(userID string) string {
|
||||
var v string
|
||||
_ = s.db.QueryRow(`SELECT voice_input FROM users WHERE id = ?`, userID).Scan(&v)
|
||||
return v
|
||||
}
|
||||
|
||||
func (s *Store) SetVoiceInput(userID, v string) error {
|
||||
if v != "" && v != "browser" {
|
||||
return ErrInvalidVoiceInput
|
||||
}
|
||||
_, err := s.db.Exec(`UPDATE users SET voice_input = ? WHERE id = ?`, v, userID)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVoiceInputChoice(t *testing.T) {
|
||||
store, err := NewStore(filepath.Join(t.TempDir(), "voice.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("NewStore: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
anna, _ := store.CreateUser("anna@example.com", "hash", "Anna", "member")
|
||||
if v := store.VoiceInput(anna.ID); v != "" {
|
||||
t.Fatalf("default should be the Whisper server (\"\"), got %q", v)
|
||||
}
|
||||
if err := store.SetVoiceInput(anna.ID, "browser"); err != nil || store.VoiceInput(anna.ID) != "browser" {
|
||||
t.Fatalf("browser not stored: %v", err)
|
||||
}
|
||||
if err := store.SetVoiceInput(anna.ID, "google"); err == nil {
|
||||
t.Fatal("unknown values must be refused")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user