feat(files): загрузка и выдача вложений
- POST /api/v1/channels/{id}/files (multipart, ATTACH_FILES): файл пишется на
диск под идентификатором, в БД хранятся метаданные и sha256; имя файла
очищается от путей и управляющих символов, объём ограничен MAX_UPLOAD_SIZE;
- GET/HEAD /files/{id}: содержимое с проверкой прав на комнату сообщения
(невидимая комната и чужие вложения → 404), ETag, immutable-кэш,
Content-Disposition с RFC 5987 для не-ASCII имён;
- вложения привязываются к сообщению при отправке (attachment_ids), сироты
ищутся через store.ListOrphanFiles для обслуживания;
- GET /api/v1/files/{id} — метаданные файла для клиента;
- chi-ручки теперь умеют отдавать huma-ошибки в общем конверте
(writeHumaAPIError), иначе 404 превращался в 500;
- READY отдаёт реальные read states пользователя.
Тесты: загрузка, скачивание участником, скрытая комната → 404, вложение в
сообщении, проверка подписи ETag.
This commit is contained in:
@@ -81,6 +81,19 @@ func writeAPIError(w http.ResponseWriter, err error) {
|
||||
})
|
||||
}
|
||||
|
||||
// writeHumaAPIError отдаёт ошибку chi-ручки: huma-ошибки уже несут код и
|
||||
// статус, доменные ошибки переводит writeAPIError (AGENT.md 8.5).
|
||||
func writeHumaAPIError(w http.ResponseWriter, err error) {
|
||||
var apiErr *humaAPIError
|
||||
if errors.As(err, &apiErr) {
|
||||
httpx.WriteJSON(w, apiErr.status, map[string]any{
|
||||
"error": map[string]any{"code": apiErr.code, "message": apiErr.message},
|
||||
})
|
||||
return
|
||||
}
|
||||
writeAPIError(w, err)
|
||||
}
|
||||
|
||||
// writeJSON пишет успешный ответ (все текущие ручки возвращают 200).
|
||||
func writeJSON(w http.ResponseWriter, body any) {
|
||||
httpx.WriteJSON(w, http.StatusOK, body)
|
||||
|
||||
Reference in New Issue
Block a user