feat(social): add friends, private chats, inbox and music sharing
ci / module boundaries / boundaries (push) Successful in 7s
ci / api / api (push) Successful in 1m9s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m8s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m23s
ci / db / db (push) Successful in 2m29s
ci / ts / ts (packages + web) (push) Successful in 2m55s

This commit is contained in:
mrleo1nid committed 2026-10-23 03:19:29 +03:00
1 parent f1528de948
commit 0a05bfe2cd
43 files changed
+2828 -389

No files matched your search

+248
View File
@@ -4,6 +4,76 @@
*/
export interface paths {
"/api/v1/me/social": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** @description Friends, incoming/outgoing requests, own blocks and up to 100 notifications, unread first. No private account fields. */
get: operations["getSocial"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/social/people": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: operations["searchPeople"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/social/actions": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** @description Request is idempotent; accept is recipient-only. Remove cancels, declines or unfriends. Block removes friendship. Unblock never restores it. Read chat acknowledges only messages through up_to_seq. Read notification uses notification ID as target_id. */
post: operations["socialAction"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/me/social/chats/{peerId}": {
parameters: {
query?: never;
header?: never;
path: {
peerId: string;
};
cookie?: never;
};
/** @description Last 50 messages in ascending sequence order. Before loads older history. Requires current friendship, never marks messages read. */
get: operations["getDirectMessages"];
put?: never;
/** @description Friends only. Client-generated UUID makes retries idempotent; changed payload for the same ID returns 409. Playlist attachment is its active share UUID; track attachment is a catalog UUID. No arbitrary URLs. */
post: operations["sendDirectMessage"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/admin/server/updates": {
parameters: {
query?: never;
@@ -1622,6 +1692,65 @@ export interface paths {
export type webhooks = Record<string, never>;
export interface components {
schemas: {
SocialPerson: {
/** Format: uuid */
id: string;
username: string;
display_name: string;
/** @enum {string} */
relationship: "none" | "incoming" | "outgoing" | "friend" | "blocked";
unread: number;
};
SocialNotification: {
/** Format: uuid */
id: string;
/** Format: uuid */
actor_id: string;
actor_name: string;
/** @enum {string} */
kind: "friend_request" | "friend_accepted" | "message" | "music";
/** Format: date-time */
created_at: string;
read: boolean;
};
SocialInbox: {
people: components["schemas"]["SocialPerson"][];
notifications: components["schemas"]["SocialNotification"][];
unread: number;
};
SocialAction: {
/** @enum {string} */
action: "request" | "accept" | "remove" | "block" | "unblock" | "read_chat" | "read_notification";
/** Format: uuid */
target_id: string;
/** Format: int64 */
up_to_seq?: number;
};
SendDirectMessage: {
/** Format: uuid */
id: string;
text: string;
/** @enum {string} */
attachment_kind: "none" | "track" | "playlist";
/** Format: uuid */
attachment_id?: string;
};
DirectMessage: {
/** Format: uuid */
id: string;
/** Format: int64 */
seq: number;
/** Format: uuid */
sender_id: string;
text: string;
/** @enum {string} */
attachment_kind: "none" | "track" | "playlist";
/** Format: uuid */
attachment_id?: string;
/** Format: date-time */
created_at: string;
read: boolean;
};
ServerSource: {
id: string;
name: string;
@@ -2788,6 +2917,125 @@ export interface components {
}
export type $defs = Record<string, never>;
export interface operations {
getSocial: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Social inbox */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SocialInbox"];
};
};
default: components["responses"]["Problem"];
};
};
searchPeople: {
parameters: {
query: {
q: string;
};
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Up to 30 people, excluding blocked accounts and either direction of personal blocking */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SocialPerson"][];
};
};
default: components["responses"]["Problem"];
};
};
socialAction: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SocialAction"];
};
};
responses: {
/** @description Applied */
204: {
headers: {
[name: string]: unknown;
};
content?: never;
};
default: components["responses"]["Problem"];
};
};
getDirectMessages: {
parameters: {
query?: {
before?: number;
};
header?: never;
path: {
peerId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Message page */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["DirectMessage"][];
};
};
default: components["responses"]["Problem"];
};
};
sendDirectMessage: {
parameters: {
query?: never;
header?: never;
path: {
peerId: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": components["schemas"]["SendDirectMessage"];
};
};
responses: {
/** @description Stored message */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["DirectMessage"];
};
};
default: components["responses"]["Problem"];
};
};
getServerUpdates: {
parameters: {
query?: {