MCPcopy Index your code
hub / github.com/coder/coder / chatsByWorkspace

Method chatsByWorkspace

coderd/exp_chats.go:247–306  ·  view source on GitHub ↗

EXPERIMENTAL: chatsByWorkspace returns a mapping of workspace ID to the latest non-archived chat ID for each requested workspace. The query returns all matching chats and RBAC post-filters them; the handler then picks the latest per workspace in Go. This avoids the DISTINCT ON + post-filter bug wher

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

245// @Success 200
246// @x-apidocgen {"skip": true}
247func (api *API) chatsByWorkspace(rw http.ResponseWriter, r *http.Request) {
248 ctx := r.Context()
249
250 idsParam := r.URL.Query().Get("workspace_ids")
251 if idsParam == "" {
252 httpapi.Write(ctx, rw, http.StatusOK, map[uuid.UUID]uuid.UUID{})
253 return
254 }
255
256 raw := strings.Split(idsParam, ",")
257
258 // maxWorkspaceIDs is coupled to DEFAULT_RECORDS_PER_PAGE (25) in
259 // site/src/components/PaginationWidget/utils.ts.
260 // If the page size changes, this limit should too.
261 const maxWorkspaceIDs = 25
262 if len(raw) > maxWorkspaceIDs {
263 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
264 Message: fmt.Sprintf("Too many workspace IDs, maximum is %d.", maxWorkspaceIDs),
265 })
266 return
267 }
268
269 workspaceIDs := make([]uuid.UUID, 0, len(raw))
270 for _, s := range raw {
271 id, err := uuid.Parse(strings.TrimSpace(s))
272 if err != nil {
273 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
274 Message: fmt.Sprintf("Invalid workspace ID %q: %s", s, err),
275 })
276 return
277 }
278 workspaceIDs = append(workspaceIDs, id)
279 }
280
281 chats, err := api.Database.GetChatsByWorkspaceIDs(ctx, workspaceIDs)
282 if httpapi.Is404Error(err) {
283 httpapi.ResourceNotFound(rw)
284 return
285 } else if err != nil {
286 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
287 Message: "Failed to get chats by workspace.",
288 Detail: err.Error(),
289 })
290 return
291 }
292
293 // The SQL orders by (workspace_id, updated_at DESC), so the first
294 // chat seen per workspace after RBAC filtering is the latest
295 // readable one.
296 result := make(map[uuid.UUID]uuid.UUID, len(chats))
297 for _, chat := range chats {
298 if chat.WorkspaceID.Valid {
299 if _, exists := result[chat.WorkspaceID.UUID]; !exists {
300 result[chat.WorkspaceID.UUID] = chat.ID
301 }
302 }
303 }
304

Callers

nothing calls this directly

Calls 8

WriteFunction · 0.92
Is404ErrorFunction · 0.92
ResourceNotFoundFunction · 0.92
ContextMethod · 0.65
GetMethod · 0.65
ParseMethod · 0.65
ErrorMethod · 0.45

Tested by

no test coverage detected