[feature] migrate to monorepo
Some checks failed
Build Backend / Build Docker Image (push) Successful in 3m33s
Test Backend / test (push) Failing after 31s

This commit is contained in:
CDN 2025-02-21 00:49:20 +08:00
commit 05ddc1f783
Signed by: CDN
GPG key ID: 0C656827F9F80080
267 changed files with 75165 additions and 0 deletions

View file

@ -0,0 +1,33 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
)
// Category holds the schema definition for the Category entity.
type Category struct {
ent.Schema
}
// Fields of the Category.
func (Category) Fields() []ent.Field {
return []ent.Field{
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Category.
func (Category) Edges() []ent.Edge {
return []ent.Edge{
edge.To("contents", CategoryContent.Type),
edge.To("posts", Post.Type),
edge.To("daily_items", Daily.Type),
}
}

View file

@ -0,0 +1,51 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/index"
)
// CategoryContent holds the schema definition for the CategoryContent entity.
type CategoryContent struct {
ent.Schema
}
// Fields of the CategoryContent.
func (CategoryContent) Fields() []ent.Field {
return []ent.Field{
field.Enum("language_code").
NamedValues(
"EN", "en",
"ZH_HANS", "zh-Hans",
"ZH_HANT", "zh-Hant",
),
field.String("name").
NotEmpty(),
field.String("description").
Optional(),
field.String("slug").
NotEmpty(),
}
}
// Edges of the CategoryContent.
func (CategoryContent) Edges() []ent.Edge {
return []ent.Edge{
edge.From("category", Category.Type).
Ref("contents").
Unique(),
}
}
// Indexes of the CategoryContent.
func (CategoryContent) Indexes() []ent.Index {
return []ent.Index{
index.Fields("language_code", "slug").
Unique(),
index.Fields("language_code").
Edges("category").
Unique(),
}
}

View file

@ -0,0 +1,41 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
)
// Contributor holds the schema definition for the Contributor entity.
type Contributor struct {
ent.Schema
}
// Fields of the Contributor.
func (Contributor) Fields() []ent.Field {
return []ent.Field{
field.String("name").
NotEmpty(),
field.String("avatar_url").
Optional(),
field.Text("bio").
Optional(),
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Contributor.
func (Contributor) Edges() []ent.Edge {
return []ent.Edge{
edge.From("user", User.Type).
Ref("contributors").
Unique(),
edge.To("social_links", ContributorSocialLink.Type),
edge.To("posts", PostContributor.Type),
}
}

View file

@ -0,0 +1,43 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"fmt"
)
// ContributorRole holds the schema definition for the ContributorRole entity.
type ContributorRole struct {
ent.Schema
}
// Fields of the ContributorRole.
func (ContributorRole) Fields() []ent.Field {
return []ent.Field{
field.String("name").
Unique().
NotEmpty().
Validate(func(s string) error {
// 检查是否是默认角色之一
validRoles := map[string]bool{
"submitter": true,
"author": true,
"reviewer": true,
"translator": true,
"translation_reviewer": true,
}
if !validRoles[s] {
return fmt.Errorf("invalid role name: %s", s)
}
return nil
}),
}
}
// Edges of the ContributorRole.
func (ContributorRole) Edges() []ent.Edge {
return []ent.Edge{
edge.To("post_contributors", PostContributor.Type),
}
}

View file

@ -0,0 +1,40 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
)
// ContributorSocialLink holds the schema definition for the ContributorSocialLink entity.
type ContributorSocialLink struct {
ent.Schema
}
// Fields of the ContributorSocialLink.
func (ContributorSocialLink) Fields() []ent.Field {
return []ent.Field{
field.Enum("type").
NamedValues(
"TWITTER", "twitter",
"FACEBOOK", "facebook",
"INSTAGRAM", "instagram",
"LINKEDIN", "linkedin",
"GITHUB", "github",
"WEBSITE", "website",
),
field.String("name").
Optional(),
field.String("value").
NotEmpty(),
}
}
// Edges of the ContributorSocialLink.
func (ContributorSocialLink) Edges() []ent.Edge {
return []ent.Edge{
edge.From("contributor", Contributor.Type).
Ref("social_links").
Unique(),
}
}

View file

@ -0,0 +1,45 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
"regexp"
)
// Daily holds the schema definition for the Daily entity.
type Daily struct {
ent.Schema
}
// Fields of the Daily.
func (Daily) Fields() []ent.Field {
return []ent.Field{
field.String("id").
Match(regexp.MustCompile(`^[0-9]{6}$`)).
Unique().
Immutable().
NotEmpty().
MaxLen(6).
MinLen(6),
field.String("image_url").
NotEmpty(),
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Daily.
func (Daily) Edges() []ent.Edge {
return []ent.Edge{
edge.From("category", Category.Type).
Ref("daily_items").
Unique().
Required(),
edge.To("contents", DailyContent.Type),
}
}

View file

@ -0,0 +1,32 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
)
// DailyCategory holds the schema definition for the DailyCategory entity.
type DailyCategory struct {
ent.Schema
}
// Fields of the DailyCategory.
func (DailyCategory) Fields() []ent.Field {
return []ent.Field{
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the DailyCategory.
func (DailyCategory) Edges() []ent.Edge {
return []ent.Edge{
edge.To("contents", DailyCategoryContent.Type),
edge.To("daily_items", Daily.Type),
}
}

View file

@ -0,0 +1,41 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/index"
)
// DailyCategoryContent holds the schema definition for the DailyCategoryContent entity.
type DailyCategoryContent struct {
ent.Schema
}
// Fields of the DailyCategoryContent.
func (DailyCategoryContent) Fields() []ent.Field {
return []ent.Field{
field.Enum("language_code").
Values("en", "zh-Hans", "zh-Hant"),
field.String("name").
NotEmpty(),
}
}
// Edges of the DailyCategoryContent.
func (DailyCategoryContent) Edges() []ent.Edge {
return []ent.Edge{
edge.From("category", DailyCategory.Type).
Ref("contents").
Unique(),
}
}
// Indexes of the DailyCategoryContent.
func (DailyCategoryContent) Indexes() []ent.Index {
return []ent.Index{
index.Fields("language_code").
Edges("category").
Unique(),
}
}

View file

@ -0,0 +1,45 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/index"
)
// DailyContent holds the schema definition for the DailyContent entity.
type DailyContent struct {
ent.Schema
}
// Fields of the DailyContent.
func (DailyContent) Fields() []ent.Field {
return []ent.Field{
field.Enum("language_code").
NamedValues(
"EN", "en",
"ZH_HANS", "zh-Hans",
"ZH_HANT", "zh-Hant",
),
field.Text("quote").
NotEmpty(),
}
}
// Edges of the DailyContent.
func (DailyContent) Edges() []ent.Edge {
return []ent.Edge{
edge.From("daily", Daily.Type).
Ref("contents").
Unique(),
}
}
// Indexes of the DailyContent.
func (DailyContent) Indexes() []ent.Index {
return []ent.Index{
index.Fields("language_code").
Edges("daily").
Unique(),
}
}

View file

@ -0,0 +1,47 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
)
// Media holds the schema definition for the Media entity.
type Media struct {
ent.Schema
}
// Fields of the Media.
func (Media) Fields() []ent.Field {
return []ent.Field{
field.String("storage_id").
NotEmpty().
Unique(),
field.String("original_name").
NotEmpty(),
field.String("mime_type").
NotEmpty(),
field.Int64("size").
Positive(),
field.String("url").
NotEmpty(),
field.Time("created_at").
Default(time.Now).
Immutable(),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
field.String("created_by").
Optional(),
}
}
// Edges of the Media.
func (Media) Edges() []ent.Edge {
return []ent.Edge{
edge.From("owner", User.Type).
Ref("media").
Unique(),
}
}

View file

@ -0,0 +1,52 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
"time"
)
// Permission holds the schema definition for the Permission entity.
type Permission struct {
ent.Schema
}
// Fields of the Permission.
func (Permission) Fields() []ent.Field {
return []ent.Field{
field.String("resource").
NotEmpty().
Comment("Resource name, e.g., 'media', 'post'"),
field.String("action").
NotEmpty().
Comment("Action name, e.g., 'create', 'read', 'update', 'delete'"),
field.String("description").
Optional().
Comment("Human readable description of the permission"),
field.Time("created_at").
Default(time.Now).
Immutable(),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Permission.
func (Permission) Edges() []ent.Edge {
return []ent.Edge{
edge.From("roles", Role.Type).
Ref("permissions"),
}
}
// Indexes of the Permission.
func (Permission) Indexes() []ent.Index {
return []ent.Index{
// Create a unique index on resource and action
index.Fields("resource", "action").
Unique(),
}
}

View file

@ -0,0 +1,41 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"time"
)
// Post holds the schema definition for the Post entity.
type Post struct {
ent.Schema
}
// Fields of the Post.
func (Post) Fields() []ent.Field {
return []ent.Field{
field.Enum("status").
Values("draft", "published", "archived").
Default("draft"),
field.String("slug").
NotEmpty().
Unique(),
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Post.
func (Post) Edges() []ent.Edge {
return []ent.Edge{
edge.To("contents", PostContent.Type),
edge.To("contributors", PostContributor.Type),
edge.From("category", Category.Type).
Ref("posts").
Unique(),
}
}

View file

@ -0,0 +1,55 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/index"
)
// PostContent holds the schema definition for the PostContent entity.
type PostContent struct {
ent.Schema
}
// Fields of the PostContent.
func (PostContent) Fields() []ent.Field {
return []ent.Field{
field.Enum("language_code").
NamedValues(
"EN", "en",
"ZH_HANS", "zh-Hans",
"ZH_HANT", "zh-Hant",
),
field.String("title").
NotEmpty(),
field.Text("content_markdown").
NotEmpty(),
field.String("summary").
NotEmpty(),
field.String("meta_keywords").
Optional(),
field.String("meta_description").
Optional(),
field.String("slug").
NotEmpty(),
}
}
// Edges of the PostContent.
func (PostContent) Edges() []ent.Edge {
return []ent.Edge{
edge.From("post", Post.Type).
Ref("contents").
Unique(),
}
}
// Indexes of the PostContent.
func (PostContent) Indexes() []ent.Index {
return []ent.Index{
index.Fields("language_code").
Edges("post").
Unique(),
}
}

View file

@ -0,0 +1,50 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/index"
"time"
)
// PostContributor holds the schema definition for the PostContributor entity.
type PostContributor struct {
ent.Schema
}
// Fields of the PostContributor.
func (PostContributor) Fields() []ent.Field {
return []ent.Field{
field.Enum("language_code").
Values("en", "zh-Hans", "zh-Hant").
Optional().
Nillable(),
field.Time("created_at").
Default(time.Now),
}
}
// Edges of the PostContributor.
func (PostContributor) Edges() []ent.Edge {
return []ent.Edge{
edge.From("post", Post.Type).
Ref("contributors").
Unique(),
edge.From("contributor", Contributor.Type).
Ref("posts").
Unique(),
edge.From("role", ContributorRole.Type).
Ref("post_contributors").
Unique(),
}
}
// Indexes of the PostContributor.
func (PostContributor) Indexes() []ent.Index {
return []ent.Index{
index.Fields("language_code").
Edges("post", "contributor", "role").
Unique(),
}
}

View file

@ -0,0 +1,41 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"time"
)
// Role holds the schema definition for the Role entity.
type Role struct {
ent.Schema
}
// Fields of the Role.
func (Role) Fields() []ent.Field {
return []ent.Field{
field.String("name").
Unique().
NotEmpty().
Comment("Role name, e.g., 'admin', 'editor'"),
field.String("description").
Optional().
Comment("Human readable description of the role"),
field.Time("created_at").
Default(time.Now).
Immutable(),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the Role.
func (Role) Edges() []ent.Edge {
return []ent.Edge{
edge.To("permissions", Permission.Type),
edge.From("users", User.Type).
Ref("roles"),
}
}

View file

@ -0,0 +1,42 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"time"
)
// User holds the schema definition for the User entity.
type User struct {
ent.Schema
}
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("email").
Unique().
NotEmpty(),
field.String("password_hash").
Sensitive().
NotEmpty(),
field.Enum("status").
Values("active", "inactive", "banned").
Default("active"),
field.Time("created_at").
Default(time.Now),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now),
}
}
// Edges of the User.
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("roles", Role.Type),
edge.To("contributors", Contributor.Type),
edge.To("media", Media.Type),
}
}