package mandantv1 import ( "context" "errors" "log/slog" "connectrpc.com/connect" "git.kocoder.xyz/kocoded/vt/fx" "git.kocoder.xyz/kocoded/vt/fx/interfaces/stores" mandantv1 "git.kocoder.xyz/kocoded/vt/gen/mandant/v1" "git.kocoder.xyz/kocoded/vt/gen/mandant/v1/mandantv1connect" "git.kocoder.xyz/kocoded/vt/interceptors" "git.kocoder.xyz/kocoded/vt/query" "gorm.io/gorm" ) func NewMandantRoute(logger *slog.Logger, db *gorm.DB, sr stores.SessionStore, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler { path, handler := mandantv1connect.NewMandantServiceHandler(&mandantService{logger: logger, db: db, sr: sr}, connect.WithInterceptors(oidcInterceptor)) return fx.NewRoute(path, handler) } type mandantService struct { logger *slog.Logger db *gorm.DB sr stores.SessionStore } func (m *mandantService) GetAllTenants(ctx context.Context, req *mandantv1.ListTenantRequest) (*mandantv1.ListProjectsResponse, error) { ma := query.Use(m.db).Mandant tenants, err := ma.Find() if err != nil { m.logger.Error("Error fetching tenants", "error", err) return nil, connect.NewError(connect.CodeUnknown, err) } tenantResponses := make([]*mandantv1.GetTenantResponse, len(tenants)) for i, t := range tenants { tenantResponses[i] = &mandantv1.GetTenantResponse{ Id: int64(t.ID), Name: t.Name, Plan: t.Plan, Logo: t.Logo, Color: t.Color, } } return &mandantv1.ListProjectsResponse{ Data: tenantResponses, Meta: &mandantv1.Metadata{ TotalCount: int32(len(tenants)), }, }, nil } func (m *mandantService) GetCurrentTenant(ctx context.Context, req *mandantv1.GetCurrentTenantRequest) (*mandantv1.GetTenantResponse, error) { s, ok := interceptors.SessionFromContext(ctx) if !ok { return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set.")) } ma := query.Use(m.db).Mandant res, err := ma.Where(ma.ID.Eq(s.MandantId)).First() if err != nil { m.logger.Error("Error fetching current tenant", "error", err) return nil, connect.NewError(connect.CodeUnknown, err) } return &mandantv1.GetTenantResponse{ Id: int64(res.ID), Name: res.Name, Plan: res.Plan, Logo: res.Logo, Color: res.Color, }, nil } func (m *mandantService) SetCurrentTenant(ctx context.Context, req *mandantv1.SetCurrentTenantRequest) (*mandantv1.SetCurrentTenantResponse, error) { s, ok := interceptors.SessionFromContext(ctx) if !ok { return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set.")) } err := m.sr.SetMandantInSession(s.Token, uint(req.TenantId)) if err != nil { m.logger.Error("Error setting mandant in session", "error", err) return nil, connect.NewError(connect.CodeUnknown, err) } return &mandantv1.SetCurrentTenantResponse{ Success: true, }, nil }