feat: implement geometry service with persistence layer and API documentation
All checks were successful
Build and Release / release (push) Successful in 1m33s

This commit is contained in:
2026-05-09 00:43:45 +07:00
parent b2ee16457d
commit 27c78db66d
7 changed files with 32 additions and 4 deletions

View File

@@ -67,7 +67,11 @@ WHERE g.is_deleted = false
)
AND (
sqlc.narg('time_point')::int IS NULL OR
int4range(g.time_start, g.time_end, '[]') @> sqlc.narg('time_point')::int
int4range(g.time_start, g.time_end, '[]') && int4range(
sqlc.narg('time_point')::int - COALESCE(sqlc.narg('time_range')::int, 0),
sqlc.narg('time_point')::int + COALESCE(sqlc.narg('time_range')::int, 0),
'[]'
)
)
AND (
sqlc.narg('entity_id')::uuid IS NULL OR

View File

@@ -756,6 +756,11 @@ const docTemplate = `{
"type": "integer",
"name": "time",
"in": "query"
},
{
"type": "integer",
"name": "time_range",
"in": "query"
}
],
"responses": {

View File

@@ -749,6 +749,11 @@
"type": "integer",
"name": "time",
"in": "query"
},
{
"type": "integer",
"name": "time_range",
"in": "query"
}
],
"responses": {

View File

@@ -1174,6 +1174,9 @@ paths:
- in: query
name: time
type: integer
- in: query
name: time_range
type: integer
produces:
- application/json
responses:

View File

@@ -6,6 +6,7 @@ type SearchGeometryDto struct {
MaxLng *float64 `json:"max_lng" query:"max_lng" validate:"required,gte=-180,lte=180"`
MaxLat *float64 `json:"max_lat" query:"max_lat" validate:"required,gte=-90,lte=90"`
TimePoint *int32 `json:"time" query:"time" validate:"omitempty,number"`
TimeRange *int32 `json:"time_range" query:"time_range" validate:"omitempty,number"`
EntityID *string `json:"entity_id" query:"entity_id" validate:"omitempty,uuid"`
ProjectID *string `json:"project_id" query:"project_id" validate:"omitempty,uuid"`
}

View File

@@ -460,15 +460,19 @@ WHERE g.is_deleted = false
)
AND (
$6::int IS NULL OR
int4range(g.time_start, g.time_end, '[]') @> $6::int
int4range(g.time_start, g.time_end, '[]') && int4range(
$6::int - COALESCE($7::int, 0),
$6::int + COALESCE($7::int, 0),
'[]'
)
)
AND (
$7::uuid IS NULL OR
$8::uuid IS NULL OR
EXISTS (
SELECT 1
FROM entity_geometries eg
WHERE eg.geometry_id = g.id
AND eg.entity_id = $7::uuid
AND eg.entity_id = $8::uuid
)
)
ORDER BY g.id DESC
@@ -481,6 +485,7 @@ type SearchGeometriesParams struct {
SearchMaxLng pgtype.Float8 `json:"search_max_lng"`
SearchMaxLat pgtype.Float8 `json:"search_max_lat"`
TimePoint pgtype.Int4 `json:"time_point"`
TimeRange pgtype.Int4 `json:"time_range"`
EntityID pgtype.UUID `json:"entity_id"`
}
@@ -509,6 +514,7 @@ func (q *Queries) SearchGeometries(ctx context.Context, arg SearchGeometriesPara
arg.SearchMaxLng,
arg.SearchMaxLat,
arg.TimePoint,
arg.TimeRange,
arg.EntityID,
)
if err != nil {

View File

@@ -61,6 +61,10 @@ func (s *geometryService) SearchGeometries(ctx context.Context, req *request.Sea
params.TimePoint = pgtype.Int4{Int32: *req.TimePoint, Valid: true}
}
if req.TimeRange != nil {
params.TimeRange = pgtype.Int4{Int32: *req.TimeRange, Valid: true}
}
if req.EntityID != nil {
entityId, err := convert.StringToUUID(*req.EntityID)
if err != nil {