{ "openapi": "3.0.0", "paths": { "/api/auth/login": { "post": { "operationId": "AuthController_login", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginDto" } } } }, "responses": { "200": { "description": "Login successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponseDto" } } } }, "401": { "description": "Invalid credentials" } }, "summary": "Login with email and password", "tags": [ "auth" ] } }, "/api/auth/refresh": { "post": { "operationId": "AuthController_refreshTokens", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefreshTokenDto" } } } }, "responses": { "200": { "description": "Token refreshed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponseDto" } } } }, "401": { "description": "Invalid refresh token" } }, "summary": "Refresh access token", "tags": [ "auth" ] } }, "/api/auth/keycloak/config": { "get": { "operationId": "AuthController_getKeycloakConfig", "parameters": [], "responses": { "200": { "description": "Keycloak config", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KeycloakConfigDto" } } } } }, "summary": "Get Keycloak configuration for frontend", "tags": [ "auth" ] } }, "/api/auth/keycloak/login": { "get": { "operationId": "AuthController_keycloakLogin", "parameters": [ { "name": "redirectTo", "required": false, "in": "query", "description": "Frontend path to redirect after login", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Login URL generated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KeycloakLoginUrlDto" } } } }, "400": { "description": "Keycloak not enabled" } }, "summary": "Get Keycloak login URL (initiates OAuth flow)", "tags": [ "auth" ] } }, "/api/auth/keycloak/callback": { "get": { "operationId": "AuthController_keycloakCallback", "parameters": [ { "name": "code", "required": true, "in": "query", "description": "Authorization code from Keycloak", "schema": { "type": "string" } }, { "name": "error", "required": false, "in": "query", "description": "Error message if authentication failed", "schema": { "type": "string" } }, { "name": "error_description", "required": false, "in": "query", "description": "Error description", "schema": { "type": "string" } }, { "name": "state", "required": true, "in": "query", "description": "State parameter for CSRF validation", "schema": { "type": "string" } } ], "responses": { "302": { "description": "Redirect to frontend with tokens" }, "401": { "description": "Authentication failed" } }, "summary": "Keycloak OAuth callback endpoint", "tags": [ "auth" ] } }, "/api/auth/keycloak": { "post": { "operationId": "AuthController_keycloakBearerLogin", "parameters": [], "responses": { "200": { "description": "Login successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponseDto" } } } }, "401": { "description": "Invalid Keycloak token" } }, "security": [ { "bearer": [] } ], "summary": "Login with Keycloak bearer token (Authorization: Bearer )", "tags": [ "auth" ] } }, "/api/users/me": { "get": { "operationId": "UserController_getProfile", "parameters": [], "responses": { "200": { "description": "User profile retrieved" }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Get current user profile", "tags": [ "users" ] }, "put": { "operationId": "UserController_updateProfile", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateUserDto" } } } }, "responses": { "200": { "description": "Profile updated" }, "401": { "description": "Unauthorized" }, "409": { "description": "Email or username already exists" } }, "security": [ { "bearer": [] } ], "summary": "Update current user profile", "tags": [ "users" ] }, "delete": { "operationId": "UserController_deleteAccount", "parameters": [], "responses": { "200": { "description": "Account deleted" }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Delete user account", "tags": [ "users" ] } }, "/api/users/me/password": { "put": { "operationId": "UserController_updatePassword", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePasswordDto" } } } }, "responses": { "200": { "description": "Password updated successfully" }, "401": { "description": "Current password incorrect" } }, "security": [ { "bearer": [] } ], "summary": "Update user password", "tags": [ "users" ] } }, "/api/characters": { "post": { "operationId": "CharacterController_create", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCharacterDto" } } } }, "responses": { "201": { "description": "Character created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CharacterResponseDto" } } } }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Create a new character", "tags": [ "characters" ] }, "get": { "operationId": "CharacterController_findAll", "parameters": [], "responses": { "200": { "description": "List of characters", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CharacterResponseDto" } } } } }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Get all characters for current user", "tags": [ "characters" ] } }, "/api/characters/{id}": { "get": { "operationId": "CharacterController_findOne", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Character found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CharacterResponseDto" } } } }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Character not found" } }, "security": [ { "bearer": [] } ], "summary": "Get character by ID", "tags": [ "characters" ] }, "put": { "operationId": "CharacterController_update", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCharacterDto" } } } }, "responses": { "200": { "description": "Character updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CharacterResponseDto" } } } }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Character not found" } }, "security": [ { "bearer": [] } ], "summary": "Update character", "tags": [ "characters" ] }, "delete": { "operationId": "CharacterController_delete", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Character deleted" }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Character not found" } }, "security": [ { "bearer": [] } ], "summary": "Delete character", "tags": [ "characters" ] } }, "/api/conversations": { "post": { "operationId": "ChatController_createConversation", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateConversationDto" } } } }, "responses": { "201": { "description": "Conversation created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationResponseDto" } } } }, "401": { "description": "Unauthorized" }, "404": { "description": "Character not found" } }, "security": [ { "bearer": [] } ], "summary": "Create a new conversation", "tags": [ "conversations" ] }, "get": { "operationId": "ChatController_getConversations", "parameters": [], "responses": { "200": { "description": "List of conversations", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ConversationResponseDto" } } } } }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Get all conversations for current user", "tags": [ "conversations" ] } }, "/api/conversations/{id}": { "get": { "operationId": "ChatController_getConversation", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Conversation ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Conversation found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationWithMessagesResponseDto" } } } }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Conversation not found" } }, "security": [ { "bearer": [] } ], "summary": "Get conversation by ID with messages", "tags": [ "conversations" ] }, "delete": { "operationId": "ChatController_deleteConversation", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Conversation ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Conversation deleted" }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Conversation not found" } }, "security": [ { "bearer": [] } ], "summary": "Delete conversation", "tags": [ "conversations" ] } }, "/api/conversations/{id}/messages": { "post": { "operationId": "ChatController_sendMessage", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Conversation ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendMessageDto" } } } }, "responses": { "200": { "description": "Message sent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendMessageResponseDto" } } } }, "401": { "description": "Unauthorized" }, "403": { "description": "Access denied" }, "404": { "description": "Conversation not found" } }, "security": [ { "bearer": [] } ], "summary": "Send a message in a conversation", "tags": [ "conversations" ] } }, "/api/import/characters/{characterId}/files": { "post": { "operationId": "ImportController_uploadFile", "parameters": [ { "name": "characterId", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "type": "string", "format": "binary", "description": "File to upload (.txt, .md)" } } } } } }, "responses": { "201": { "description": "File uploaded and processing" }, "400": { "description": "Invalid file type" }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Upload a file for character knowledge", "tags": [ "import" ] } }, "/api/import/knowledge/{knowledgeId}/status": { "get": { "operationId": "ImportController_getKnowledgeStatus", "parameters": [ { "name": "knowledgeId", "required": true, "in": "path", "description": "Knowledge ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Knowledge status" }, "401": { "description": "Unauthorized" }, "404": { "description": "Knowledge not found" } }, "security": [ { "bearer": [] } ], "summary": "Get knowledge processing status", "tags": [ "import" ] } }, "/api/import/characters/{characterId}/knowledge": { "get": { "operationId": "ImportController_getCharacterKnowledge", "parameters": [ { "name": "characterId", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of knowledge" }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Get all knowledge for a character", "tags": [ "import" ] } }, "/api/import/knowledge/{knowledgeId}": { "delete": { "operationId": "ImportController_deleteKnowledge", "parameters": [ { "name": "knowledgeId", "required": true, "in": "path", "description": "Knowledge ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Knowledge deleted" }, "401": { "description": "Unauthorized" }, "404": { "description": "Knowledge not found" } }, "security": [ { "bearer": [] } ], "summary": "Delete knowledge", "tags": [ "import" ] } }, "/api/import/characters/{characterId}/url": { "post": { "operationId": "ImportController_importFromUrl", "parameters": [ { "name": "characterId", "required": true, "in": "path", "description": "Character ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImportUrlDto" } } } }, "responses": { "201": { "description": "URL content is being imported and processed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadResponseDto" } } } }, "400": { "description": "Invalid URL or unsupported website" }, "401": { "description": "Unauthorized" } }, "security": [ { "bearer": [] } ], "summary": "Import content from URL for character knowledge", "tags": [ "import" ] } } }, "info": { "title": "DreamChat API", "description": "The DreamChat API documentation", "version": "1.0.0", "contact": {} }, "tags": [], "servers": [], "components": { "securitySchemes": { "bearer": { "scheme": "bearer", "bearerFormat": "JWT", "type": "http" } }, "schemas": { "LoginDto": { "type": "object", "properties": { "email": { "type": "string", "description": "User email address", "example": "admin@dreamchat.local" }, "password": { "type": "string", "description": "User password", "example": "password123" } }, "required": [ "email", "password" ] }, "UserDto": { "type": "object", "properties": { "id": { "type": "string", "description": "User ID", "example": "550e8400-e29b-41d4-a716-446655440000" }, "email": { "type": "string", "description": "User email", "example": "admin@dreamchat.local" }, "username": { "type": "string", "description": "User username", "example": "admin" }, "role": { "type": "string", "description": "User role", "example": "USER", "enum": [ "USER", "ADMIN" ] } }, "required": [ "id", "email", "username", "role" ] }, "AuthResponseDto": { "type": "object", "properties": { "accessToken": { "type": "string", "description": "JWT access token" }, "refreshToken": { "type": "string", "description": "JWT refresh token" }, "user": { "description": "User information", "allOf": [ { "$ref": "#/components/schemas/UserDto" } ] } }, "required": [ "accessToken", "refreshToken", "user" ] }, "RefreshTokenDto": { "type": "object", "properties": { "refreshToken": { "type": "string", "description": "Refresh token", "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } }, "required": [ "refreshToken" ] }, "KeycloakConfigDto": { "type": "object", "properties": { "enabled": { "type": "boolean", "description": "Whether Keycloak authentication is enabled" }, "url": { "type": "string", "description": "Keycloak realm URL" }, "realm": { "type": "string", "description": "Keycloak realm name" }, "clientId": { "type": "string", "description": "Keycloak client ID" } }, "required": [ "enabled" ] }, "KeycloakLoginUrlDto": { "type": "object", "properties": { "loginUrl": { "type": "string", "description": "Keycloak login URL to redirect the user to" }, "state": { "type": "string", "description": "State parameter for CSRF protection" } }, "required": [ "loginUrl", "state" ] }, "UpdateUserDto": { "type": "object", "properties": { "email": { "type": "string", "description": "New email address", "example": "newemail@example.com" }, "username": { "type": "string", "description": "New username", "example": "newusername" } } }, "UpdatePasswordDto": { "type": "object", "properties": { "currentPassword": { "type": "string", "description": "Current password", "example": "oldpassword123" }, "newPassword": { "type": "string", "description": "New password", "example": "newpassword123" } } }, "CreateCharacterDto": { "type": "object", "properties": { "name": { "type": "string", "description": "Character name", "example": "Alice the Explorer" }, "avatarUrl": { "type": "string", "description": "Avatar URL", "example": "https://example.com/avatar.jpg" }, "personalityPrompt": { "type": "string", "description": "Personality prompt that guides AI responses", "example": "You are Alice, a curious and adventurous explorer..." }, "attributes": { "type": "object", "description": "Custom attributes (JSON)", "example": { "age": 25, "traits": [ "curious", "brave" ] } }, "config": { "type": "object", "description": "Character configuration (JSON)", "example": { "voice": "friendly" } }, "isPublic": { "type": "boolean", "description": "Whether the character is publicly visible", "example": false } }, "required": [ "name", "personalityPrompt" ] }, "CharacterResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Character ID", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "description": "Character name", "example": "Alice the Explorer" }, "avatarUrl": { "type": "string", "description": "Avatar URL", "example": "https://example.com/avatar.jpg" }, "personalityPrompt": { "type": "string", "description": "Personality prompt", "example": "You are Alice, a curious explorer..." }, "attributes": { "type": "object", "description": "Custom attributes", "example": { "age": 25, "traits": [ "curious" ] } }, "config": { "type": "object", "description": "Character configuration", "example": {} }, "isPublic": { "type": "boolean", "description": "Whether character is public", "example": false }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation date" }, "updatedAt": { "format": "date-time", "type": "string", "description": "Last update date" }, "userId": { "type": "string", "description": "User ID", "example": "550e8400-e29b-41d4-a716-446655440000" } }, "required": [ "id", "name", "personalityPrompt", "attributes", "config", "isPublic", "createdAt", "updatedAt", "userId" ] }, "UpdateCharacterDto": { "type": "object", "properties": { "name": { "type": "string", "description": "Character name", "example": "Alice the Explorer" }, "avatarUrl": { "type": "string", "description": "Avatar URL", "example": "https://example.com/avatar.jpg" }, "personalityPrompt": { "type": "string", "description": "Personality prompt", "example": "You are Alice..." }, "attributes": { "type": "object", "description": "Custom attributes (JSON)" }, "config": { "type": "object", "description": "Character configuration (JSON)" }, "isPublic": { "type": "boolean", "description": "Whether the character is publicly visible" } } }, "CreateConversationDto": { "type": "object", "properties": { "characterId": { "type": "string", "description": "Character ID to chat with", "example": "550e8400-e29b-41d4-a716-446655440000" }, "title": { "type": "string", "description": "Conversation title", "example": "My Adventure with Alice" } }, "required": [ "characterId" ] }, "CharacterSummaryDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Character ID" }, "name": { "type": "string", "description": "Character name" }, "avatarUrl": { "type": "string", "description": "Avatar URL" } }, "required": [ "id", "name" ] }, "ConversationResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Conversation ID" }, "title": { "type": "string", "description": "Conversation title" }, "characterId": { "type": "string", "description": "Character ID" }, "messageCount": { "type": "number", "description": "Number of messages" }, "totalTokens": { "type": "number", "description": "Total tokens used" }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation date" }, "updatedAt": { "format": "date-time", "type": "string", "description": "Last update date" }, "character": { "description": "Character info", "allOf": [ { "$ref": "#/components/schemas/CharacterSummaryDto" } ] } }, "required": [ "id", "characterId", "messageCount", "totalTokens", "createdAt", "updatedAt" ] }, "MessageResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Message ID" }, "role": { "type": "string", "description": "Message role", "enum": [ "user", "assistant", "system" ] }, "content": { "type": "string", "description": "Message content" }, "tokensUsed": { "type": "number", "description": "Tokens used" }, "model": { "type": "string", "description": "Model used" }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation date" } }, "required": [ "id", "role", "content", "createdAt" ] }, "ConversationWithMessagesResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Conversation ID" }, "title": { "type": "string", "description": "Conversation title" }, "characterId": { "type": "string", "description": "Character ID" }, "messageCount": { "type": "number", "description": "Number of messages" }, "totalTokens": { "type": "number", "description": "Total tokens used" }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation date" }, "updatedAt": { "format": "date-time", "type": "string", "description": "Last update date" }, "character": { "description": "Character info", "allOf": [ { "$ref": "#/components/schemas/CharacterSummaryDto" } ] }, "messages": { "description": "Messages in conversation", "type": "array", "items": { "$ref": "#/components/schemas/MessageResponseDto" } } }, "required": [ "id", "characterId", "messageCount", "totalTokens", "createdAt", "updatedAt", "messages" ] }, "SendMessageDto": { "type": "object", "properties": { "content": { "type": "string", "description": "Message content", "example": "Hello! Tell me about yourself." } }, "required": [ "content" ] }, "SendMessageResponseDto": { "type": "object", "properties": { "userMessage": { "description": "User message", "allOf": [ { "$ref": "#/components/schemas/MessageResponseDto" } ] }, "assistantMessage": { "description": "Assistant response", "allOf": [ { "$ref": "#/components/schemas/MessageResponseDto" } ] } }, "required": [ "userMessage", "assistantMessage" ] }, "ImportUrlDto": { "type": "object", "properties": { "url": { "type": "string", "description": "URL to import", "example": "https://sakurazaka46.com/s/s46/diary/detail/68008" } }, "required": [ "url" ] }, "UploadResponseDto": { "type": "object", "properties": { "knowledgeId": { "type": "string", "description": "Knowledge ID" }, "message": { "type": "string", "description": "Status message" } }, "required": [ "knowledgeId", "message" ] } } } }