From 9002862415ea545e4fc10cd0430e8a28b93d046c Mon Sep 17 00:00:00 2001 From: Rogee Date: Wed, 15 Jan 2025 14:47:10 +0800 Subject: [PATCH] feat: add posts --- backend/app/http/medias/controller.go | 2 +- backend/app/http/medias/service.go | 32 +++ backend/app/http/posts/controller.go | 39 ++-- backend/app/http/posts/dto.go | 14 +- backend/database/fields/medias.gen.go | 199 ++++++++++++++++++ backend/database/fields/medias.go | 18 ++ .../migrations/20250109095933_create_post.sql | 2 +- .../20250110093636_create_medias.sql | 2 +- .../models/qvyun_v2/public/model/medias.go | 2 +- .../models/qvyun_v2/public/model/posts.go | 38 ++-- .../models/qvyun_v2/public/table/medias.go | 10 +- .../models/qvyun_v2/public/table/posts.go | 118 +++++------ backend/database/transform.yaml | 2 + 13 files changed, 374 insertions(+), 104 deletions(-) create mode 100644 backend/database/fields/medias.gen.go create mode 100644 backend/database/fields/medias.go diff --git a/backend/app/http/medias/controller.go b/backend/app/http/medias/controller.go index b54daa3..d33ea80 100644 --- a/backend/app/http/medias/controller.go +++ b/backend/app/http/medias/controller.go @@ -70,8 +70,8 @@ func (ctl *Controller) Upload(ctx fiber.Ctx, claim *jwt.Claims, tenantSlug strin TenantID: tenant.ID, UserID: claim.UserID, StorageID: defaultStorage.ID, + Hash: uploadedFile.Hash, Name: uploadedFile.Name, - UUID: uploadedFile.Hash, MimeType: uploadedFile.MimeType, Size: uploadedFile.Size, Path: uploadedFile.Path, diff --git a/backend/app/http/medias/service.go b/backend/app/http/medias/service.go index 60cb54b..d5af069 100644 --- a/backend/app/http/medias/service.go +++ b/backend/app/http/medias/service.go @@ -9,6 +9,7 @@ import ( "backend/providers/otel" . "github.com/go-jet/jet/v2/postgres" + "github.com/samber/lo" log "github.com/sirupsen/logrus" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) @@ -40,3 +41,34 @@ func (svc *Service) Create(ctx context.Context, m *model.Medias) (*model.Medias, } return &ret, nil } + +// GetMediasByHash +func (svc *Service) GetMediasByHash(ctx context.Context, tenantID, userID int64, hashes []string) ([]*model.Medias, error) { + _, span := otel.Start(ctx, "medias.service.GetMediasByHash") + defer span.End() + + hashExpr := lo.Map(hashes, func(item string, index int) Expression { return String(item) }) + + tbl := table.Medias + stmt := tbl. + SELECT(tbl.AllColumns). + WHERE( + tbl.TenantID. + EQ(Int64(tenantID)). + AND( + tbl.UserID.EQ(Int64(userID)), + ). + AND( + tbl.Hash.IN(hashExpr...), + ), + ) + span.SetAttributes(semconv.DBStatementKey.String(stmt.DebugSql())) + + var ret []model.Medias + if err := stmt.QueryContext(ctx, svc.db, &ret); err != nil { + return nil, err + } + return lo.Map(ret, func(item model.Medias, _ int) *model.Medias { + return &item + }), nil +} diff --git a/backend/app/http/posts/controller.go b/backend/app/http/posts/controller.go index 23cb597..d3a1904 100644 --- a/backend/app/http/posts/controller.go +++ b/backend/app/http/posts/controller.go @@ -4,6 +4,7 @@ import ( "time" "backend/app/errorx" + "backend/app/http/medias" "backend/app/http/tenants" "backend/app/http/users" "backend/app/requests" @@ -24,6 +25,7 @@ type Controller struct { hashIds *hashids.HashID userSvc *users.Service tenantSvc *tenants.Service + mediaSvc *medias.Service log *log.Entry `inject:"false"` } @@ -153,24 +155,37 @@ func (ctl *Controller) Create(ctx fiber.Ctx, claim *jwt.Claims, tenantSlug strin return err } + // check media assets exists + hashes := lo.Map(body.Assets.Data, func(item fields.MediaAsset, _ int) string { return item.Hash }) + medias, err := ctl.mediaSvc.GetMediasByHash(ctx.Context(), tenant.ID, user.ID, hashes) + if err != nil { + return err + } + + if len(medias) != len(lo.Uniq(hashes)) { + return errorx.BadRequest + } + post := &model.Posts{ - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - TenantID: tenant.ID, - UserID: user.ID, - Title: body.Title, - Description: body.Description, - Content: body.Content, - PosterAssetID: 0, - Stage: fields.PostStagePending, - Status: fields.PostStatusPending, - Price: body.Price, - Discount: body.Discount, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + TenantID: tenant.ID, + UserID: user.ID, + Title: body.Title, + Description: body.Description, + Content: body.Content, + Stage: fields.PostStagePending, + Status: fields.PostStatusPending, + Price: body.Price, + Discount: body.Discount, + Assets: body.Assets, + Tags: body.Tags, } if err := ctl.svc.Create(ctx.Context(), tenant, user, post); err != nil { return err } + // TODO: trigger event && jobs return nil } diff --git a/backend/app/http/posts/dto.go b/backend/app/http/posts/dto.go index 5c933d0..bc7f161 100644 --- a/backend/app/http/posts/dto.go +++ b/backend/app/http/posts/dto.go @@ -2,6 +2,8 @@ package posts import ( "time" + + "backend/database/fields" ) type UserPost struct { @@ -32,9 +34,11 @@ type UserPostFilter struct { } type PostBody struct { - Title string - Description string - Content string - Price int64 - Discount int16 + Title string `json:"title,omitempty"` + Tags fields.Json[[]string] `json:"tags,omitempty"` + Description string `json:"description,omitempty"` + Content string `json:"content,omitempty"` + Price int64 `json:"price,omitempty"` + Discount int16 `json:"discount,omitempty"` + Assets fields.Json[[]fields.MediaAsset] `json:"assets,omitempty"` } diff --git a/backend/database/fields/medias.gen.go b/backend/database/fields/medias.gen.go new file mode 100644 index 0000000..76263da --- /dev/null +++ b/backend/database/fields/medias.gen.go @@ -0,0 +1,199 @@ +// Code generated by go-enum DO NOT EDIT. +// Version: - +// Revision: - +// Build Date: - +// Built By: - + +package fields + +import ( + "database/sql/driver" + "errors" + "fmt" + "strings" +) + +const ( + // MediaAssetTypeUnknown is a MediaAssetType of type Unknown. + MediaAssetTypeUnknown MediaAssetType = "unknown" + // MediaAssetTypePoster is a MediaAssetType of type Poster. + MediaAssetTypePoster MediaAssetType = "poster" + // MediaAssetTypeImage is a MediaAssetType of type Image. + MediaAssetTypeImage MediaAssetType = "image" + // MediaAssetTypeVideo is a MediaAssetType of type Video. + MediaAssetTypeVideo MediaAssetType = "video" + // MediaAssetTypeAudio is a MediaAssetType of type Audio. + MediaAssetTypeAudio MediaAssetType = "audio" + // MediaAssetTypeDocument is a MediaAssetType of type Document. + MediaAssetTypeDocument MediaAssetType = "document" + // MediaAssetTypeOther is a MediaAssetType of type Other. + MediaAssetTypeOther MediaAssetType = "other" +) + +var ErrInvalidMediaAssetType = fmt.Errorf("not a valid MediaAssetType, try [%s]", strings.Join(_MediaAssetTypeNames, ", ")) + +var _MediaAssetTypeNames = []string{ + string(MediaAssetTypeUnknown), + string(MediaAssetTypePoster), + string(MediaAssetTypeImage), + string(MediaAssetTypeVideo), + string(MediaAssetTypeAudio), + string(MediaAssetTypeDocument), + string(MediaAssetTypeOther), +} + +// MediaAssetTypeNames returns a list of possible string values of MediaAssetType. +func MediaAssetTypeNames() []string { + tmp := make([]string, len(_MediaAssetTypeNames)) + copy(tmp, _MediaAssetTypeNames) + return tmp +} + +// MediaAssetTypeValues returns a list of the values for MediaAssetType +func MediaAssetTypeValues() []MediaAssetType { + return []MediaAssetType{ + MediaAssetTypeUnknown, + MediaAssetTypePoster, + MediaAssetTypeImage, + MediaAssetTypeVideo, + MediaAssetTypeAudio, + MediaAssetTypeDocument, + MediaAssetTypeOther, + } +} + +// String implements the Stringer interface. +func (x MediaAssetType) String() string { + return string(x) +} + +// IsValid provides a quick way to determine if the typed value is +// part of the allowed enumerated values +func (x MediaAssetType) IsValid() bool { + _, err := ParseMediaAssetType(string(x)) + return err == nil +} + +var _MediaAssetTypeValue = map[string]MediaAssetType{ + "unknown": MediaAssetTypeUnknown, + "poster": MediaAssetTypePoster, + "image": MediaAssetTypeImage, + "video": MediaAssetTypeVideo, + "audio": MediaAssetTypeAudio, + "document": MediaAssetTypeDocument, + "other": MediaAssetTypeOther, +} + +// ParseMediaAssetType attempts to convert a string to a MediaAssetType. +func ParseMediaAssetType(name string) (MediaAssetType, error) { + if x, ok := _MediaAssetTypeValue[name]; ok { + return x, nil + } + return MediaAssetType(""), fmt.Errorf("%s is %w", name, ErrInvalidMediaAssetType) +} + +var errMediaAssetTypeNilPtr = errors.New("value pointer is nil") // one per type for package clashes + +// Scan implements the Scanner interface. +func (x *MediaAssetType) Scan(value interface{}) (err error) { + if value == nil { + *x = MediaAssetType("") + return + } + + // A wider range of scannable types. + // driver.Value values at the top of the list for expediency + switch v := value.(type) { + case string: + *x, err = ParseMediaAssetType(v) + case []byte: + *x, err = ParseMediaAssetType(string(v)) + case MediaAssetType: + *x = v + case *MediaAssetType: + if v == nil { + return errMediaAssetTypeNilPtr + } + *x = *v + case *string: + if v == nil { + return errMediaAssetTypeNilPtr + } + *x, err = ParseMediaAssetType(*v) + default: + return errors.New("invalid type for MediaAssetType") + } + + return +} + +// Value implements the driver Valuer interface. +func (x MediaAssetType) Value() (driver.Value, error) { + return x.String(), nil +} + +// Set implements the Golang flag.Value interface func. +func (x *MediaAssetType) Set(val string) error { + v, err := ParseMediaAssetType(val) + *x = v + return err +} + +// Get implements the Golang flag.Getter interface func. +func (x *MediaAssetType) Get() interface{} { + return *x +} + +// Type implements the github.com/spf13/pFlag Value interface. +func (x *MediaAssetType) Type() string { + return "MediaAssetType" +} + +type NullMediaAssetType struct { + MediaAssetType MediaAssetType + Valid bool +} + +func NewNullMediaAssetType(val interface{}) (x NullMediaAssetType) { + err := x.Scan(val) // yes, we ignore this error, it will just be an invalid value. + _ = err // make any errcheck linters happy + return +} + +// Scan implements the Scanner interface. +func (x *NullMediaAssetType) Scan(value interface{}) (err error) { + if value == nil { + x.MediaAssetType, x.Valid = MediaAssetType(""), false + return + } + + err = x.MediaAssetType.Scan(value) + x.Valid = (err == nil) + return +} + +// Value implements the driver Valuer interface. +func (x NullMediaAssetType) Value() (driver.Value, error) { + if !x.Valid { + return nil, nil + } + // driver.Value accepts int64 for int values. + return string(x.MediaAssetType), nil +} + +type NullMediaAssetTypeStr struct { + NullMediaAssetType +} + +func NewNullMediaAssetTypeStr(val interface{}) (x NullMediaAssetTypeStr) { + x.Scan(val) // yes, we ignore this error, it will just be an invalid value. + return +} + +// Value implements the driver Valuer interface. +func (x NullMediaAssetTypeStr) Value() (driver.Value, error) { + if !x.Valid { + return nil, nil + } + return x.MediaAssetType.String(), nil +} diff --git a/backend/database/fields/medias.go b/backend/database/fields/medias.go new file mode 100644 index 0000000..0aa8726 --- /dev/null +++ b/backend/database/fields/medias.go @@ -0,0 +1,18 @@ +package fields + +type MediaAsset struct { + Type MediaAssetType `json:"type"` + Hash string `json:"hash"` +} + +// swagger:enum MediaAssetType +// ENUM( +// Unknown = "unknown", +// Poster = "poster", +// Image = "image", +// Video = "video", +// Audio = "audio", +// Document = "document", +// Other = "other" +// ) +type MediaAssetType string diff --git a/backend/database/migrations/20250109095933_create_post.sql b/backend/database/migrations/20250109095933_create_post.sql index c6e2e61..11f5a44 100644 --- a/backend/database/migrations/20250109095933_create_post.sql +++ b/backend/database/migrations/20250109095933_create_post.sql @@ -17,13 +17,13 @@ CREATE TABLE title VARCHAR(128) NOT NULL, description VARCHAR(256) NOT NULL, - poster_asset_id INT8 NOT NULL, content TEXT NOT NULL, price INT8 NOT NULL default 0, discount INT2 NOT NULL default 100, views INT8 NOT NULL default 0, likes INT8 NOT NULL default 0, meta jsonb default '{}'::jsonb, + tags jsonb default '{}'::jsonb, assets jsonb default '{}'::jsonb ); -- create indexes diff --git a/backend/database/migrations/20250110093636_create_medias.sql b/backend/database/migrations/20250110093636_create_medias.sql index a333981..c8a09d6 100644 --- a/backend/database/migrations/20250110093636_create_medias.sql +++ b/backend/database/migrations/20250110093636_create_medias.sql @@ -10,8 +10,8 @@ CREATE TABLE medias ( user_id INT8 NOT NULL, post_id INT8 NOT NULL, storage_id INT8 NOT NULL, + hash VARCHAR(32) NOT NULL, name VARCHAR(255) NOT NULL default '', - uuid VARCHAR(128) NOT NULL, mime_type VARCHAR(128) NOT NULL default '', size INT8 NOT NULL default 0, path VARCHAR(255) NOT NULL default '' diff --git a/backend/database/models/qvyun_v2/public/model/medias.go b/backend/database/models/qvyun_v2/public/model/medias.go index a81787a..894ee62 100644 --- a/backend/database/models/qvyun_v2/public/model/medias.go +++ b/backend/database/models/qvyun_v2/public/model/medias.go @@ -19,8 +19,8 @@ type Medias struct { UserID int64 `json:"user_id"` PostID int64 `json:"post_id"` StorageID int64 `json:"storage_id"` + Hash string `json:"hash"` Name string `json:"name"` - UUID string `json:"uuid"` MimeType string `json:"mime_type"` Size int64 `json:"size"` Path string `json:"path"` diff --git a/backend/database/models/qvyun_v2/public/model/posts.go b/backend/database/models/qvyun_v2/public/model/posts.go index 2e09b23..d2a189c 100644 --- a/backend/database/models/qvyun_v2/public/model/posts.go +++ b/backend/database/models/qvyun_v2/public/model/posts.go @@ -13,23 +13,23 @@ import ( ) type Posts struct { - ID int64 `sql:"primary_key" json:"id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - DeletedAt *time.Time `json:"deleted_at"` - Type fields.PostType `json:"type"` - Stage fields.PostStage `json:"stage"` - Status fields.PostStatus `json:"status"` - TenantID int64 `json:"tenant_id"` - UserID int64 `json:"user_id"` - Title string `json:"title"` - Description string `json:"description"` - PosterAssetID int64 `json:"poster_asset_id"` - Content string `json:"content"` - Price int64 `json:"price"` - Discount int16 `json:"discount"` - Views int64 `json:"views"` - Likes int64 `json:"likes"` - Meta *string `json:"meta"` - Assets *string `json:"assets"` + ID int64 `sql:"primary_key" json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt *time.Time `json:"deleted_at"` + Type fields.PostType `json:"type"` + Stage fields.PostStage `json:"stage"` + Status fields.PostStatus `json:"status"` + TenantID int64 `json:"tenant_id"` + UserID int64 `json:"user_id"` + Title string `json:"title"` + Description string `json:"description"` + Content string `json:"content"` + Price int64 `json:"price"` + Discount int16 `json:"discount"` + Views int64 `json:"views"` + Likes int64 `json:"likes"` + Meta *string `json:"meta"` + Tags fields.Json[[]string] `json:"tags"` + Assets fields.Json[[]fields.MediaAsset] `json:"assets"` } diff --git a/backend/database/models/qvyun_v2/public/table/medias.go b/backend/database/models/qvyun_v2/public/table/medias.go index 0a3c67c..ebfd34d 100644 --- a/backend/database/models/qvyun_v2/public/table/medias.go +++ b/backend/database/models/qvyun_v2/public/table/medias.go @@ -24,8 +24,8 @@ type mediasTable struct { UserID postgres.ColumnInteger PostID postgres.ColumnInteger StorageID postgres.ColumnInteger + Hash postgres.ColumnString Name postgres.ColumnString - UUID postgres.ColumnString MimeType postgres.ColumnString Size postgres.ColumnInteger Path postgres.ColumnString @@ -76,13 +76,13 @@ func newMediasTableImpl(schemaName, tableName, alias string) mediasTable { UserIDColumn = postgres.IntegerColumn("user_id") PostIDColumn = postgres.IntegerColumn("post_id") StorageIDColumn = postgres.IntegerColumn("storage_id") + HashColumn = postgres.StringColumn("hash") NameColumn = postgres.StringColumn("name") - UUIDColumn = postgres.StringColumn("uuid") MimeTypeColumn = postgres.StringColumn("mime_type") SizeColumn = postgres.IntegerColumn("size") PathColumn = postgres.StringColumn("path") - allColumns = postgres.ColumnList{IDColumn, CreatedAtColumn, UpdatedAtColumn, TenantIDColumn, UserIDColumn, PostIDColumn, StorageIDColumn, NameColumn, UUIDColumn, MimeTypeColumn, SizeColumn, PathColumn} - mutableColumns = postgres.ColumnList{CreatedAtColumn, UpdatedAtColumn, TenantIDColumn, UserIDColumn, PostIDColumn, StorageIDColumn, NameColumn, UUIDColumn, MimeTypeColumn, SizeColumn, PathColumn} + allColumns = postgres.ColumnList{IDColumn, CreatedAtColumn, UpdatedAtColumn, TenantIDColumn, UserIDColumn, PostIDColumn, StorageIDColumn, HashColumn, NameColumn, MimeTypeColumn, SizeColumn, PathColumn} + mutableColumns = postgres.ColumnList{CreatedAtColumn, UpdatedAtColumn, TenantIDColumn, UserIDColumn, PostIDColumn, StorageIDColumn, HashColumn, NameColumn, MimeTypeColumn, SizeColumn, PathColumn} ) return mediasTable{ @@ -96,8 +96,8 @@ func newMediasTableImpl(schemaName, tableName, alias string) mediasTable { UserID: UserIDColumn, PostID: PostIDColumn, StorageID: StorageIDColumn, + Hash: HashColumn, Name: NameColumn, - UUID: UUIDColumn, MimeType: MimeTypeColumn, Size: SizeColumn, Path: PathColumn, diff --git a/backend/database/models/qvyun_v2/public/table/posts.go b/backend/database/models/qvyun_v2/public/table/posts.go index 1b3f722..09f5860 100644 --- a/backend/database/models/qvyun_v2/public/table/posts.go +++ b/backend/database/models/qvyun_v2/public/table/posts.go @@ -17,25 +17,25 @@ type postsTable struct { postgres.Table // Columns - ID postgres.ColumnInteger - CreatedAt postgres.ColumnTimestamp - UpdatedAt postgres.ColumnTimestamp - DeletedAt postgres.ColumnTimestamp - Type postgres.ColumnInteger - Stage postgres.ColumnInteger - Status postgres.ColumnInteger - TenantID postgres.ColumnInteger - UserID postgres.ColumnInteger - Title postgres.ColumnString - Description postgres.ColumnString - PosterAssetID postgres.ColumnInteger - Content postgres.ColumnString - Price postgres.ColumnInteger - Discount postgres.ColumnInteger - Views postgres.ColumnInteger - Likes postgres.ColumnInteger - Meta postgres.ColumnString - Assets postgres.ColumnString + ID postgres.ColumnInteger + CreatedAt postgres.ColumnTimestamp + UpdatedAt postgres.ColumnTimestamp + DeletedAt postgres.ColumnTimestamp + Type postgres.ColumnInteger + Stage postgres.ColumnInteger + Status postgres.ColumnInteger + TenantID postgres.ColumnInteger + UserID postgres.ColumnInteger + Title postgres.ColumnString + Description postgres.ColumnString + Content postgres.ColumnString + Price postgres.ColumnInteger + Discount postgres.ColumnInteger + Views postgres.ColumnInteger + Likes postgres.ColumnInteger + Meta postgres.ColumnString + Tags postgres.ColumnString + Assets postgres.ColumnString AllColumns postgres.ColumnList MutableColumns postgres.ColumnList @@ -76,52 +76,52 @@ func newPostsTable(schemaName, tableName, alias string) *PostsTable { func newPostsTableImpl(schemaName, tableName, alias string) postsTable { var ( - IDColumn = postgres.IntegerColumn("id") - CreatedAtColumn = postgres.TimestampColumn("created_at") - UpdatedAtColumn = postgres.TimestampColumn("updated_at") - DeletedAtColumn = postgres.TimestampColumn("deleted_at") - TypeColumn = postgres.IntegerColumn("type") - StageColumn = postgres.IntegerColumn("stage") - StatusColumn = postgres.IntegerColumn("status") - TenantIDColumn = postgres.IntegerColumn("tenant_id") - UserIDColumn = postgres.IntegerColumn("user_id") - TitleColumn = postgres.StringColumn("title") - DescriptionColumn = postgres.StringColumn("description") - PosterAssetIDColumn = postgres.IntegerColumn("poster_asset_id") - ContentColumn = postgres.StringColumn("content") - PriceColumn = postgres.IntegerColumn("price") - DiscountColumn = postgres.IntegerColumn("discount") - ViewsColumn = postgres.IntegerColumn("views") - LikesColumn = postgres.IntegerColumn("likes") - MetaColumn = postgres.StringColumn("meta") - AssetsColumn = postgres.StringColumn("assets") - allColumns = postgres.ColumnList{IDColumn, CreatedAtColumn, UpdatedAtColumn, DeletedAtColumn, TypeColumn, StageColumn, StatusColumn, TenantIDColumn, UserIDColumn, TitleColumn, DescriptionColumn, PosterAssetIDColumn, ContentColumn, PriceColumn, DiscountColumn, ViewsColumn, LikesColumn, MetaColumn, AssetsColumn} - mutableColumns = postgres.ColumnList{CreatedAtColumn, UpdatedAtColumn, DeletedAtColumn, TypeColumn, StageColumn, StatusColumn, TenantIDColumn, UserIDColumn, TitleColumn, DescriptionColumn, PosterAssetIDColumn, ContentColumn, PriceColumn, DiscountColumn, ViewsColumn, LikesColumn, MetaColumn, AssetsColumn} + IDColumn = postgres.IntegerColumn("id") + CreatedAtColumn = postgres.TimestampColumn("created_at") + UpdatedAtColumn = postgres.TimestampColumn("updated_at") + DeletedAtColumn = postgres.TimestampColumn("deleted_at") + TypeColumn = postgres.IntegerColumn("type") + StageColumn = postgres.IntegerColumn("stage") + StatusColumn = postgres.IntegerColumn("status") + TenantIDColumn = postgres.IntegerColumn("tenant_id") + UserIDColumn = postgres.IntegerColumn("user_id") + TitleColumn = postgres.StringColumn("title") + DescriptionColumn = postgres.StringColumn("description") + ContentColumn = postgres.StringColumn("content") + PriceColumn = postgres.IntegerColumn("price") + DiscountColumn = postgres.IntegerColumn("discount") + ViewsColumn = postgres.IntegerColumn("views") + LikesColumn = postgres.IntegerColumn("likes") + MetaColumn = postgres.StringColumn("meta") + TagsColumn = postgres.StringColumn("tags") + AssetsColumn = postgres.StringColumn("assets") + allColumns = postgres.ColumnList{IDColumn, CreatedAtColumn, UpdatedAtColumn, DeletedAtColumn, TypeColumn, StageColumn, StatusColumn, TenantIDColumn, UserIDColumn, TitleColumn, DescriptionColumn, ContentColumn, PriceColumn, DiscountColumn, ViewsColumn, LikesColumn, MetaColumn, TagsColumn, AssetsColumn} + mutableColumns = postgres.ColumnList{CreatedAtColumn, UpdatedAtColumn, DeletedAtColumn, TypeColumn, StageColumn, StatusColumn, TenantIDColumn, UserIDColumn, TitleColumn, DescriptionColumn, ContentColumn, PriceColumn, DiscountColumn, ViewsColumn, LikesColumn, MetaColumn, TagsColumn, AssetsColumn} ) return postsTable{ Table: postgres.NewTable(schemaName, tableName, alias, allColumns...), //Columns - ID: IDColumn, - CreatedAt: CreatedAtColumn, - UpdatedAt: UpdatedAtColumn, - DeletedAt: DeletedAtColumn, - Type: TypeColumn, - Stage: StageColumn, - Status: StatusColumn, - TenantID: TenantIDColumn, - UserID: UserIDColumn, - Title: TitleColumn, - Description: DescriptionColumn, - PosterAssetID: PosterAssetIDColumn, - Content: ContentColumn, - Price: PriceColumn, - Discount: DiscountColumn, - Views: ViewsColumn, - Likes: LikesColumn, - Meta: MetaColumn, - Assets: AssetsColumn, + ID: IDColumn, + CreatedAt: CreatedAtColumn, + UpdatedAt: UpdatedAtColumn, + DeletedAt: DeletedAtColumn, + Type: TypeColumn, + Stage: StageColumn, + Status: StatusColumn, + TenantID: TenantIDColumn, + UserID: UserIDColumn, + Title: TitleColumn, + Description: DescriptionColumn, + Content: ContentColumn, + Price: PriceColumn, + Discount: DiscountColumn, + Views: ViewsColumn, + Likes: LikesColumn, + Meta: MetaColumn, + Tags: TagsColumn, + Assets: AssetsColumn, AllColumns: allColumns, MutableColumns: mutableColumns, diff --git a/backend/database/transform.yaml b/backend/database/transform.yaml index 2c0578a..a51d62d 100644 --- a/backend/database/transform.yaml +++ b/backend/database/transform.yaml @@ -20,6 +20,8 @@ types: stage: PostStage status: PostStatus type: PostType + assets: Json[[]MediaAsset] + tags: Json[[]string] orders: type: OrderType