forked from mirrors/homebox
feat: Notifiers CRUD (#337)
* introduce scaffold for new models * wip: shoutrrr wrapper (may remove) * update schema files * gen: ent code * gen: migrations * go mod tidy * add group_id to notifier * db migration * new mapper helpers * notifier repo * introduce experimental adapter pattern for hdlrs * refactor adapters to fit more common use cases * new routes for notifiers * update errors to fix validation panic * go tidy * reverse checkbox label display * wip: notifiers UI * use badges instead of text * improve documentation * add scaffold schema reference * remove notifier service * refactor schema folder * support group edges via scaffold * delete test file * include link to API docs * audit and update documentation + improve format * refactor schema edges * refactor * add custom validator * set validate + order fields by name * fix failing tests
This commit is contained in:
parent
2665b666f1
commit
23b5892aef
100 changed files with 11437 additions and 2075 deletions
|
@ -16,6 +16,7 @@ type Document struct {
|
|||
func (Document) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
GroupMixin{ref: "documents"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,10 +35,6 @@ func (Document) Fields() []ent.Field {
|
|||
// Edges of the Document.
|
||||
func (Document) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("group", Group.Type).
|
||||
Ref("documents").
|
||||
Required().
|
||||
Unique(),
|
||||
edge.To("attachments", Attachment.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/mixin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||
)
|
||||
|
||||
|
@ -33,30 +35,53 @@ func (Group) Fields() []ent.Field {
|
|||
|
||||
// Edges of the Home.
|
||||
func (Group) Edges() []ent.Edge {
|
||||
owned := func(name string, t any) ent.Edge {
|
||||
return edge.To(name, t).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
})
|
||||
}
|
||||
|
||||
return []ent.Edge{
|
||||
edge.To("users", User.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("locations", Location.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("items", Item.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("labels", Label.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("documents", Document.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("invitation_tokens", GroupInvitationToken.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
owned("users", User.Type),
|
||||
owned("locations", Location.Type),
|
||||
owned("items", Item.Type),
|
||||
owned("labels", Label.Type),
|
||||
owned("documents", Document.Type),
|
||||
owned("invitation_tokens", GroupInvitationToken.Type),
|
||||
owned("notifiers", Notifier.Type),
|
||||
// $scaffold_edge
|
||||
}
|
||||
}
|
||||
|
||||
// GroupMixin when embedded in an ent.Schema, adds a reference to
|
||||
// the Group entity.
|
||||
type GroupMixin struct {
|
||||
ref string
|
||||
field string
|
||||
mixin.Schema
|
||||
}
|
||||
|
||||
func (g GroupMixin) Fields() []ent.Field {
|
||||
if g.field != "" {
|
||||
return []ent.Field{
|
||||
field.UUID(g.field, uuid.UUID{}),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (g GroupMixin) Edges() []ent.Edge {
|
||||
edge := edge.From("group", Group.Type).
|
||||
Ref(g.ref).
|
||||
Unique().
|
||||
Required()
|
||||
|
||||
if g.field != "" {
|
||||
edge = edge.Field(g.field)
|
||||
}
|
||||
|
||||
return []ent.Edge{edge}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ func (Item) Mixin() []ent.Mixin {
|
|||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
mixins.DetailsMixin{},
|
||||
GroupMixin{ref: "items"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,30 +99,24 @@ func (Item) Fields() []ent.Field {
|
|||
|
||||
// Edges of the Item.
|
||||
func (Item) Edges() []ent.Edge {
|
||||
owned := func(s string, t any) ent.Edge {
|
||||
return edge.To(s, t).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
})
|
||||
}
|
||||
|
||||
return []ent.Edge{
|
||||
edge.To("children", Item.Type).
|
||||
From("parent").
|
||||
Unique(),
|
||||
edge.From("group", Group.Type).
|
||||
Ref("items").
|
||||
Required().
|
||||
Unique(),
|
||||
edge.From("label", Label.Type).
|
||||
Ref("items"),
|
||||
edge.From("location", Location.Type).
|
||||
Ref("items").
|
||||
Unique(),
|
||||
edge.To("fields", ItemField.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("maintenance_entries", MaintenanceEntry.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("attachments", Attachment.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
owned("fields", ItemField.Type),
|
||||
owned("maintenance_entries", MaintenanceEntry.Type),
|
||||
owned("attachments", Attachment.Type),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ func (Label) Mixin() []ent.Mixin {
|
|||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
mixins.DetailsMixin{},
|
||||
GroupMixin{ref: "labels"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,10 +32,6 @@ func (Label) Fields() []ent.Field {
|
|||
// Edges of the Label.
|
||||
func (Label) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("group", Group.Type).
|
||||
Ref("labels").
|
||||
Required().
|
||||
Unique(),
|
||||
edge.To("items", Item.Type),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ func (Location) Mixin() []ent.Mixin {
|
|||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
mixins.DetailsMixin{},
|
||||
GroupMixin{ref: "locations"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,10 +31,6 @@ func (Location) Edges() []ent.Edge {
|
|||
edge.To("children", Location.Type).
|
||||
From("parent").
|
||||
Unique(),
|
||||
edge.From("group", Group.Type).
|
||||
Ref("locations").
|
||||
Unique().
|
||||
Required(),
|
||||
edge.To("items", Item.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
|
|
51
backend/internal/data/ent/schema/notifier.go
Executable file
51
backend/internal/data/ent/schema/notifier.go
Executable file
|
@ -0,0 +1,51 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||
)
|
||||
|
||||
type Notifier struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (Notifier) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
GroupMixin{
|
||||
ref: "notifiers",
|
||||
field: "group_id",
|
||||
},
|
||||
UserMixin{
|
||||
ref: "notifiers",
|
||||
field: "user_id",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Fields of the Notifier.
|
||||
func (Notifier) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").
|
||||
MaxLen(255).
|
||||
NotEmpty(),
|
||||
field.String("url").
|
||||
Sensitive().
|
||||
MaxLen(2083). // supposed max length of URL
|
||||
NotEmpty(),
|
||||
field.Bool("is_active").
|
||||
Default(true),
|
||||
}
|
||||
}
|
||||
|
||||
func (Notifier) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("user_id"),
|
||||
index.Fields("user_id", "is_active"),
|
||||
index.Fields("group_id"),
|
||||
index.Fields("group_id", "is_active"),
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import (
|
|||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/mixin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||
)
|
||||
|
||||
|
@ -16,6 +18,7 @@ type User struct {
|
|||
func (User) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
GroupMixin{ref: "users"},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,11 +38,11 @@ func (User) Fields() []ent.Field {
|
|||
Sensitive(),
|
||||
field.Bool("is_superuser").
|
||||
Default(false),
|
||||
field.Bool("superuser").
|
||||
Default(false),
|
||||
field.Enum("role").
|
||||
Default("user").
|
||||
Values("user", "owner"),
|
||||
field.Bool("superuser").
|
||||
Default(false),
|
||||
field.Time("activated_on").
|
||||
Optional(),
|
||||
}
|
||||
|
@ -48,13 +51,45 @@ func (User) Fields() []ent.Field {
|
|||
// Edges of the User.
|
||||
func (User) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("group", Group.Type).
|
||||
Ref("users").
|
||||
Required().
|
||||
Unique(),
|
||||
edge.To("auth_tokens", AuthTokens.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
edge.To("notifiers", Notifier.Type).
|
||||
Annotations(entsql.Annotation{
|
||||
OnDelete: entsql.Cascade,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// UserMixin when embedded in an ent.Schema, adds a reference to
|
||||
// the Group entity.
|
||||
type UserMixin struct {
|
||||
ref string
|
||||
field string
|
||||
mixin.Schema
|
||||
}
|
||||
|
||||
func (g UserMixin) Fields() []ent.Field {
|
||||
if g.field != "" {
|
||||
return []ent.Field{
|
||||
field.UUID(g.field, uuid.UUID{}),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (g UserMixin) Edges() []ent.Edge {
|
||||
edge := edge.From("user", User.Type).
|
||||
Ref(g.ref).
|
||||
Unique().
|
||||
Required()
|
||||
|
||||
if g.field != "" {
|
||||
edge = edge.Field(g.field)
|
||||
}
|
||||
|
||||
return []ent.Edge{edge}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue