mirror of
https://github.com/emo2007/block-accounting.git
synced 2025-04-12 08:56:28 +00:00
schema changes + hal added
This commit is contained in:
parent
eea7891fc4
commit
7806e2f677
@ -3,11 +3,14 @@ package domain
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/emochka2007/block-accounting/internal/interface/rest/domain/hal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generic
|
// Generic
|
||||||
|
|
||||||
type Collection[T any] struct {
|
type Collection[T any] struct {
|
||||||
|
*hal.Resource
|
||||||
Items []T `json:"items,omitempty"`
|
Items []T `json:"items,omitempty"`
|
||||||
Pagination Pagination `json:"pagination,omitempty"`
|
Pagination Pagination `json:"pagination,omitempty"`
|
||||||
}
|
}
|
||||||
@ -50,20 +53,12 @@ type NewOrganizationRequest struct {
|
|||||||
WalletMnemonic string `json:"wallet_mnemonic,omitempty"`
|
WalletMnemonic string `json:"wallet_mnemonic,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NewOrganizationResponse struct {
|
|
||||||
Organization Organization `json:"organization"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListOrganizationsRequest struct {
|
type ListOrganizationsRequest struct {
|
||||||
Cursor string `json:"cursor,omitempty"`
|
Cursor string `json:"cursor,omitempty"`
|
||||||
Limit uint8 `json:"limit,omitempty"` // Default: 50, Max: 50
|
Limit uint8 `json:"limit,omitempty"` // Default: 50, Max: 50
|
||||||
OffsetDate int64 `json:"offset_date,omitempty"` // List organizations, updated since the date
|
OffsetDate int64 `json:"offset_date,omitempty"` // List organizations, updated since the date
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListOrganizationsResponse struct {
|
|
||||||
Collection[Organization]
|
|
||||||
}
|
|
||||||
|
|
||||||
func BuildRequest[T any](data []byte) (*T, error) {
|
func BuildRequest[T any](data []byte) (*T, error) {
|
||||||
var req T
|
var req T
|
||||||
|
|
||||||
|
69
backend/internal/interface/rest/domain/hal/hal.go
Normal file
69
backend/internal/interface/rest/domain/hal/hal.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package hal
|
||||||
|
|
||||||
|
type Link struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Method string `json:"method,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Resource struct {
|
||||||
|
Type string `json:"_type,omitempty"`
|
||||||
|
Links map[string]Link `json:"_links"`
|
||||||
|
Embedded map[string]any `json:"_embedded,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Payload interface{}
|
||||||
|
|
||||||
|
type NewResourceOption func(r *Resource)
|
||||||
|
|
||||||
|
func NewResource(selfLink string, opts ...NewResourceOption) *Resource {
|
||||||
|
r := &Resource{
|
||||||
|
Links: map[string]Link{
|
||||||
|
"self": {
|
||||||
|
Href: selfLink,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithType(t string) NewResourceOption {
|
||||||
|
return func(r *Resource) {
|
||||||
|
r.Type = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSelfTitle(t string) NewResourceOption {
|
||||||
|
return func(r *Resource) {
|
||||||
|
if l, ok := r.Links["self"]; ok {
|
||||||
|
l.Title = t
|
||||||
|
|
||||||
|
r.Links["self"] = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resource) Embed(relation string, resource *Resource) {
|
||||||
|
if r.Embedded == nil {
|
||||||
|
r.Embedded = make(map[string]any, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Embedded[relation] = resource
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resource) AddLink(relation string, link Link) {
|
||||||
|
if r.Links == nil {
|
||||||
|
r.Links = make(map[string]Link, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Links[relation] = link
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resource) SetType(t string) {
|
||||||
|
r.Type = t
|
||||||
|
}
|
@ -1,6 +1,11 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/emochka2007/block-accounting/internal/interface/rest/domain/hal"
|
||||||
|
)
|
||||||
|
|
||||||
type Organization struct {
|
type Organization struct {
|
||||||
|
*hal.Resource
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"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/domain/hal"
|
||||||
"github.com/emochka2007/block-accounting/internal/pkg/models"
|
"github.com/emochka2007/block-accounting/internal/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,17 +23,20 @@ func NewOrganizationsPresenter() OrganizationsPresenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *organizationsPresenter) ResponseCreate(o *models.Organization) ([]byte, error) {
|
func (p *organizationsPresenter) ResponseCreate(o *models.Organization) ([]byte, error) {
|
||||||
resp := &domain.NewOrganizationResponse{
|
org := domain.Organization{
|
||||||
Organization: domain.Organization{
|
Id: o.ID.String(),
|
||||||
Id: o.ID.String(),
|
Name: o.Name,
|
||||||
Name: o.Name,
|
Address: o.Address,
|
||||||
Address: o.Address,
|
CreatedAt: uint64(o.CreatedAt.UnixMilli()),
|
||||||
CreatedAt: uint64(o.CreatedAt.UnixMilli()),
|
UpdatedAt: uint64(o.UpdatedAt.UnixMilli()),
|
||||||
UpdatedAt: uint64(o.UpdatedAt.UnixMilli()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := json.Marshal(resp)
|
r := hal.NewResource(
|
||||||
|
"/organizations/"+org.Id,
|
||||||
|
hal.WithType("organization"),
|
||||||
|
)
|
||||||
|
|
||||||
|
out, err := json.Marshal(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error marshal organization create response. %w", err)
|
return nil, fmt.Errorf("error marshal organization create response. %w", err)
|
||||||
}
|
}
|
||||||
@ -41,17 +45,19 @@ func (p *organizationsPresenter) ResponseCreate(o *models.Organization) ([]byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *organizationsPresenter) ResponseList(orgs []*models.Organization, nextCursor string) ([]byte, error) {
|
func (p *organizationsPresenter) ResponseList(orgs []*models.Organization, nextCursor string) ([]byte, error) {
|
||||||
resp := &domain.ListOrganizationsResponse{
|
dtoOrgs := domain.Collection[domain.Organization]{
|
||||||
Collection: domain.Collection[domain.Organization]{
|
Resource: hal.NewResource(
|
||||||
Items: p.Organizations(orgs),
|
"/organizations",
|
||||||
Pagination: domain.Pagination{
|
hal.WithType("organizations"),
|
||||||
NextCursor: nextCursor,
|
),
|
||||||
TotalItems: uint32(len(orgs)),
|
Items: p.Organizations(orgs),
|
||||||
},
|
Pagination: domain.Pagination{
|
||||||
|
NextCursor: nextCursor,
|
||||||
|
TotalItems: uint32(len(orgs)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := json.Marshal(resp)
|
out, err := json.Marshal(dtoOrgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error marshal organizations list response. %w", err)
|
return nil, fmt.Errorf("error marshal organizations list response. %w", err)
|
||||||
}
|
}
|
||||||
@ -63,13 +69,16 @@ func (p *organizationsPresenter) Organizations(orgs []*models.Organization) []do
|
|||||||
out := make([]domain.Organization, len(orgs))
|
out := make([]domain.Organization, len(orgs))
|
||||||
|
|
||||||
for i, o := range orgs {
|
for i, o := range orgs {
|
||||||
out[i] = domain.Organization{
|
org := domain.Organization{
|
||||||
|
Resource: hal.NewResource("/organizations/" + o.ID.String()),
|
||||||
Id: o.ID.String(),
|
Id: o.ID.String(),
|
||||||
Name: o.Name,
|
Name: o.Name,
|
||||||
Address: o.Address,
|
Address: o.Address,
|
||||||
CreatedAt: uint64(o.CreatedAt.UnixMilli()),
|
CreatedAt: uint64(o.CreatedAt.UnixMilli()),
|
||||||
UpdatedAt: uint64(o.UpdatedAt.UnixMilli()),
|
UpdatedAt: uint64(o.UpdatedAt.UnixMilli()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out[i] = org
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
@ -113,4 +113,16 @@ create table transactions_confirmations (
|
|||||||
);
|
);
|
||||||
|
|
||||||
create index if not exists index_transactions_confirmations_tx_id_user_id_organization_id
|
create index if not exists index_transactions_confirmations_tx_id_user_id_organization_id
|
||||||
on transactions_confirmations (tx_id, user_id, organization_id);
|
on transactions_confirmations (tx_id, user_id, organization_id);
|
||||||
|
|
||||||
|
create table contracts (
|
||||||
|
id uuid primary key,
|
||||||
|
title varchar(250) default 'New Contract',
|
||||||
|
description text not null,
|
||||||
|
|
||||||
|
created_by uuid not null references users(id),
|
||||||
|
organization_id uuid not null references organizations(id),
|
||||||
|
|
||||||
|
created_at timestamp default current_timestamp,
|
||||||
|
updated_at timestamp default current_timestamp
|
||||||
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user