redeem_code.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package schema
  2. import (
  3. "time"
  4. "github.com/Wei-Shaw/sub2api/internal/domain"
  5. "entgo.io/ent"
  6. "entgo.io/ent/dialect"
  7. "entgo.io/ent/dialect/entsql"
  8. "entgo.io/ent/schema"
  9. "entgo.io/ent/schema/edge"
  10. "entgo.io/ent/schema/field"
  11. "entgo.io/ent/schema/index"
  12. )
  13. // RedeemCode holds the schema definition for the RedeemCode entity.
  14. //
  15. // 删除策略:硬删除
  16. // RedeemCode 使用硬删除而非软删除,原因如下:
  17. // - 兑换码具有一次性使用特性,删除后无需保留历史记录
  18. // - 已使用的兑换码通过 status 和 used_at 字段追踪,无需依赖软删除
  19. // - 减少数据库存储压力和查询复杂度
  20. //
  21. // 如需审计已删除的兑换码,建议在删除前将关键信息写入审计日志表。
  22. type RedeemCode struct {
  23. ent.Schema
  24. }
  25. func (RedeemCode) Annotations() []schema.Annotation {
  26. return []schema.Annotation{
  27. entsql.Annotation{Table: "redeem_codes"},
  28. }
  29. }
  30. func (RedeemCode) Fields() []ent.Field {
  31. return []ent.Field{
  32. field.String("code").
  33. MaxLen(32).
  34. NotEmpty().
  35. Unique(),
  36. field.String("type").
  37. MaxLen(20).
  38. Default(domain.RedeemTypeBalance),
  39. field.Float("value").
  40. SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
  41. Default(0),
  42. field.String("status").
  43. MaxLen(20).
  44. Default(domain.StatusUnused),
  45. field.Int64("used_by").
  46. Optional().
  47. Nillable(),
  48. field.Time("used_at").
  49. Optional().
  50. Nillable().
  51. SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
  52. field.String("notes").
  53. Optional().
  54. Nillable().
  55. SchemaType(map[string]string{dialect.Postgres: "text"}),
  56. field.Time("created_at").
  57. Immutable().
  58. Default(time.Now).
  59. SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
  60. field.Time("expires_at").
  61. Optional().
  62. Nillable().
  63. SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
  64. field.Int64("group_id").
  65. Optional().
  66. Nillable(),
  67. field.Int("validity_days").
  68. Default(30),
  69. }
  70. }
  71. func (RedeemCode) Edges() []ent.Edge {
  72. return []ent.Edge{
  73. edge.From("user", User.Type).
  74. Ref("redeem_codes").
  75. Field("used_by").
  76. Unique(),
  77. edge.From("group", Group.Type).
  78. Ref("redeem_codes").
  79. Field("group_id").
  80. Unique(),
  81. }
  82. }
  83. func (RedeemCode) Indexes() []ent.Index {
  84. return []ent.Index{
  85. // code 字段已在 Fields() 中声明 Unique(),无需重复索引
  86. index.Fields("status"),
  87. index.Fields("used_by"),
  88. index.Fields("group_id"),
  89. index.Fields("expires_at"),
  90. }
  91. }