Commit: Bulk unfinished work
This commit is contained in:
@@ -1,128 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ansprechpartnerRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterAnsprechpartnerRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &ansprechpartnerRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Post("/new", router.createAnsprechpartner)
|
||||
r.Get("/all", router.getAllAnsprechpartners)
|
||||
r.Get("/:id<int>", router.getAnsprechpartner)
|
||||
r.Get("/:id<int>/firmen", router.getAnsprechpartnerFirmen)
|
||||
r.Put("/:id<int>", router.updateAnsprechpartner)
|
||||
r.Delete("/:id<int>", router.deleteAnsprechpartner)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) createAnsprechpartner(c *fiber.Ctx) error {
|
||||
ansprechpartner := new(model.Ansprechpartner)
|
||||
|
||||
if err := c.BodyParser(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Ansprechpartner
|
||||
|
||||
if err := ap.Omit(ap.UpdatedAt, ap.DeletedAt).Create(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendString("Hello")
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAllAnsprechpartners(c *fiber.Ctx) error {
|
||||
aps, err := query.Ansprechpartner.Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.JSON(aps)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAnsprechpartner(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAnsprechpartnerFirmen(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
firmen, err := query.Ansprechpartner.Firmen.Model(ap).Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap.Firmen = firmen
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) updateAnsprechpartner(c *fiber.Ctx) error {
|
||||
ansprechpartner := new(model.Ansprechpartner)
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.BodyParser(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Ansprechpartner
|
||||
|
||||
res, err := ap.Where(ap.ID.Eq(uint(id))).Omit(ap.ID, ap.CreatedAt, ap.UpdatedAt, ap.DeletedAt).Updates(ansprechpartner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) deleteAnsprechpartner(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Value(uint(id))).Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
105
routers/firma.go
105
routers/firma.go
@@ -1,105 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type firmaRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterFirmaRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &firmaRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Post("/new", router.createFirma)
|
||||
r.Get("/all", router.getAllFirmen)
|
||||
r.Get("/:id<int>", router.getFirma)
|
||||
r.Put("/:id<int>", router.updateFirma)
|
||||
r.Delete("/:id<int>", router.deleteFirma)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) createFirma(c *fiber.Ctx) error {
|
||||
firma := new(model.Firma)
|
||||
|
||||
if err := c.BodyParser(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Firma
|
||||
|
||||
if err := ap.Omit(ap.UpdatedAt, ap.DeletedAt).Create(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendString("Hello")
|
||||
}
|
||||
|
||||
func (r *firmaRouter) getAllFirmen(c *fiber.Ctx) error {
|
||||
aps, err := query.Firma.Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.JSON(aps)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *firmaRouter) getFirma(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Firma.Where(query.Firma.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) updateFirma(c *fiber.Ctx) error {
|
||||
firma := new(model.Firma)
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.BodyParser(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Firma
|
||||
|
||||
res, err := ap.Where(ap.ID.Eq(uint(id))).Omit(ap.ID, ap.CreatedAt, ap.UpdatedAt, ap.DeletedAt).Updates(firma)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) deleteFirma(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := query.Firma.Where(query.Firma.ID.Value(uint(id))).Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type mandantRouter struct {
|
||||
utils.Application
|
||||
currentMandant uint
|
||||
}
|
||||
|
||||
func RegisterMandantRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &mandantRouter{currentMandant: 1, Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/current", router.getCurrentMandant)
|
||||
r.Put("/current", router.setCurrentMandant)
|
||||
r.Get("/all", router.getAllMandant)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) getCurrentMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
|
||||
currentMandant, err := m.Where(m.ID.Eq(r.currentMandant)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentMandant)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) getAllMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
|
||||
mandanten, err := m.Find()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(mandanten)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) setCurrentMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
mandant := &model.Mandant{}
|
||||
|
||||
if err := c.BodyParser(mandant); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.currentMandant = mandant.ID
|
||||
|
||||
currentMandant, err := m.Where(m.ID.Eq(r.currentMandant)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentMandant)
|
||||
}
|
||||
96
routers/mandant/v1/mandant.go
Normal file
96
routers/mandant/v1/mandant.go
Normal file
@@ -0,0 +1,96 @@
|
||||
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
|
||||
}
|
||||
48
routers/mandant/v1/mandant.proto
Normal file
48
routers/mandant/v1/mandant.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mandant.v1;
|
||||
|
||||
message GetCurrentTenantRequest {
|
||||
}
|
||||
|
||||
message GetTenantRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message GetTenantResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string plan = 3;
|
||||
string logo = 4;
|
||||
string color = 5;
|
||||
}
|
||||
|
||||
message ListTenantRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetTenantResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
message SetCurrentTenantRequest {
|
||||
int64 tenant_id = 1;
|
||||
}
|
||||
|
||||
message SetCurrentTenantResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
service MandantService {
|
||||
rpc GetCurrentTenant(GetCurrentTenantRequest) returns (GetTenantResponse);
|
||||
rpc GetAllTenants(ListTenantRequest) returns (ListProjectsResponse);
|
||||
rpc SetCurrentTenant(SetCurrentTenantRequest) returns (SetCurrentTenantResponse);
|
||||
}
|
||||
48
routers/message/v1/message.proto
Normal file
48
routers/message/v1/message.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mandant.v1;
|
||||
|
||||
message GetCurrentTenantRequest {
|
||||
}
|
||||
|
||||
message GetTenantRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message GetTenantResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string plan = 3;
|
||||
string logo = 4;
|
||||
string color = 5;
|
||||
}
|
||||
|
||||
message ListTenantRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetTenantResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
message SetCurrentTenantRequest {
|
||||
int64 tenant_id = 1;
|
||||
}
|
||||
|
||||
message SetCurrentTenantResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
service MandantService {
|
||||
rpc GetCurrentTenant(GetCurrentTenantRequest) returns (GetTenantResponse);
|
||||
rpc GetAllTenants(ListTenantRequest) returns (ListProjectsResponse);
|
||||
rpc SetCurrentTenant(SetCurrentTenantRequest) returns (SetCurrentTenantResponse);
|
||||
}
|
||||
30
routers/messagebus/v1/messagebus.go
Normal file
30
routers/messagebus/v1/messagebus.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package messagebusv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
kfx "git.kocoder.xyz/kocoded/vt/fx"
|
||||
messagebusv1 "git.kocoder.xyz/kocoded/vt/gen/messagebus/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/messagebus/v1/messagebusv1connect"
|
||||
)
|
||||
|
||||
func NewMessagebusRoute() kfx.Handler {
|
||||
path, handler := messagebusv1connect.NewMessageBusServiceHandler(&messagebusService{})
|
||||
|
||||
return kfx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type messagebusService struct {
|
||||
}
|
||||
|
||||
func (mbs *messagebusService) SubscribeToConnectInvalidationRequests(ctx context.Context, req *messagebusv1.SubscribeToConnectInvalidationRequestsRequest, res *connect.ServerStream[messagebusv1.MessageBusEntity]) error {
|
||||
for {
|
||||
err := res.Send(&messagebusv1.MessageBusEntity{QueryKey: "Hello World!"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
}
|
||||
18
routers/messagebus/v1/messagebus.proto
Normal file
18
routers/messagebus/v1/messagebus.proto
Normal file
@@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package messagebus.v1;
|
||||
|
||||
enum MessageBusEntityType {
|
||||
OTHER = 0;
|
||||
INVALIDATION_REQUEST = 1;
|
||||
}
|
||||
|
||||
message MessageBusEntity {
|
||||
string queryKey = 1;
|
||||
}
|
||||
|
||||
message SubscribeToConnectInvalidationRequestsRequest {}
|
||||
|
||||
service MessageBusService {
|
||||
rpc SubscribeToConnectInvalidationRequests(SubscribeToConnectInvalidationRequestsRequest) returns (stream MessageBusEntity);
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type projectRouter struct {
|
||||
utils.Application
|
||||
currentMandant uint
|
||||
}
|
||||
|
||||
func RegisterProjectRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &projectRouter{currentMandant: 1, Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/all", router.getAllProjects)
|
||||
r.Post("/new", router.createNewProject)
|
||||
r.Get("/:id<int>", router.getProject)
|
||||
r.Post("/:id<int>/edit", router.editProject)
|
||||
r.Delete("/:id<int>/delete", router.deleteProject)
|
||||
}
|
||||
|
||||
func (r *projectRouter) getAllProjects(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
pph := c.Get("X-PER-PAGE")
|
||||
ofh := c.Get("X-OFFSET")
|
||||
|
||||
params := struct {
|
||||
Id string `params:"id"`
|
||||
Desc bool `params:"desc"`
|
||||
}{}
|
||||
|
||||
if err := c.QueryParser(¶ms); err != nil {
|
||||
r.Logger.Warn("Param Parser Error: ", "err", err)
|
||||
}
|
||||
|
||||
var pp, of int
|
||||
pp, err := strconv.Atoi(pph)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Per Page header not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
of, err = strconv.Atoi(ofh)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Offset header not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
query := p.Where().Limit(pp).Offset(of)
|
||||
|
||||
if params.Id != "" {
|
||||
f, ok := p.GetFieldByName(params.Id)
|
||||
if ok {
|
||||
if params.Desc {
|
||||
query = query.Order(f.Desc())
|
||||
} else {
|
||||
query = query.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
query = query.Order(p.ID.Asc())
|
||||
}
|
||||
|
||||
projects, err := query.Order(p.Name.Asc()).Find()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
cnt, err := p.Count()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
res := &PaginatedProjects{Data: projects, Meta: struct {
|
||||
TotalProjectsCount int64 `json:"totalProjectsCount"`
|
||||
}{TotalProjectsCount: cnt}}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
type PaginatedProjects struct {
|
||||
Data []*model.Projekt `json:"data"`
|
||||
Meta struct {
|
||||
TotalProjectsCount int64 `json:"totalProjectsCount"`
|
||||
} `json:"meta"`
|
||||
}
|
||||
|
||||
func (r *projectRouter) getProject(c *fiber.Ctx) error {
|
||||
ids := c.Params("id")
|
||||
id, err := strconv.ParseUint(ids, 10, 32)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Id is not an int.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
p := query.Projekt
|
||||
|
||||
currentProject, err := p.Where(p.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentProject)
|
||||
}
|
||||
|
||||
func (r *projectRouter) createNewProject(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
project := &model.Projekt{}
|
||||
|
||||
if err := c.BodyParser(project); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := p.Create(project)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "list"}})
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "get"}, Id: int(project.ID)})
|
||||
|
||||
return c.JSON(project)
|
||||
}
|
||||
|
||||
func (r *projectRouter) editProject(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
project := &model.Projekt{}
|
||||
|
||||
if err := c.BodyParser(project); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := p.Where(p.ID.Eq(project.ID)).Updates(project)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "list"}})
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "get"}, Id: int(project.ID)})
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *projectRouter) deleteProject(c *fiber.Ctx) error {
|
||||
ids := c.Params("id")
|
||||
id, err := strconv.ParseUint(ids, 10, 32)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Id is not an int.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
p := query.Projekt
|
||||
|
||||
res, err := p.Where(p.ID.Eq(uint(id))).Delete()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
125
routers/project/v1/project.go
Normal file
125
routers/project/v1/project.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package projectv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"slices"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
projectv1 "git.kocoder.xyz/kocoded/vt/gen/project/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewProjectRoute(db *gorm.DB, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
||||
path, handler := projectv1connect.NewProjectServiceHandler(&projectService{db: db}, connect.WithInterceptors(oidcInterceptor))
|
||||
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type projectService struct{ db *gorm.DB }
|
||||
|
||||
// ListProjects implements projectv1connect.ProjectServiceHandler.
|
||||
func (s *projectService) ListProjects(ctx context.Context, req *projectv1.ListProjectsRequest) (*projectv1.ListProjectsResponse, error) {
|
||||
session, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
||||
}
|
||||
|
||||
p := query.Use(s.db).Projekt
|
||||
|
||||
query := p.Where(p.MandantID.Eq(session.MandantId)).Limit(int(req.PerPage)).Offset(int(req.Page))
|
||||
|
||||
if req.OrberBy != "" {
|
||||
f, ok := p.GetFieldByName(req.OrberBy)
|
||||
if ok {
|
||||
if !req.Asc {
|
||||
query = query.Order(f.Desc())
|
||||
} else {
|
||||
query = query.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
query = query.Order(p.ID.Asc())
|
||||
}
|
||||
|
||||
projects, err := query.Find()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnknown, err)
|
||||
}
|
||||
|
||||
cnt, err := p.Where(p.MandantID.Eq(session.MandantId)).Count()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, err)
|
||||
}
|
||||
|
||||
data := make([]*projectv1.GetProjectResponse, len(projects))
|
||||
for i, p := range projects {
|
||||
data[i] = &projectv1.GetProjectResponse{
|
||||
Id: int64(p.ID),
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
IsMaterialized: newPointerBoolean(true),
|
||||
IsPersonalized: newPointerBoolean(true),
|
||||
IsConfirmed: newPointerBoolean(true),
|
||||
IsPaid: nil,
|
||||
IsDone: s.IsDone(p),
|
||||
}
|
||||
}
|
||||
|
||||
return &projectv1.ListProjectsResponse{
|
||||
Data: data,
|
||||
Meta: &projectv1.Metadata{TotalCount: int32(cnt)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func newPointerBoolean(val bool) *bool {
|
||||
b := val
|
||||
return &b
|
||||
}
|
||||
|
||||
func (s *projectService) IsDone(p *model.Projekt) *bool {
|
||||
t := query.Use(s.db).Task
|
||||
tasks, err := t.Where(t.ProjektID.Eq(p.ID)).Find()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(tasks) == 0 {
|
||||
return nil
|
||||
}
|
||||
if i := slices.IndexFunc(tasks, func(t *model.Task) bool {
|
||||
return !t.Status.IsDone()
|
||||
}); i != -1 {
|
||||
return newPointerBoolean(false)
|
||||
}
|
||||
return newPointerBoolean(true)
|
||||
}
|
||||
|
||||
func (s *projectService) GetProject(ctx context.Context, req *projectv1.GetProjectRequest) (*projectv1.GetProjectResponse, error) {
|
||||
session, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
||||
}
|
||||
|
||||
p := query.Use(s.db).Projekt
|
||||
|
||||
query, err := p.Where(p.ID.Eq(uint(req.Id))).Where(p.MandantID.Eq(session.MandantId)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &projectv1.GetProjectResponse{
|
||||
Id: int64(query.ID),
|
||||
Name: query.Name,
|
||||
Description: query.Description,
|
||||
IsMaterialized: newPointerBoolean(true),
|
||||
IsPersonalized: newPointerBoolean(true),
|
||||
IsConfirmed: newPointerBoolean(true),
|
||||
IsPaid: newPointerBoolean(true),
|
||||
IsDone: newPointerBoolean(true),
|
||||
}, nil
|
||||
}
|
||||
39
routers/project/v1/project.proto
Normal file
39
routers/project/v1/project.proto
Normal file
@@ -0,0 +1,39 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package project.v1;
|
||||
|
||||
message GetProjectRequest {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message GetProjectResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string description = 3;
|
||||
optional bool is_materialized = 5;
|
||||
optional bool is_personalized = 6;
|
||||
optional bool is_confirmed = 7;
|
||||
optional bool is_paid = 8;
|
||||
optional bool is_done = 9;
|
||||
}
|
||||
|
||||
message ListProjectsRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetProjectResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
service ProjectService {
|
||||
rpc GetProject(GetProjectRequest) returns (GetProjectResponse);
|
||||
rpc ListProjects(ListProjectsRequest) returns (ListProjectsResponse);
|
||||
}
|
||||
182
routers/todo/v1/todo.go
Normal file
182
routers/todo/v1/todo.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package todov1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
todov1 "git.kocoder.xyz/kocoded/vt/gen/todo/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/todo/v1/todov1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewTodoRoute(db *gorm.DB, logger *slog.Logger, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
||||
path, handler := todov1connect.NewTodoServiceHandler(&todoService{logger: logger, db: db}, connect.WithInterceptors(oidcInterceptor))
|
||||
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type todoService struct {
|
||||
logger *slog.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func (ts *todoService) GetTodo(ctx context.Context, req *todov1.GetTodosRequest) (*todov1.GetTodosResponse, error) {
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
t := query.Use(ts.db).Task
|
||||
res, err := t.Where(t.ID.Eq(uint(req.Id))).Where(t.MandantID.Eq(s.MandantId)).First()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
tres := &todov1.GetTodosResponse{
|
||||
Id: int64(res.ID),
|
||||
Title: res.Titel,
|
||||
Description: res.Description,
|
||||
Status: todov1.Status(res.Status),
|
||||
}
|
||||
|
||||
return tres, nil
|
||||
|
||||
// return &todov1.GetTodosResponse{
|
||||
// Id: 1,
|
||||
// Title: "Sample Todo",
|
||||
// Description: "This is a sample todo item.",
|
||||
// Status: todov1.Status_Doing,
|
||||
// }, nil
|
||||
}
|
||||
|
||||
func (ts *todoService) ContributeToQuery(f *todov1.Filter, q query.ITaskDo) query.ITaskDo {
|
||||
t := query.Use(ts.db).Task
|
||||
|
||||
switch f.Field {
|
||||
case todov1.Field_FieldDescription, todov1.Field_FieldTitle:
|
||||
var field field.String
|
||||
if f.Field == todov1.Field_FieldDescription {
|
||||
field = t.Description
|
||||
} else {
|
||||
field = t.Titel
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(field.Eq(f.Value))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(field.Neq(f.Value))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(field.Gt(f.Value))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(field.Lt(f.Value))
|
||||
case todov1.Operation_Like:
|
||||
q = q.Where(field.Like(f.Value))
|
||||
}
|
||||
case todov1.Field_FieldId:
|
||||
i, err := strconv.Atoi(f.Value)
|
||||
if err != nil {
|
||||
slog.Warn("Value not an int", "err", err)
|
||||
return q
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(t.ID.Eq(uint(i)))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(t.ID.Neq(uint(i)))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(t.ID.Gt(uint(i)))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(t.ID.Lt(uint(i)))
|
||||
}
|
||||
case todov1.Field_FieldStatus:
|
||||
i, err := strconv.Atoi(f.Value)
|
||||
if err != nil {
|
||||
slog.Warn("Value not an int", "err", err)
|
||||
return q
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(t.Status.Eq(i))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(t.Status.Neq(i))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(t.Status.Gt(i))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(t.Status.Lt(i))
|
||||
}
|
||||
default:
|
||||
return q
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func (ts *todoService) ListTodos(ctx context.Context, req *todov1.ListTodosRequest) (*todov1.ListTodosResponse, error) {
|
||||
ts.logger.Info("ListTodos called", "request", req)
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
t := query.Use(ts.db).Task
|
||||
taskQuery := t.Where(t.MandantID.Eq(s.MandantId))
|
||||
|
||||
for _, v := range req.Filters {
|
||||
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
||||
}
|
||||
|
||||
taskQuery = taskQuery.Limit(int(req.PerPage)).Offset(int(req.Page))
|
||||
if req.OrberBy != "" {
|
||||
f, ok := t.GetFieldByName(req.OrberBy)
|
||||
if ok {
|
||||
if !req.Asc {
|
||||
taskQuery = taskQuery.Order(f.Desc())
|
||||
} else {
|
||||
taskQuery = taskQuery.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
taskQuery = taskQuery.Order(t.ID.Asc())
|
||||
}
|
||||
|
||||
tasks, err := taskQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskQuery = t.Where(t.MandantID.Eq(s.MandantId))
|
||||
|
||||
for _, v := range req.Filters {
|
||||
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
||||
}
|
||||
|
||||
cnt, err := taskQuery.Count()
|
||||
|
||||
if err != nil {
|
||||
ts.logger.Info("Counting Todos failed", "request", req, "err", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
data := make([]*todov1.GetTodosResponse, len(tasks))
|
||||
for i, p := range tasks {
|
||||
data[i] = &todov1.GetTodosResponse{
|
||||
Id: int64(p.ID),
|
||||
Title: p.Titel,
|
||||
Description: p.Description,
|
||||
Status: todov1.Status(p.Status),
|
||||
}
|
||||
}
|
||||
|
||||
return &todov1.ListTodosResponse{
|
||||
Data: data,
|
||||
Meta: &todov1.Metadata{
|
||||
TotalCount: int32(cnt),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
64
routers/todo/v1/todo.proto
Normal file
64
routers/todo/v1/todo.proto
Normal file
@@ -0,0 +1,64 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package todo.v1;
|
||||
|
||||
enum Status {
|
||||
Todo = 0;
|
||||
NeedsMoreInfo = 1;
|
||||
Doing = 2;
|
||||
Done = 3;
|
||||
}
|
||||
|
||||
enum Field {
|
||||
FieldId = 0;
|
||||
FieldTitle = 1;
|
||||
FieldDescription = 2;
|
||||
FieldStatus = 3;
|
||||
}
|
||||
|
||||
enum Operation {
|
||||
Equals = 0;
|
||||
NotEquals = 1;
|
||||
GreaterThan = 2;
|
||||
LessThan = 3;
|
||||
Like = 4;
|
||||
}
|
||||
|
||||
message GetTodosRequest {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message GetTodosResponse {
|
||||
int64 id = 1;
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
Status status = 4;
|
||||
}
|
||||
|
||||
message ListTodosRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
repeated Filter filters = 5;
|
||||
}
|
||||
|
||||
message Filter {
|
||||
Field field = 1;
|
||||
string value = 2;
|
||||
Operation operation = 3;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListTodosResponse {
|
||||
repeated GetTodosResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
service TodoService {
|
||||
rpc GetTodo(GetTodosRequest) returns (GetTodosResponse);
|
||||
rpc ListTodos(ListTodosRequest) returns (ListTodosResponse);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type userRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterUserRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &userRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/current", router.getCurrentUserInfo)
|
||||
}
|
||||
|
||||
func (r *userRouter) getCurrentUserInfo(c *fiber.Ctx) error {
|
||||
u := query.User
|
||||
|
||||
session := c.Locals("USER_KEY").(*utils.Session)
|
||||
|
||||
currentUser, err := u.Where(u.ID.Eq(session.UserID)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentUser)
|
||||
}
|
||||
Reference in New Issue
Block a user