diff --git a/api/v1.yaml b/api/v1.yaml
index 7453be5..652067e 100644
--- a/api/v1.yaml
+++ b/api/v1.yaml
@@ -27,10 +27,10 @@ paths:
description: Successfully retrieved interest data
content:
application/json:
- schema:
- type: array
- items:
- $ref: '#/components/schemas/TokenInfo'
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/TokenInfo'
'401':
description: Unauthorized
content:
@@ -70,8 +70,8 @@ paths:
type: string
content:
application/json:
- schema:
- $ref: '#/components/schemas/VkAuthCallbackResponse'
+ schema:
+ $ref: '#/components/schemas/VkAuthCallbackResponse'
'400':
description: Bad request
content:
@@ -201,8 +201,8 @@ paths:
description: Successfully saved user search query
content:
application/json:
- schema:
- $ref: '#/components/schemas/SaveUserQueryResponse'
+ schema:
+ $ref: '#/components/schemas/SaveUserQueryResponse'
'400':
description: Bad request
content:
@@ -247,10 +247,10 @@ paths:
description: Successfully retrieved user search queries
content:
application/json:
- schema:
- type: array
- items:
- $ref: '#/components/schemas/UserSearchQuery'
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UserSearchQuery'
'401':
description: Unauthorized
content:
@@ -336,6 +336,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
+ '404':
+ description: Token not found
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
'409':
description: Conflict - already subscribed
content:
@@ -431,6 +437,49 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
+ put:
+ tags: [user]
+ summary: Update user's token subscription
+ operationId: updateUserTokenSub
+ security:
+ - cookieAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateUserTokenSubRequest'
+ responses:
+ '200':
+ description: Successfully updated user's token sub
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateUserTokenSubResponse'
+ '400':
+ description: Bad request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ '401':
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ '404':
+ description: Not found
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
+ '500':
+ description: Internal server error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Error'
components:
securitySchemes:
@@ -613,6 +662,9 @@ components:
type: string
method:
type: string
+ threshold:
+ type: number
+ format: float64
current_interest:
type: number
format: float64
@@ -622,7 +674,31 @@ components:
last_scan:
type: string
format: date-time
- required: [id, token, category, method, current_interest, previous_interest, last_scan]
+ required: [id, token, category, method, threshold, current_interest, previous_interest, last_scan]
+ UpdateUserTokenSubRequest:
+ type: object
+ properties:
+ id:
+ type: string
+ minLength: 1
+ maxLength: 128
+ threshold:
+ type: number
+ method:
+ type: string
+ minLength: 1
+ maxLength: 128
+ required: [id, threshold, method]
+ UpdateUserTokenSubResponse:
+ type: object
+ properties:
+ current_interest:
+ type: number
+ format: float64
+ previous_interest:
+ type: number
+ format: float64
+ required: [current_interest, previous_interest]
Error:
type: object
diff --git a/app/pages/token-subscriptions/ui/token-subscriptions.ui.tsx b/app/pages/token-subscriptions/ui/token-subscriptions.ui.tsx
index 314c332..28ae11f 100644
--- a/app/pages/token-subscriptions/ui/token-subscriptions.ui.tsx
+++ b/app/pages/token-subscriptions/ui/token-subscriptions.ui.tsx
@@ -117,6 +117,11 @@ export const TokenSubscriptionsPage = () => {
{mapMethodToLabel(subscription.method)}
+
+
+ Уведомить при изменении на{' '}
+ {Math.round((subscription.threshold - 1) * 100)}%
+
diff --git a/app/shared/api/gen/v1.d.ts b/app/shared/api/gen/v1.d.ts
index cd1489f..8539a03 100644
--- a/app/shared/api/gen/v1.d.ts
+++ b/app/shared/api/gen/v1.d.ts
@@ -117,7 +117,8 @@ export interface paths {
};
/** Get user's token subs */
get: operations['getUserTokenSubs'];
- put?: never;
+ /** Update user's token subscription */
+ put: operations['updateUserTokenSub'];
/** Subscribe user to specified token */
post: operations['subscribeUserToToken'];
/** Delete user's token subscription */
@@ -209,12 +210,25 @@ export interface components {
category: string;
method: string;
/** Format: float64 */
+ threshold: number;
+ /** Format: float64 */
current_interest: number;
/** Format: float64 */
previous_interest: number;
/** Format: date-time */
last_scan: string;
};
+ UpdateUserTokenSubRequest: {
+ id: string;
+ threshold: number;
+ method: string;
+ };
+ UpdateUserTokenSubResponse: {
+ /** Format: float64 */
+ current_interest: number;
+ /** Format: float64 */
+ previous_interest: number;
+ };
Error: {
error: string;
};
@@ -663,6 +677,66 @@ export interface operations {
};
};
};
+ updateUserTokenSub: {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ requestBody: {
+ content: {
+ 'application/json': components['schemas']['UpdateUserTokenSubRequest'];
+ };
+ };
+ responses: {
+ /** @description Successfully updated user's token sub */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['UpdateUserTokenSubResponse'];
+ };
+ };
+ /** @description Bad request */
+ 400: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Unauthorized */
+ 401: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Not found */
+ 404: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ /** @description Internal server error */
+ 500: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
+ };
+ };
subscribeUserToToken: {
parameters: {
query?: never;
@@ -703,6 +777,15 @@ export interface operations {
'application/json': components['schemas']['Error'];
};
};
+ /** @description Token not found */
+ 404: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ 'application/json': components['schemas']['Error'];
+ };
+ };
/** @description Conflict - already subscribed */
409: {
headers: {
diff --git a/app/shared/api/mocks.ts b/app/shared/api/mocks.ts
index 14657ea..1753179 100644
--- a/app/shared/api/mocks.ts
+++ b/app/shared/api/mocks.ts
@@ -141,6 +141,7 @@ export const mockFetch = async (input: RequestInfo, init?: RequestInit) => {
token: 'россия',
category: 'news',
method: 'denormalized',
+ threshold: 1.5,
current_interest: 55,
previous_interest: 0,
last_scan: '2026-01-09T00:00:00Z',