feat(coderd): add inbox notifications endpoints (#16889)

This PR is part of the inbox notifications topic, and rely on previous
PRs merged - it adds :

- Endpoints to : 
  - WS : watch new inbox notifications
  - REST : list inbox notifications
  - REST : update the read status of a notification

Also, this PR acts as a follow-up PR from previous work and : 

- fix DB query issues
- fix DBMem logic to match DB
This commit is contained in:
Vincent Vielle
2025-03-18 00:02:47 +01:00
committed by GitHub
parent e85c92e7d5
commit 3ae55bbbf4
20 changed files with 2093 additions and 65 deletions

206
coderd/apidoc/docs.go generated
View File

@ -1660,6 +1660,130 @@ const docTemplate = `{
}
}
},
"/notifications/inbox": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Notifications"
],
"summary": "List inbox notifications",
"operationId": "list-inbox-notifications",
"parameters": [
{
"type": "string",
"description": "Comma-separated list of target IDs to filter notifications",
"name": "targets",
"in": "query"
},
{
"type": "string",
"description": "Comma-separated list of template IDs to filter notifications",
"name": "templates",
"in": "query"
},
{
"type": "string",
"description": "Filter notifications by read status. Possible values: read, unread, all",
"name": "read_status",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.ListInboxNotificationsResponse"
}
}
}
}
},
"/notifications/inbox/watch": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Notifications"
],
"summary": "Watch for new inbox notifications",
"operationId": "watch-for-new-inbox-notifications",
"parameters": [
{
"type": "string",
"description": "Comma-separated list of target IDs to filter notifications",
"name": "targets",
"in": "query"
},
{
"type": "string",
"description": "Comma-separated list of template IDs to filter notifications",
"name": "templates",
"in": "query"
},
{
"type": "string",
"description": "Filter notifications by read status. Possible values: read, unread, all",
"name": "read_status",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.GetInboxNotificationResponse"
}
}
}
}
},
"/notifications/inbox/{id}/read-status": {
"put": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Notifications"
],
"summary": "Update read status of a notification",
"operationId": "update-read-status-of-a-notification",
"parameters": [
{
"type": "string",
"description": "id of the notification",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.Response"
}
}
}
}
},
"/notifications/settings": {
"get": {
"security": [
@ -11890,6 +12014,17 @@ const docTemplate = `{
}
}
},
"codersdk.GetInboxNotificationResponse": {
"type": "object",
"properties": {
"notification": {
"$ref": "#/definitions/codersdk.InboxNotification"
},
"unread_count": {
"type": "integer"
}
}
},
"codersdk.GetUserStatusCountsResponse": {
"type": "object",
"properties": {
@ -12071,6 +12206,63 @@ const docTemplate = `{
}
}
},
"codersdk.InboxNotification": {
"type": "object",
"properties": {
"actions": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.InboxNotificationAction"
}
},
"content": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"icon": {
"type": "string"
},
"id": {
"type": "string",
"format": "uuid"
},
"read_at": {
"type": "string"
},
"targets": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"template_id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"user_id": {
"type": "string",
"format": "uuid"
}
}
},
"codersdk.InboxNotificationAction": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"codersdk.InsightsReportInterval": {
"type": "string",
"enum": [
@ -12181,6 +12373,20 @@ const docTemplate = `{
}
}
},
"codersdk.ListInboxNotificationsResponse": {
"type": "object",
"properties": {
"notifications": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.InboxNotification"
}
},
"unread_count": {
"type": "integer"
}
}
},
"codersdk.LogLevel": {
"type": "string",
"enum": [

View File

@ -1445,6 +1445,118 @@
}
}
},
"/notifications/inbox": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Notifications"],
"summary": "List inbox notifications",
"operationId": "list-inbox-notifications",
"parameters": [
{
"type": "string",
"description": "Comma-separated list of target IDs to filter notifications",
"name": "targets",
"in": "query"
},
{
"type": "string",
"description": "Comma-separated list of template IDs to filter notifications",
"name": "templates",
"in": "query"
},
{
"type": "string",
"description": "Filter notifications by read status. Possible values: read, unread, all",
"name": "read_status",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.ListInboxNotificationsResponse"
}
}
}
}
},
"/notifications/inbox/watch": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Notifications"],
"summary": "Watch for new inbox notifications",
"operationId": "watch-for-new-inbox-notifications",
"parameters": [
{
"type": "string",
"description": "Comma-separated list of target IDs to filter notifications",
"name": "targets",
"in": "query"
},
{
"type": "string",
"description": "Comma-separated list of template IDs to filter notifications",
"name": "templates",
"in": "query"
},
{
"type": "string",
"description": "Filter notifications by read status. Possible values: read, unread, all",
"name": "read_status",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.GetInboxNotificationResponse"
}
}
}
}
},
"/notifications/inbox/{id}/read-status": {
"put": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Notifications"],
"summary": "Update read status of a notification",
"operationId": "update-read-status-of-a-notification",
"parameters": [
{
"type": "string",
"description": "id of the notification",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.Response"
}
}
}
}
},
"/notifications/settings": {
"get": {
"security": [
@ -10667,6 +10779,17 @@
}
}
},
"codersdk.GetInboxNotificationResponse": {
"type": "object",
"properties": {
"notification": {
"$ref": "#/definitions/codersdk.InboxNotification"
},
"unread_count": {
"type": "integer"
}
}
},
"codersdk.GetUserStatusCountsResponse": {
"type": "object",
"properties": {
@ -10842,6 +10965,63 @@
}
}
},
"codersdk.InboxNotification": {
"type": "object",
"properties": {
"actions": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.InboxNotificationAction"
}
},
"content": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"icon": {
"type": "string"
},
"id": {
"type": "string",
"format": "uuid"
},
"read_at": {
"type": "string"
},
"targets": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"template_id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"user_id": {
"type": "string",
"format": "uuid"
}
}
},
"codersdk.InboxNotificationAction": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"codersdk.InsightsReportInterval": {
"type": "string",
"enum": ["day", "week"],
@ -10938,6 +11118,20 @@
}
}
},
"codersdk.ListInboxNotificationsResponse": {
"type": "object",
"properties": {
"notifications": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.InboxNotification"
}
},
"unread_count": {
"type": "integer"
}
}
},
"codersdk.LogLevel": {
"type": "string",
"enum": ["trace", "debug", "info", "warn", "error"],