package biz import ( "context" "io" "time" ) // Cache is the shared cache seam. The data implementation uses Redis when it // is reachable and falls back to process memory for local development. type Cache interface { Get(context.Context, string) (string, bool, error) Set(context.Context, string, string, time.Duration) error Delete(context.Context, string) error Increment(context.Context, string, time.Duration) (int64, error) } type StoredFile struct { Name string Path string URL string Size int64 } // FileStorage owns the persistence boundary for uploaded files. type FileStorage interface { Put(context.Context, string, io.Reader) (*StoredFile, error) Open(context.Context, string) (io.ReadCloser, error) Delete(context.Context, string) error Compose(context.Context, []string, string) (*StoredFile, string, error) DeletePrefix(context.Context, string) error List(context.Context, string, string, int) ([]*StoredFile, string, bool, error) } type JWTSettings struct { SigningKey string Issuer string Expires time.Duration Buffer time.Duration } type CaptchaSettings struct { KeyLong int ImageWidth int ImageHeight int StoreExpiration time.Duration } type MediaSettings struct { SessionTTL int MaxFileSize int64 } // RuntimeSettings exposes only the active values needed by the application. // The data implementation resolves every call from conf.Runtime so hot reloads // take effect without rebuilding services. type RuntimeSettings interface { RouterPrefix() string JWTSettings() JWTSettings CaptchaSettings() CaptchaSettings MediaSettings() MediaSettings UseMultipoint() bool } type IssuedToken struct { Value string ExpiresAt time.Time TTL time.Duration } type TokenIssuer interface { IssueToken(*User, uint, bool, time.Duration) (*IssuedToken, error) }