Validate PF project listings and sync own price
All checks were successful
CI / go (push) Successful in 41s
CI / python (push) Successful in 2s
Build and Deploy / build-and-deploy (push) Successful in 33s

This commit is contained in:
Grendgi
2026-06-11 14:46:35 +03:00
parent d53ecb2add
commit c763ff423d
3 changed files with 171 additions and 6 deletions

View File

@@ -5,12 +5,15 @@ import (
"database/sql"
"errors"
"fmt"
"regexp"
"strings"
)
var ErrNotFound = errors.New("not found")
var ErrTelegramRequired = errors.New("telegram required")
var propertyFinderListingURLRe = regexp.MustCompile(`(?i)propertyfinder\.ae/.+-(\d+)\.html(?:[?#].*)?$`)
func (a *App) CurrentEmployee(ctx context.Context, portalUserID string, required bool) (*Employee, error) {
if portalUserID == "" {
if required {
@@ -301,6 +304,11 @@ func (a *App) CreateProject(ctx context.Context, ownerID int64, p ProjectPayload
if err != nil {
return nil, err
}
p.Title = title
p.DealType = deal
if err := validateProjectRequired(p); err != nil {
return nil, err
}
res, err := a.DB.ExecContext(ctx, `
INSERT INTO projects
(title, deal_type, owner_id, our_price, notes, dld_permit, building, bedrooms, size_sqft, our_url, created_at)
@@ -334,6 +342,12 @@ func (a *App) UpdateProject(ctx context.Context, ownerID, projectID int64, p Pro
return nil, err
}
}
p = mergeProjectPayload(current, p)
p.Title = title
p.DealType = deal
if err := validateProjectRequired(p); err != nil {
return nil, err
}
_, err = a.DB.ExecContext(ctx, `
UPDATE projects
SET title = ?, deal_type = ?, our_price = ?, notes = ?, dld_permit = ?,
@@ -348,6 +362,59 @@ func (a *App) UpdateProject(ctx context.Context, ownerID, projectID int64, p Pro
return a.ProjectByID(ctx, ownerID, projectID, true)
}
func mergeProjectPayload(current *Project, p ProjectPayload) ProjectPayload {
if current == nil {
return p
}
if p.OurPrice == nil {
p.OurPrice = current.OurPrice
}
if cleanPtr(p.DLDPermit) == nil {
p.DLDPermit = current.DLDPermit
}
if cleanPtr(p.Building) == nil {
p.Building = current.Building
}
if p.Bedrooms == nil {
p.Bedrooms = current.Bedrooms
}
if p.SizeSqft == nil {
p.SizeSqft = current.SizeSqft
}
if cleanPtr(p.OurURL) == nil {
p.OurURL = current.OurURL
}
return p
}
func validateProjectRequired(p ProjectPayload) error {
if cleanString(p.Title) == "" {
return fmt.Errorf("title is required")
}
if p.OurPrice == nil || *p.OurPrice <= 0 {
return fmt.Errorf("our_price is required")
}
if cleanPtr(p.DLDPermit) == nil {
return fmt.Errorf("dld_permit is required")
}
if cleanPtr(p.Building) == nil {
return fmt.Errorf("building is required")
}
if p.Bedrooms == nil {
return fmt.Errorf("bedrooms is required")
}
if p.SizeSqft == nil || *p.SizeSqft <= 0 {
return fmt.Errorf("size_sqft is required")
}
if cleanPtr(p.OurURL) == nil {
return fmt.Errorf("our_url is required")
}
if !propertyFinderListingURLRe.MatchString(strings.TrimSpace(*p.OurURL)) {
return fmt.Errorf("our_url must be a concrete PropertyFinder listing URL")
}
return nil
}
func (a *App) DeleteProject(ctx context.Context, ownerID, projectID int64) error {
tx, err := a.DB.BeginTx(ctx, nil)
if err != nil {