Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/GoCodeAlone/workflow/dynamic"
"github.com/GoCodeAlone/workflow/environment"
"github.com/GoCodeAlone/workflow/handlers"
"github.com/GoCodeAlone/workflow/interfaces"
"github.com/GoCodeAlone/workflow/module"
"github.com/GoCodeAlone/workflow/observability"
"github.com/GoCodeAlone/workflow/observability/tracing"
Expand Down Expand Up @@ -471,8 +472,8 @@ func registerManagementServices(logger *slog.Logger, app *serverApp) {

// Enrich OpenAPI spec via the service registry
for _, svc := range engine.GetApp().SvcRegistry() {
if gen, ok := svc.(*module.OpenAPIGenerator); ok {
module.RegisterAdminSchemas(gen)
if gen, ok := svc.(interfaces.SchemaRegistrar); ok {
gen.RegisterAdminSchemas()
gen.ApplySchemas()
logger.Info("Registered typed OpenAPI schemas", "module", gen.Name())
}
Expand All @@ -498,10 +499,12 @@ func (app *serverApp) initStores(logger *slog.Logger) error {
// Discover the WorkflowRegistry from the service registry
var store *module.V1Store
for _, svc := range engine.GetApp().SvcRegistry() {
if reg, ok := svc.(*module.WorkflowRegistry); ok {
store = reg.Store()
logger.Info("Using WorkflowRegistry store", "module", reg.Name())
break
if provider, ok := svc.(interfaces.WorkflowStoreProvider); ok {
if s, ok := provider.WorkflowStore().(*module.V1Store); ok {
store = s
logger.Info("Using WorkflowRegistry store", "module", provider.Name())
break
}
}
}

Expand Down
35 changes: 35 additions & 0 deletions interfaces/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package interfaces

// SchemaRegistrar is implemented by any service that can register admin
// schemas into an OpenAPI specification and apply them. Using this interface
// in cmd/server allows the server to enrich the OpenAPI spec without holding
// a concrete *module.OpenAPIGenerator pointer.
//
// *module.OpenAPIGenerator satisfies this interface.
type SchemaRegistrar interface {
// Name returns the module name (used for logging).
Name() string

// RegisterAdminSchemas registers all admin API request/response schemas
// onto this generator. Equivalent to calling module.RegisterAdminSchemas(gen).
RegisterAdminSchemas()

// ApplySchemas applies all previously registered component schemas and
// operation schema overrides to the current OpenAPI spec.
ApplySchemas()
}

// WorkflowStoreProvider is implemented by any service that exposes a workflow
// data store. Using this interface in cmd/server decouples the server startup
// code from the concrete *module.WorkflowRegistry type.
//
// *module.WorkflowRegistry satisfies this interface.
type WorkflowStoreProvider interface {
// Name returns the module name (used for logging).
Name() string

// WorkflowStore returns the underlying workflow data store as an opaque
// value. The caller is responsible for asserting the concrete type
// (typically *module.V1Store) when further operations are required.
WorkflowStore() any
}
11 changes: 11 additions & 0 deletions module/openapi_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import (
"sync"

"github.com/CrisisTextLine/modular"
"github.com/GoCodeAlone/workflow/interfaces"
"gopkg.in/yaml.v3"
)

// Compile-time assertion: *OpenAPIGenerator must satisfy interfaces.SchemaRegistrar.
var _ interfaces.SchemaRegistrar = (*OpenAPIGenerator)(nil)

// --- OpenAPI 3.0 spec structs (minimal inline definitions) ---

// OpenAPISpec represents a minimal OpenAPI 3.0 specification document.
Expand Down Expand Up @@ -681,3 +685,10 @@ func (g *OpenAPIGenerator) ApplySchemas() {
}
}
}

// RegisterAdminSchemas satisfies the interfaces.SchemaRegistrar interface.
// It delegates to the package-level RegisterAdminSchemas function, registering
// all admin API request/response schemas onto this generator.
func (g *OpenAPIGenerator) RegisterAdminSchemas() {
RegisterAdminSchemas(g)
}
11 changes: 11 additions & 0 deletions module/workflow_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
"fmt"

"github.com/CrisisTextLine/modular"
"github.com/GoCodeAlone/workflow/interfaces"
)

// Compile-time assertion: *WorkflowRegistry must satisfy interfaces.WorkflowStoreProvider.
var _ interfaces.WorkflowStoreProvider = (*WorkflowRegistry)(nil)

// WorkflowRegistry is a module that provides the V1Store as a service,
// making the workflow data store (companies, projects, workflows) available
// to other modules via the service registry. It can either use a shared
Expand Down Expand Up @@ -84,6 +88,13 @@ func (w *WorkflowRegistry) Store() *V1Store {
return w.store
}

// WorkflowStore satisfies the interfaces.WorkflowStoreProvider interface.
// It returns the underlying V1Store as an opaque any value so that the
// interfaces package does not need to import the module package.
func (w *WorkflowRegistry) WorkflowStore() any {
return w.store
}

func (w *WorkflowRegistry) ProvidesServices() []modular.ServiceProvider {
return []modular.ServiceProvider{
{Name: w.name, Description: "Workflow data registry (companies, projects, workflows)", Instance: w},
Expand Down
Loading