Skip to content

Commit 49f7d69

Browse files
committed
Reorganize OpenAPI spec into separate admin.yaml file
1 parent a40270b commit 49f7d69

15 files changed

Lines changed: 612 additions & 131 deletions

File tree

api/gen/admin/gen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package api
22

3-
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target . --clean ../../openapi.yaml
3+
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target . --clean ../../openapi/admin.yaml
File renamed without changes.

cmd/api/main.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,28 @@ func main() {
3434
handlers.SetHideErrorDetails(true)
3535
}
3636

37-
// Create service (implements ogen Handler interface)
38-
service := services.NewAdminService(db).Build()
37+
// Create individual domain services
38+
authService := services.NewAuthService(db).Build()
39+
userService := services.NewUserService(db).Build()
40+
taskService := services.NewTaskService(db).Build()
41+
appService := services.NewAppService(db).Build()
42+
chatService := services.NewChatService(db).Build()
43+
dashboardService := services.NewDashboardService().Build()
3944

40-
// Create server via handlers package (includes ErrorHandler)
41-
server, err := handlers.NewServer(service)
45+
// Create OgenHandler with all services
46+
handler := services.NewOgenHandler().
47+
WithAuthService(authService).
48+
WithUserService(userService).
49+
WithTaskService(taskService).
50+
WithAppService(appService).
51+
WithChatService(chatService).
52+
WithDashboardService(dashboardService).
53+
Build()
54+
55+
// Create router with ogen server
56+
router, err := handlers.NewRouter(handler).Build()
4257
if err != nil {
43-
log.Fatalf("Failed to create server: %v", err)
58+
log.Fatalf("Failed to create router: %v", err)
4459
}
4560

4661
// Get port from environment
@@ -50,7 +65,7 @@ func main() {
5065
}
5166

5267
log.Printf("Starting server on :%s", port)
53-
if err := http.ListenAndServe(":"+port, server); err != nil {
68+
if err := http.ListenAndServe(":"+port, router); err != nil {
5469
log.Fatalf("Failed to start server: %v", err)
5570
}
5671
}

handlers/server.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package handlers
22

33
import (
4+
"net/http"
5+
46
api "github.com/sunfmin/shadcn-admin-go/api/gen/admin"
57
)
68

@@ -12,3 +14,40 @@ func NewServer(h api.Handler) (*api.Server, error) {
1214
api.WithErrorHandler(OgenErrorHandler),
1315
)
1416
}
17+
18+
// RouterBuilder builds an HTTP router with the ogen server and optional middleware
19+
type RouterBuilder struct {
20+
handler api.Handler
21+
middlewares []func(http.Handler) http.Handler
22+
}
23+
24+
// NewRouter creates a new RouterBuilder
25+
func NewRouter(handler api.Handler) *RouterBuilder {
26+
return &RouterBuilder{
27+
handler: handler,
28+
middlewares: make([]func(http.Handler) http.Handler, 0),
29+
}
30+
}
31+
32+
// WithMiddleware adds a middleware to the router
33+
func (b *RouterBuilder) WithMiddleware(mw func(http.Handler) http.Handler) *RouterBuilder {
34+
b.middlewares = append(b.middlewares, mw)
35+
return b
36+
}
37+
38+
// Build creates the HTTP handler with all configured middleware
39+
func (b *RouterBuilder) Build() (http.Handler, error) {
40+
server, err := NewServer(b.handler)
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
var handler http.Handler = server
46+
47+
// Apply middlewares in reverse order so they execute in the order they were added
48+
for i := len(b.middlewares) - 1; i >= 0; i-- {
49+
handler = b.middlewares[i](handler)
50+
}
51+
52+
return handler, nil
53+
}

internal/models/models.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func generateTaskID(num int) string {
5353
func padNumber(num, width int) string {
5454
s := ""
5555
for i := 0; i < width; i++ {
56-
s = string('0'+num%10) + s
56+
s = string(rune('0'+num%10)) + s
5757
num /= 10
5858
}
5959
return s

services/admin_service.go

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,41 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"strings"
87

98
api "github.com/sunfmin/shadcn-admin-go/api/gen/admin"
109
"github.com/sunfmin/shadcn-admin-go/internal/models"
1110
"gorm.io/gorm"
1211
)
1312

14-
// ListApps implements api.Handler.
15-
func (s *AdminService) ListApps(ctx context.Context, params api.ListAppsParams) (*api.AppListResponse, error) {
13+
// AppService interface for app operations
14+
type AppService interface {
15+
List(ctx context.Context, params api.ListAppsParams) (*api.AppListResponse, error)
16+
Connect(ctx context.Context, params api.ConnectAppParams) (*api.App, error)
17+
Disconnect(ctx context.Context, params api.DisconnectAppParams) (*api.App, error)
18+
}
19+
20+
// appServiceImpl implements AppService
21+
type appServiceImpl struct {
22+
db *gorm.DB
23+
}
24+
25+
// appServiceBuilder is the builder for AppService
26+
type appServiceBuilder struct {
27+
db *gorm.DB
28+
}
29+
30+
// NewAppService creates a new AppService builder
31+
func NewAppService(db *gorm.DB) *appServiceBuilder {
32+
return &appServiceBuilder{db: db}
33+
}
34+
35+
// Build creates the AppService
36+
func (b *appServiceBuilder) Build() AppService {
37+
return &appServiceImpl{db: b.db}
38+
}
39+
40+
// List implements AppService
41+
func (s *appServiceImpl) List(ctx context.Context, params api.ListAppsParams) (*api.AppListResponse, error) {
1642
select {
1743
case <-ctx.Done():
1844
return nil, ctx.Err()
@@ -62,8 +88,8 @@ func (s *AdminService) ListApps(ctx context.Context, params api.ListAppsParams)
6288
}, nil
6389
}
6490

65-
// ConnectApp implements api.Handler.
66-
func (s *AdminService) ConnectApp(ctx context.Context, params api.ConnectAppParams) (*api.App, error) {
91+
// Connect implements AppService
92+
func (s *appServiceImpl) Connect(ctx context.Context, params api.ConnectAppParams) (*api.App, error) {
6793
select {
6894
case <-ctx.Done():
6995
return nil, ctx.Err()
@@ -87,8 +113,8 @@ func (s *AdminService) ConnectApp(ctx context.Context, params api.ConnectAppPara
87113
return &result, nil
88114
}
89115

90-
// DisconnectApp implements api.Handler.
91-
func (s *AdminService) DisconnectApp(ctx context.Context, params api.DisconnectAppParams) (*api.App, error) {
116+
// Disconnect implements AppService
117+
func (s *appServiceImpl) Disconnect(ctx context.Context, params api.DisconnectAppParams) (*api.App, error) {
92118
select {
93119
case <-ctx.Done():
94120
return nil, ctx.Err()
@@ -127,8 +153,3 @@ func appToAPI(a models.App) api.App {
127153

128154
return result
129155
}
130-
131-
// generateAppID generates a unique app ID
132-
func generateAppID(name string) string {
133-
return strings.ToLower(strings.ReplaceAll(name, " ", "-"))
134-
}
Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,35 @@ import (
1212
"gorm.io/gorm"
1313
)
1414

15-
// Login implements api.Handler.
16-
func (s *AdminService) Login(ctx context.Context, req *api.LoginRequest) (api.LoginRes, error) {
15+
// AuthService interface for authentication operations
16+
type AuthService interface {
17+
Login(ctx context.Context, req *api.LoginRequest) (api.LoginRes, error)
18+
Logout(ctx context.Context) error
19+
GetCurrentUser(ctx context.Context) (api.GetCurrentUserRes, error)
20+
}
21+
22+
// authServiceImpl implements AuthService
23+
type authServiceImpl struct {
24+
db *gorm.DB
25+
}
26+
27+
// authServiceBuilder is the builder for AuthService
28+
type authServiceBuilder struct {
29+
db *gorm.DB
30+
}
31+
32+
// NewAuthService creates a new AuthService builder
33+
func NewAuthService(db *gorm.DB) *authServiceBuilder {
34+
return &authServiceBuilder{db: db}
35+
}
36+
37+
// Build creates the AuthService
38+
func (b *authServiceBuilder) Build() AuthService {
39+
return &authServiceImpl{db: b.db}
40+
}
41+
42+
// Login implements AuthService
43+
func (s *authServiceImpl) Login(ctx context.Context, req *api.LoginRequest) (api.LoginRes, error) {
1744
select {
1845
case <-ctx.Done():
1946
return nil, ctx.Err()
@@ -46,13 +73,13 @@ func (s *AdminService) Login(ctx context.Context, req *api.LoginRequest) (api.Lo
4673
}, nil
4774
}
4875

49-
// Logout implements api.Handler.
50-
func (s *AdminService) Logout(ctx context.Context) error {
76+
// Logout implements AuthService
77+
func (s *authServiceImpl) Logout(ctx context.Context) error {
5178
return nil
5279
}
5380

54-
// GetCurrentUser implements api.Handler.
55-
func (s *AdminService) GetCurrentUser(ctx context.Context) (api.GetCurrentUserRes, error) {
81+
// GetCurrentUser implements AuthService
82+
func (s *authServiceImpl) GetCurrentUser(ctx context.Context) (api.GetCurrentUserRes, error) {
5683
return &api.GetCurrentUserUnauthorized{}, nil
5784
}
5885

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,35 @@ import (
1111
"gorm.io/gorm"
1212
)
1313

14-
// ListChats implements api.Handler.
15-
func (s *AdminService) ListChats(ctx context.Context, params api.ListChatsParams) (*api.ChatListResponse, error) {
14+
// ChatService interface for chat operations
15+
type ChatService interface {
16+
List(ctx context.Context, params api.ListChatsParams) (*api.ChatListResponse, error)
17+
Get(ctx context.Context, params api.GetChatParams) (api.GetChatRes, error)
18+
SendMessage(ctx context.Context, req *api.SendMessageRequest, params api.SendMessageParams) (*api.ChatMessage, error)
19+
}
20+
21+
// chatServiceImpl implements ChatService
22+
type chatServiceImpl struct {
23+
db *gorm.DB
24+
}
25+
26+
// chatServiceBuilder is the builder for ChatService
27+
type chatServiceBuilder struct {
28+
db *gorm.DB
29+
}
30+
31+
// NewChatService creates a new ChatService builder
32+
func NewChatService(db *gorm.DB) *chatServiceBuilder {
33+
return &chatServiceBuilder{db: db}
34+
}
35+
36+
// Build creates the ChatService
37+
func (b *chatServiceBuilder) Build() ChatService {
38+
return &chatServiceImpl{db: b.db}
39+
}
40+
41+
// List implements ChatService
42+
func (s *chatServiceImpl) List(ctx context.Context, params api.ListChatsParams) (*api.ChatListResponse, error) {
1643
select {
1744
case <-ctx.Done():
1845
return nil, ctx.Err()
@@ -41,8 +68,8 @@ func (s *AdminService) ListChats(ctx context.Context, params api.ListChatsParams
4168
}, nil
4269
}
4370

44-
// GetChat implements api.Handler.
45-
func (s *AdminService) GetChat(ctx context.Context, params api.GetChatParams) (api.GetChatRes, error) {
71+
// Get implements ChatService
72+
func (s *chatServiceImpl) Get(ctx context.Context, params api.GetChatParams) (api.GetChatRes, error) {
4673
select {
4774
case <-ctx.Done():
4875
return nil, ctx.Err()
@@ -61,8 +88,8 @@ func (s *AdminService) GetChat(ctx context.Context, params api.GetChatParams) (a
6188
return &result, nil
6289
}
6390

64-
// SendMessage implements api.Handler.
65-
func (s *AdminService) SendMessage(ctx context.Context, req *api.SendMessageRequest, params api.SendMessageParams) (*api.ChatMessage, error) {
91+
// SendMessage implements ChatService
92+
func (s *chatServiceImpl) SendMessage(ctx context.Context, req *api.SendMessageRequest, params api.SendMessageParams) (*api.ChatMessage, error) {
6693
select {
6794
case <-ctx.Done():
6895
return nil, ctx.Err()
Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,31 @@ import (
66
api "github.com/sunfmin/shadcn-admin-go/api/gen/admin"
77
)
88

9-
// GetDashboardStats implements api.Handler.
10-
func (s *AdminService) GetDashboardStats(ctx context.Context) (*api.DashboardStats, error) {
9+
// DashboardService interface for dashboard operations
10+
type DashboardService interface {
11+
GetStats(ctx context.Context) (*api.DashboardStats, error)
12+
GetOverview(ctx context.Context) (*api.DashboardOverview, error)
13+
GetRecentSales(ctx context.Context) (*api.RecentSalesResponse, error)
14+
}
15+
16+
// dashboardServiceImpl implements DashboardService
17+
type dashboardServiceImpl struct{}
18+
19+
// dashboardServiceBuilder is the builder for DashboardService
20+
type dashboardServiceBuilder struct{}
21+
22+
// NewDashboardService creates a new DashboardService builder
23+
func NewDashboardService() *dashboardServiceBuilder {
24+
return &dashboardServiceBuilder{}
25+
}
26+
27+
// Build creates the DashboardService
28+
func (b *dashboardServiceBuilder) Build() DashboardService {
29+
return &dashboardServiceImpl{}
30+
}
31+
32+
// GetStats implements DashboardService
33+
func (s *dashboardServiceImpl) GetStats(ctx context.Context) (*api.DashboardStats, error) {
1134
select {
1235
case <-ctx.Done():
1336
return nil, ctx.Err()
@@ -35,8 +58,8 @@ func (s *AdminService) GetDashboardStats(ctx context.Context) (*api.DashboardSta
3558
}, nil
3659
}
3760

38-
// GetDashboardOverview implements api.Handler.
39-
func (s *AdminService) GetDashboardOverview(ctx context.Context) (*api.DashboardOverview, error) {
61+
// GetOverview implements DashboardService
62+
func (s *dashboardServiceImpl) GetOverview(ctx context.Context) (*api.DashboardOverview, error) {
4063
select {
4164
case <-ctx.Done():
4265
return nil, ctx.Err()
@@ -64,8 +87,8 @@ func (s *AdminService) GetDashboardOverview(ctx context.Context) (*api.Dashboard
6487
}, nil
6588
}
6689

67-
// GetRecentSales implements api.Handler.
68-
func (s *AdminService) GetRecentSales(ctx context.Context) (*api.RecentSalesResponse, error) {
90+
// GetRecentSales implements DashboardService
91+
func (s *dashboardServiceImpl) GetRecentSales(ctx context.Context) (*api.RecentSalesResponse, error) {
6992
select {
7093
case <-ctx.Done():
7194
return nil, ctx.Err()

0 commit comments

Comments
 (0)