Search API
Base path: /api/search
File: ayts-api/src/routes/search.ts
Auth required: No
GET /api/search
Full-text search across stores and products.
Query params:
| Param | Type | Description |
|---|---|---|
q | string | Search query (required) |
type | all|stores|products | Scope (default: all) |
category | string | Filter by category |
limit | number | Max results (default: 20) |
offset | number | Pagination offset |
Response 200:
{
"success": true,
"query": "rice",
"results": {
"stores": [{
"id": "uuid",
"name": "Fresh Mart Grocery",
"category": "grocery",
"rating": 4.5
}],
"products": [{
"id": "uuid",
"name": "Sinandomeng Rice 5kg",
"price": 285.00,
"store": { "id": "uuid", "name": "Fresh Mart Grocery" }
}]
},
"total": { "stores": 3, "products": 12 }
}
GET /api/search/autocomplete
Returns autocomplete suggestions as the user types.
Query params: q (min 2 chars), limit (default: 5)
Response 200:
{
"success": true,
"suggestions": [
{ "type": "product", "text": "Sinandomeng Rice 5kg", "id": "uuid" },
{ "type": "store", "text": "Fresh Mart Grocery", "id": "uuid" }
]
}
Implementation
Uses PostgreSQL FTS with to_tsvector + to_tsquery:
-- Products FTS index
CREATE INDEX idx_products_fts
ON products USING GIN(to_tsvector('english', name || ' ' || coalesce(description, '')));
-- Stores FTS index
CREATE INDEX idx_stores_fts
ON stores USING GIN(to_tsvector('english', name || ' ' || coalesce(description, '')));
Query:
SELECT * FROM products
WHERE to_tsvector('english', name || ' ' || coalesce(description, ''))
@@ plainto_tsquery('english', $1)
ORDER BY ts_rank(...) DESC;