package schema import ( "time" "github.com/Wei-Shaw/sub2api/ent/schema/mixins" "github.com/Wei-Shaw/sub2api/internal/service" "entgo.io/ent" "entgo.io/ent/dialect" "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" ) // UserSubscription holds the schema definition for the UserSubscription entity. type UserSubscription struct { ent.Schema } func (UserSubscription) Annotations() []schema.Annotation { return []schema.Annotation{ entsql.Annotation{Table: "user_subscriptions"}, } } func (UserSubscription) Mixin() []ent.Mixin { return []ent.Mixin{ mixins.TimeMixin{}, mixins.SoftDeleteMixin{}, } } func (UserSubscription) Fields() []ent.Field { return []ent.Field{ field.Int64("user_id"), field.Int64("group_id"), field.Time("starts_at"). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.Time("expires_at"). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.String("status"). MaxLen(20). Default(service.SubscriptionStatusActive), field.Time("daily_window_start"). Optional(). Nillable(). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.Time("weekly_window_start"). Optional(). Nillable(). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.Time("monthly_window_start"). Optional(). Nillable(). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.Float("daily_usage_usd"). SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}). Default(0), field.Float("weekly_usage_usd"). SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}). Default(0), field.Float("monthly_usage_usd"). SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}). Default(0), field.Int64("assigned_by"). Optional(). Nillable(), field.Time("assigned_at"). Default(time.Now). SchemaType(map[string]string{dialect.Postgres: "timestamptz"}), field.String("notes"). Optional(). Nillable(). SchemaType(map[string]string{dialect.Postgres: "text"}), } } func (UserSubscription) Edges() []ent.Edge { return []ent.Edge{ edge.From("user", User.Type). Ref("subscriptions"). Field("user_id"). Unique(). Required(), edge.From("group", Group.Type). Ref("subscriptions"). Field("group_id"). Unique(). Required(), edge.From("assigned_by_user", User.Type). Ref("assigned_subscriptions"). Field("assigned_by"). Unique(), edge.To("usage_logs", UsageLog.Type), } } func (UserSubscription) Indexes() []ent.Index { return []ent.Index{ index.Fields("user_id"), index.Fields("group_id"), index.Fields("status"), index.Fields("expires_at"), index.Fields("assigned_by"), // 唯一约束通过部分索引实现(WHERE deleted_at IS NULL),支持软删除后重新订阅 // 见迁移文件 016_soft_delete_partial_unique_indexes.sql index.Fields("user_id", "group_id"), index.Fields("deleted_at"), } }