Versions in this module Expand all Collapse all v0 v0.6.0 Apr 12, 2026 Changes in this version + var ErrAppAlreadyRegistered = errors.New("multiapp: app already registered") + var ErrAppNotFound = errors.New("multiapp: app not found") + var ErrCacheMiss = errors.New("cache miss") + var ErrFeatureNotEnabled = errors.New("multiapp: feature not enabled for this app") + var ErrInvalidSchemaName = errors.New("multiapp: invalid schema name") + var ErrMigrationFailed = errors.New("multiapp: migration failed") + var ErrNoAppContext = errors.New("multiapp: no app context in request") + var ErrNotAuthenticated = errors.New("multiapp: authentication required") + func AppIDFromContext(ctx context.Context) string + func AppIDFromSessionMetadata(session *bff.Session) string + func AppLogger(next http.Handler) http.Handler + func AppSessionMetadata(appID, appSlug string) map[string]string + func AppSlugFromContext(ctx context.Context) string + func AppSlugFromSessionMetadata(session *bff.Session) string + func AuthMiddleware(cfg MiddlewareConfig) func(http.Handler) http.Handler + func DatabaseSchemaFromContext(ctx context.Context) string + func EnrichContext(ctx context.Context, appCtx *AppContext) context.Context + func GetSetting(ctx context.Context, key string) any + func HasAppContext(ctx context.Context) bool + func HasFeature(ctx context.Context, feature string) bool + func InjectRLS() func(http.Handler) http.Handler + func RequireApp() func(http.Handler) http.Handler + func RequireAuth(ctx context.Context) (uuid.UUID, error) + func RequireAuthentication() func(http.Handler) http.Handler + func RequireFeature(feature string) func(http.Handler) http.Handler + func RequirePermission(permission string) func(http.Handler) http.Handler + func RequireRole(role string) func(http.Handler) http.Handler + func SchemaFromAppSlug(slug string) string + func SessionKeyWithApp(appID, sessionID string) string + func ValidateAppAccess(ctx context.Context) error + func ValidateAppFeature(ctx context.Context, feature string) error + func WithAppContext(ctx context.Context, appCtx *AppContext) context.Context + func WithRLSFromClaims(ctx context.Context) context.Context + type AppAwareDB struct + func NewAppAwareDB(databaseURL string) (*AppAwareDB, error) + func (db *AppAwareDB) Close() error + func (db *AppAwareDB) CreateSchema(ctx context.Context, schemaName string) error + func (db *AppAwareDB) DropSchema(ctx context.Context, schemaName string) error + func (db *AppAwareDB) ForSchema(schemaName string) *SchemaDB + func (db *AppAwareDB) GetSchemaSize(ctx context.Context, schemaName string) (int64, error) + func (db *AppAwareDB) ListSchemas(ctx context.Context) ([]string, error) + func (db *AppAwareDB) Pool() *pgxpool.Pool + type AppBackend interface + EntSchemas func() []ent.Schema + Migrations func() []Migration + Name func() string + OnRegister func(ctx context.Context, cfg *AppConfig) error + OnShutdown func(ctx context.Context) error + Routes func(deps Dependencies) chi.Router + Slug func() string + type AppClaims struct + AppID string + AppSlug string + func AppClaimsFromContext(ctx any) *AppClaims + func NewAppClaims(claims *jwt.Claims) *AppClaims + func NewAppClaimsForApp(claims *jwt.Claims, appID, appSlug string) *AppClaims + func (c *AppClaims) WithApp(appID, appSlug string) *AppClaims + type AppConfig struct + AppID string + DatabaseSchema string + Features []string + Settings map[string]any + Slug string + type AppContext struct + AppID string + AppName string + AppSlug string + DatabaseSchema string + Features []string + Settings map[string]any + func AppContextFromContext(ctx context.Context) *AppContext + type AppSession struct + AppID string + AppSlug string + func CreateAppSession(appID, appSlug string, userID uuid.UUID, accessToken, refreshToken string, ...) (*AppSession, error) + func NewAppSession(session *bff.Session, appID, appSlug string) *AppSession + type Cache interface + Delete func(ctx context.Context, key string) error + Get func(ctx context.Context, key string) ([]byte, error) + Set func(ctx context.Context, key string, value []byte, ttlSeconds int) error + WithPrefix func(prefix string) Cache + type Config struct + DatabaseURL string + Logger *slog.Logger + Mode ServerMode + RedisURL string + type Dependencies struct + Cache Cache + Config *AppConfig + DB *SchemaDB + Logger *slog.Logger + type EntClientFactory struct + func NewEntClientFactory(db *AppAwareDB) *EntClientFactory + func (f *EntClientFactory) EntDriverForSchema(ctx context.Context, schema string) (*entsql.Driver, error) + func (f *EntClientFactory) PgxConnWithSchema(ctx context.Context, schema string) (*pgx.Conn, error) + func (f *EntClientFactory) StdDBForSchema(ctx context.Context, schema string) (*sql.DB, error) + type EntConfig struct + Debug bool + Schema string + type EntConnHook struct + func NewEntConnHook(db *AppAwareDB) *EntConnHook + func (h *EntConnHook) SetSchemaFromContext(ctx context.Context, conn *sql.Conn) error + type FullContext struct + App *AppContext + Claims *jwt.Claims + FederationID uuid.UUID + TenantID uuid.UUID + UserID uuid.UUID + func FullContextFromContext(ctx context.Context) *FullContext + func RequireAppAndAuth(ctx context.Context) (*FullContext, error) + func (fc *FullContext) HasApp() bool + func (fc *FullContext) IsAuthenticated() bool + func (fc *FullContext) IsFederated() bool + func (fc *FullContext) OrganizationID() *uuid.UUID + func (fc *FullContext) PrincipalID() uuid.UUID + type MemoryCache struct + func NewMemoryCache() *MemoryCache + func (c *MemoryCache) Delete(ctx context.Context, key string) error + func (c *MemoryCache) Get(ctx context.Context, key string) ([]byte, error) + func (c *MemoryCache) Set(ctx context.Context, key string, value []byte, ttlSeconds int) error + func (c *MemoryCache) WithPrefix(prefix string) Cache + type MiddlewareConfig struct + JWTService *jwt.Service + OnError func(w http.ResponseWriter, r *http.Request, err error) + RequireAuth bool + SetRLSContext bool + type Migration struct + Down func(ctx context.Context, db *SchemaDB) error + Name string + Up func(ctx context.Context, db *SchemaDB) error + Version int + type RedisCache struct + func NewRedisCache(redisURL string) (*RedisCache, error) + func (c *RedisCache) Close() error + func (c *RedisCache) Delete(ctx context.Context, key string) error + func (c *RedisCache) Get(ctx context.Context, key string) ([]byte, error) + func (c *RedisCache) Set(ctx context.Context, key string, value []byte, ttlSeconds int) error + func (c *RedisCache) WithPrefix(prefix string) Cache + type SchemaDB struct + func (db *SchemaDB) AcquireConn(ctx context.Context) (*pgxpool.Conn, error) + func (db *SchemaDB) Begin(ctx context.Context) (*SchemaTx, error) + func (db *SchemaDB) BeginTx(ctx context.Context, opts pgx.TxOptions) (*SchemaTx, error) + func (db *SchemaDB) Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) + func (db *SchemaDB) Pool() *pgxpool.Pool + func (db *SchemaDB) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) + func (db *SchemaDB) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row + func (db *SchemaDB) Schema() string + func (db *SchemaDB) StdDB(ctx context.Context) (*sql.DB, error) + type SchemaTx struct + func (tx *SchemaTx) Commit(ctx context.Context) error + func (tx *SchemaTx) Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) + func (tx *SchemaTx) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) + func (tx *SchemaTx) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row + func (tx *SchemaTx) Rollback(ctx context.Context) error + type Server struct + func NewServer(cfg Config) (*Server, error) + func (s *Server) Apps() []string + func (s *Server) GetApp(slug string) (AppBackend, bool) + func (s *Server) RegisterApp(backend AppBackend) error + func (s *Server) Router() *chi.Mux + func (s *Server) Run(addr string) error + func (s *Server) Shutdown(ctx context.Context) error + type ServerMode string + const MultiAppMode + const SingleAppMode