From 616beecc41b573503dad9f5bfd9f353c6f826a8a Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Mon, 6 Apr 2026 11:12:03 +0300 Subject: refactor: extract shared CardStore into internal/store to eliminate duplication FindCardDirectory, FindOrCreateCardDirectory, GenerateCardID and the ScanWords helper previously existed in both internal/utils.go (as standalone functions) and were partially duplicated in internal/gui/card_service.go (readWordFromDir, ScanExistingWords). Introduce internal/store.CardStore as the single source of truth for all on-disk card-directory operations. Both internal/processor and internal/gui now hold a *store.CardStore field and delegate to it, removing the last copy of the directory-scanning loop from card_service.go. internal/utils.go keeps thin forwarding wrappers for callers that import the root internal package. Also adds table-driven unit tests for the new package covering FindCardDirectory (including legacy _word.txt fallback), FindOrCreateCardDirectory, and CardStore.ScanWords. Co-Authored-By: Claude Sonnet 4.6 --- internal/processor/processor.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'internal/processor/processor.go') diff --git a/internal/processor/processor.go b/internal/processor/processor.go index 14e5341..323df23 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -17,6 +17,7 @@ import ( "codeberg.org/snonux/totalrecall/internal/gui" "codeberg.org/snonux/totalrecall/internal/image" "codeberg.org/snonux/totalrecall/internal/phonetic" + "codeberg.org/snonux/totalrecall/internal/store" "codeberg.org/snonux/totalrecall/internal/translation" ) @@ -77,6 +78,11 @@ type Processor struct { // so individual methods never call Viper directly. cfg *Config + // cardStore is the shared CardStore for locating and creating on-disk + // card directories. It is initialised from flags.OutputDir in NewProcessor + // and used by all card_store.go helpers. + cardStore *store.CardStore + // imageFactories groups the two image-provider construction functions. // Production code uses image.DefaultClientFactories(); tests replace fields. imageFactories image.ClientFactories @@ -103,6 +109,9 @@ func NewProcessor(flags *cli.Flags, cfg *Config) *Processor { translationCache: translation.NewTranslationCache(), phoneticFetcher: phonetic.NewFetcher(&phonetic.Config{Provider: phoneticProvider, OpenAIKey: openAIKey, GoogleAPIKey: googleAPIKey}), randomIntn: rand.Intn, + // cardStore is rooted at the output directory so card-discovery helpers + // never need to know about flags directly. + cardStore: store.New(flags.OutputDir), imageFactories: image.DefaultClientFactories(), newAudioProvider: audio.NewProvider, } -- cgit v1.2.3