From ef6296bd227558865afee6986532a88b4f7e361a Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 27 Aug 2026 23:47:58 +0800 Subject: [PATCH] feat(core): add typed eventbus and domain extension points --- core/contracts/cache.go | 28 ++++++++++++++++++ core/contracts/database.go | 19 +++++++++++++ core/contracts/logger.go | 35 +++++++++++++++++++++++ core/contracts/storage.go | 58 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 core/contracts/cache.go create mode 100644 core/contracts/database.go create mode 100644 core/contracts/logger.go create mode 100644 core/contracts/storage.go diff --git a/core/contracts/cache.go b/core/contracts/cache.go new file mode 100644 index 00000000..2777bfef --- /dev/null +++ b/core/contracts/cache.go @@ -0,0 +1,28 @@ +package contracts + +import ( + "context" + "errors" + "time" +) + +// ErrCacheMiss is returned when an item is not found in the cache. +var ErrCacheMiss = errors.New("contracts/cache: key not found") + +// CacheService defines the contract for multi-layer cache operations (RAM L1 + Redis L2 + Pub/Sub invalidation). +type CacheService interface { + // Get retrieves an item from cache into target. Returns ErrCacheMiss if not found. + Get(ctx context.Context, key string, target any) error + + // Set stores an item into cache with a specified time-to-live duration. + Set(ctx context.Context, key string, value any, ttl time.Duration) error + + // Delete evicts a key from local and remote cache tiers and broadcasts invalidation. + Delete(ctx context.Context, key string) error + + // GetOrSet retrieves an item from cache, or calls loader to populate and return if missing. + GetOrSet(ctx context.Context, key string, target any, ttl time.Duration, loader func() (any, error)) error + + // Invalidate is a semantic alias for Delete. + Invalidate(ctx context.Context, key string) error +} diff --git a/core/contracts/database.go b/core/contracts/database.go new file mode 100644 index 00000000..73c06c50 --- /dev/null +++ b/core/contracts/database.go @@ -0,0 +1,19 @@ +package contracts + +import ( + "context" + + "gorm.io/gorm" +) + +// DBService defines the standard contract for relational database access and multi-datasource routing. +type DBService interface { + // GORM returns the underlying GORM database instance. + GORM() *gorm.DB + + // DB returns the GORM database instance bound to the given context. + DB(ctx context.Context) *gorm.DB + + // Named returns a named database connection if multiple data sources or replicas are configured. + Named(name string) *gorm.DB +} diff --git a/core/contracts/logger.go b/core/contracts/logger.go new file mode 100644 index 00000000..7eb1d260 --- /dev/null +++ b/core/contracts/logger.go @@ -0,0 +1,35 @@ +package contracts + +import ( + "context" +) + +// LoggerService defines the contract for structured logging with trace ID and context correlation. +type LoggerService interface { + // Debug logs a debug message with optional key-value structured fields. + Debug(ctx context.Context, msg string, keysAndValues ...any) + + // Info logs an informational message with optional key-value structured fields. + Info(ctx context.Context, msg string, keysAndValues ...any) + + // Warn logs a warning message with optional key-value structured fields. + Warn(ctx context.Context, msg string, keysAndValues ...any) + + // Error logs an error message with optional key-value structured fields. + Error(ctx context.Context, msg string, keysAndValues ...any) + + // Debugf logs a formatted debug message. + Debugf(ctx context.Context, format string, args ...any) + + // Infof logs a formatted informational message. + Infof(ctx context.Context, format string, args ...any) + + // Warnf logs a formatted warning message. + Warnf(ctx context.Context, format string, args ...any) + + // Errorf logs a formatted error message. + Errorf(ctx context.Context, format string, args ...any) + + // With returns a child logger enriched with additional key-value attributes. + With(keysAndValues ...any) LoggerService +} diff --git a/core/contracts/storage.go b/core/contracts/storage.go new file mode 100644 index 00000000..4dcad26b --- /dev/null +++ b/core/contracts/storage.go @@ -0,0 +1,58 @@ +package contracts + +import ( + "context" + "io" +) + +// StorageObject represents a retrieved file object from the storage backend. +type StorageObject struct { + Key string + CachePath string + Body io.ReadCloser + ContentLength int64 + ContentType string +} + +// StoragePutResult describes the output of a successful Put operation. +type StoragePutResult struct { + Key string + Bucket string +} + +// IngestOptions configures programmatic ingest of files into the platform storage. +type IngestOptions struct { + UserID uint64 + Type string + FileName string + MimeType string + Extension string + Size int64 + Policy int + Metadata map[string]any +} + +// IngestResult reports the outcome of a programmatic file ingest operation. +type IngestResult struct { + ID uint64 + Key string + URL string + Created bool + Stored bool + Resolved bool +} + +// StorageService defines the contract for unified object storage and managed file ingestion. +type StorageService interface { + // Put writes an object to storage. + Put(ctx context.Context, key string, body io.Reader, size int64, contentType string) (StoragePutResult, error) + + // Get retrieves an object from storage. + Get(ctx context.Context, key string) (*StorageObject, error) + + // Delete removes an object from storage. + Delete(ctx context.Context, key string) error + + // Ingest performs managed file ingestion into the platform storage domain with deduplication and metadata tracking. + Ingest(ctx context.Context, reader io.Reader, opts IngestOptions) (*IngestResult, error) +}