fix: normalize ImagePath for old database entries with storage/ prefix

- Added normalizeImagePath() helper that strips legacy storage/ prefix
- Applied in ViewEventExpenses, SaveExpense, UpdateExpense, EditExpense
- Prevents double storage/storage/ in image URLs for old expenses
This commit is contained in:
Claus Lohmar 2026-06-01 23:30:56 +00:00
parent bb2c06fa3a
commit 0b55ac1fac
3 changed files with 25 additions and 1 deletions

View file

@ -242,6 +242,11 @@ func (h *EventHandler) ViewEventExpenses(w http.ResponseWriter, r *http.Request)
} }
} }
// Normalize ImagePath for all expenses (old DB entries may have storage/ prefix).
for i := range expenses {
expenses[i].ImagePath = normalizeImagePath(expenses[i].ImagePath)
}
data := map[string]interface{}{ data := map[string]interface{}{
"Event": event, "Event": event,
"Expenses": expenses, "Expenses": expenses,

View file

@ -308,6 +308,10 @@ func (h *ExpenseHandler) SaveExpense(w http.ResponseWriter, r *http.Request) {
} }
// 7. Render the expense_list.html fragment. // 7. Render the expense_list.html fragment.
// Normalize ImagePath for old DB entries that may have storage/ prefix.
for i := range expenses {
expenses[i].ImagePath = normalizeImagePath(expenses[i].ImagePath)
}
listTmpl := getTemplate("expense_list.html") listTmpl := getTemplate("expense_list.html")
var listBuf strings.Builder var listBuf strings.Builder
@ -363,7 +367,7 @@ func (h *ExpenseHandler) EditExpense(w http.ResponseWriter, r *http.Request) {
tmpl := getTemplate("receipt_form.html") tmpl := getTemplate("receipt_form.html")
data := map[string]interface{}{ data := map[string]interface{}{
"ImagePath": expense.ImagePath, "ImagePath": normalizeImagePath(expense.ImagePath),
"AIError": "", "AIError": "",
"Amount": strconv.FormatFloat(expense.Amount, 'f', 2, 64), "Amount": strconv.FormatFloat(expense.Amount, 'f', 2, 64),
"Currency": expense.Currency, "Currency": expense.Currency,
@ -375,6 +379,7 @@ func (h *ExpenseHandler) EditExpense(w http.ResponseWriter, r *http.Request) {
"ExchangeRate": 0.0, "ExchangeRate": 0.0,
"ConvertedAmount": strconv.FormatFloat(expense.ConvertedAmount, 'f', 2, 64), "ConvertedAmount": strconv.FormatFloat(expense.ConvertedAmount, 'f', 2, 64),
"EditID": expense.ID, "EditID": expense.ID,
"ID": expense.ID,
} }
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
@ -456,6 +461,10 @@ func (h *ExpenseHandler) UpdateExpense(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Failed to fetch expenses", http.StatusInternalServerError) http.Error(w, "Failed to fetch expenses", http.StatusInternalServerError)
return return
} }
// Normalize ImagePath for old DB entries.
for i := range expenses {
expenses[i].ImagePath = normalizeImagePath(expenses[i].ImagePath)
}
listTmpl := getTemplate("expense_list.html") listTmpl := getTemplate("expense_list.html")

View file

@ -0,0 +1,10 @@
package handlers
import "strings"
// normalizeImagePath strips a legacy "storage/" prefix if present, so that
// the template can safely build "/storage/{filename}" URLs regardless of
// whether the database entry was stored as "uuid.jpg" or "storage/uuid.jpg".
func normalizeImagePath(path string) string {
return strings.TrimPrefix(path, "storage/")
}