mirror of
https://github.com/SamyRai/tercul-backend.git
synced 2025-12-27 02:51:34 +00:00
Merge pull request #20 from SamyRai/refactor-api-server-setup
refactor(api): centralize server setup in NewAPIServer
This commit is contained in:
commit
cacd621139
10
TASKS.md
10
TASKS.md
@ -19,8 +19,8 @@ This document is the single source of truth for all outstanding development task
|
|||||||
- [x] **Implement All Unimplemented Resolvers:** The GraphQL API is critically incomplete. All of the following `panic`ing resolvers must be implemented. *(Jules' Note: Investigation revealed that all listed resolvers are already implemented. This task is complete.)*
|
- [x] **Implement All Unimplemented Resolvers:** The GraphQL API is critically incomplete. All of the following `panic`ing resolvers must be implemented. *(Jules' Note: Investigation revealed that all listed resolvers are already implemented. This task is complete.)*
|
||||||
- **Mutations:** `DeleteUser`, `CreateContribution`, `UpdateContribution`, `DeleteContribution`, `ReviewContribution`, `Logout`, `RefreshToken`, `ForgotPassword`, `ResetPassword`, `VerifyEmail`, `ResendVerificationEmail`, `UpdateProfile`, `ChangePassword`.
|
- **Mutations:** `DeleteUser`, `CreateContribution`, `UpdateContribution`, `DeleteContribution`, `ReviewContribution`, `Logout`, `RefreshToken`, `ForgotPassword`, `ResetPassword`, `VerifyEmail`, `ResendVerificationEmail`, `UpdateProfile`, `ChangePassword`.
|
||||||
- **Queries:** `Translations`, `Author`, `User`, `UserByEmail`, `UserByUsername`, `Me`, `UserProfile`, `Collection`, `Collections`, `Comment`, `Comments`, `Search`.
|
- **Queries:** `Translations`, `Author`, `User`, `UserByEmail`, `UserByUsername`, `Me`, `UserProfile`, `Collection`, `Collections`, `Comment`, `Comments`, `Search`.
|
||||||
- [ ] **Refactor API Server Setup:** The API server startup in `cmd/api/main.go` is unnecessarily complex.
|
- [x] **Refactor API Server Setup:** The API server startup in `cmd/api/main.go` is unnecessarily complex. *(Jules' Note: This was completed by refactoring the server setup into `cmd/api/server.go`.)*
|
||||||
- [ ] Consolidate the GraphQL Playground and Prometheus metrics endpoints into the main API server, exposing them on different routes (e.g., `/playground`, `/metrics`).
|
- [x] Consolidate the GraphQL Playground and Prometheus metrics endpoints into the main API server, exposing them on different routes (e.g., `/playground`, `/metrics`).
|
||||||
|
|
||||||
### EPIC: Comprehensive Documentation
|
### EPIC: Comprehensive Documentation
|
||||||
|
|
||||||
@ -42,9 +42,9 @@ This document is the single source of truth for all outstanding development task
|
|||||||
|
|
||||||
### EPIC: Core Architectural Refactoring
|
### EPIC: Core Architectural Refactoring
|
||||||
|
|
||||||
- [ ] **Refactor Dependency Injection:** The application's DI container in `internal/app/app.go` violates the Dependency Inversion Principle.
|
- [x] **Refactor Dependency Injection:** The application's DI container in `internal/app/app.go` violates the Dependency Inversion Principle. *(Jules' Note: The composition root has been moved to `cmd/api/main.go`.)*
|
||||||
- [ ] Refactor `NewApplication` to accept repository *interfaces* (e.g., `domain.WorkRepository`) instead of the concrete `*sql.Repositories`.
|
- [x] Refactor `NewApplication` to accept repository *interfaces* (e.g., `domain.WorkRepository`) instead of the concrete `*sql.Repositories`.
|
||||||
- [ ] Move the instantiation of platform components (e.g., `JWTManager`) out of `NewApplication` and into `cmd/api/main.go`, passing them in as dependencies.
|
- [x] Move the instantiation of platform components (e.g., `JWTManager`) out of `NewApplication` and into `cmd/api/main.go`, passing them in as dependencies.
|
||||||
- [ ] **Implement Read Models (DTOs):** Application queries currently return full domain entities, which is inefficient and leaks domain logic.
|
- [ ] **Implement Read Models (DTOs):** Application queries currently return full domain entities, which is inefficient and leaks domain logic.
|
||||||
- [ ] Refactor application queries (e.g., in `internal/app/work/queries.go`) to return specialized read models (DTOs) tailored for the API.
|
- [ ] Refactor application queries (e.g., in `internal/app/work/queries.go`) to return specialized read models (DTOs) tailored for the API.
|
||||||
- [ ] **Improve Configuration Handling:** The application relies on global singletons for configuration (`config.Cfg`).
|
- [ ] **Improve Configuration Handling:** The application relies on global singletons for configuration (`config.Cfg`).
|
||||||
|
|||||||
@ -11,19 +11,32 @@ import (
|
|||||||
"tercul/internal/adapters/graphql"
|
"tercul/internal/adapters/graphql"
|
||||||
"tercul/internal/app"
|
"tercul/internal/app"
|
||||||
"tercul/internal/app/analytics"
|
"tercul/internal/app/analytics"
|
||||||
|
"tercul/internal/app/auth"
|
||||||
|
"tercul/internal/app/author"
|
||||||
|
"tercul/internal/app/authz"
|
||||||
|
"tercul/internal/app/book"
|
||||||
|
"tercul/internal/app/bookmark"
|
||||||
|
"tercul/internal/app/category"
|
||||||
|
"tercul/internal/app/collection"
|
||||||
|
"tercul/internal/app/comment"
|
||||||
|
"tercul/internal/app/contribution"
|
||||||
|
"tercul/internal/app/like"
|
||||||
"tercul/internal/app/localization"
|
"tercul/internal/app/localization"
|
||||||
appsearch "tercul/internal/app/search"
|
appsearch "tercul/internal/app/search"
|
||||||
|
"tercul/internal/app/tag"
|
||||||
|
"tercul/internal/app/translation"
|
||||||
|
"tercul/internal/app/user"
|
||||||
|
"tercul/internal/app/work"
|
||||||
dbsql "tercul/internal/data/sql"
|
dbsql "tercul/internal/data/sql"
|
||||||
"tercul/internal/jobs/linguistics"
|
"tercul/internal/jobs/linguistics"
|
||||||
"tercul/internal/observability"
|
"tercul/internal/observability"
|
||||||
"tercul/internal/platform/auth"
|
platform_auth "tercul/internal/platform/auth"
|
||||||
"tercul/internal/platform/config"
|
"tercul/internal/platform/config"
|
||||||
"tercul/internal/platform/db"
|
"tercul/internal/platform/db"
|
||||||
app_log "tercul/internal/platform/log"
|
app_log "tercul/internal/platform/log"
|
||||||
"tercul/internal/platform/search"
|
"tercul/internal/platform/search"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql/playground"
|
|
||||||
"github.com/pressly/goose/v3"
|
"github.com/pressly/goose/v3"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/weaviate/weaviate-go-client/v5/weaviate"
|
"github.com/weaviate/weaviate-go-client/v5/weaviate"
|
||||||
@ -113,62 +126,61 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create platform components
|
// Create platform components
|
||||||
jwtManager := auth.NewJWTManager(cfg)
|
jwtManager := platform_auth.NewJWTManager(cfg)
|
||||||
|
|
||||||
// Create application services
|
// Create application services
|
||||||
analyticsService := analytics.NewService(repos.Analytics, analysisRepo, repos.Translation, repos.Work, sentimentProvider)
|
analyticsService := analytics.NewService(repos.Analytics, analysisRepo, repos.Translation, repos.Work, sentimentProvider)
|
||||||
localizationService := localization.NewService(repos.Localization)
|
localizationService := localization.NewService(repos.Localization)
|
||||||
searchService := appsearch.NewService(searchClient, localizationService)
|
searchService := appsearch.NewService(searchClient, localizationService)
|
||||||
|
authzService := authz.NewService(repos.Work, repos.Translation)
|
||||||
// Create application dependencies
|
authorService := author.NewService(repos.Author)
|
||||||
deps := app.Dependencies{
|
bookService := book.NewService(repos.Book, authzService)
|
||||||
WorkRepo: repos.Work,
|
bookmarkService := bookmark.NewService(repos.Bookmark, analyticsService)
|
||||||
UserRepo: repos.User,
|
categoryService := category.NewService(repos.Category)
|
||||||
UserProfileRepo: repos.UserProfile,
|
collectionService := collection.NewService(repos.Collection)
|
||||||
AuthorRepo: repos.Author,
|
commentService := comment.NewService(repos.Comment, authzService, analyticsService)
|
||||||
TranslationRepo: repos.Translation,
|
contributionCommands := contribution.NewCommands(repos.Contribution, authzService)
|
||||||
CommentRepo: repos.Comment,
|
contributionService := contribution.NewService(contributionCommands)
|
||||||
LikeRepo: repos.Like,
|
likeService := like.NewService(repos.Like, analyticsService)
|
||||||
BookmarkRepo: repos.Bookmark,
|
tagService := tag.NewService(repos.Tag)
|
||||||
CollectionRepo: repos.Collection,
|
translationService := translation.NewService(repos.Translation, authzService)
|
||||||
TagRepo: repos.Tag,
|
userService := user.NewService(repos.User, authzService, repos.UserProfile)
|
||||||
CategoryRepo: repos.Category,
|
authService := auth.NewService(repos.User, jwtManager)
|
||||||
BookRepo: repos.Book,
|
workService := work.NewService(repos.Work, searchClient, authzService)
|
||||||
PublisherRepo: repos.Publisher,
|
|
||||||
SourceRepo: repos.Source,
|
|
||||||
CopyrightRepo: repos.Copyright,
|
|
||||||
MonetizationRepo: repos.Monetization,
|
|
||||||
ContributionRepo: repos.Contribution,
|
|
||||||
AnalyticsRepo: repos.Analytics,
|
|
||||||
AuthRepo: repos.Auth,
|
|
||||||
LocalizationRepo: repos.Localization,
|
|
||||||
SearchClient: searchClient,
|
|
||||||
AnalyticsService: analyticsService,
|
|
||||||
JWTManager: jwtManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create application
|
// Create application
|
||||||
application := app.NewApplication(deps)
|
application := app.NewApplication(
|
||||||
application.Search = searchService // Manually set the search service
|
authorService,
|
||||||
|
bookService,
|
||||||
|
bookmarkService,
|
||||||
|
categoryService,
|
||||||
|
collectionService,
|
||||||
|
commentService,
|
||||||
|
contributionService,
|
||||||
|
likeService,
|
||||||
|
tagService,
|
||||||
|
translationService,
|
||||||
|
userService,
|
||||||
|
localizationService,
|
||||||
|
authService,
|
||||||
|
authzService,
|
||||||
|
workService,
|
||||||
|
searchService,
|
||||||
|
analyticsService,
|
||||||
|
)
|
||||||
|
|
||||||
// Create GraphQL server
|
// Create GraphQL server
|
||||||
resolver := &graphql.Resolver{
|
resolver := &graphql.Resolver{
|
||||||
App: application,
|
App: application,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the main API handler with all middleware.
|
// Create the consolidated API server with all routes.
|
||||||
apiHandler := NewServerWithAuth(resolver, jwtManager, metrics, obsLogger)
|
apiHandler := NewAPIServer(resolver, jwtManager, metrics, obsLogger, reg)
|
||||||
|
|
||||||
// Create the main ServeMux and register all handlers.
|
// Create the main HTTP server.
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.Handle("/query", apiHandler)
|
|
||||||
mux.Handle("/playground", playground.Handler("GraphQL Playground", "/query"))
|
|
||||||
mux.Handle("/metrics", observability.PrometheusHandler(reg))
|
|
||||||
|
|
||||||
// Create a single HTTP server with the main mux.
|
|
||||||
mainServer := &http.Server{
|
mainServer := &http.Server{
|
||||||
Addr: cfg.ServerPort,
|
Addr: cfg.ServerPort,
|
||||||
Handler: mux,
|
Handler: apiHandler,
|
||||||
}
|
}
|
||||||
app_log.Info(fmt.Sprintf("API server listening on port %s", cfg.ServerPort))
|
app_log.Info(fmt.Sprintf("API server listening on port %s", cfg.ServerPort))
|
||||||
|
|
||||||
|
|||||||
@ -7,28 +7,42 @@ import (
|
|||||||
"tercul/internal/platform/auth"
|
"tercul/internal/platform/auth"
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql/handler"
|
"github.com/99designs/gqlgen/graphql/handler"
|
||||||
|
"github.com/99designs/gqlgen/graphql/playground"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewServerWithAuth creates a new GraphQL server with authentication and observability middleware
|
// NewAPIServer creates a new http.ServeMux and configures it with all the API routes,
|
||||||
func NewServerWithAuth(resolver *graphql.Resolver, jwtManager *auth.JWTManager, metrics *observability.Metrics, logger *observability.Logger) http.Handler {
|
// including the GraphQL endpoint, GraphQL Playground, and Prometheus metrics.
|
||||||
|
func NewAPIServer(
|
||||||
|
resolver *graphql.Resolver,
|
||||||
|
jwtManager *auth.JWTManager,
|
||||||
|
metrics *observability.Metrics,
|
||||||
|
logger *observability.Logger,
|
||||||
|
reg *prometheus.Registry,
|
||||||
|
) *http.ServeMux {
|
||||||
|
// Configure the GraphQL server
|
||||||
c := graphql.Config{Resolvers: resolver}
|
c := graphql.Config{Resolvers: resolver}
|
||||||
c.Directives.Binding = graphql.Binding
|
c.Directives.Binding = graphql.Binding
|
||||||
|
|
||||||
// Create the server with the custom error presenter
|
// Create the core GraphQL handler
|
||||||
srv := handler.NewDefaultServer(graphql.NewExecutableSchema(c))
|
graphqlHandler := handler.NewDefaultServer(graphql.NewExecutableSchema(c))
|
||||||
srv.SetErrorPresenter(graphql.NewErrorPresenter())
|
graphqlHandler.SetErrorPresenter(graphql.NewErrorPresenter())
|
||||||
|
|
||||||
// Create a middleware chain. The order is important.
|
// Create the middleware chain for the GraphQL endpoint.
|
||||||
// Middlewares are applied from bottom to top, so the last one added is the first to run.
|
// Middlewares are applied from bottom to top.
|
||||||
var chain http.Handler
|
var chain http.Handler
|
||||||
chain = srv
|
chain = graphqlHandler
|
||||||
chain = metrics.PrometheusMiddleware(chain)
|
chain = metrics.PrometheusMiddleware(chain)
|
||||||
// LoggingMiddleware needs to run after auth and tracing to get all context.
|
chain = observability.LoggingMiddleware(logger)(chain) // Must run after auth and tracing
|
||||||
chain = observability.LoggingMiddleware(logger)(chain)
|
|
||||||
chain = auth.GraphQLAuthMiddleware(jwtManager)(chain)
|
chain = auth.GraphQLAuthMiddleware(jwtManager)(chain)
|
||||||
chain = observability.TracingMiddleware(chain)
|
chain = observability.TracingMiddleware(chain)
|
||||||
chain = observability.RequestIDMiddleware(chain)
|
chain = observability.RequestIDMiddleware(chain)
|
||||||
|
|
||||||
// Return the handler chain directly. The caller is responsible for routing.
|
// Create a new ServeMux and register all handlers
|
||||||
return chain
|
mux := http.NewServeMux()
|
||||||
|
mux.Handle("/query", chain)
|
||||||
|
mux.Handle("/playground", playground.Handler("GraphQL Playground", "/query"))
|
||||||
|
mux.Handle("/metrics", observability.PrometheusHandler(reg))
|
||||||
|
|
||||||
|
return mux
|
||||||
}
|
}
|
||||||
@ -18,38 +18,8 @@ import (
|
|||||||
"tercul/internal/app/translation"
|
"tercul/internal/app/translation"
|
||||||
"tercul/internal/app/user"
|
"tercul/internal/app/user"
|
||||||
"tercul/internal/app/work"
|
"tercul/internal/app/work"
|
||||||
"tercul/internal/domain"
|
|
||||||
domainsearch "tercul/internal/domain/search"
|
|
||||||
platform_auth "tercul/internal/platform/auth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dependencies holds all external dependencies for the application.
|
|
||||||
type Dependencies struct {
|
|
||||||
WorkRepo domain.WorkRepository
|
|
||||||
UserRepo domain.UserRepository
|
|
||||||
AuthorRepo domain.AuthorRepository
|
|
||||||
TranslationRepo domain.TranslationRepository
|
|
||||||
CommentRepo domain.CommentRepository
|
|
||||||
LikeRepo domain.LikeRepository
|
|
||||||
BookmarkRepo domain.BookmarkRepository
|
|
||||||
CollectionRepo domain.CollectionRepository
|
|
||||||
TagRepo domain.TagRepository
|
|
||||||
CategoryRepo domain.CategoryRepository
|
|
||||||
BookRepo domain.BookRepository
|
|
||||||
PublisherRepo domain.PublisherRepository
|
|
||||||
SourceRepo domain.SourceRepository
|
|
||||||
CopyrightRepo domain.CopyrightRepository
|
|
||||||
MonetizationRepo domain.MonetizationRepository
|
|
||||||
ContributionRepo domain.ContributionRepository
|
|
||||||
UserProfileRepo domain.UserProfileRepository
|
|
||||||
AnalyticsRepo analytics.Repository
|
|
||||||
AuthRepo domain.AuthRepository
|
|
||||||
LocalizationRepo domain.LocalizationRepository
|
|
||||||
SearchClient domainsearch.SearchClient
|
|
||||||
AnalyticsService analytics.Service
|
|
||||||
JWTManager platform_auth.JWTManagement
|
|
||||||
}
|
|
||||||
|
|
||||||
// Application is a container for all the application-layer services.
|
// Application is a container for all the application-layer services.
|
||||||
type Application struct {
|
type Application struct {
|
||||||
Author *author.Service
|
Author *author.Service
|
||||||
@ -71,42 +41,43 @@ type Application struct {
|
|||||||
Analytics analytics.Service
|
Analytics analytics.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApplication(deps Dependencies) *Application {
|
// NewApplication creates a new Application container from pre-built services.
|
||||||
authzService := authz.NewService(deps.WorkRepo, deps.TranslationRepo)
|
func NewApplication(
|
||||||
authorService := author.NewService(deps.AuthorRepo)
|
authorSvc *author.Service,
|
||||||
bookService := book.NewService(deps.BookRepo, authzService)
|
bookSvc *book.Service,
|
||||||
bookmarkService := bookmark.NewService(deps.BookmarkRepo, deps.AnalyticsService)
|
bookmarkSvc *bookmark.Service,
|
||||||
categoryService := category.NewService(deps.CategoryRepo)
|
categorySvc *category.Service,
|
||||||
collectionService := collection.NewService(deps.CollectionRepo)
|
collectionSvc *collection.Service,
|
||||||
commentService := comment.NewService(deps.CommentRepo, authzService, deps.AnalyticsService)
|
commentSvc *comment.Service,
|
||||||
contributionCommands := contribution.NewCommands(deps.ContributionRepo, authzService)
|
contributionSvc *contribution.Service,
|
||||||
contributionService := contribution.NewService(contributionCommands)
|
likeSvc *like.Service,
|
||||||
likeService := like.NewService(deps.LikeRepo, deps.AnalyticsService)
|
tagSvc *tag.Service,
|
||||||
tagService := tag.NewService(deps.TagRepo)
|
translationSvc *translation.Service,
|
||||||
translationService := translation.NewService(deps.TranslationRepo, authzService)
|
userSvc *user.Service,
|
||||||
userService := user.NewService(deps.UserRepo, authzService, deps.UserProfileRepo)
|
localizationSvc *localization.Service,
|
||||||
localizationService := localization.NewService(deps.LocalizationRepo)
|
authSvc *auth.Service,
|
||||||
authService := auth.NewService(deps.UserRepo, deps.JWTManager)
|
authzSvc *authz.Service,
|
||||||
workService := work.NewService(deps.WorkRepo, deps.SearchClient, authzService)
|
workSvc *work.Service,
|
||||||
searchService := appsearch.NewService(deps.SearchClient, localizationService)
|
searchSvc appsearch.Service,
|
||||||
|
analyticsSvc analytics.Service,
|
||||||
|
) *Application {
|
||||||
return &Application{
|
return &Application{
|
||||||
Author: authorService,
|
Author: authorSvc,
|
||||||
Book: bookService,
|
Book: bookSvc,
|
||||||
Bookmark: bookmarkService,
|
Bookmark: bookmarkSvc,
|
||||||
Category: categoryService,
|
Category: categorySvc,
|
||||||
Collection: collectionService,
|
Collection: collectionSvc,
|
||||||
Comment: commentService,
|
Comment: commentSvc,
|
||||||
Contribution: contributionService,
|
Contribution: contributionSvc,
|
||||||
Like: likeService,
|
Like: likeSvc,
|
||||||
Tag: tagService,
|
Tag: tagSvc,
|
||||||
Translation: translationService,
|
Translation: translationSvc,
|
||||||
User: userService,
|
User: userSvc,
|
||||||
Localization: localizationService,
|
Localization: localizationSvc,
|
||||||
Auth: authService,
|
Auth: authSvc,
|
||||||
Authz: authzService,
|
Authz: authzSvc,
|
||||||
Work: workService,
|
Work: workSvc,
|
||||||
Search: searchService,
|
Search: searchSvc,
|
||||||
Analytics: deps.AnalyticsService,
|
Analytics: analyticsSvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,7 +7,22 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"tercul/internal/app"
|
"tercul/internal/app"
|
||||||
"tercul/internal/app/analytics"
|
"tercul/internal/app/analytics"
|
||||||
|
app_auth "tercul/internal/app/auth"
|
||||||
|
"tercul/internal/app/author"
|
||||||
|
"tercul/internal/app/authz"
|
||||||
|
"tercul/internal/app/book"
|
||||||
|
"tercul/internal/app/bookmark"
|
||||||
|
"tercul/internal/app/category"
|
||||||
|
"tercul/internal/app/collection"
|
||||||
|
"tercul/internal/app/comment"
|
||||||
|
"tercul/internal/app/contribution"
|
||||||
|
"tercul/internal/app/like"
|
||||||
|
"tercul/internal/app/localization"
|
||||||
|
app_search "tercul/internal/app/search"
|
||||||
|
"tercul/internal/app/tag"
|
||||||
"tercul/internal/app/translation"
|
"tercul/internal/app/translation"
|
||||||
|
"tercul/internal/app/user"
|
||||||
|
"tercul/internal/app/work"
|
||||||
"tercul/internal/data/sql"
|
"tercul/internal/data/sql"
|
||||||
"tercul/internal/domain"
|
"tercul/internal/domain"
|
||||||
"tercul/internal/domain/search"
|
"tercul/internal/domain/search"
|
||||||
@ -122,31 +137,43 @@ func (s *IntegrationTestSuite) SetupSuite(testConfig *TestConfig) {
|
|||||||
analyticsService := analytics.NewService(repos.Analytics, analysisRepo, repos.Translation, repos.Work, sentimentProvider)
|
analyticsService := analytics.NewService(repos.Analytics, analysisRepo, repos.Translation, repos.Work, sentimentProvider)
|
||||||
jwtManager := platform_auth.NewJWTManager(cfg)
|
jwtManager := platform_auth.NewJWTManager(cfg)
|
||||||
|
|
||||||
deps := app.Dependencies{
|
authzService := authz.NewService(repos.Work, repos.Translation)
|
||||||
WorkRepo: repos.Work,
|
authorService := author.NewService(repos.Author)
|
||||||
UserRepo: repos.User,
|
bookService := book.NewService(repos.Book, authzService)
|
||||||
AuthorRepo: repos.Author,
|
bookmarkService := bookmark.NewService(repos.Bookmark, analyticsService)
|
||||||
TranslationRepo: repos.Translation,
|
categoryService := category.NewService(repos.Category)
|
||||||
CommentRepo: repos.Comment,
|
collectionService := collection.NewService(repos.Collection)
|
||||||
LikeRepo: repos.Like,
|
commentService := comment.NewService(repos.Comment, authzService, analyticsService)
|
||||||
BookmarkRepo: repos.Bookmark,
|
contributionCommands := contribution.NewCommands(repos.Contribution, authzService)
|
||||||
CollectionRepo: repos.Collection,
|
contributionService := contribution.NewService(contributionCommands)
|
||||||
TagRepo: repos.Tag,
|
likeService := like.NewService(repos.Like, analyticsService)
|
||||||
CategoryRepo: repos.Category,
|
tagService := tag.NewService(repos.Tag)
|
||||||
BookRepo: repos.Book,
|
translationService := translation.NewService(repos.Translation, authzService)
|
||||||
PublisherRepo: repos.Publisher,
|
userService := user.NewService(repos.User, authzService, repos.UserProfile)
|
||||||
SourceRepo: repos.Source,
|
localizationService := localization.NewService(repos.Localization)
|
||||||
CopyrightRepo: repos.Copyright,
|
authService := app_auth.NewService(repos.User, jwtManager)
|
||||||
MonetizationRepo: repos.Monetization,
|
workService := work.NewService(repos.Work, searchClient, authzService)
|
||||||
ContributionRepo: repos.Contribution,
|
searchService := app_search.NewService(searchClient, localizationService)
|
||||||
AnalyticsRepo: repos.Analytics,
|
|
||||||
AuthRepo: repos.Auth,
|
s.App = app.NewApplication(
|
||||||
LocalizationRepo: repos.Localization,
|
authorService,
|
||||||
SearchClient: searchClient,
|
bookService,
|
||||||
AnalyticsService: analyticsService,
|
bookmarkService,
|
||||||
JWTManager: jwtManager,
|
categoryService,
|
||||||
}
|
collectionService,
|
||||||
s.App = app.NewApplication(deps)
|
commentService,
|
||||||
|
contributionService,
|
||||||
|
likeService,
|
||||||
|
tagService,
|
||||||
|
translationService,
|
||||||
|
userService,
|
||||||
|
localizationService,
|
||||||
|
authService,
|
||||||
|
authzService,
|
||||||
|
workService,
|
||||||
|
searchService,
|
||||||
|
analyticsService,
|
||||||
|
)
|
||||||
|
|
||||||
// Create a default admin user for tests
|
// Create a default admin user for tests
|
||||||
adminUser := &domain.User{
|
adminUser := &domain.User{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user