package credential import ( "errors" "fmt" "gorm.io/gorm" ) var ErrCredentialNotConfigured = errors.New("摄像头凭据尚未配置") type Value struct { Username string Password string } // Read is an internal adapter port. HTTP handlers must never expose Value. func Read(db *gorm.DB, deviceID, purpose string) (Value, error) { var row DeviceCredential if err := db.First(&row, "device_id = ? AND purpose = ?", deviceID, purpose).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return Value{}, ErrCredentialNotConfigured } return Value{}, fmt.Errorf("read device credential: %w", err) } vault, err := NewVaultFromEnvironment() if err != nil { return Value{}, err } username, password, err := vault.Decrypt(deviceID, purpose, row.Ciphertext) if err != nil { return Value{}, err } return Value{Username: username, Password: password}, nil }