initial commit

This commit is contained in:
2025-11-29 00:28:21 +05:00
parent 46229acc82
commit ec3b03a935
76 changed files with 13492 additions and 0 deletions

View File

@@ -0,0 +1,412 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: geospatial.sql
package database
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const CountRequestsNearby = `-- name: CountRequestsNearby :one
SELECT COUNT(*) FROM requests r
WHERE r.deleted_at IS NULL
AND r.status = $3
AND ST_DWithin(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography,
$4
)
`
type CountRequestsNearbyParams struct {
StMakepoint interface{} `json:"st_makepoint"`
StMakepoint_2 interface{} `json:"st_makepoint_2"`
Status NullRequestStatus `json:"status"`
StDwithin interface{} `json:"st_dwithin"`
}
// ============================================================================
// Подсчет заявок поблизости
// ============================================================================
func (q *Queries) CountRequestsNearby(ctx context.Context, arg CountRequestsNearbyParams) (int64, error) {
row := q.db.QueryRow(ctx, CountRequestsNearby,
arg.StMakepoint,
arg.StMakepoint_2,
arg.Status,
arg.StDwithin,
)
var count int64
err := row.Scan(&count)
return count, err
}
const FindNearestRequestsForVolunteer = `-- name: FindNearestRequestsForVolunteer :many
SELECT
r.id,
r.title,
r.description,
r.urgency,
r.status,
r.created_at,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
ST_Distance(
r.location,
(SELECT u.location FROM users u WHERE u.id = $1)
) as distance_meters,
rt.name as request_type_name,
rt.icon as request_type_icon
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
WHERE r.deleted_at IS NULL
AND r.status = 'approved'
AND r.assigned_volunteer_id IS NULL
AND ST_DWithin(
r.location,
(SELECT u.location FROM users u WHERE u.id = $1),
$2
)
ORDER BY
CASE r.urgency
WHEN 'urgent' THEN 1
WHEN 'high' THEN 2
WHEN 'medium' THEN 3
ELSE 4
END,
distance_meters
LIMIT $3
`
type FindNearestRequestsForVolunteerParams struct {
ID int64 `json:"id"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
}
type FindNearestRequestsForVolunteerRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
RequestTypeName string `json:"request_type_name"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
}
// ============================================================================
// Поиск ближайших заявок для волонтера
// ============================================================================
func (q *Queries) FindNearestRequestsForVolunteer(ctx context.Context, arg FindNearestRequestsForVolunteerParams) ([]FindNearestRequestsForVolunteerRow, error) {
rows, err := q.db.Query(ctx, FindNearestRequestsForVolunteer, arg.ID, arg.StDwithin, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindNearestRequestsForVolunteerRow{}
for rows.Next() {
var i FindNearestRequestsForVolunteerRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Description,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
&i.RequestTypeName,
&i.RequestTypeIcon,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindRequestsInBounds = `-- name: FindRequestsInBounds :many
SELECT
r.id,
r.title,
r.urgency,
r.status,
r.created_at,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
rt.icon as request_type_icon,
rt.name as request_type_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
WHERE r.deleted_at IS NULL
AND r.status::text = ANY($1::text[])
AND ST_Within(
r.location::geometry,
ST_MakeEnvelope($2, $3, $4, $5, 4326)
)
ORDER BY r.created_at DESC
LIMIT 200
`
type FindRequestsInBoundsParams struct {
Column1 []string `json:"column_1"`
StMakeenvelope interface{} `json:"st_makeenvelope"`
StMakeenvelope_2 interface{} `json:"st_makeenvelope_2"`
StMakeenvelope_3 interface{} `json:"st_makeenvelope_3"`
StMakeenvelope_4 interface{} `json:"st_makeenvelope_4"`
}
type FindRequestsInBoundsRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
RequestTypeName string `json:"request_type_name"`
}
// ============================================================================
// Поиск заявок в прямоугольной области (для карты)
// ============================================================================
func (q *Queries) FindRequestsInBounds(ctx context.Context, arg FindRequestsInBoundsParams) ([]FindRequestsInBoundsRow, error) {
rows, err := q.db.Query(ctx, FindRequestsInBounds,
arg.Column1,
arg.StMakeenvelope,
arg.StMakeenvelope_2,
arg.StMakeenvelope_3,
arg.StMakeenvelope_4,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindRequestsInBoundsRow{}
for rows.Next() {
var i FindRequestsInBoundsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.Latitude,
&i.Longitude,
&i.RequestTypeIcon,
&i.RequestTypeName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindRequestsNearby = `-- name: FindRequestsNearby :many
SELECT
r.id,
r.title,
r.description,
r.address,
r.city,
r.urgency,
r.status,
r.created_at,
r.desired_completion_date,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
ST_Distance(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography
) as distance_meters,
rt.name as request_type_name,
rt.icon as request_type_icon,
(u.first_name || ' ' || u.last_name) as requester_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
WHERE r.deleted_at IS NULL
AND r.status::text = ANY($3::text[])
AND ST_DWithin(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography,
$4
)
ORDER BY distance_meters
LIMIT $5 OFFSET $6
`
type FindRequestsNearbyParams struct {
StMakepoint interface{} `json:"st_makepoint"`
StMakepoint_2 interface{} `json:"st_makepoint_2"`
Column3 []string `json:"column_3"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type FindRequestsNearbyRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Address string `json:"address"`
City pgtype.Text `json:"city"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
RequestTypeName string `json:"request_type_name"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
RequesterName interface{} `json:"requester_name"`
}
// Фаза 2B: Геопространственные запросы (ВЫСОКИЙ ПРИОРИТЕТ)
// PostGIS запросы для поиска заявок по геолокации
// ============================================================================
// Поиск заявок рядом с точкой
// ============================================================================
func (q *Queries) FindRequestsNearby(ctx context.Context, arg FindRequestsNearbyParams) ([]FindRequestsNearbyRow, error) {
rows, err := q.db.Query(ctx, FindRequestsNearby,
arg.StMakepoint,
arg.StMakepoint_2,
arg.Column3,
arg.StDwithin,
arg.Limit,
arg.Offset,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindRequestsNearbyRow{}
for rows.Next() {
var i FindRequestsNearbyRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Description,
&i.Address,
&i.City,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.DesiredCompletionDate,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
&i.RequestTypeName,
&i.RequestTypeIcon,
&i.RequesterName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindVolunteersNearRequest = `-- name: FindVolunteersNearRequest :many
SELECT
u.id,
(u.first_name || ' ' || u.last_name) as full_name,
u.avatar_url,
u.volunteer_rating,
u.completed_requests_count,
ST_Y(u.location::geometry) as latitude,
ST_X(u.location::geometry) as longitude,
ST_Distance(
u.location,
(SELECT req.location FROM requests req WHERE req.id = $1)
) as distance_meters
FROM users u
JOIN user_roles ur ON ur.user_id = u.id
JOIN roles r ON r.id = ur.role_id
WHERE r.name = 'volunteer'
AND u.deleted_at IS NULL
AND u.is_blocked = FALSE
AND u.location IS NOT NULL
AND ST_DWithin(
u.location,
(SELECT req.location FROM requests req WHERE req.id = $1),
$2
)
ORDER BY distance_meters
LIMIT $3
`
type FindVolunteersNearRequestParams struct {
ID int64 `json:"id"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
}
type FindVolunteersNearRequestRow struct {
ID int64 `json:"id"`
FullName interface{} `json:"full_name"`
AvatarUrl pgtype.Text `json:"avatar_url"`
VolunteerRating pgtype.Numeric `json:"volunteer_rating"`
CompletedRequestsCount pgtype.Int4 `json:"completed_requests_count"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
}
// ============================================================================
// Поиск волонтеров рядом с заявкой
// ============================================================================
func (q *Queries) FindVolunteersNearRequest(ctx context.Context, arg FindVolunteersNearRequestParams) ([]FindVolunteersNearRequestRow, error) {
rows, err := q.db.Query(ctx, FindVolunteersNearRequest, arg.ID, arg.StDwithin, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindVolunteersNearRequestRow{}
for rows.Next() {
var i FindVolunteersNearRequestRow
if err := rows.Scan(
&i.ID,
&i.FullName,
&i.AvatarUrl,
&i.VolunteerRating,
&i.CompletedRequestsCount,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}