mirror of
https://github.com/emo2007/block-accounting.git
synced 2025-04-12 08:56:28 +00:00
tmp
This commit is contained in:
parent
876957aabe
commit
866a862087
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@ -12,15 +12,18 @@
|
|||||||
"program": "${workspaceRoot}/backend/cmd/main.go",
|
"program": "${workspaceRoot}/backend/cmd/main.go",
|
||||||
"args": [
|
"args": [
|
||||||
"-log-level=debug",
|
"-log-level=debug",
|
||||||
"-log-local=true",
|
"-log-local=false",
|
||||||
"-log-add-source=true",
|
"-log-add-source=true",
|
||||||
|
"-jwt-secret=local_jwt_secret",
|
||||||
|
|
||||||
"-rest-address=localhost:8080",
|
"-rest-address=localhost:8081",
|
||||||
"-db-host=localhost:8432",
|
"-db-host=localhost:8432",
|
||||||
"-db-database=blockd",
|
"-db-database=blockd",
|
||||||
"-db-user=blockd",
|
"-db-user=blockd",
|
||||||
"-db-secret=blockd",
|
"-db-secret=blockd",
|
||||||
"-db-enable-tls=false"
|
"-db-enable-tls=false",
|
||||||
|
|
||||||
|
"-cache-host=localhost:6379"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -8,4 +8,3 @@
|
|||||||
|
|
||||||
- On First Login - Owner inputs his SEED_KEY (mnemonic), creates an organization, we save its seed hash for future login and signing internal txs.
|
- On First Login - Owner inputs his SEED_KEY (mnemonic), creates an organization, we save its seed hash for future login and signing internal txs.
|
||||||
- When inviting an employee to organization- we generate an invitation link, then after clicking on this link - the user is asked for seed, if he's already registered or able to generate a seed for new account.
|
- When inviting an employee to organization- we generate an invitation link, then after clicking on this link - the user is asked for seed, if he's already registered or able to generate a seed for new account.
|
||||||
-
|
|
||||||
|
3
backend/.vscode/launch.json
vendored
3
backend/.vscode/launch.json
vendored
@ -1,7 +1,4 @@
|
|||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
|
@ -6,10 +6,12 @@ import (
|
|||||||
"github.com/emochka2007/block-accounting/internal/pkg/config"
|
"github.com/emochka2007/block-accounting/internal/pkg/config"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/transactions"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
|
||||||
orepo "github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
|
orepo "github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
|
||||||
|
txRepo "github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
|
||||||
urepo "github.com/emochka2007/block-accounting/internal/usecase/repository/users"
|
urepo "github.com/emochka2007/block-accounting/internal/usecase/repository/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,3 +37,15 @@ func provideOrganizationsInteractor(
|
|||||||
) organizations.OrganizationsInteractor {
|
) organizations.OrganizationsInteractor {
|
||||||
return organizations.NewOrganizationsInteractor(log, orgRepo, cache)
|
return organizations.NewOrganizationsInteractor(log, orgRepo, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func provideTxInteractor(
|
||||||
|
log *slog.Logger,
|
||||||
|
txRepo txRepo.Repository,
|
||||||
|
orgInteractor organizations.OrganizationsInteractor,
|
||||||
|
) transactions.TransactionsInteractor {
|
||||||
|
return transactions.NewTransactionsInteractor(
|
||||||
|
log.WithGroup("transaction-interactor"),
|
||||||
|
txRepo,
|
||||||
|
orgInteractor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/emochka2007/block-accounting/internal/pkg/logger"
|
"github.com/emochka2007/block-accounting/internal/pkg/logger"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/transactions"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ var interfaceSet wire.ProviderSet = wire.NewSet(
|
|||||||
provideAuthController,
|
provideAuthController,
|
||||||
provideOrganizationsController,
|
provideOrganizationsController,
|
||||||
provideControllers,
|
provideControllers,
|
||||||
|
provideTxController,
|
||||||
|
|
||||||
provideAuthPresenter,
|
provideAuthPresenter,
|
||||||
provideOrganizationsPresenter,
|
provideOrganizationsPresenter,
|
||||||
@ -84,15 +86,27 @@ func provideOrganizationsController(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func provideTxController(
|
||||||
|
log *slog.Logger,
|
||||||
|
txInteractor transactions.TransactionsInteractor,
|
||||||
|
) controllers.TransactionsController {
|
||||||
|
return controllers.NewTransactionsController(
|
||||||
|
log.WithGroup("transactions-controller"),
|
||||||
|
txInteractor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func provideControllers(
|
func provideControllers(
|
||||||
log *slog.Logger,
|
log *slog.Logger,
|
||||||
authController controllers.AuthController,
|
authController controllers.AuthController,
|
||||||
orgController controllers.OrganizationsController,
|
orgController controllers.OrganizationsController,
|
||||||
|
txController controllers.TransactionsController,
|
||||||
) *controllers.RootController {
|
) *controllers.RootController {
|
||||||
return &controllers.RootController{
|
return &controllers.RootController{
|
||||||
Ping: controllers.NewPingController(log.WithGroup("ping-controller")),
|
Ping: controllers.NewPingController(log.WithGroup("ping-controller")),
|
||||||
Auth: authController,
|
Auth: authController,
|
||||||
Organizations: orgController,
|
Organizations: orgController,
|
||||||
|
Transactions: txController,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
@ -16,8 +17,15 @@ func provideUsersRepository(db *sql.DB) users.Repository {
|
|||||||
return users.NewRepository(db)
|
return users.NewRepository(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func provideOrganizationsRepository(db *sql.DB) organizations.Repository {
|
func provideOrganizationsRepository(
|
||||||
return organizations.NewRepository(db)
|
db *sql.DB,
|
||||||
|
uRepo users.Repository,
|
||||||
|
) organizations.Repository {
|
||||||
|
return organizations.NewRepository(db, uRepo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func provideTxRepository(db *sql.DB) transactions.Repository {
|
||||||
|
return transactions.NewRepository(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func provideAuthRepository(db *sql.DB) auth.Repository {
|
func provideAuthRepository(db *sql.DB) auth.Repository {
|
||||||
|
@ -18,8 +18,10 @@ func ProvideService(c config.Config) (service.Service, func(), error) {
|
|||||||
provideRedisCache,
|
provideRedisCache,
|
||||||
provideUsersRepository,
|
provideUsersRepository,
|
||||||
provideUsersInteractor,
|
provideUsersInteractor,
|
||||||
|
provideTxRepository,
|
||||||
provideOrganizationsRepository,
|
provideOrganizationsRepository,
|
||||||
provideOrganizationsInteractor,
|
provideOrganizationsInteractor,
|
||||||
|
provideTxInteractor,
|
||||||
provideAuthRepository,
|
provideAuthRepository,
|
||||||
provideJWTInteractor,
|
provideJWTInteractor,
|
||||||
interfaceSet,
|
interfaceSet,
|
||||||
|
@ -26,13 +26,16 @@ func ProvideService(c config.Config) (service.Service, func(), error) {
|
|||||||
jwtInteractor := provideJWTInteractor(c, usersInteractor, authRepository)
|
jwtInteractor := provideJWTInteractor(c, usersInteractor, authRepository)
|
||||||
authPresenter := provideAuthPresenter(jwtInteractor)
|
authPresenter := provideAuthPresenter(jwtInteractor)
|
||||||
authController := provideAuthController(logger, usersInteractor, authPresenter, jwtInteractor)
|
authController := provideAuthController(logger, usersInteractor, authPresenter, jwtInteractor)
|
||||||
organizationsRepository := provideOrganizationsRepository(db)
|
organizationsRepository := provideOrganizationsRepository(db, usersRepository)
|
||||||
client, cleanup2 := provideRedisConnection(c)
|
client, cleanup2 := provideRedisConnection(c)
|
||||||
cache := provideRedisCache(client, logger)
|
cache := provideRedisCache(client, logger)
|
||||||
organizationsInteractor := provideOrganizationsInteractor(logger, organizationsRepository, cache)
|
organizationsInteractor := provideOrganizationsInteractor(logger, organizationsRepository, cache)
|
||||||
organizationsPresenter := provideOrganizationsPresenter()
|
organizationsPresenter := provideOrganizationsPresenter()
|
||||||
organizationsController := provideOrganizationsController(logger, organizationsInteractor, organizationsPresenter)
|
organizationsController := provideOrganizationsController(logger, organizationsInteractor, organizationsPresenter)
|
||||||
rootController := provideControllers(logger, authController, organizationsController)
|
transactionsRepository := provideTxRepository(db)
|
||||||
|
transactionsInteractor := provideTxInteractor(logger, transactionsRepository, organizationsInteractor)
|
||||||
|
transactionsController := provideTxController(logger, transactionsInteractor)
|
||||||
|
rootController := provideControllers(logger, authController, organizationsController, transactionsController)
|
||||||
server := provideRestServer(logger, rootController, c, jwtInteractor)
|
server := provideRestServer(logger, rootController, c, jwtInteractor)
|
||||||
serviceService := service.NewService(logger, server)
|
serviceService := service.NewService(logger, server)
|
||||||
return serviceService, func() {
|
return serviceService, func() {
|
||||||
|
@ -9,13 +9,14 @@ import (
|
|||||||
|
|
||||||
"github.com/emochka2007/block-accounting/internal/interface/rest/domain"
|
"github.com/emochka2007/block-accounting/internal/interface/rest/domain"
|
||||||
"github.com/emochka2007/block-accounting/internal/interface/rest/presenters"
|
"github.com/emochka2007/block-accounting/internal/interface/rest/presenters"
|
||||||
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
|
|
||||||
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OrganizationsController interface {
|
type OrganizationsController interface {
|
||||||
NewOrganization(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
NewOrganization(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
||||||
ListOrganizations(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
ListOrganizations(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
||||||
|
// todo delete
|
||||||
|
// todo update
|
||||||
}
|
}
|
||||||
|
|
||||||
type organizationsController struct {
|
type organizationsController struct {
|
||||||
@ -66,13 +67,7 @@ func (c *organizationsController) ListOrganizations(w http.ResponseWriter, r *ht
|
|||||||
ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second)
|
ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
user, err := ctxmeta.User(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error fetch user from context. %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.orgInteractor.List(ctx, organizations.ListParams{
|
resp, err := c.orgInteractor.List(ctx, organizations.ListParams{
|
||||||
UserId: user.Id(),
|
|
||||||
Cursor: req.Cursor,
|
Cursor: req.Cursor,
|
||||||
Limit: req.Limit,
|
Limit: req.Limit,
|
||||||
OffsetDate: time.UnixMilli(req.OffsetDate),
|
OffsetDate: time.UnixMilli(req.OffsetDate),
|
||||||
|
@ -4,16 +4,19 @@ type RootController struct {
|
|||||||
Ping PingController
|
Ping PingController
|
||||||
Auth AuthController
|
Auth AuthController
|
||||||
Organizations OrganizationsController
|
Organizations OrganizationsController
|
||||||
|
Transactions TransactionsController
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRootController(
|
func NewRootController(
|
||||||
ping PingController,
|
ping PingController,
|
||||||
auth AuthController,
|
auth AuthController,
|
||||||
organizations OrganizationsController,
|
organizations OrganizationsController,
|
||||||
|
transactions TransactionsController,
|
||||||
) *RootController {
|
) *RootController {
|
||||||
return &RootController{
|
return &RootController{
|
||||||
Ping: ping,
|
Ping: ping,
|
||||||
Auth: auth,
|
Auth: auth,
|
||||||
Organizations: organizations,
|
Organizations: organizations,
|
||||||
|
Transactions: transactions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
backend/internal/interface/rest/controllers/transactions.go
Normal file
36
backend/internal/interface/rest/controllers/transactions.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/transactions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TransactionsController interface {
|
||||||
|
New(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
||||||
|
List(w http.ResponseWriter, r *http.Request) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type transactionsController struct {
|
||||||
|
log *slog.Logger
|
||||||
|
txInteractor transactions.TransactionsInteractor
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTransactionsController(
|
||||||
|
log *slog.Logger,
|
||||||
|
txInteractor transactions.TransactionsInteractor,
|
||||||
|
) TransactionsController {
|
||||||
|
return &transactionsController{
|
||||||
|
log: log,
|
||||||
|
txInteractor: txInteractor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *transactionsController) New(w http.ResponseWriter, r *http.Request) ([]byte, error) {
|
||||||
|
panic("implement me!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *transactionsController) List(w http.ResponseWriter, r *http.Request) ([]byte, error) {
|
||||||
|
panic("implement me!")
|
||||||
|
}
|
@ -109,8 +109,8 @@ func (s *Server) buildRouter() {
|
|||||||
// r.Delete("/", s.handle(s.controllers.Organizations.NewOrganization, "delete_organization"))
|
// r.Delete("/", s.handle(s.controllers.Organizations.NewOrganization, "delete_organization"))
|
||||||
|
|
||||||
r.Route("/transactions", func(r chi.Router) {
|
r.Route("/transactions", func(r chi.Router) {
|
||||||
r.Get("/", nil) // list todo add cache
|
r.Get("/", s.handle(s.controllers.Transactions.List, "tx_list"))
|
||||||
r.Post("/", nil) // add
|
r.Post("/", s.handle(s.controllers.Transactions.New, "new_tx"))
|
||||||
r.Put("/{tx_id}", nil) // update / approve (or maybe body?)
|
r.Put("/{tx_id}", nil) // update / approve (or maybe body?)
|
||||||
r.Delete("/{tx_id}", nil) // remove
|
r.Delete("/{tx_id}", nil) // remove
|
||||||
})
|
})
|
||||||
|
@ -11,7 +11,7 @@ type Transaction struct {
|
|||||||
|
|
||||||
Description string
|
Description string
|
||||||
OrganizationId uuid.UUID
|
OrganizationId uuid.UUID
|
||||||
CreatedBy *User
|
CreatedBy *OrganizationUser
|
||||||
Amount int64
|
Amount int64
|
||||||
|
|
||||||
ToAddr []byte
|
ToAddr []byte
|
||||||
|
@ -60,7 +60,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type OrganizationParticipant interface {
|
type OrganizationParticipant interface {
|
||||||
UserIdentity
|
Id() uuid.UUID
|
||||||
|
|
||||||
Type() OrganizationParticipantType
|
Type() OrganizationParticipantType
|
||||||
|
|
||||||
@ -102,12 +102,21 @@ func (u *OrganizationUser) Position() string {
|
|||||||
|
|
||||||
type Employee struct {
|
type Employee struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
|
UserID uuid.UUID
|
||||||
OrganizationId uuid.UUID
|
OrganizationId uuid.UUID
|
||||||
WalletAddress []byte
|
WalletAddress []byte
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *Employee) Id() uuid.UUID {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Employee) UserId() uuid.UUID {
|
||||||
|
return u.UserID
|
||||||
|
}
|
||||||
|
|
||||||
func (u *Employee) Type() OrganizationParticipantType {
|
func (u *Employee) Type() OrganizationParticipantType {
|
||||||
return OrganizationParticipantTypeEmployee
|
return OrganizationParticipantTypeEmployee
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,24 @@ type ListParams struct {
|
|||||||
Limit uint8 // Max limit is 50 (may change)
|
Limit uint8 // Max limit is 50 (may change)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ParticipantParams struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
OrganizationID uuid.UUID
|
||||||
|
|
||||||
|
UsersOnly bool
|
||||||
|
ActiveOnly bool
|
||||||
|
EmployeesOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParticipantsParams struct {
|
||||||
|
IDs uuid.UUIDs
|
||||||
|
OrganizationID uuid.UUID
|
||||||
|
|
||||||
|
UsersOnly bool
|
||||||
|
ActiveOnly bool
|
||||||
|
EmployeesOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
type OrganizationsInteractor interface {
|
type OrganizationsInteractor interface {
|
||||||
Create(
|
Create(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@ -46,6 +64,14 @@ type OrganizationsInteractor interface {
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
params ListParams,
|
params ListParams,
|
||||||
) (*ListResponse, error)
|
) (*ListResponse, error)
|
||||||
|
Participant(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantParams,
|
||||||
|
) (models.OrganizationParticipant, error)
|
||||||
|
Participants(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantsParams,
|
||||||
|
) ([]models.OrganizationParticipant, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type organizationsInteractor struct {
|
type organizationsInteractor struct {
|
||||||
@ -226,3 +252,62 @@ func (i *organizationsInteractor) Create(
|
|||||||
|
|
||||||
return &org, nil
|
return &org, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *organizationsInteractor) Participant(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantParams,
|
||||||
|
) (models.OrganizationParticipant, error) {
|
||||||
|
participants, err := i.Participants(ctx, ParticipantsParams{
|
||||||
|
IDs: uuid.UUIDs{params.ID},
|
||||||
|
OrganizationID: params.OrganizationID,
|
||||||
|
ActiveOnly: params.ActiveOnly,
|
||||||
|
UsersOnly: params.UsersOnly,
|
||||||
|
EmployeesOnly: params.EmployeesOnly,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch organization participant. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(participants) == 0 {
|
||||||
|
return nil, fmt.Errorf("error organization participant empty. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return participants[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *organizationsInteractor) Participants(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantsParams,
|
||||||
|
) ([]models.OrganizationParticipant, error) {
|
||||||
|
// TODO check access for ctx user
|
||||||
|
user, err := ctxmeta.User(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch user from context. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = i.orgRepository.Participants(ctx, organizations.ParticipantsParams{
|
||||||
|
Ids: uuid.UUIDs{user.Id()},
|
||||||
|
OrganizationId: params.OrganizationID,
|
||||||
|
ActiveOnly: params.ActiveOnly,
|
||||||
|
UsersOnly: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Join(
|
||||||
|
fmt.Errorf("error fetch organization user. %w", err),
|
||||||
|
ErrorUnauthorizedAccess,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
participants, err := i.orgRepository.Participants(ctx, organizations.ParticipantsParams{
|
||||||
|
Ids: params.IDs,
|
||||||
|
OrganizationId: params.OrganizationID,
|
||||||
|
UsersOnly: params.UsersOnly,
|
||||||
|
EmployeesOnly: params.EmployeesOnly,
|
||||||
|
ActiveOnly: params.ActiveOnly,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch organization participants. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return participants, nil
|
||||||
|
}
|
||||||
|
140
backend/internal/usecase/interactors/transactions/interactor.go
Normal file
140
backend/internal/usecase/interactors/transactions/interactor.go
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package transactions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/pkg/models"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListParams struct {
|
||||||
|
IDs uuid.UUIDs
|
||||||
|
OrganizationID uuid.UUID
|
||||||
|
CreatedBy uuid.UUID
|
||||||
|
|
||||||
|
To []byte
|
||||||
|
|
||||||
|
Limit int64
|
||||||
|
Cursor string
|
||||||
|
|
||||||
|
WithCancelled bool
|
||||||
|
WithConfirmed bool
|
||||||
|
WithCommited bool
|
||||||
|
WithExpired bool
|
||||||
|
|
||||||
|
WithConfirmations bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateParams struct {
|
||||||
|
Tx models.Transaction
|
||||||
|
OrganizationId uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfirmParams struct {
|
||||||
|
TxID uuid.UUID
|
||||||
|
OrganizationID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
type CancelParams struct {
|
||||||
|
TxID uuid.UUID
|
||||||
|
OrganizationID uuid.UUID
|
||||||
|
Cause string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionsInteractor interface {
|
||||||
|
List(ctx context.Context, params ListParams) ([]*models.Transaction, error)
|
||||||
|
Create(ctx context.Context, params CreateParams) (*models.Transaction, error)
|
||||||
|
Confirm(ctx context.Context, params ConfirmParams) (*models.Transaction, error)
|
||||||
|
Cancel(ctx context.Context, params CancelParams) (*models.Transaction, error)
|
||||||
|
// TODO delete
|
||||||
|
// TODO update
|
||||||
|
}
|
||||||
|
|
||||||
|
type transactionsInteractor struct {
|
||||||
|
log *slog.Logger
|
||||||
|
txRepo transactions.Repository
|
||||||
|
orgInteractor organizations.OrganizationsInteractor
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTransactionsInteractor(
|
||||||
|
log *slog.Logger,
|
||||||
|
txRepo transactions.Repository,
|
||||||
|
orgInteractor organizations.OrganizationsInteractor,
|
||||||
|
) TransactionsInteractor {
|
||||||
|
return &transactionsInteractor{
|
||||||
|
log: log,
|
||||||
|
txRepo: txRepo,
|
||||||
|
orgInteractor: orgInteractor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *transactionsInteractor) List(ctx context.Context, params ListParams) ([]*models.Transaction, error) {
|
||||||
|
filters := make([]transactions.GetTransactionsFilter, 0)
|
||||||
|
|
||||||
|
if params.WithCancelled {
|
||||||
|
filters = append(filters, transactions.GetFilterCancelled)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.WithConfirmed {
|
||||||
|
filters = append(filters, transactions.GetFilterConfirmed)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.WithCommited {
|
||||||
|
filters = append(filters, transactions.GetFilterCommited)
|
||||||
|
}
|
||||||
|
|
||||||
|
txs, err := i.txRepo.GetTransactions(ctx, transactions.GetTransactionsParams{
|
||||||
|
Ids: params.IDs,
|
||||||
|
OrganizationId: params.OrganizationID,
|
||||||
|
CreatedById: params.CreatedBy,
|
||||||
|
Filters: filters,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch transaction from repository. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return txs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *transactionsInteractor) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
params CreateParams,
|
||||||
|
) (*models.Transaction, error) {
|
||||||
|
user, err := ctxmeta.User(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch user from context. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := params.Tx
|
||||||
|
|
||||||
|
participant, err := i.orgInteractor.Participant(ctx, organizations.ParticipantParams{
|
||||||
|
ID: user.Id(),
|
||||||
|
ActiveOnly: true,
|
||||||
|
UsersOnly: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetch actor prticipant. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.CreatedBy = participant.GetUser()
|
||||||
|
tx.CreatedAt = time.Now()
|
||||||
|
|
||||||
|
if err = i.txRepo.CreateTransaction(ctx, tx); err != nil {
|
||||||
|
return nil, fmt.Errorf("error create new tx. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *transactionsInteractor) Confirm(ctx context.Context, params ConfirmParams) (*models.Transaction, error) {
|
||||||
|
panic("implement me!")
|
||||||
|
}
|
||||||
|
func (i *transactionsInteractor) Cancel(ctx context.Context, params CancelParams) (*models.Transaction, error) {
|
||||||
|
panic("implement me!")
|
||||||
|
}
|
@ -10,7 +10,13 @@ import (
|
|||||||
sq "github.com/Masterminds/squirrel"
|
sq "github.com/Masterminds/squirrel"
|
||||||
"github.com/emochka2007/block-accounting/internal/pkg/models"
|
"github.com/emochka2007/block-accounting/internal/pkg/models"
|
||||||
sqltools "github.com/emochka2007/block-accounting/internal/pkg/sqlutils"
|
sqltools "github.com/emochka2007/block-accounting/internal/pkg/sqlutils"
|
||||||
|
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrorNotFound = errors.New("not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
type GetParams struct {
|
type GetParams struct {
|
||||||
@ -51,17 +57,23 @@ type Repository interface {
|
|||||||
Update(ctx context.Context, org models.Organization) error
|
Update(ctx context.Context, org models.Organization) error
|
||||||
Delete(ctx context.Context, id uuid.UUID) error
|
Delete(ctx context.Context, id uuid.UUID) error
|
||||||
AddParticipant(ctx context.Context, params AddParticipantParams) error
|
AddParticipant(ctx context.Context, params AddParticipantParams) error
|
||||||
|
Participants(ctx context.Context, params ParticipantsParams) ([]models.OrganizationParticipant, error)
|
||||||
CreateAndAdd(ctx context.Context, org models.Organization, user *models.User) error
|
CreateAndAdd(ctx context.Context, org models.Organization, user *models.User) error
|
||||||
DeleteParticipant(ctx context.Context, params DeleteParticipantParams) error
|
DeleteParticipant(ctx context.Context, params DeleteParticipantParams) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type repositorySQL struct {
|
type repositorySQL struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
usersRepository users.Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(db *sql.DB) Repository {
|
func NewRepository(
|
||||||
|
db *sql.DB,
|
||||||
|
usersRepository users.Repository,
|
||||||
|
) Repository {
|
||||||
return &repositorySQL{
|
return &repositorySQL{
|
||||||
db: db,
|
db: db,
|
||||||
|
usersRepository: usersRepository,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,22 +274,6 @@ func (r *repositorySQL) CreateAndAdd(ctx context.Context, org models.Organizatio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *repositorySQL) Participants(
|
|
||||||
ctx context.Context,
|
|
||||||
params ParticipantsParams,
|
|
||||||
) ([]models.OrganizationParticipant, error) {
|
|
||||||
participants := make([]models.OrganizationParticipant, 0, len(params.Ids))
|
|
||||||
|
|
||||||
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return participants, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *repositorySQL) AddParticipant(ctx context.Context, params AddParticipantParams) error {
|
func (r *repositorySQL) AddParticipant(ctx context.Context, params AddParticipantParams) error {
|
||||||
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
||||||
query := sq.Insert("organizations_users").
|
query := sq.Insert("organizations_users").
|
||||||
@ -349,3 +345,291 @@ func (r *repositorySQL) DeleteParticipant(ctx context.Context, params DeletePart
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *repositorySQL) Participants(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantsParams,
|
||||||
|
) ([]models.OrganizationParticipant, error) {
|
||||||
|
participants := make([]models.OrganizationParticipant, 0, len(params.Ids))
|
||||||
|
|
||||||
|
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
||||||
|
orgUsersModels, err := r.fetchOrganizationUsers(ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetch organization users raw models. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
eg, egCtx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
var employees []*models.Employee = make([]*models.Employee, 0, len(orgUsersModels))
|
||||||
|
eg.Go(func() error {
|
||||||
|
ids := make(uuid.UUIDs, 0, len(orgUsersModels))
|
||||||
|
|
||||||
|
for _, m := range orgUsersModels {
|
||||||
|
if m.employeeID != uuid.Nil {
|
||||||
|
ids = append(ids, m.employeeID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
employees, err = r.fetchEmployees(egCtx, fetchEmployeesParams{
|
||||||
|
IDs: ids,
|
||||||
|
OrganizationId: params.OrganizationId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetch employees. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var usrs []*models.User
|
||||||
|
eg.Go(func() error {
|
||||||
|
ids := make(uuid.UUIDs, 0, len(orgUsersModels))
|
||||||
|
|
||||||
|
for _, m := range orgUsersModels {
|
||||||
|
if m.userID != uuid.Nil {
|
||||||
|
ids = append(ids, m.employeeID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usrs, err = r.usersRepository.Get(egCtx, users.GetParams{
|
||||||
|
Ids: ids,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetch users by ids. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err = eg.Wait(); err != nil {
|
||||||
|
return fmt.Errorf("error organizations users entitiels. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ou := range orgUsersModels {
|
||||||
|
var employee *models.Employee
|
||||||
|
|
||||||
|
if ou.employeeID != uuid.Nil {
|
||||||
|
for _, e := range employees {
|
||||||
|
if e.ID == ou.employeeID {
|
||||||
|
employee = e
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ou.userID == uuid.Nil && employee != nil {
|
||||||
|
participants = append(participants, employee)
|
||||||
|
}
|
||||||
|
|
||||||
|
var orgUser *models.OrganizationUser
|
||||||
|
|
||||||
|
for _, u := range usrs {
|
||||||
|
if u.Id() == ou.userID {
|
||||||
|
orgUser = &models.OrganizationUser{
|
||||||
|
User: *u,
|
||||||
|
OrgPosition: ou.position,
|
||||||
|
Admin: ou.isAdmin,
|
||||||
|
Employee: employee,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
participants = append(participants, orgUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, fmt.Errorf("error execute transactional operation. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(participants) == 0 {
|
||||||
|
return nil, ErrorNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return participants, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fetchOrganizationUsersModel struct {
|
||||||
|
organizationID uuid.UUID
|
||||||
|
userID uuid.UUID
|
||||||
|
employeeID uuid.UUID
|
||||||
|
position string
|
||||||
|
addedAt time.Time
|
||||||
|
updatedAt time.Time
|
||||||
|
deletedAt time.Time
|
||||||
|
isAdmin bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *repositorySQL) fetchOrganizationUsers(
|
||||||
|
ctx context.Context,
|
||||||
|
params ParticipantsParams,
|
||||||
|
) ([]fetchOrganizationUsersModel, error) {
|
||||||
|
participants := make([]fetchOrganizationUsersModel, 0, len(params.Ids))
|
||||||
|
|
||||||
|
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
||||||
|
ouQuery := sq.Select(
|
||||||
|
"ou.organization_id",
|
||||||
|
"ou.user_id",
|
||||||
|
"ou.employee_id",
|
||||||
|
"ou.position",
|
||||||
|
"ou.added_at",
|
||||||
|
"ou.updated_at",
|
||||||
|
"ou.deleted_at",
|
||||||
|
"ou.is_admin",
|
||||||
|
).Where(sq.Eq{
|
||||||
|
"ou.organization_id": params.OrganizationId,
|
||||||
|
}).PlaceholderFormat(sq.Dollar)
|
||||||
|
|
||||||
|
if len(params.Ids) > 0 {
|
||||||
|
ouQuery = ouQuery.Where(sq.Eq{
|
||||||
|
"ou.user_id": params.Ids,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := ouQuery.RunWith(r.Conn(ctx)).QueryContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetch organization participants. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if closeErr := rows.Close(); closeErr != nil {
|
||||||
|
err = errors.Join(fmt.Errorf("error close rows. %w", closeErr), err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var (
|
||||||
|
organizationID uuid.UUID
|
||||||
|
userID uuid.UUID
|
||||||
|
employeeID uuid.UUID
|
||||||
|
position string
|
||||||
|
addedAt time.Time
|
||||||
|
updatedAt time.Time
|
||||||
|
deletedAt sql.NullTime
|
||||||
|
isAdmin bool
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = rows.Scan(
|
||||||
|
&organizationID,
|
||||||
|
&userID,
|
||||||
|
&employeeID,
|
||||||
|
&position,
|
||||||
|
&addedAt,
|
||||||
|
&updatedAt,
|
||||||
|
&deletedAt,
|
||||||
|
&isAdmin,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("error scan row. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.EmployeesOnly && employeeID == uuid.Nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.UsersOnly && userID == uuid.Nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ActiveOnly && deletedAt.Valid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
participants = append(participants, fetchOrganizationUsersModel{
|
||||||
|
organizationID: organizationID,
|
||||||
|
userID: userID,
|
||||||
|
employeeID: employeeID,
|
||||||
|
position: position,
|
||||||
|
addedAt: addedAt,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
deletedAt: deletedAt.Time,
|
||||||
|
isAdmin: isAdmin,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
return nil, fmt.Errorf("error execute transactional operation. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return participants, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fetchEmployeesParams struct {
|
||||||
|
IDs uuid.UUIDs
|
||||||
|
OrganizationId uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *repositorySQL) fetchEmployees(
|
||||||
|
ctx context.Context,
|
||||||
|
params fetchEmployeesParams,
|
||||||
|
) ([]*models.Employee, error) {
|
||||||
|
employees := make([]*models.Employee, 0, len(params.IDs))
|
||||||
|
|
||||||
|
if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) (err error) {
|
||||||
|
query := sq.Select(
|
||||||
|
"e.id",
|
||||||
|
"e.user_id",
|
||||||
|
"e.organization_id",
|
||||||
|
"e.wallet_address",
|
||||||
|
"e.created_at",
|
||||||
|
"e.updated_at",
|
||||||
|
).Where(sq.Eq{
|
||||||
|
"e.organization_id": params.OrganizationId,
|
||||||
|
}).PlaceholderFormat(sq.Dollar)
|
||||||
|
|
||||||
|
if len(params.IDs) > 0 {
|
||||||
|
query = query.Where(sq.Eq{
|
||||||
|
"e.id": params.IDs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := query.RunWith(r.Conn(ctx)).QueryContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetch employees from database. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if closeErr := rows.Close(); closeErr != nil {
|
||||||
|
err = errors.Join(fmt.Errorf("error close rows. %w", closeErr), err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var (
|
||||||
|
id uuid.UUID
|
||||||
|
userID uuid.UUID
|
||||||
|
orgID uuid.UUID
|
||||||
|
walletAddr []byte
|
||||||
|
createdAt time.Time
|
||||||
|
updatedAt time.Time
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = rows.Scan(
|
||||||
|
&id,
|
||||||
|
&userID,
|
||||||
|
&orgID,
|
||||||
|
&walletAddr,
|
||||||
|
&createdAt,
|
||||||
|
&updatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("error scan row. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
employees = append(employees, &models.Employee{
|
||||||
|
ID: id,
|
||||||
|
UserID: userID,
|
||||||
|
OrganizationId: orgID,
|
||||||
|
WalletAddress: walletAddr,
|
||||||
|
CreatedAt: createdAt,
|
||||||
|
UpdatedAt: updatedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, fmt.Errorf("error execute transactional operation. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return employees, nil
|
||||||
|
}
|
||||||
|
@ -143,9 +143,11 @@ func (r *repositorySQL) GetTransactions(
|
|||||||
Amount: amount,
|
Amount: amount,
|
||||||
ToAddr: toAddr,
|
ToAddr: toAddr,
|
||||||
MaxFeeAllowed: maxFeeAllowed,
|
MaxFeeAllowed: maxFeeAllowed,
|
||||||
CreatedBy: &models.User{
|
CreatedBy: &models.OrganizationUser{
|
||||||
ID: createdById,
|
User: models.User{
|
||||||
Bip39Seed: createdBySeed,
|
ID: createdById,
|
||||||
|
Bip39Seed: createdBySeed,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CreatedAt: createdAt,
|
CreatedAt: createdAt,
|
||||||
UpdatedAt: updatedAt,
|
UpdatedAt: updatedAt,
|
||||||
|
@ -54,7 +54,7 @@ create index if not exists index_organizations_id
|
|||||||
|
|
||||||
create table employees (
|
create table employees (
|
||||||
id uuid primary key,
|
id uuid primary key,
|
||||||
user_id uuid references users(id),
|
user_id uuid,
|
||||||
organization_id uuid not null references organizations(id),
|
organization_id uuid not null references organizations(id),
|
||||||
wallet_address text not null,
|
wallet_address text not null,
|
||||||
created_at timestamp default current_timestamp,
|
created_at timestamp default current_timestamp,
|
||||||
@ -97,6 +97,7 @@ create table if not exists transactions (
|
|||||||
amount bigint default 0,
|
amount bigint default 0,
|
||||||
|
|
||||||
to_addr bytea not null,
|
to_addr bytea not null,
|
||||||
|
tx_index bytea default null,
|
||||||
|
|
||||||
max_fee_allowed bigint default 0,
|
max_fee_allowed bigint default 0,
|
||||||
deadline timestamp default null,
|
deadline timestamp default null,
|
||||||
@ -138,9 +139,14 @@ create table contracts (
|
|||||||
|
|
||||||
address bytea not null,
|
address bytea not null,
|
||||||
|
|
||||||
|
payload bytea not null,
|
||||||
|
|
||||||
created_by uuid not null references users(id),
|
created_by uuid not null references users(id),
|
||||||
organization_id uuid not null references organizations(id),
|
organization_id uuid not null references organizations(id),
|
||||||
|
|
||||||
|
status tinyint default 0,
|
||||||
|
tx_index bytea default null,
|
||||||
|
|
||||||
created_at timestamp default current_timestamp,
|
created_at timestamp default current_timestamp,
|
||||||
updated_at timestamp default current_timestamp
|
updated_at timestamp default current_timestamp
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user