-
Notifications
You must be signed in to change notification settings - Fork 0
feat(chat): add chat api schemas #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| name: chatId | ||
| in: path | ||
| required: true | ||
| schema: | ||
| type: string | ||
| format: uuid |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| description: RFC 7807 problem response | ||
| content: | ||
| application/problem+json: | ||
| schema: | ||
| $ref: '../schemas/Problem.yaml' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| type: object | ||
| properties: | ||
| id: { type: string, format: uuid } | ||
| participants: | ||
| type: array | ||
| items: { $ref: './ChatParticipant.yaml' } | ||
| createdAt: { type: string, format: date-time } | ||
| updatedAt: { type: string, format: date-time } | ||
| required: [id, participants, createdAt] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| type: object | ||
| description: >- | ||
| Create a new chat. The authenticated user is added as a participant | ||
| automatically. Provide the identity IDs of other participants. | ||
| properties: | ||
| participantIds: | ||
| type: array | ||
| items: { type: string, format: uuid } | ||
| minItems: 1 | ||
| description: Identity IDs of other participants. | ||
| required: [participantIds] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| type: object | ||
| properties: | ||
| id: { type: string, format: uuid } | ||
| chatId: { type: string, format: uuid } | ||
| senderId: { type: string, format: uuid } | ||
| body: { type: string } | ||
| fileIds: | ||
| type: array | ||
| items: { type: string, format: uuid } | ||
| createdAt: { type: string, format: date-time } | ||
| required: [id, chatId, senderId, body, fileIds, createdAt] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| type: object | ||
| description: >- | ||
| Send a message in a chat. The sender is the authenticated user. | ||
| At least one of body or fileIds must be provided. | ||
| properties: | ||
| body: | ||
| type: string | ||
| description: Text content. May be empty when fileIds is non-empty. | ||
| fileIds: | ||
| type: array | ||
| items: { type: string, format: uuid } | ||
| description: File references (UUIDs). May be empty when body is non-empty. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| type: object | ||
| properties: | ||
| id: { type: string, format: uuid } | ||
| joinedAt: { type: string, format: date-time } | ||
| required: [id, joinedAt] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| type: object | ||
| description: Mark messages as read for the authenticated user. | ||
| properties: | ||
| messageIds: | ||
| type: array | ||
| items: { type: string, format: uuid } | ||
| minItems: 1 | ||
| description: Message UUIDs to acknowledge as read. Must belong to the specified chat. | ||
| required: [messageIds] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| type: object | ||
| properties: | ||
| readCount: | ||
| type: integer | ||
| minimum: 0 | ||
| description: >- | ||
| Number of messages newly marked as read. Already-read and unknown | ||
| IDs are silently ignored for idempotency. | ||
| required: [readCount] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| type: object | ||
| properties: | ||
| items: | ||
| type: array | ||
| items: { $ref: './ChatMessage.yaml' } | ||
| nextPageToken: | ||
| type: string | ||
| description: Opaque cursor for the next page. Absent when there are no more results. | ||
| unreadCount: | ||
| type: integer | ||
| minimum: 0 | ||
| description: Number of unread messages for the authenticated user in this chat. | ||
| required: [items, unreadCount] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| type: object | ||
| properties: | ||
| items: | ||
| type: array | ||
| items: { $ref: './Chat.yaml' } | ||
| nextPageToken: | ||
| type: string | ||
| description: Opaque cursor for the next page. Absent when there are no more results. | ||
| required: [items] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| type: object | ||
| properties: | ||
| type: { type: string, format: uri } | ||
| title: { type: string } | ||
| status: { type: integer } | ||
| detail: { type: string } | ||
| instance: { type: string, format: uri } | ||
| required: [title, status] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| openapi: 3.0.3 | ||
| info: | ||
| title: Chat API | ||
| version: 0.1.0 | ||
| servers: | ||
| - url: https://api.example.com | ||
| tags: | ||
| - name: Chats | ||
| - name: Messages | ||
| paths: | ||
| /chats: | ||
| $ref: './paths/chats.yaml' | ||
| /chats/{chatId}/messages: | ||
| $ref: './paths/chat-messages.yaml' | ||
| /chats/{chatId}/read: | ||
| $ref: './paths/chat-read.yaml' | ||
| components: | ||
| parameters: | ||
| ChatIdPath: | ||
| $ref: './components/parameters/ChatIdPath.yaml' | ||
| responses: | ||
| ProblemResponse: | ||
| $ref: './components/responses/ProblemResponse.yaml' | ||
| schemas: | ||
| Problem: | ||
| $ref: './components/schemas/Problem.yaml' | ||
| Chat: | ||
| $ref: './components/schemas/Chat.yaml' | ||
| ChatParticipant: | ||
| $ref: './components/schemas/ChatParticipant.yaml' | ||
| ChatCreateRequest: | ||
| $ref: './components/schemas/ChatCreateRequest.yaml' | ||
| PaginatedChats: | ||
| $ref: './components/schemas/PaginatedChats.yaml' | ||
| ChatMessage: | ||
| $ref: './components/schemas/ChatMessage.yaml' | ||
| ChatMessageCreateRequest: | ||
| $ref: './components/schemas/ChatMessageCreateRequest.yaml' | ||
| PaginatedChatMessages: | ||
| $ref: './components/schemas/PaginatedChatMessages.yaml' | ||
| MarkAsReadRequest: | ||
| $ref: './components/schemas/MarkAsReadRequest.yaml' | ||
| MarkAsReadResponse: | ||
| $ref: './components/schemas/MarkAsReadResponse.yaml' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| get: | ||
| operationId: getChatMessages | ||
| tags: [Messages] | ||
| summary: List messages | ||
| description: >- | ||
| List messages in a chat with cursor-based pagination. | ||
| Includes unread count for the authenticated user. | ||
| Read-only — does not change acknowledgment state. | ||
| parameters: | ||
| - $ref: '../components/parameters/ChatIdPath.yaml' | ||
| - in: query | ||
| name: pageSize | ||
| schema: | ||
| type: integer | ||
| minimum: 1 | ||
| maximum: 100 | ||
| default: 20 | ||
| description: Maximum number of messages to return. | ||
| - in: query | ||
| name: pageToken | ||
| schema: | ||
| type: string | ||
| description: Opaque cursor from a previous response's nextPageToken. | ||
| responses: | ||
| '200': | ||
| description: OK | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/PaginatedChatMessages.yaml' | ||
| default: | ||
| $ref: '../components/responses/ProblemResponse.yaml' | ||
| post: | ||
| operationId: sendChatMessage | ||
| tags: [Messages] | ||
| summary: Send message | ||
| description: >- | ||
| Send a message in a chat. The sender is the authenticated user. | ||
| At least one of body or fileIds must be provided. | ||
| parameters: | ||
| - $ref: '../components/parameters/ChatIdPath.yaml' | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/ChatMessageCreateRequest.yaml' | ||
| responses: | ||
| '201': | ||
| description: Created | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/ChatMessage.yaml' | ||
| default: | ||
| $ref: '../components/responses/ProblemResponse.yaml' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| post: | ||
| operationId: markChatAsRead | ||
| tags: [Messages] | ||
| summary: Mark messages as read | ||
| description: >- | ||
| Mark messages as read for the authenticated user. Delegates to | ||
| Threads AckMessages. Already-read and unknown IDs are silently | ||
| ignored for idempotency. | ||
| parameters: | ||
| - $ref: '../components/parameters/ChatIdPath.yaml' | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/MarkAsReadRequest.yaml' | ||
| responses: | ||
| '200': | ||
| description: OK | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/MarkAsReadResponse.yaml' | ||
| default: | ||
| $ref: '../components/responses/ProblemResponse.yaml' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| get: | ||
| operationId: getChats | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] The chat path files include Not blocking — ideally the older specs would be backfilled with |
||
| tags: [Chats] | ||
| summary: List chats | ||
| description: >- | ||
| List chats for the authenticated user with cursor-based pagination. | ||
| parameters: | ||
| - in: query | ||
| name: pageSize | ||
| schema: | ||
| type: integer | ||
| minimum: 1 | ||
| maximum: 100 | ||
| default: 20 | ||
| description: Maximum number of chats to return. | ||
| - in: query | ||
| name: pageToken | ||
| schema: | ||
| type: string | ||
| description: Opaque cursor from a previous response's nextPageToken. | ||
| responses: | ||
| '200': | ||
| description: OK | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/PaginatedChats.yaml' | ||
| default: | ||
| $ref: '../components/responses/ProblemResponse.yaml' | ||
| post: | ||
| operationId: createChat | ||
| tags: [Chats] | ||
| summary: Create chat | ||
| description: >- | ||
| Create a new chat thread. The authenticated user is automatically | ||
| added as a participant. | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/ChatCreateRequest.yaml' | ||
| responses: | ||
| '201': | ||
| description: Created | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../components/schemas/Chat.yaml' | ||
| default: | ||
| $ref: '../components/responses/ProblemResponse.yaml' | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[minor] This schema has no
requiredlist, so{}is a valid request body at the schema level. The "at least one of body or fileIds" rule is documented in the description but is invisible to schema validators and codegen.Consider adding a comment or using an OpenAPI description on the schema itself to make it explicit this is enforced server-side. Alternatively, if there's a dominant use case (e.g., most messages have a body), you could require
bodyand keepfileIdsoptional — though that changes the contract slightly.Not a blocker since the constraint is well-documented in descriptions here and in the proto, but worth noting for consumers relying on schema validation.