addrkit: deterministic address resolution service (Go)

- domain: address normalization/parsing, matching with explicit statuses
- adapters: SQLite registry store, ArcGIS outages client, optional LLM rewriter, HTTP API
- seed pipeline with duplicate handling and unparsed reporting
- CLI (seed/verify/resolve), systemd unit, OpenAPI contract, tests
This commit is contained in:
Maksim Totmin
2026-10-09 21:40:46 +07:00
commit 7b152c7fb3
34 changed files with 3446 additions and 0 deletions
@@ -0,0 +1,59 @@
package registrystore
import (
"path/filepath"
"testing"
"git.totmin.ru/en2zmax/addrkit/internal/domain/address"
)
func TestSaveLoadRoundTrip(t *testing.T) {
path := filepath.Join(t.TempDir(), "registry.db")
addr := "Станционная улица 1/1"
p := address.Parse(addr)
entries := []address.Entry{{
ID: "a1", Address: addr, District: "Ленинский",
Ordinal: p.Ordinal, NameKey: p.NameKey, StreetType: p.StreetType, StreetKey: p.StreetKey,
House: p.House, HouseFrac: p.HouseFrac,
}}
if err := Save(path, "2026-10-09", entries); err != nil {
t.Fatalf("Save: %v", err)
}
version, got, err := Load(path)
if err != nil {
t.Fatalf("Load: %v", err)
}
if version != "2026-10-09" {
t.Errorf("version = %q", version)
}
if len(got) != 1 {
t.Fatalf("entries = %d, want 1", len(got))
}
if got[0].Address != addr || got[0].District != "Ленинский" || got[0].StreetKey != p.StreetKey {
t.Errorf("round-tripped entry mismatch: %+v", got[0])
}
}
// TestSaveIsAtomicOverwrite verifies that re-seeding replaces the previous data
// rather than merging with it.
func TestSaveIsAtomicOverwrite(t *testing.T) {
path := filepath.Join(t.TempDir(), "registry.db")
if err := Save(path, "v1", []address.Entry{{ID: "x", Address: "Первая улица 1"}}); err != nil {
t.Fatalf("Save v1: %v", err)
}
if err := Save(path, "v2", []address.Entry{{ID: "y", Address: "Вторая улица 2"}}); err != nil {
t.Fatalf("Save v2: %v", err)
}
version, got, err := Load(path)
if err != nil {
t.Fatalf("Load: %v", err)
}
if version != "v2" || len(got) != 1 || got[0].Address != "Вторая улица 2" {
t.Fatalf("unexpected state after overwrite: version=%q entries=%+v", version, got)
}
}