refactor(storage): split Storage into per-aggregate stores#448
Draft
0x46616c6b wants to merge 3 commits into
Draft
refactor(storage): split Storage into per-aggregate stores#4480x46616c6b wants to merge 3 commits into
0x46616c6b wants to merge 3 commits into
Conversation
The 44-method `storage.Storage` interface was a single shape shared by every handler, middleware, and bridge — its generated mock alone was 2.6 KLOC and grew with every method. Replace it with five focused stores carried by a `Stores` aggregate: UserStore, TickerStore (owning membership, websites, and the four integration configs collapsed to ClearIntegration/ClearIntegrations), MessageStore, UploadStore, and a SettingsStore with a generic GetSettings[T]/SaveSettings[T] surface over the three settings rows. Each store also exposes a WithXxxTx method, and a new UnitOfWork.Do scopes them to a shared transaction. Bridges now hold only the stores they need (UploadStore + SettingsStore for Telegram and Signal; UploadStore for Mastodon and Bluesky), and the prefetch middlewares take their narrow store directly. Co-Authored-By: Claude <claude@anthropic.com>
Drive-by — gofmt flagged the missing space after `//` on the comment. Co-Authored-By: Claude <claude@anthropic.com>
The UnitOfWork interface, Tx struct, and per-store WithXxxTx helpers introduced alongside the storage interface split had no production callers and no tests exercising them. Drop the dead infrastructure until a real consumer exists. - Delete unit_of_work.go (UnitOfWork, Tx, Do) - Delete mock_UnitOfWork.go - Remove WithXxxTx from all five store interfaces, impls, and mocks - Drop MockStorage.UoW field and the unused MockGetSettingMissing helper - Keep Stores + NewStores in new stores.go Co-Authored-By: OpenCode <noreply@opencode.ai>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
The
storage.Storageinterface had grown to 44 methods spanning users, tickers, ticker↔user membership, ticker websites, the four integration configs, uploads, messages, three settings pairs, and a filesystem path. There was a single production implementation (SqlStorage) and a 2,631-line generated mock that every handler imported in full. Splitting along aggregates gives each handler a narrow dependency, shrinks the mocking surface per call site, and gives us clear seams for follow-up work (e.g. a future message-publication module).What changed
internal/storage/:UserStore,TickerStore,MessageStore,UploadStore,SettingsStore. Each carriesWithXxxTx(*gorm.DB)for transactional scoping.DeleteTelegram/DeleteMastodon/DeleteBluesky/DeleteSignalGroupmethods with a singleClearIntegration(ticker, Integration);DeleteIntegrationsbecomesClearIntegrations. Naming staysIntegrationto match the existing domain term.GetSettings[T]/SaveSettings[T]over a tinyGetSetting/SaveSettinginterface, withInactiveSetting,TelegramSetting,SignalGroupSettingdescriptors.Storesaggregate carried by handlers, the bridge layer, andcmd/;UnitOfWork.Do(fn func(Tx) error)scopes all five stores to one GORM transaction.uploads,settings), removing the fullstorage.Storagedependency.PrefetchTicker(TickerStore)).MockStoragewrapper (77 LOC) bundles the five mockery-generated per-store mocks, exposing aStores()accessor for handler tests. Settings helpers (MockGetTelegram,MockSaveSignalGroup, …) preserve the previous test ergonomics.Storageinterface andmock_Storage.goare deleted.Why
mockerygenerates them automatically from.mockery.yml).The changes and the PR were generated by Claude.