Skip to content

feat!: introduce storage abstraction layer - #40

Merged
paullla merged 1 commit into
Locastic:masterfrom
paullla:feat/storage-abstraction
Jul 3, 2026
Merged

feat!: introduce storage abstraction layer#40
paullla merged 1 commit into
Locastic:masterfrom
paullla:feat/storage-abstraction

Conversation

@paullla

@paullla paullla commented Jul 3, 2026

Copy link
Copy Markdown
Member
Q A
Bug fix? yes (removed a method that threw TypeError on every hit, see below)
New feature? yes
BC breaks? yes
Deprecations? no
Issues -
License MIT

Problem

Loggastic is hard-wired to Elasticsearch: the data processor, both data providers, the populate handler and the console commands all inject ElasticsearchServiceInterface, ElasticsearchContextFactoryInterface or ElasticsearchIndexFactoryInterface directly. There is no way to store activity logs in another backend without forking, and #32 (bridge interfaces) only made the existing Elasticsearch services decoratable. #38 prepared the modern bundle layout so this abstraction could land on top of it.

Changes

  • New Locastic\Loggastic\Storage namespace with three storage-agnostic interfaces: ActivityLogStorageInterface (write/read activity logs), CurrentDataTrackerStorageInterface (save/update/bulk-save/find trackers) and StorageInitializerInterface (create or recreate the underlying storage per loggable class, idempotent initialize* methods return whether the storage was created)
  • Elasticsearch implementations in Bridge\Elasticsearch\Storage (ElasticsearchActivityLogStorage, ElasticsearchCurrentDataTrackerStorage, ElasticsearchStorageInitializer), aliased to the interfaces, so existing apps need no configuration changes. Custom backends implement the three interfaces and override the aliases (documented in the README)
  • Breaking: ActivityLogProcessor, ActivityLogProvider, CurrentDataTrackerProvider, PopulateCurrentDataTrackersHandler and both console commands now depend on the storage interfaces; their constructor signatures changed
  • Breaking: ActivityLogProviderInterface::getActivityLogsByIndexAndId() (from Add limit and offset to ActivityLogProvider #24) moved to ElasticsearchActivityLogStorage::findByIndexAndObjectId(): an index-name-based read is inherently Elasticsearch-specific and does not belong on the storage-agnostic provider
  • Breaking: ElasticNormalizationContextTrait moved to Serializer\Traits\NormalizationContextTrait; it only forces the \DateTime::ATOM date format and was the last Bridge\Elasticsearch reference in the logger and update handler
  • Removed ActivityLogProvider::getCurrentDataTrackerByClassAndId(): it declared an ?array return type while the denormalizer returns a CurrentDataTracker object, so any call that found a tracker threw a TypeError (CurrentDataTrackerProviderInterface provides the working equivalent)
  • Removed the unused IndexNotFoundException; CreateLoggableIndexesCommand no longer catches the Elasticsearch client exception itself, the "already exists" handling lives in the initializer
  • CHANGELOG, UPGRADE-2.0.md and README updated (custom storage backend how-to); PHPStan baseline shrank by the entries for removed methods, no new entries added

Verification

  • Full PHPUnit suite (24 tests, 53 assertions) passes against Elasticsearch 9.0
  • locastic:activity-logs:create-loggable-indexes exercised twice end-to-end through the test kernel: first run creates all indexes, second run prints "Index already exists, skipping." for each and exits 0
  • PHPStan reports no errors; PHP-CS-Fixer reports 0 fixable files; composer validate --strict passes

Core services no longer depend on the Elasticsearch bridge. New
ActivityLogStorageInterface, CurrentDataTrackerStorageInterface and
StorageInitializerInterface in Locastic\Loggastic\Storage decouple the
processor, providers, message handlers and console commands from the
backend; the default Elasticsearch implementations live in
Bridge\Elasticsearch\Storage and are wired via interface aliases.

Also moves ElasticNormalizationContextTrait to
Serializer\Traits\NormalizationContextTrait, replaces
ActivityLogProviderInterface::getActivityLogsByIndexAndId() with
ElasticsearchActivityLogStorage::findByIndexAndObjectId(), and removes
the broken ActivityLogProvider::getCurrentDataTrackerByClassAndId()
and the unused IndexNotFoundException.
@paullla
paullla merged commit 707e9bc into Locastic:master Jul 3, 2026
12 checks passed
@paullla
paullla deleted the feat/storage-abstraction branch July 3, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant