fix(outages): parse portal address at the boundary; strip district suffix
The outages portal appends the district in parentheses, e.g. "Медкадры улица, 1 (Заельцовский район)". That suffix hid the house number from the parser, so every portal address failed house matching and /v1/outages always returned empty. - address: NormalizeText drops a trailing "(...)" group (root fix, benefits every source) - outages: introduce HouseUnit; the ArcGIS adapter parses the (cleaned) address at the boundary and stores the structured unit; MatchingHouse matches on the unit (with a parse fallback for sources that only provide text) - config: portal.url is now optional (core runs without the events module) - httpapi: always return "outages": [] (no more omitempty); report "detail" when the events module is not configured - tests: regression coverage for the portal district format
This commit is contained in:
@@ -32,7 +32,8 @@ type ResolveConfig struct {
|
||||
MaxCandidates int `json:"max_candidates"`
|
||||
}
|
||||
|
||||
// PortalConfig configures the external outages portal (ArcGIS).
|
||||
// PortalConfig configures the external outages portal (ArcGIS). When URL is
|
||||
// empty the "events by house" module is disabled and only /v1/resolve works.
|
||||
type PortalConfig struct {
|
||||
URL string `json:"url"`
|
||||
TimeoutSeconds int `json:"timeout_seconds"`
|
||||
@@ -116,9 +117,8 @@ func (c Config) validate() error {
|
||||
if c.LLM.Enabled && c.LLM.URL == "" {
|
||||
return fmt.Errorf("config: llm.url is required when llm.enabled is true")
|
||||
}
|
||||
if c.Portal.URL == "" {
|
||||
return fmt.Errorf("config: portal.url is required")
|
||||
}
|
||||
// portal.url is optional: without it the "events by house" module is
|
||||
// disabled and only /v1/resolve is served.
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -60,10 +60,11 @@ func TestLoadMissingSystemPromptFileFailsClosed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRequiresPortalURL(t *testing.T) {
|
||||
func TestPortalURLOptional(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// No portal.url: the events module is disabled, the core still loads.
|
||||
path := writeFile(t, dir, "config.json", `{"addr": ":6171", "data_path": "x.db"}`)
|
||||
if _, err := Load(path); err == nil {
|
||||
t.Fatal("expected error for missing portal.url")
|
||||
if _, err := Load(path); err != nil {
|
||||
t.Fatalf("portal.url must be optional: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user