- internal/ai/types.go: IntakeRequest, IntakeResult, TierConfig, AIConfig domain types - internal/ai/client.go: AIClient interface + TierClient (go-openai, BaseURL tier-routing) - internal/ai/mock.go: MockAIClient test double with HighConfidenceResult/LowConfidenceResult fixtures - internal/ai/prompts/intake.go: BuildIntakePrompt() JSON-extraction prompt template - internal/config/config.go: Config.AI AIConfig field, tier defaults, env bindings, ai_config.json merge - ai_config.json: template config with placeholder Tier2 API key - .gitignore: add ai_config.local.json pattern for real keys (T-02-01 mitigation) - All tests pass: TestMockAIClient, TestMockAIClientError, TestTierClientConstruction, TestAIConfigDefaults
38 lines
1.1 KiB
Go
38 lines
1.1 KiB
Go
package ai
|
|
|
|
import "context"
|
|
|
|
// MockAIClient is a test double for AIClient.
|
|
// Set FixedResult and/or FixedError before use.
|
|
type MockAIClient struct {
|
|
FixedResult *IntakeResult
|
|
FixedError error
|
|
Calls []IntakeRequest
|
|
}
|
|
|
|
func (m *MockAIClient) AnalyzePhotos(_ context.Context, req IntakeRequest) (*IntakeResult, error) {
|
|
m.Calls = append(m.Calls, req)
|
|
return m.FixedResult, m.FixedError
|
|
}
|
|
|
|
// HighConfidenceResult returns a fixture IntakeResult with confidence 0.95.
|
|
func HighConfidenceResult() *IntakeResult {
|
|
return &IntakeResult{
|
|
Model: "Raspberry Pi 4 Model B",
|
|
Manufacturer: "Raspberry Pi Foundation",
|
|
Category: "compute",
|
|
Specs: map[string]string{"ram": "4GB", "cpu": "BCM2711"},
|
|
SuggestedTags: []string{"raspberry-pi", "compute", "arm"},
|
|
Confidence: 0.95,
|
|
}
|
|
}
|
|
|
|
// LowConfidenceResult returns a fixture with confidence 0.40 (below threshold).
|
|
func LowConfidenceResult() *IntakeResult {
|
|
return &IntakeResult{
|
|
Model: "Unknown Device",
|
|
Category: "unknown",
|
|
Confidence: 0.40,
|
|
ConfidenceNote: "Cannot identify markings clearly",
|
|
}
|
|
}
|