fx build fix
Some checks failed
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/fx/1 Pipeline failed
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/fx/2 Pipeline failed

This commit is contained in:
Stephan D
2025-11-08 00:30:29 +01:00
parent 590fad0071
commit 49b86efecb
165 changed files with 9466 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type AcceptInvitation struct {
Account *model.AccountData `json:"account,omitempty"`
}

View File

@@ -0,0 +1,12 @@
package srequest
import (
"github.com/tech/sendico/pkg/model"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ChangePolicies struct {
RoleRef primitive.ObjectID `json:"roleRef"`
Add *[]model.RolePolicy `json:"add,omitempty"`
Remove *[]model.RolePolicy `json:"remove,omitempty"`
}

View File

@@ -0,0 +1,8 @@
package srequest
import "go.mongodb.org/mongo-driver/bson/primitive"
type ChangeRole struct {
AccountRef primitive.ObjectID `json:"accountRef"`
NewRoleDescriptionRef primitive.ObjectID `json:"newRoleDescriptionRef"`
}

View File

@@ -0,0 +1,7 @@
package srequest
import "go.mongodb.org/mongo-driver/bson/primitive"
type FileUpload struct {
ObjRef primitive.ObjectID `json:"objRef"`
}

View File

@@ -0,0 +1,7 @@
package srequest
import (
"github.com/tech/sendico/pkg/model"
)
type CreateInvitation = model.Invitation

View File

@@ -0,0 +1,8 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type Login struct {
model.SessionIdentifier `json:",inline"`
model.LoginData `json:"login"`
}

View File

@@ -0,0 +1,15 @@
package srequest
type ChangePassword struct {
Old string `json:"old"`
New string `json:"new"`
DeviceID string `json:"deviceId"`
}
type ResetPassword struct {
Password string `json:"password"`
}
type ForgotPassword struct {
Login string `json:"login"`
}

View File

@@ -0,0 +1,8 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type CreatePriorityGroup struct {
Description model.Describable `json:"description"`
Priorities []model.Colorable `json:"priorities"`
}

View File

@@ -0,0 +1,31 @@
package srequest
import (
"github.com/tech/sendico/pkg/model"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type CreateProject struct {
Project model.Describable `json:"project"`
LogoURI *string `json:"logoUrl,omitempty"`
PrioriyGroupRef primitive.ObjectID `json:"priorityGroupRef"`
StatusGroupRef primitive.ObjectID `json:"statusGroupRef"`
Mnemonic string `json:"mnemonic"`
}
type ProjectPreview struct {
Projects []primitive.ObjectID `json:"projects"`
}
type TagFilterMode string
const (
TagFilterModeNone TagFilterMode = "none"
TagFilterModePresent TagFilterMode = "present"
TagFilterModeMissing TagFilterMode = "missing"
TagFilterModeIncludeAny TagFilterMode = "includeAny"
TagFilterModeIncludeAll TagFilterMode = "includeAll"
TagFilterModeExcludeAny TagFilterMode = "excludeAny"
)
type ProjectsFilter = model.ProjectFilterBase

View File

@@ -0,0 +1,11 @@
package srequest
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
// DeleteProject represents a request to delete a project
type DeleteProject struct {
OrganizationRef primitive.ObjectID `json:"organizationRef"` // If provided, move tasks to this project. If null, delete all tasks
MoveTasksToProjectRef *primitive.ObjectID `json:"moveTasksToProjectRef,omitempty"` // If provided, move tasks to this project. If null, delete all tasks
}

View File

@@ -0,0 +1,5 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type AccessTokenRefresh = model.ClientRefreshToken

View File

@@ -0,0 +1,19 @@
package srequest
import "go.mongodb.org/mongo-driver/bson/primitive"
type Reorder struct {
ParentRef primitive.ObjectID `json:"parentRef"`
From int `json:"from"`
To int `json:"to"`
}
type ReorderX struct {
ObjectRef primitive.ObjectID `json:"objectRef"`
To int `json:"to"`
}
type ReorderXDefault struct {
ReorderX `json:",inline"`
ParentRef primitive.ObjectID `json:"parentRef"`
}

View File

@@ -0,0 +1,5 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type TokenRefreshRotate = model.ClientRefreshToken

View File

@@ -0,0 +1,13 @@
package srequest
import "go.mongodb.org/mongo-driver/bson/primitive"
type GroupItemChange struct {
GroupRef primitive.ObjectID `json:"groupRef"`
ItemRef primitive.ObjectID `json:"itemRef"`
}
type RemoveItemFromGroup struct {
GroupItemChange `json:",inline"`
TargetItemRef primitive.ObjectID `json:"targetItemRef"`
}

View File

@@ -0,0 +1,14 @@
package srequest
import "github.com/tech/sendico/pkg/model"
type Signup struct {
Account model.AccountData `json:"account"`
OrganizationName string `json:"organizationName"`
OrganizationTimeZone string `json:"organizationTimeZone"`
DefaultPriorityGroup CreatePriorityGroup `json:"defaultPriorityGroup"`
DefaultStatusGroup CreateStatusGroup `json:"defaultStatusGroup"`
AnonymousUser model.Describable `json:"anonymousUser"`
OwnerRole model.Describable `json:"ownerRole"`
AnonymousRole model.Describable `json:"anonymousRole"`
}

View File

@@ -0,0 +1,312 @@
package srequest_test
import (
"encoding/json"
"fmt"
"testing"
"github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/server/interface/api/srequest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Helper function to create string pointers
func stringPtr(s string) *string {
return &s
}
func TestSignupRequest_JSONSerialization(t *testing.T) {
signup := srequest.Signup{
Account: model.AccountData{
LoginData: model.LoginData{
UserDataBase: model.UserDataBase{
Login: "test@example.com",
},
Password: "TestPassword123!",
},
Name: "Test User",
},
OrganizationName: "Test Organization",
OrganizationTimeZone: "UTC",
DefaultPriorityGroup: srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "Default Priority Group",
},
Priorities: []model.Colorable{
{
Describable: model.Describable{Name: "High"},
Color: stringPtr("#FF0000"),
},
{
Describable: model.Describable{Name: "Medium"},
Color: stringPtr("#FFFF00"),
},
{
Describable: model.Describable{Name: "Low"},
Color: stringPtr("#00FF00"),
},
},
},
AnonymousUser: model.Describable{
Name: "Anonymous User",
},
OwnerRole: model.Describable{
Name: "Owner",
},
AnonymousRole: model.Describable{
Name: "Anonymous",
},
}
// Test JSON marshaling
jsonData, err := json.Marshal(signup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.Signup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify all fields are properly serialized/deserialized
assert.Equal(t, signup.Account.Name, unmarshaled.Account.Name)
assert.Equal(t, signup.Account.Login, unmarshaled.Account.Login)
assert.Equal(t, signup.Account.Password, unmarshaled.Account.Password)
assert.Equal(t, signup.OrganizationName, unmarshaled.OrganizationName)
assert.Equal(t, signup.OrganizationTimeZone, unmarshaled.OrganizationTimeZone)
assert.Equal(t, signup.DefaultPriorityGroup.Description.Name, unmarshaled.DefaultPriorityGroup.Description.Name)
assert.Equal(t, len(signup.DefaultPriorityGroup.Priorities), len(unmarshaled.DefaultPriorityGroup.Priorities))
assert.Equal(t, signup.AnonymousUser.Name, unmarshaled.AnonymousUser.Name)
assert.Equal(t, signup.OwnerRole.Name, unmarshaled.OwnerRole.Name)
assert.Equal(t, signup.AnonymousRole.Name, unmarshaled.AnonymousRole.Name)
// Verify priorities
for i, priority := range signup.DefaultPriorityGroup.Priorities {
assert.Equal(t, priority.Name, unmarshaled.DefaultPriorityGroup.Priorities[i].Name)
if priority.Color != nil && unmarshaled.DefaultPriorityGroup.Priorities[i].Color != nil {
assert.Equal(t, *priority.Color, *unmarshaled.DefaultPriorityGroup.Priorities[i].Color)
}
}
}
func TestSignupRequest_MinimalValidRequest(t *testing.T) {
signup := srequest.Signup{
Account: model.AccountData{
LoginData: model.LoginData{
UserDataBase: model.UserDataBase{
Login: "test@example.com",
},
Password: "TestPassword123!",
},
Name: "Test User",
},
OrganizationName: "Test Organization",
OrganizationTimeZone: "UTC",
DefaultPriorityGroup: srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "Default",
},
Priorities: []model.Colorable{
{
Describable: model.Describable{Name: "Normal"},
Color: stringPtr("#000000"),
},
},
},
AnonymousUser: model.Describable{
Name: "Anonymous",
},
OwnerRole: model.Describable{
Name: "Owner",
},
AnonymousRole: model.Describable{
Name: "Anonymous",
},
}
// Test JSON marshaling
jsonData, err := json.Marshal(signup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.Signup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify minimal request is valid
assert.Equal(t, signup.Account.Name, unmarshaled.Account.Name)
assert.Equal(t, signup.Account.Login, unmarshaled.Account.Login)
assert.Equal(t, signup.OrganizationName, unmarshaled.OrganizationName)
assert.Len(t, unmarshaled.DefaultPriorityGroup.Priorities, 1)
}
func TestSignupRequest_InvalidJSON(t *testing.T) {
invalidJSONs := []string{
`{"account": invalid}`,
`{"organizationName": 123}`,
`{"organizationTimeZone": true}`,
`{"defaultPriorityGroup": "not_an_object"}`,
`{"anonymousUser": []}`,
`{"anonymousRole": 456}`,
`{invalid json}`,
}
for i, invalidJSON := range invalidJSONs {
t.Run(fmt.Sprintf("Invalid JSON %d", i), func(t *testing.T) {
var signup srequest.Signup
err := json.Unmarshal([]byte(invalidJSON), &signup)
require.Error(t, err)
})
}
}
func TestSignupRequest_UnicodeCharacters(t *testing.T) {
signup := srequest.Signup{
Account: model.AccountData{
LoginData: model.LoginData{
UserDataBase: model.UserDataBase{
Login: "测试@example.com",
},
Password: "TestPassword123!",
},
Name: "Test 用户 Üser",
},
OrganizationName: "测试 Organization",
OrganizationTimeZone: "UTC",
DefaultPriorityGroup: srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "默认 Priority Group",
},
Priorities: []model.Colorable{
{
Describable: model.Describable{Name: "高"},
Color: stringPtr("#FF0000"),
},
},
},
AnonymousUser: model.Describable{
Name: "匿名 User",
},
OwnerRole: model.Describable{
Name: "所有者",
},
AnonymousRole: model.Describable{
Name: "匿名",
},
}
// Test JSON marshaling
jsonData, err := json.Marshal(signup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.Signup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify unicode characters are properly handled
assert.Equal(t, "测试@example.com", unmarshaled.Account.Login)
assert.Equal(t, "Test 用户 Üser", unmarshaled.Account.Name)
assert.Equal(t, "测试 Organization", unmarshaled.OrganizationName)
assert.Equal(t, "默认 Priority Group", unmarshaled.DefaultPriorityGroup.Description.Name)
assert.Equal(t, "高", unmarshaled.DefaultPriorityGroup.Priorities[0].Name)
assert.Equal(t, "匿名 User", unmarshaled.AnonymousUser.Name)
assert.Equal(t, "所有者", unmarshaled.OwnerRole.Name)
assert.Equal(t, "匿名", unmarshaled.AnonymousRole.Name)
}
func TestCreatePriorityGroup_JSONSerialization(t *testing.T) {
priorityGroup := srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "Test Priority Group",
},
Priorities: []model.Colorable{
{
Describable: model.Describable{Name: "Critical"},
Color: stringPtr("#FF0000"),
},
{
Describable: model.Describable{Name: "High"},
Color: stringPtr("#FF8000"),
},
{
Describable: model.Describable{Name: "Medium"},
Color: stringPtr("#FFFF00"),
},
{
Describable: model.Describable{Name: "Low"},
Color: stringPtr("#00FF00"),
},
},
}
// Test JSON marshaling
jsonData, err := json.Marshal(priorityGroup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.CreatePriorityGroup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify all fields are properly serialized/deserialized
assert.Equal(t, priorityGroup.Description.Name, unmarshaled.Description.Name)
assert.Equal(t, len(priorityGroup.Priorities), len(unmarshaled.Priorities))
for i, priority := range priorityGroup.Priorities {
assert.Equal(t, priority.Name, unmarshaled.Priorities[i].Name)
if priority.Color != nil && unmarshaled.Priorities[i].Color != nil {
assert.Equal(t, *priority.Color, *unmarshaled.Priorities[i].Color)
}
}
}
func TestCreatePriorityGroup_EmptyPriorities(t *testing.T) {
priorityGroup := srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "Empty Priority Group",
},
Priorities: []model.Colorable{},
}
// Test JSON marshaling
jsonData, err := json.Marshal(priorityGroup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.CreatePriorityGroup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify empty priorities array is handled correctly
assert.Equal(t, priorityGroup.Description.Name, unmarshaled.Description.Name)
assert.Empty(t, unmarshaled.Priorities)
}
func TestCreatePriorityGroup_NilPriorities(t *testing.T) {
priorityGroup := srequest.CreatePriorityGroup{
Description: model.Describable{
Name: "Nil Priority Group",
},
Priorities: nil,
}
// Test JSON marshaling
jsonData, err := json.Marshal(priorityGroup)
require.NoError(t, err)
assert.NotEmpty(t, jsonData)
// Test JSON unmarshaling
var unmarshaled srequest.CreatePriorityGroup
err = json.Unmarshal(jsonData, &unmarshaled)
require.NoError(t, err)
// Verify nil priorities is handled correctly
assert.Equal(t, priorityGroup.Description.Name, unmarshaled.Description.Name)
assert.Nil(t, unmarshaled.Priorities)
}

View File

@@ -0,0 +1,16 @@
package srequest
import (
"github.com/tech/sendico/pkg/model"
)
type CreateStatus struct {
model.Colorable `json:"description"`
Icon string `json:"icon"`
IsFinal bool `json:"isFinal"`
}
type CreateStatusGroup struct {
Description model.Describable `json:"description"`
Statuses []CreateStatus `json:"statuses"`
}

View File

@@ -0,0 +1,20 @@
package srequest
import "go.mongodb.org/mongo-driver/bson/primitive"
// TaggableSingle is used for single tag operations (add/remove tag)
type TaggableSingle struct {
ObjectRef primitive.ObjectID `json:"objectRef"`
TagRef primitive.ObjectID `json:"tagRef"`
}
// TaggableMultiple is used for multiple tag operations (add tags, set tags)
type TaggableMultiple struct {
ObjectRef primitive.ObjectID `json:"objectRef"`
TagRefs []primitive.ObjectID `json:"tagRefs"`
}
// TaggableObject is used for object-only operations (remove all tags, get tags)
type TaggableObject struct {
ObjectRef primitive.ObjectID `json:"objectRef"`
}