fix: increase connectTimeout and replace expires_at stored column refs
- api_client.dart: connectTimeout 10s → 60s — Flutter was cancelling requests to /recommendations after 10s while the server waited for OpenAI, causing 'context canceled' on the server side - product/repository.go ListForPrompt: expires_at is computed via (added_at + storage_days * INTERVAL '1 day'), not a stored column; wrap in CTE to reference it by alias in SELECT/ORDER BY - home/handler.go getExpiringSoon: same fix — use CTE to compute expires_at before filtering/ordering by it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -150,12 +150,16 @@ func defaultPlan() []MealPlan {
|
|||||||
// getExpiringSoon returns products expiring within the next 3 days.
|
// getExpiringSoon returns products expiring within the next 3 days.
|
||||||
func (h *Handler) getExpiringSoon(ctx context.Context, userID string) []ExpiringSoon {
|
func (h *Handler) getExpiringSoon(ctx context.Context, userID string) []ExpiringSoon {
|
||||||
rows, err := h.pool.Query(ctx, `
|
rows, err := h.pool.Query(ctx, `
|
||||||
|
WITH p AS (
|
||||||
SELECT name, quantity, unit,
|
SELECT name, quantity, unit,
|
||||||
GREATEST(0, EXTRACT(EPOCH FROM (expires_at - now())) / 86400)::int
|
(added_at + storage_days * INTERVAL '1 day') AS expires_at
|
||||||
FROM products
|
FROM products
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
AND expires_at IS NOT NULL
|
)
|
||||||
AND expires_at > now()
|
SELECT name, quantity, unit,
|
||||||
|
GREATEST(0, EXTRACT(EPOCH FROM (expires_at - now())) / 86400)::int
|
||||||
|
FROM p
|
||||||
|
WHERE expires_at > now()
|
||||||
AND expires_at <= now() + INTERVAL '3 days'
|
AND expires_at <= now() + INTERVAL '3 days'
|
||||||
ORDER BY expires_at
|
ORDER BY expires_at
|
||||||
LIMIT 5`,
|
LIMIT 5`,
|
||||||
|
|||||||
@@ -117,9 +117,14 @@ func (r *Repository) Delete(ctx context.Context, id, userID string) error {
|
|||||||
// Expiring soon items are marked with ⚠.
|
// Expiring soon items are marked with ⚠.
|
||||||
func (r *Repository) ListForPrompt(ctx context.Context, userID string) ([]string, error) {
|
func (r *Repository) ListForPrompt(ctx context.Context, userID string) ([]string, error) {
|
||||||
rows, err := r.pool.Query(ctx, `
|
rows, err := r.pool.Query(ctx, `
|
||||||
SELECT name, quantity, unit, expires_at
|
WITH p AS (
|
||||||
|
SELECT name, quantity, unit,
|
||||||
|
(added_at + storage_days * INTERVAL '1 day') AS expires_at
|
||||||
FROM products
|
FROM products
|
||||||
WHERE user_id = $1
|
WHERE user_id = $1
|
||||||
|
)
|
||||||
|
SELECT name, quantity, unit, expires_at
|
||||||
|
FROM p
|
||||||
ORDER BY expires_at ASC`, userID)
|
ORDER BY expires_at ASC`, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("list products for prompt: %w", err)
|
return nil, fmt.Errorf("list products for prompt: %w", err)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class ApiClient {
|
|||||||
ApiClient({required String baseUrl, required SecureStorageService storage}) {
|
ApiClient({required String baseUrl, required SecureStorageService storage}) {
|
||||||
_dio = Dio(BaseOptions(
|
_dio = Dio(BaseOptions(
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
connectTimeout: const Duration(seconds: 10),
|
connectTimeout: const Duration(seconds: 60),
|
||||||
receiveTimeout: const Duration(seconds: 120),
|
receiveTimeout: const Duration(seconds: 120),
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user