{ "swagger": "2.0", "info": { "contact": {} }, "paths": { "/activities": { "get": { "description": "Возвращает список действий пользователей с пагинацией", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Activities" ], "summary": "Получить активность пользователей", "parameters": [ { "type": "integer", "description": "Family ID", "name": "family_id", "in": "query" }, { "type": "integer", "description": "User ID", "name": "user_id", "in": "query" }, { "type": "integer", "description": "Limit, default 10", "name": "limit", "in": "query" }, { "type": "integer", "description": "Offset", "name": "offset", "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/dto.ActivityListResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/families": { "post": { "description": "Создает новую семью", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Families" ], "summary": "Создать семью", "parameters": [ { "description": "Family info", "name": "family", "in": "body", "required": true, "schema": { "$ref": "#/definitions/domain.CreateFamilyRequest" } } ], "responses": { "201": { "description": "Created", "schema": { "$ref": "#/definitions/domain.FamilyResponse" } }, "400": { "description": "invalid body", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "500": { "description": "internal server error", "schema": { "type": "object", "additionalProperties": { "type": "string" } } } } } }, "/families/{id}": { "get": { "description": "Возвращает семью по ее внутреннему ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Families" ], "summary": "Получить семью по ID", "parameters": [ { "type": "integer", "description": "Family ID", "name": "id", "in": "path", "required": true } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.FamilyResponse" } }, "400": { "description": "invalid id", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "404": { "description": "family not found", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "500": { "description": "internal server error", "schema": { "type": "object", "additionalProperties": { "type": "string" } } } } }, "delete": { "description": "Удаляет семью по ее ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Families" ], "summary": "Удалить семью", "parameters": [ { "type": "integer", "description": "Family ID", "name": "id", "in": "path", "required": true } ], "responses": { "204": { "description": "no content", "schema": { "type": "string" } }, "400": { "description": "invalid id", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "404": { "description": "family not found", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "500": { "description": "internal server error", "schema": { "type": "object", "additionalProperties": { "type": "string" } } } } }, "patch": { "description": "Частично обновляет данные семьи по ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Families" ], "summary": "Обновить семью", "parameters": [ { "type": "integer", "description": "Family ID", "name": "id", "in": "path", "required": true }, { "description": "Данные для обновления", "name": "family", "in": "body", "required": true, "schema": { "$ref": "#/definitions/domain.UpdateFamilyRequest" } } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.FamilyResponse" } }, "400": { "description": "name is required", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "404": { "description": "family not found", "schema": { "type": "object", "additionalProperties": { "type": "string" } } }, "500": { "description": "internal server error", "schema": { "type": "object", "additionalProperties": { "type": "string" } } } } } }, "/receipts": { "post": { "description": "Загружает чек из внешнего сервиса и опционально автоматически создает связанную транзакцию", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Receipts" ], "summary": "Загрузить чек", "parameters": [ { "description": "Receipt payload", "name": "receipt", "in": "body", "required": true, "schema": { "$ref": "#/definitions/domain.AddReceiptRequest" } } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.AddReceiptResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/receipts/photo": { "post": { "description": "Принимает фото, распознает текст через Google OCR и создает чек с позициями; опционально создает связанную транзакцию", "consumes": [ "multipart/form-data" ], "produces": [ "application/json" ], "tags": [ "Receipts" ], "summary": "Загрузить чек по фото", "parameters": [ { "type": "file", "description": "Receipt photo", "name": "photo", "in": "formData", "required": true }, { "type": "integer", "description": "Family ID for auto-created transaction", "name": "family_id", "in": "formData" }, { "type": "integer", "description": "User ID for auto-created transaction", "name": "created_by", "in": "formData" }, { "type": "string", "description": "Transaction type, default expense", "name": "type", "in": "formData" }, { "type": "string", "description": "Transaction category, default receipt", "name": "category", "in": "formData" }, { "type": "string", "description": "Transaction description override", "name": "description", "in": "formData" } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.AddReceiptResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/transactions": { "get": { "description": "Возвращает список транзакций с фильтрами и пагинацией", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Получить список транзакций", "parameters": [ { "type": "integer", "description": "Family ID", "name": "family_id", "in": "query" }, { "type": "integer", "description": "User ID", "name": "created_by", "in": "query" }, { "type": "string", "description": "Transaction type", "name": "type", "in": "query" }, { "type": "string", "description": "Category", "name": "category", "in": "query" }, { "type": "string", "description": "RFC3339 start datetime", "name": "date_from", "in": "query" }, { "type": "string", "description": "RFC3339 end datetime", "name": "date_to", "in": "query" }, { "type": "integer", "description": "Limit, default 50", "name": "limit", "in": "query" }, { "type": "integer", "description": "Offset", "name": "offset", "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/dto.TransactionListResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } }, "post": { "description": "Создает новую транзакцию и при необходимости привязывает к ней чек", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Создать транзакцию", "parameters": [ { "description": "Transaction payload", "name": "transaction", "in": "body", "required": true, "schema": { "$ref": "#/definitions/dto.CreateTransactionRequest" } } ], "responses": { "201": { "description": "Created", "schema": { "$ref": "#/definitions/dto.TransactionResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "404": { "description": "Not Found", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/transactions/analytics": { "get": { "description": "Возвращает расходы, доходы и total за период. При фильтре по type второй тип возвращается как 0.", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Получить аналитику по транзакциям", "parameters": [ { "type": "integer", "description": "Family ID", "name": "family_id", "in": "query" }, { "type": "string", "description": "Transaction type: income or expense", "name": "type", "in": "query" }, { "type": "string", "description": "RFC3339 start datetime", "name": "date_from", "in": "query", "required": true }, { "type": "string", "description": "RFC3339 end datetime", "name": "date_to", "in": "query", "required": true } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/dto.TransactionAnalyticsResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/transactions/{id}": { "get": { "description": "Возвращает транзакцию по ее внутреннему ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Получить транзакцию по ID", "parameters": [ { "type": "integer", "description": "Transaction ID", "name": "id", "in": "path", "required": true } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/dto.TransactionResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "404": { "description": "Not Found", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } }, "delete": { "description": "Удаляет транзакцию по ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Удалить транзакцию", "parameters": [ { "type": "integer", "description": "Transaction ID", "name": "id", "in": "path", "required": true } ], "responses": { "204": { "description": "no content", "schema": { "type": "string" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "404": { "description": "Not Found", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } }, "patch": { "description": "Частично обновляет данные транзакции и связь с чеком", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Transactions" ], "summary": "Обновить транзакцию", "parameters": [ { "type": "integer", "description": "Transaction ID", "name": "id", "in": "path", "required": true }, { "description": "Transaction patch payload", "name": "transaction", "in": "body", "required": true, "schema": { "$ref": "#/definitions/dto.UpdateTransactionRequest" } } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/dto.TransactionResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "404": { "description": "Not Found", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/dto.ErrorResponse" } } } } }, "/users": { "post": { "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Users" ], "summary": "Создать пользователя", "parameters": [ { "description": "User info", "name": "user", "in": "body", "required": true, "schema": { "$ref": "#/definitions/domain.CreateUserRequest" } } ], "responses": { "201": { "description": "Created", "schema": { "$ref": "#/definitions/domain.UserResponse" } }, "400": { "description": "Bad Request", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "500": { "description": "Internal Server Error", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } } } } }, "/users/by-telegram/{telegramId}": { "get": { "description": "Возвращает пользователя по его Telegram ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Users" ], "summary": "Получить пользователя по Telegram ID", "parameters": [ { "type": "integer", "description": "Telegram ID", "name": "telegramId", "in": "path", "required": true } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.UserResponse" } }, "400": { "description": "invalid telegram id", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "500": { "description": "internal server error", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } } } } }, "/users/{id}": { "get": { "description": "Возвращает пользователя по его внутреннему ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Users" ], "summary": "Получить пользователя по ID", "parameters": [ { "type": "integer", "description": "User ID", "name": "id", "in": "path", "required": true } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.UserResponse" } }, "400": { "description": "invalid id", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "500": { "description": "internal server error", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } } } }, "delete": { "description": "Удаляет пользователя по его ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Users" ], "summary": "Удалить пользователя", "parameters": [ { "type": "integer", "description": "User ID", "name": "id", "in": "path", "required": true } ], "responses": { "204": { "description": "no content", "schema": { "type": "string" } }, "400": { "description": "invalid id", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "500": { "description": "internal server error", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } } } }, "patch": { "description": "Частично обновляет данные пользователя по ID", "consumes": [ "application/json" ], "produces": [ "application/json" ], "tags": [ "Users" ], "summary": "Обновить пользователя", "parameters": [ { "type": "integer", "description": "User ID", "name": "id", "in": "path", "required": true }, { "description": "Данные для обновления", "name": "user", "in": "body", "required": true, "schema": { "$ref": "#/definitions/domain.UpdateUserRequest" } } ], "responses": { "200": { "description": "OK", "schema": { "$ref": "#/definitions/domain.UserResponse" } }, "400": { "description": "invalid id or invalid body", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "404": { "description": "user not found", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } }, "500": { "description": "internal server error", "schema": { "$ref": "#/definitions/domain.UserErrorResponse" } } } } } }, "definitions": { "domain.AddReceiptRequest": { "type": "object", "required": [ "date", "number" ], "properties": { "category": { "type": "string" }, "created_by": { "type": "integer" }, "date": { "type": "string" }, "description": { "type": "string" }, "family_id": { "type": "integer" }, "number": { "type": "string", "maxLength": 24, "minLength": 24 }, "type": { "type": "string" } } }, "domain.AddReceiptResponse": { "type": "object", "properties": { "date": { "type": "string" }, "id": { "type": "integer" }, "number": { "type": "string" }, "transaction_id": { "type": "integer" } } }, "domain.CreateFamilyRequest": { "type": "object", "properties": { "name": { "type": "string" }, "owner_id": { "type": "integer" }, "telegram_chat_id": { "type": "integer" }, "telegram_chat_name": { "type": "string" } } }, "domain.CreateUserRequest": { "type": "object", "required": [ "first_name", "telegram_id" ], "properties": { "first_name": { "type": "string" }, "language_code": { "type": "string" }, "last_name": { "type": "string" }, "telegram_id": { "type": "integer" }, "username": { "type": "string" } } }, "domain.FamilyResponse": { "type": "object", "properties": { "created_at": { "type": "string" }, "id": { "type": "integer" }, "name": { "type": "string" }, "owner_id": { "type": "integer" }, "telegram_chat_id": { "type": "integer" }, "telegram_chat_name": { "type": "string" }, "updated_at": { "type": "string" } } }, "domain.UpdateFamilyRequest": { "type": "object", "properties": { "name": { "type": "string" }, "telegram_chat_id": { "type": "integer" }, "telegram_chat_name": { "type": "string" } } }, "domain.UpdateUserRequest": { "type": "object", "properties": { "first_name": { "type": "string" }, "language_code": { "type": "string" }, "last_name": { "type": "string" }, "username": { "type": "string" } } }, "domain.UserErrorResponse": { "type": "object", "properties": { "error": { "type": "string" } } }, "domain.UserResponse": { "type": "object", "properties": { "created_at": { "type": "string" }, "first_name": { "type": "string" }, "id": { "type": "integer" }, "language_code": { "type": "string" }, "last_name": { "type": "string" }, "telegram_id": { "type": "integer" }, "updated_at": { "type": "string" }, "username": { "type": "string" } } }, "dto.ActivityListResponse": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/definitions/dto.ActivityResponse" } }, "limit": { "type": "integer" }, "offset": { "type": "integer" } } }, "dto.ActivityResponse": { "type": "object", "properties": { "action": { "type": "string" }, "created_at": { "type": "string" }, "description": { "type": "string" }, "entity_id": { "type": "integer" }, "entity_type": { "type": "string" }, "family_id": { "type": "integer" }, "id": { "type": "integer" }, "user_id": { "type": "integer" } } }, "dto.CreateTransactionRequest": { "type": "object", "required": [ "amount", "category", "created_by", "datetime", "family_id", "type" ], "properties": { "amount": { "type": "number" }, "category": { "type": "string" }, "created_by": { "type": "integer" }, "datetime": { "type": "string" }, "description": { "type": "string" }, "family_id": { "type": "integer" }, "receipt_id": { "type": "integer" }, "type": { "type": "string" } } }, "dto.ErrorResponse": { "type": "object", "properties": { "message": { "type": "string" } } }, "dto.TransactionAnalyticsResponse": { "type": "object", "properties": { "expenses": { "type": "number" }, "incomes": { "type": "number" }, "total": { "type": "number" } } }, "dto.TransactionListResponse": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/definitions/dto.TransactionResponse" } } } }, "dto.TransactionResponse": { "type": "object", "properties": { "amount": { "type": "number" }, "category": { "type": "string" }, "created_at": { "type": "string" }, "created_by": { "type": "integer" }, "datetime": { "type": "string" }, "description": { "type": "string" }, "family_id": { "type": "integer" }, "id": { "type": "integer" }, "receipt_id": { "type": "integer" }, "type": { "type": "string" } } }, "dto.UpdateTransactionRequest": { "type": "object", "properties": { "amount": { "type": "number" }, "category": { "type": "string" }, "datetime": { "type": "string" }, "description": { "type": "string" }, "detach_receipt": { "type": "boolean" }, "receipt_id": { "type": "integer" }, "type": { "type": "string" } } } } }