Add new view for report counts and invalidated status

Also drop site.version from the primary key.
This commit is contained in:
Eli Ribble 2026-03-12 15:27:36 +00:00
parent 9525363bc8
commit 32dcc50c94
No known key found for this signature in database
23 changed files with 1656 additions and 623 deletions

View file

@ -64,6 +64,8 @@ type PublicreportNuisance struct {
Location null.Val[string] `db:"location" `
AddressNumber string `db:"address_number" `
AddressID null.Val[int32] `db:"address_id" `
Reviewed null.Val[time.Time] `db:"reviewed" `
ReviewerID null.Val[int32] `db:"reviewer_id" `
R publicreportNuisanceR `db:"-" `
}
@ -84,13 +86,14 @@ type publicreportNuisanceR struct {
NotifyPhoneNuisances PublicreportNotifyPhoneNuisanceSlice // publicreport.notify_phone_nuisance.notify_phone_nuisance_nuisance_id_fkey
Address *Address // publicreport.nuisance.nuisance_address_id_fkey
Organization *Organization // publicreport.nuisance.nuisance_organization_id_fkey
ReviewerUser *User // publicreport.nuisance.nuisance_reviewer_id_fkey
Images PublicreportImageSlice // publicreport.nuisance_image.nuisance_image_image_id_fkeypublicreport.nuisance_image.nuisance_image_nuisance_id_fkey
}
func buildPublicreportNuisanceColumns(alias string) publicreportNuisanceColumns {
return publicreportNuisanceColumns{
ColumnsExpr: expr.NewColumnsExpr(
"id", "additional_info", "created", "duration", "source_container", "source_description", "source_stagnant", "public_id", "reporter_email", "reporter_name", "reporter_phone", "address_raw", "status", "organization_id", "source_gutter", "h3cell", "address_country", "address_locality", "address_postal_code", "address_region", "address_street", "is_location_backyard", "is_location_frontyard", "is_location_garden", "is_location_other", "is_location_pool", "map_zoom", "tod_early", "tod_day", "tod_evening", "tod_night", "latlng_accuracy_type", "latlng_accuracy_value", "reporter_contact_consent", "location", "address_number", "address_id",
"id", "additional_info", "created", "duration", "source_container", "source_description", "source_stagnant", "public_id", "reporter_email", "reporter_name", "reporter_phone", "address_raw", "status", "organization_id", "source_gutter", "h3cell", "address_country", "address_locality", "address_postal_code", "address_region", "address_street", "is_location_backyard", "is_location_frontyard", "is_location_garden", "is_location_other", "is_location_pool", "map_zoom", "tod_early", "tod_day", "tod_evening", "tod_night", "latlng_accuracy_type", "latlng_accuracy_value", "reporter_contact_consent", "location", "address_number", "address_id", "reviewed", "reviewer_id",
).WithParent("publicreport.nuisance"),
tableAlias: alias,
ID: psql.Quote(alias, "id"),
@ -130,6 +133,8 @@ func buildPublicreportNuisanceColumns(alias string) publicreportNuisanceColumns
Location: psql.Quote(alias, "location"),
AddressNumber: psql.Quote(alias, "address_number"),
AddressID: psql.Quote(alias, "address_id"),
Reviewed: psql.Quote(alias, "reviewed"),
ReviewerID: psql.Quote(alias, "reviewer_id"),
}
}
@ -173,6 +178,8 @@ type publicreportNuisanceColumns struct {
Location psql.Expression
AddressNumber psql.Expression
AddressID psql.Expression
Reviewed psql.Expression
ReviewerID psql.Expression
}
func (c publicreportNuisanceColumns) Alias() string {
@ -224,10 +231,12 @@ type PublicreportNuisanceSetter struct {
Location omitnull.Val[string] `db:"location" `
AddressNumber omit.Val[string] `db:"address_number" `
AddressID omitnull.Val[int32] `db:"address_id" `
Reviewed omitnull.Val[time.Time] `db:"reviewed" `
ReviewerID omitnull.Val[int32] `db:"reviewer_id" `
}
func (s PublicreportNuisanceSetter) SetColumns() []string {
vals := make([]string, 0, 37)
vals := make([]string, 0, 39)
if s.ID.IsValue() {
vals = append(vals, "id")
}
@ -339,6 +348,12 @@ func (s PublicreportNuisanceSetter) SetColumns() []string {
if !s.AddressID.IsUnset() {
vals = append(vals, "address_id")
}
if !s.Reviewed.IsUnset() {
vals = append(vals, "reviewed")
}
if !s.ReviewerID.IsUnset() {
vals = append(vals, "reviewer_id")
}
return vals
}
@ -454,6 +469,12 @@ func (s PublicreportNuisanceSetter) Overwrite(t *PublicreportNuisance) {
if !s.AddressID.IsUnset() {
t.AddressID = s.AddressID.MustGetNull()
}
if !s.Reviewed.IsUnset() {
t.Reviewed = s.Reviewed.MustGetNull()
}
if !s.ReviewerID.IsUnset() {
t.ReviewerID = s.ReviewerID.MustGetNull()
}
}
func (s *PublicreportNuisanceSetter) Apply(q *dialect.InsertQuery) {
@ -462,7 +483,7 @@ func (s *PublicreportNuisanceSetter) Apply(q *dialect.InsertQuery) {
})
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
vals := make([]bob.Expression, 37)
vals := make([]bob.Expression, 39)
if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet())
} else {
@ -685,6 +706,18 @@ func (s *PublicreportNuisanceSetter) Apply(q *dialect.InsertQuery) {
vals[36] = psql.Raw("DEFAULT")
}
if !s.Reviewed.IsUnset() {
vals[37] = psql.Arg(s.Reviewed.MustGetNull())
} else {
vals[37] = psql.Raw("DEFAULT")
}
if !s.ReviewerID.IsUnset() {
vals[38] = psql.Arg(s.ReviewerID.MustGetNull())
} else {
vals[38] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -694,7 +727,7 @@ func (s PublicreportNuisanceSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s PublicreportNuisanceSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 37)
exprs := make([]bob.Expression, 0, 39)
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -955,6 +988,20 @@ func (s PublicreportNuisanceSetter) Expressions(prefix ...string) []bob.Expressi
}})
}
if !s.Reviewed.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "reviewed")...),
psql.Arg(s.Reviewed),
}})
}
if !s.ReviewerID.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "reviewer_id")...),
psql.Arg(s.ReviewerID),
}})
}
return exprs
}
@ -1277,6 +1324,30 @@ func (os PublicreportNuisanceSlice) Organization(mods ...bob.Mod[*dialect.Select
)...)
}
// ReviewerUser starts a query for related objects on user_
func (o *PublicreportNuisance) ReviewerUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
return Users.Query(append(mods,
sm.Where(Users.Columns.ID.EQ(psql.Arg(o.ReviewerID))),
)...)
}
func (os PublicreportNuisanceSlice) ReviewerUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
pkReviewerID := make(pgtypes.Array[null.Val[int32]], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkReviewerID = append(pkReviewerID, o.ReviewerID)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkReviewerID), "integer[]")),
))
return Users.Query(append(mods,
sm.Where(psql.Group(Users.Columns.ID).OP("IN", PKArgExpr)),
)...)
}
// Images starts a query for related objects on publicreport.image
func (o *PublicreportNuisance) Images(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportImagesQuery {
return PublicreportImages.Query(append(mods,
@ -1538,6 +1609,54 @@ func (publicreportNuisance0 *PublicreportNuisance) AttachOrganization(ctx contex
return nil
}
func attachPublicreportNuisanceReviewerUser0(ctx context.Context, exec bob.Executor, count int, publicreportNuisance0 *PublicreportNuisance, user1 *User) (*PublicreportNuisance, error) {
setter := &PublicreportNuisanceSetter{
ReviewerID: omitnull.From(user1.ID),
}
err := publicreportNuisance0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachPublicreportNuisanceReviewerUser0: %w", err)
}
return publicreportNuisance0, nil
}
func (publicreportNuisance0 *PublicreportNuisance) InsertReviewerUser(ctx context.Context, exec bob.Executor, related *UserSetter) error {
var err error
user1, err := Users.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachPublicreportNuisanceReviewerUser0(ctx, exec, 1, publicreportNuisance0, user1)
if err != nil {
return err
}
publicreportNuisance0.R.ReviewerUser = user1
user1.R.ReviewerNuisances = append(user1.R.ReviewerNuisances, publicreportNuisance0)
return nil
}
func (publicreportNuisance0 *PublicreportNuisance) AttachReviewerUser(ctx context.Context, exec bob.Executor, user1 *User) error {
var err error
_, err = attachPublicreportNuisanceReviewerUser0(ctx, exec, 1, publicreportNuisance0, user1)
if err != nil {
return err
}
publicreportNuisance0.R.ReviewerUser = user1
user1.R.ReviewerNuisances = append(user1.R.ReviewerNuisances, publicreportNuisance0)
return nil
}
func attachPublicreportNuisanceImages0(ctx context.Context, exec bob.Executor, count int, publicreportNuisance0 *PublicreportNuisance, publicreportImages2 PublicreportImageSlice) (PublicreportNuisanceImageSlice, error) {
setters := make([]*PublicreportNuisanceImageSetter, count)
for i := range count {
@ -1641,6 +1760,8 @@ type publicreportNuisanceWhere[Q psql.Filterable] struct {
Location psql.WhereNullMod[Q, string]
AddressNumber psql.WhereMod[Q, string]
AddressID psql.WhereNullMod[Q, int32]
Reviewed psql.WhereNullMod[Q, time.Time]
ReviewerID psql.WhereNullMod[Q, int32]
}
func (publicreportNuisanceWhere[Q]) AliasedAs(alias string) publicreportNuisanceWhere[Q] {
@ -1686,6 +1807,8 @@ func buildPublicreportNuisanceWhere[Q psql.Filterable](cols publicreportNuisance
Location: psql.WhereNull[Q, string](cols.Location),
AddressNumber: psql.Where[Q, string](cols.AddressNumber),
AddressID: psql.WhereNull[Q, int32](cols.AddressID),
Reviewed: psql.WhereNull[Q, time.Time](cols.Reviewed),
ReviewerID: psql.WhereNull[Q, int32](cols.ReviewerID),
}
}
@ -1747,6 +1870,18 @@ func (o *PublicreportNuisance) Preload(name string, retrieved any) error {
rel.R.Nuisances = PublicreportNuisanceSlice{o}
}
return nil
case "ReviewerUser":
rel, ok := retrieved.(*User)
if !ok {
return fmt.Errorf("publicreportNuisance cannot load %T as %q", retrieved, name)
}
o.R.ReviewerUser = rel
if rel != nil {
rel.R.ReviewerNuisances = PublicreportNuisanceSlice{o}
}
return nil
case "Images":
rels, ok := retrieved.(PublicreportImageSlice)
if !ok {
@ -1769,6 +1904,7 @@ func (o *PublicreportNuisance) Preload(name string, retrieved any) error {
type publicreportNuisancePreloader struct {
Address func(...psql.PreloadOption) psql.Preloader
Organization func(...psql.PreloadOption) psql.Preloader
ReviewerUser func(...psql.PreloadOption) psql.Preloader
}
func buildPublicreportNuisancePreloader() publicreportNuisancePreloader {
@ -1799,6 +1935,19 @@ func buildPublicreportNuisancePreloader() publicreportNuisancePreloader {
},
}, Organizations.Columns.Names(), opts...)
},
ReviewerUser: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*User, UserSlice](psql.PreloadRel{
Name: "ReviewerUser",
Sides: []psql.PreloadSide{
{
From: PublicreportNuisances,
To: Users,
FromColumns: []string{"reviewer_id"},
ToColumns: []string{"id"},
},
},
}, Users.Columns.Names(), opts...)
},
}
}
@ -1807,6 +1956,7 @@ type publicreportNuisanceThenLoader[Q orm.Loadable] struct {
NotifyPhoneNuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Address func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
ReviewerUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Images func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
@ -1823,6 +1973,9 @@ func buildPublicreportNuisanceThenLoader[Q orm.Loadable]() publicreportNuisanceT
type OrganizationLoadInterface interface {
LoadOrganization(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type ReviewerUserLoadInterface interface {
LoadReviewerUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type ImagesLoadInterface interface {
LoadImages(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -1852,6 +2005,12 @@ func buildPublicreportNuisanceThenLoader[Q orm.Loadable]() publicreportNuisanceT
return retrieved.LoadOrganization(ctx, exec, mods...)
},
),
ReviewerUser: thenLoadBuilder[Q](
"ReviewerUser",
func(ctx context.Context, exec bob.Executor, retrieved ReviewerUserLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadReviewerUser(ctx, exec, mods...)
},
),
Images: thenLoadBuilder[Q](
"Images",
func(ctx context.Context, exec bob.Executor, retrieved ImagesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -2093,6 +2252,61 @@ func (os PublicreportNuisanceSlice) LoadOrganization(ctx context.Context, exec b
return nil
}
// LoadReviewerUser loads the publicreportNuisance's ReviewerUser into the .R struct
func (o *PublicreportNuisance) LoadReviewerUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.ReviewerUser = nil
related, err := o.ReviewerUser(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.ReviewerNuisances = PublicreportNuisanceSlice{o}
o.R.ReviewerUser = related
return nil
}
// LoadReviewerUser loads the publicreportNuisance's ReviewerUser into the .R struct
func (os PublicreportNuisanceSlice) LoadReviewerUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
users, err := os.ReviewerUser(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range users {
if !o.ReviewerID.IsValue() {
continue
}
if !(o.ReviewerID.IsValue() && o.ReviewerID.MustGet() == rel.ID) {
continue
}
rel.R.ReviewerNuisances = append(rel.R.ReviewerNuisances, o)
o.R.ReviewerUser = rel
break
}
}
return nil
}
// LoadImages loads the publicreportNuisance's Images into the .R struct
func (o *PublicreportNuisance) LoadImages(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {