linkFilesToChat inserts file-link rows into the chat_file_links join table. Cap enforcement and dedup are handled atomically in SQL. On success returns (nil, false). On failure returns the full input fileIDs slice — linking is all-or-nothing because the SQL operates on the batch atomically. capExcee
(ctx context.Context, chatID uuid.UUID, fileIDs []uuid.UUID)
| 6351 | // or a database error (false). |
| 6352 | // Failures are logged but never block the caller. |
| 6353 | func (api *API) linkFilesToChat(ctx context.Context, chatID uuid.UUID, fileIDs []uuid.UUID) (unlinked []uuid.UUID, capExceeded bool) { |
| 6354 | if len(fileIDs) == 0 { |
| 6355 | return nil, false |
| 6356 | } |
| 6357 | rejected, err := api.Database.LinkChatFiles(ctx, database.LinkChatFilesParams{ |
| 6358 | ChatID: chatID, |
| 6359 | MaxFileLinks: int32(codersdk.MaxChatFileIDs), |
| 6360 | FileIds: fileIDs, |
| 6361 | }) |
| 6362 | if err != nil { |
| 6363 | api.Logger.Error(ctx, "failed to link files to chat", |
| 6364 | slog.F("chat_id", chatID), |
| 6365 | slog.F("file_ids", fileIDs), |
| 6366 | slog.Error(err), |
| 6367 | ) |
| 6368 | return fileIDs, false |
| 6369 | } |
| 6370 | if rejected > 0 { |
| 6371 | api.Logger.Warn(ctx, "file cap reached, files not linked", |
| 6372 | slog.F("chat_id", chatID), |
| 6373 | slog.F("file_ids", fileIDs), |
| 6374 | slog.F("max_file_links", codersdk.MaxChatFileIDs), |
| 6375 | ) |
| 6376 | return fileIDs, true |
| 6377 | } |
| 6378 | return nil, false |
| 6379 | } |
| 6380 | |
| 6381 | // fileLinkCapWarning builds a user-facing warning when a batch |
| 6382 | // of file IDs was atomically rejected because the resulting |
no test coverage detected