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,62 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type accountData struct {
model.AccountPublic `json:",inline"`
IsAnonymous bool `json:"isAnonymous"`
}
type accountResponse struct {
authResponse `json:",inline"`
Account accountData `json:"account"`
}
func _createAccount(account *model.Account, isAnonymous bool) *accountData {
return &accountData{
AccountPublic: account.AccountPublic,
IsAnonymous: isAnonymous,
}
}
func _toAccount(account *model.Account, orgRef primitive.ObjectID) *accountData {
return _createAccount(account, model.AccountIsAnonymous(&account.UserDataBase, orgRef))
}
func Account(logger mlogger.Logger, account *model.Account, accessToken *TokenData) http.HandlerFunc {
return response.Ok(
logger,
&accountResponse{
Account: *_createAccount(account, false),
authResponse: authResponse{AccessToken: *accessToken},
},
)
}
type accountsResponse struct {
authResponse `json:",inline"`
Accounts []accountData `json:"accounts"`
}
func Accounts(logger mlogger.Logger, accounts []model.Account, orgRef primitive.ObjectID, accessToken *TokenData) http.HandlerFunc {
// Convert each account to its public representation.
publicAccounts := make([]accountData, len(accounts))
for i, a := range accounts {
publicAccounts[i] = *_toAccount(&a, orgRef)
}
return response.Ok(
logger,
&accountsResponse{
Accounts: publicAccounts,
authResponse: authResponse{AccessToken: *accessToken},
},
)
}

View File

@@ -0,0 +1,5 @@
package sresponse
type authResponse struct {
AccessToken TokenData `json:"accessToken"`
}

View File

@@ -0,0 +1,15 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/mservice"
"go.uber.org/zap"
)
func BadRPassword(logger mlogger.Logger, source mservice.Type, err error) http.HandlerFunc {
logger.Info("Failed password validation check", zap.Error(err))
return response.BadRequest(logger, source, "invalid_request", err.Error())
}

View File

@@ -0,0 +1,24 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type commentPreviewResponse struct {
authResponse `json:",inline"`
Comments []model.CommentPreview `json:"comments"`
}
func CommentPreview(logger mlogger.Logger, accessToken *TokenData, comments []model.CommentPreview) http.HandlerFunc {
return response.Ok(
logger,
&commentPreviewResponse{
Comments: comments,
authResponse: authResponse{AccessToken: *accessToken},
},
)
}

View File

@@ -0,0 +1,24 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type dzoneResponse struct {
authResponse `json:",inline"`
DZone model.DZone `json:"dzone"`
}
func DZone(logger mlogger.Logger, dzone *model.DZone, accessToken *TokenData) http.HandlerFunc {
return response.Ok(
logger,
&dzoneResponse{
DZone: *dzone,
authResponse: authResponse{AccessToken: *accessToken},
},
)
}

View File

@@ -0,0 +1,16 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
)
type fileUpladed struct {
URL string `json:"url"`
}
func FileUploaded(logger mlogger.Logger, url string) http.HandlerFunc {
return response.Ok(logger, &fileUpladed{URL: url})
}

View File

@@ -0,0 +1,21 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type invitationResp struct {
Invitation model.PublicInvitation `json:"invitation"`
}
func Invitation(logger mlogger.Logger, invitation *model.PublicInvitation) http.HandlerFunc {
return response.Ok(logger, &invitationResp{Invitation: *invitation})
}
func Invitations(logger mlogger.Logger, invitations []model.Invitation) http.HandlerFunc {
return response.Ok(logger, invitations)
}

View File

@@ -0,0 +1,27 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type loginResponse struct {
accountResponse
RefreshToken TokenData `json:"refreshToken"`
}
func Login(logger mlogger.Logger, account *model.Account, accessToken, refreshToken *TokenData) http.HandlerFunc {
return response.Ok(
logger,
&loginResponse{
accountResponse: accountResponse{
Account: *_createAccount(account, false),
authResponse: authResponse{AccessToken: *accessToken},
},
RefreshToken: *refreshToken,
},
)
}

View File

@@ -0,0 +1,49 @@
package sresponse
import (
"encoding/json"
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/mservice"
)
type DynamicResponse[T any] struct {
authResponse `json:",inline"`
Items []T
// FieldName is the JSON key to use for the items.
FieldName string
}
func (dr DynamicResponse[T]) MarshalJSON() ([]byte, error) {
// Create a temporary map to hold the keys and values.
m := map[string]any{
dr.FieldName: dr.Items,
"accessToken": dr.AccessToken,
}
return json.Marshal(m)
}
type handler = func(logger mlogger.Logger, data any) http.HandlerFunc
func objectsAuth[T any](logger mlogger.Logger, items []T, accessToken *TokenData, resource mservice.Type, handler handler) http.HandlerFunc {
resp := &DynamicResponse[T]{
Items: items,
authResponse: authResponse{AccessToken: *accessToken},
FieldName: resource,
}
return handler(logger, resp)
}
func ObjectsAuth[T any](logger mlogger.Logger, items []T, accessToken *TokenData, resource mservice.Type) http.HandlerFunc {
return objectsAuth(logger, items, accessToken, resource, response.Ok)
}
func ObjectAuth[T any](logger mlogger.Logger, item *T, accessToken *TokenData, resource mservice.Type) http.HandlerFunc {
return ObjectsAuth(logger, []T{*item}, accessToken, resource)
}
func ObjectAuthCreated[T any](logger mlogger.Logger, item *T, accessToken *TokenData, resource mservice.Type) http.HandlerFunc {
return objectsAuth(logger, []T{*item}, accessToken, resource, response.Created)
}

View File

@@ -0,0 +1,35 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type organizationsResponse struct {
authResponse `json:",inline"`
Organizations []model.Organization `json:"organizations"`
}
func Organization(logger mlogger.Logger, organization *model.Organization, accessToken *TokenData) http.HandlerFunc {
return Organizations(logger, []model.Organization{*organization}, accessToken)
}
func Organizations(logger mlogger.Logger, organizations []model.Organization, accessToken *TokenData) http.HandlerFunc {
return response.Ok(logger, organizationsResponse{
Organizations: organizations,
authResponse: authResponse{AccessToken: *accessToken},
})
}
type organizationPublicResponse struct {
Organizations []model.OrganizationBase `json:"organizations"`
}
func OrganizationPublic(logger mlogger.Logger, organization *model.OrganizationBase) http.HandlerFunc {
return response.Ok(logger, organizationPublicResponse{
[]model.OrganizationBase{*organization},
})
}

View File

@@ -0,0 +1,45 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type permissionsDescription struct {
Roles []model.RoleDescription `json:"roles"`
Policies []model.PolicyDescription `json:"policies"`
}
type permissionsData struct {
Roles []model.Role `json:"roles"`
Policies []model.RolePolicy `json:"policies"`
Permissions []model.Permission `json:"permissions"`
}
type permissionsResponse struct {
authResponse `json:",inline"`
Descriptions permissionsDescription `json:"descriptions"`
Permissions permissionsData `json:"permissions"`
}
func Permisssions(logger mlogger.Logger,
rolesDescs []model.RoleDescription, policiesDescs []model.PolicyDescription,
roles []model.Role, policies []model.RolePolicy, permissions []model.Permission,
accessToken *TokenData,
) http.HandlerFunc {
return response.Ok(logger, permissionsResponse{
Descriptions: permissionsDescription{
Roles: rolesDescs,
Policies: policiesDescs,
},
Permissions: permissionsData{
Roles: roles,
Policies: policies,
Permissions: permissions,
},
authResponse: authResponse{AccessToken: *accessToken},
})
}

View File

@@ -0,0 +1,37 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type projectsResponse struct {
authResponse `json:",inline"`
Projects []model.Project `json:"projects"`
}
func Projects(logger mlogger.Logger, projects []model.Project, accessToken *TokenData) http.HandlerFunc {
return response.Ok(logger, projectsResponse{
Projects: projects,
authResponse: authResponse{AccessToken: *accessToken},
})
}
func Project(logger mlogger.Logger, project *model.Project, accessToken *TokenData) http.HandlerFunc {
return Projects(logger, []model.Project{*project}, accessToken)
}
type projectPreviewsResponse struct {
authResponse `json:",inline"`
Previews []model.ProjectPreview `json:"previews"`
}
func ProjectsPreviews(logger mlogger.Logger, previews []model.ProjectPreview, accessToken *TokenData) http.HandlerFunc {
return response.Ok(logger, &projectPreviewsResponse{
authResponse: authResponse{AccessToken: *accessToken},
Previews: previews,
})
}

View File

@@ -0,0 +1,12 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/model"
)
type (
HandlerFunc = func(r *http.Request) http.HandlerFunc
AccountHandlerFunc = func(r *http.Request, account *model.Account, accessToken *TokenData) http.HandlerFunc
)

View File

@@ -0,0 +1,27 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
)
type resultAuth struct {
authResponse `json:",inline"`
response.Result `json:",inline"`
}
func Success(logger mlogger.Logger, accessToken *TokenData) http.HandlerFunc {
return response.Ok(logger, &resultAuth{
Result: response.Result{Result: true},
authResponse: authResponse{AccessToken: *accessToken},
})
}
func Failed(logger mlogger.Logger, accessToken *TokenData) http.HandlerFunc {
return response.Accepted(logger, &resultAuth{
Result: response.Result{Result: false},
authResponse: authResponse{AccessToken: *accessToken},
})
}

View File

@@ -0,0 +1,16 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
func SignUp(logger mlogger.Logger, account *model.Account) http.HandlerFunc {
return response.Ok(
logger,
&account.AccountBase,
)
}

View File

@@ -0,0 +1,25 @@
package sresponse
import (
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
type statusesResponse struct {
authResponse `json:",inline"`
Statuses []model.Status `json:"statuses"`
}
func Statuses(logger mlogger.Logger, statuses []model.Status, accessToken *TokenData) http.HandlerFunc {
return response.Ok(logger, statusesResponse{
Statuses: statuses,
authResponse: authResponse{AccessToken: *accessToken},
})
}
func Status(logger mlogger.Logger, status *model.Status, accessToken *TokenData) http.HandlerFunc {
return Statuses(logger, []model.Status{*status}, accessToken)
}

View File

@@ -0,0 +1,8 @@
package sresponse
import "time"
type TokenData struct {
Token string `json:"token"`
Expiration time.Time `json:"expiration"`
}

View File

@@ -0,0 +1,57 @@
package ws
import (
"net/http"
api "github.com/tech/sendico/pkg/api/http"
r "github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/server/interface/api/ws"
"go.uber.org/zap"
"golang.org/x/net/websocket"
)
func respond(logger mlogger.Logger, conn *websocket.Conn, messageType, apiStatus, requestID string, data any) {
message := ws.Message{
BaseResponse: r.BaseResponse{
Status: apiStatus,
Data: data,
},
ID: requestID,
MessageType: messageType,
}
if err := websocket.JSON.Send(conn, message); err != nil {
logger.Warn("Failed to send error message", zap.Error(err), zap.Any("message", message))
}
}
func errorf(logger mlogger.Logger, messageType, requestID string, conn *websocket.Conn, resp r.ErrorResponse) {
logger.Debug(
"Writing error sresponse",
zap.String("error", resp.Error),
zap.String("details", resp.Details),
zap.Int("code", resp.Code),
)
respond(logger, conn, messageType, api.MSError, requestID, &resp)
}
func Ok(logger mlogger.Logger, requestID string, data any) ws.ResponseHandler {
res := func(messageType string, conn *websocket.Conn) {
logger.Debug("Successfully executed request", zap.Any("sresponse", data))
respond(logger, conn, messageType, api.MSSuccess, requestID, data)
}
return res
}
func Internal(logger mlogger.Logger, requestID string, err error) ws.ResponseHandler {
res := func(messageType string, conn *websocket.Conn) {
errorf(logger, messageType, requestID, conn,
r.ErrorResponse{
Error: "internal_error",
Details: err.Error(),
Code: http.StatusInternalServerError,
})
}
return res
}