user_attribute_definition.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package schema
  2. import (
  3. "github.com/Wei-Shaw/sub2api/ent/schema/mixins"
  4. "entgo.io/ent"
  5. "entgo.io/ent/dialect"
  6. "entgo.io/ent/dialect/entsql"
  7. "entgo.io/ent/schema"
  8. "entgo.io/ent/schema/edge"
  9. "entgo.io/ent/schema/field"
  10. "entgo.io/ent/schema/index"
  11. )
  12. // UserAttributeDefinition holds the schema definition for custom user attributes.
  13. //
  14. // This entity defines the metadata for user attributes, such as:
  15. // - Attribute key (unique identifier like "company_name")
  16. // - Display name shown in forms
  17. // - Field type (text, number, select, etc.)
  18. // - Validation rules
  19. // - Whether the field is required or enabled
  20. type UserAttributeDefinition struct {
  21. ent.Schema
  22. }
  23. func (UserAttributeDefinition) Annotations() []schema.Annotation {
  24. return []schema.Annotation{
  25. entsql.Annotation{Table: "user_attribute_definitions"},
  26. }
  27. }
  28. func (UserAttributeDefinition) Mixin() []ent.Mixin {
  29. return []ent.Mixin{
  30. mixins.TimeMixin{},
  31. mixins.SoftDeleteMixin{},
  32. }
  33. }
  34. func (UserAttributeDefinition) Fields() []ent.Field {
  35. return []ent.Field{
  36. // key: Unique identifier for the attribute (e.g., "company_name")
  37. // Used for programmatic reference
  38. field.String("key").
  39. MaxLen(100).
  40. NotEmpty(),
  41. // name: Display name shown in forms (e.g., "Company Name")
  42. field.String("name").
  43. MaxLen(255).
  44. NotEmpty(),
  45. // description: Optional description/help text for the attribute
  46. field.String("description").
  47. SchemaType(map[string]string{dialect.Postgres: "text"}).
  48. Default(""),
  49. // type: Attribute type - text, textarea, number, email, url, date, select, multi_select
  50. field.String("type").
  51. MaxLen(20).
  52. NotEmpty(),
  53. // options: Select options for select/multi_select types (stored as JSONB)
  54. // Format: [{"value": "xxx", "label": "XXX"}, ...]
  55. field.JSON("options", []map[string]any{}).
  56. Default([]map[string]any{}).
  57. SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
  58. // required: Whether this attribute is required when editing a user
  59. field.Bool("required").
  60. Default(false),
  61. // validation: Validation rules for the attribute value (stored as JSONB)
  62. // Format: {"min_length": 1, "max_length": 100, "min": 0, "max": 100, "pattern": "^[a-z]+$", "message": "..."}
  63. field.JSON("validation", map[string]any{}).
  64. Default(map[string]any{}).
  65. SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
  66. // placeholder: Placeholder text shown in input fields
  67. field.String("placeholder").
  68. MaxLen(255).
  69. Default(""),
  70. // display_order: Order in which attributes are displayed (lower = first)
  71. field.Int("display_order").
  72. Default(0),
  73. // enabled: Whether this attribute is active and shown in forms
  74. field.Bool("enabled").
  75. Default(true),
  76. }
  77. }
  78. func (UserAttributeDefinition) Edges() []ent.Edge {
  79. return []ent.Edge{
  80. // values: All user values for this attribute definition
  81. edge.To("values", UserAttributeValue.Type),
  82. }
  83. }
  84. func (UserAttributeDefinition) Indexes() []ent.Index {
  85. return []ent.Index{
  86. // Partial unique index on key (WHERE deleted_at IS NULL) via migration
  87. index.Fields("key"),
  88. index.Fields("enabled"),
  89. index.Fields("display_order"),
  90. index.Fields("deleted_at"),
  91. }
  92. }