interface.go raw

   1  package database
   2  
   3  import (
   4  	"context"
   5  	"io"
   6  	"time"
   7  
   8  	"next.orly.dev/pkg/database/indexes/types"
   9  	"next.orly.dev/pkg/nostr/encoders/event"
  10  	"next.orly.dev/pkg/nostr/encoders/filter"
  11  	"next.orly.dev/pkg/nostr/encoders/tag"
  12  	"next.orly.dev/pkg/interfaces/store"
  13  )
  14  
  15  // Database defines the interface that all database implementations must satisfy.
  16  // This allows switching between different storage backends (badger, neo4j, etc.)
  17  type Database interface {
  18  	// Core lifecycle methods
  19  	Path() string
  20  	Init(path string) error
  21  	Sync() error
  22  	Close() error
  23  	Wipe() error
  24  	SetLogLevel(level string)
  25  	Ready() <-chan struct{} // Returns a channel that closes when database is ready to serve requests
  26  
  27  	// Event storage and retrieval
  28  	SaveEvent(c context.Context, ev *event.E) (exists bool, err error)
  29  	GetSerialsFromFilter(f *filter.F) (serials types.Uint40s, err error)
  30  	WouldReplaceEvent(ev *event.E) (bool, types.Uint40s, error)
  31  
  32  	QueryEvents(c context.Context, f *filter.F) (evs event.S, err error)
  33  	QueryAllVersions(c context.Context, f *filter.F) (evs event.S, err error)
  34  	QueryEventsWithOptions(c context.Context, f *filter.F, includeDeleteEvents bool, showAllVersions bool) (evs event.S, err error)
  35  	QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) (evs event.S, err error)
  36  	QueryForSerials(c context.Context, f *filter.F) (serials types.Uint40s, err error)
  37  	QueryForIds(c context.Context, f *filter.F) (idPkTs []*store.IdPkTs, err error)
  38  
  39  	CountEvents(c context.Context, f *filter.F) (count int, approximate bool, err error)
  40  
  41  	FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error)
  42  	FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error)
  43  
  44  	GetSerialById(id []byte) (ser *types.Uint40, err error)
  45  	GetSerialsByIds(ids *tag.T) (serials map[string]*types.Uint40, err error)
  46  	GetSerialsByIdsWithFilter(ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool) (serials map[string]*types.Uint40, err error)
  47  	GetSerialsByRange(idx Range) (serials types.Uint40s, err error)
  48  
  49  	GetFullIdPubkeyBySerial(ser *types.Uint40) (fidpk *store.IdPkTs, err error)
  50  	GetFullIdPubkeyBySerials(sers []*types.Uint40) (fidpks []*store.IdPkTs, err error)
  51  
  52  	// Event deletion
  53  	DeleteEvent(c context.Context, eid []byte) error
  54  	DeleteEventBySerial(c context.Context, ser *types.Uint40, ev *event.E) error
  55  	DeleteExpired()
  56  	ProcessDelete(ev *event.E, admins [][]byte) error
  57  	CheckForDeleted(ev *event.E, admins [][]byte) error
  58  
  59  	// Import/Export
  60  	Import(rr io.Reader)
  61  	Export(c context.Context, w io.Writer, pubkeys ...[]byte)
  62  	ImportEventsFromReader(ctx context.Context, rr io.Reader) error
  63  	ImportEventsFromStrings(ctx context.Context, eventJSONs []string, policyManager interface{ CheckPolicy(action string, ev *event.E, pubkey []byte, remote string) (bool, error) }) error
  64  
  65  	// Relay identity
  66  	GetRelayIdentitySecret() (skb []byte, err error)
  67  	SetRelayIdentitySecret(skb []byte) error
  68  	GetOrCreateRelayIdentitySecret() (skb []byte, err error)
  69  
  70  	// Markers (metadata key-value storage)
  71  	SetMarker(key string, value []byte) error
  72  	GetMarker(key string) (value []byte, err error)
  73  	HasMarker(key string) bool
  74  	DeleteMarker(key string) error
  75  
  76  	// Subscriptions (payment-based access control)
  77  	GetSubscription(pubkey []byte) (*Subscription, error)
  78  	IsSubscriptionActive(pubkey []byte) (bool, error)
  79  	ExtendSubscription(pubkey []byte, days int) error
  80  	RecordPayment(pubkey []byte, amount int64, invoice, preimage string) error
  81  	GetPaymentHistory(pubkey []byte) ([]Payment, error)
  82  	ExtendBlossomSubscription(pubkey []byte, tier string, storageMB int64, daysExtended int) error
  83  	GetBlossomStorageQuota(pubkey []byte) (quotaMB int64, err error)
  84  	IsFirstTimeUser(pubkey []byte) (bool, error)
  85  
  86  	// Paid ACL (Lightning payment-gated access)
  87  	SavePaidSubscription(sub *PaidSubscription) error
  88  	GetPaidSubscription(pubkeyHex string) (*PaidSubscription, error)
  89  	DeletePaidSubscription(pubkeyHex string) error
  90  	ListPaidSubscriptions() ([]*PaidSubscription, error)
  91  	ClaimAlias(alias, pubkeyHex string) error
  92  	GetAliasByPubkey(pubkeyHex string) (string, error)
  93  	GetPubkeyByAlias(alias string) (string, error)
  94  	IsAliasTaken(alias string) (bool, error)
  95  
  96  	// NIP-43 Invite-based ACL
  97  	AddNIP43Member(pubkey []byte, inviteCode string) error
  98  	RemoveNIP43Member(pubkey []byte) error
  99  	IsNIP43Member(pubkey []byte) (isMember bool, err error)
 100  	GetNIP43Membership(pubkey []byte) (*NIP43Membership, error)
 101  	GetAllNIP43Members() ([][]byte, error)
 102  	StoreInviteCode(code string, expiresAt time.Time) error
 103  	ValidateInviteCode(code string) (valid bool, err error)
 104  	DeleteInviteCode(code string) error
 105  	PublishNIP43MembershipEvent(kind int, pubkey []byte) error
 106  
 107  	// Migrations (version tracking for schema updates)
 108  	RunMigrations()
 109  
 110  	// Query cache methods
 111  	GetCachedJSON(f *filter.F) ([][]byte, bool)
 112  	CacheMarshaledJSON(f *filter.F, marshaledJSON [][]byte)
 113  	GetCachedEvents(f *filter.F) (event.S, bool)
 114  	CacheEvents(f *filter.F, events event.S)
 115  	InvalidateQueryCache()
 116  
 117  	// Access tracking for storage management (garbage collection based on access patterns)
 118  	// RecordEventAccess records an access to an event by a connection.
 119  	// The connectionID is used to deduplicate accesses from the same connection.
 120  	RecordEventAccess(serial uint64, connectionID string) error
 121  	// GetEventAccessInfo returns the last access time and access count for an event.
 122  	GetEventAccessInfo(serial uint64) (lastAccess int64, accessCount uint32, err error)
 123  	// GetLeastAccessedEvents returns event serials sorted by coldness (oldest/lowest access).
 124  	// limit: max events to return, minAgeSec: minimum age in seconds since last access.
 125  	GetLeastAccessedEvents(limit int, minAgeSec int64) (serials []uint64, err error)
 126  
 127  	// Utility methods
 128  	EventIdsBySerial(start uint64, count int) (evs []uint64, err error)
 129  
 130  	// Blob storage (Blossom)
 131  	SaveBlob(sha256Hash []byte, data []byte, pubkey []byte, mimeType string, extension string) error
 132  	SaveBlobMetadata(sha256Hash []byte, size int64, pubkey []byte, mimeType string, extension string) error
 133  	GetBlob(sha256Hash []byte) (data []byte, metadata *BlobMetadata, err error)
 134  	HasBlob(sha256Hash []byte) (exists bool, err error)
 135  	DeleteBlob(sha256Hash []byte, pubkey []byte) error
 136  	ListBlobs(pubkey []byte, since, until int64) ([]*BlobDescriptor, error)
 137  	ListAllBlobs() ([]*BlobDescriptor, error)
 138  	GetBlobMetadata(sha256Hash []byte) (*BlobMetadata, error)
 139  	GetTotalBlobStorageUsed(pubkey []byte) (totalMB int64, err error)
 140  	SaveBlobReport(sha256Hash []byte, reportData []byte) error
 141  	ListAllBlobUserStats() ([]*UserBlobStats, error)
 142  	ReconcileBlobMetadata() (reconciled int, err error)
 143  
 144  	// Thumbnail caching
 145  	GetThumbnail(key string) (data []byte, err error)
 146  	SaveThumbnail(key string, data []byte) error
 147  
 148  	// NRC (Nostr Relay Connect) client management
 149  	CreateNRCConnection(label string, createdBy []byte) (*NRCConnection, error)
 150  	GetNRCConnection(id string) (*NRCConnection, error)
 151  	GetNRCConnectionByDerivedPubkey(derivedPubkey []byte) (*NRCConnection, error)
 152  	SaveNRCConnection(conn *NRCConnection) error
 153  	DeleteNRCConnection(id string) error
 154  	GetAllNRCConnections() ([]*NRCConnection, error)
 155  	GetNRCAuthorizedSecrets() (map[string]string, error)
 156  	UpdateNRCConnectionLastUsed(id string) error
 157  	GetNRCConnectionURI(conn *NRCConnection, relayPubkey []byte, rendezvousURL string) (string, error)
 158  }
 159