first commit
Some checks failed
Publish NPM Package / Publish Job (push) Failing after 1m34s

This commit is contained in:
lendry
2026-05-21 21:49:32 +03:00
commit fbe3b0327c
48 changed files with 5523 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
syntax = "proto3";
package glifa.auth.v1;
import "google/protobuf/timestamp.proto";
import "glifa/common/v1/types.proto";
import "glifa/common/v1/authz.proto";
import "glifa/auth/v1/types.proto";
option go_package = "glifa/contracts/gen/go/auth/v1;authv1";
service AuthService {
rpc Register(RegisterRequest) returns (RegisterResponse);
rpc LoginWithPassword(LoginWithPasswordRequest) returns (LoginWithPasswordResponse);
rpc VerifySecondFactor(VerifySecondFactorRequest) returns (VerifySecondFactorResponse);
rpc RefreshSession(RefreshSessionRequest) returns (RefreshSessionResponse);
rpc LogoutSession(LogoutSessionRequest) returns (LogoutSessionResponse);
rpc RevokeSession(RevokeSessionRequest) returns (RevokeSessionResponse);
rpc LockSession(LockSessionRequest) returns (LockSessionResponse);
rpc UnlockSession(UnlockSessionRequest) returns (UnlockSessionResponse);
rpc ValidateAccessToken(ValidateAccessTokenRequest) returns (ValidateAccessTokenResponse);
rpc GetSession(GetSessionRequest) returns (GetSessionResponse);
rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse);
rpc CreateQrLogin(CreateQrLoginRequest) returns (CreateQrLoginResponse);
rpc ApproveQrLogin(ApproveQrLoginRequest) returns (ApproveQrLoginResponse);
rpc ExchangeQrLogin(ExchangeQrLoginRequest) returns (ExchangeQrLoginResponse);
rpc SendAuthChallenge(SendAuthChallengeRequest) returns (SendAuthChallengeResponse);
rpc VerifyAuthChallenge(VerifyAuthChallengeRequest) returns (VerifyAuthChallengeResponse);
rpc ListSecurityEvents(ListSecurityEventsRequest) returns (ListSecurityEventsResponse);
}
message RegisterRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string username = 2; // Уникальное имя пользователя, которое будет использоваться для входа в систему
string email = 3; // Электронная почта пользователя, которая может использоваться для входа в систему и получения уведомлений
string phone = 4; // Номер телефона пользователя, который может использоваться для входа в систему и получения уведомлений
string password = 5; // Пароль пользователя, который будет использоваться для аутентификации при входе в систему
string display_name = 6; // Отображаемое имя пользователя, которое будет показываться другим пользователям в системе
string device_id = 7; // UUID устройства, с которого пользователь регистрируется, для отслеживания и управления сессиями на разных устройствах
string device_name = 8; // Человекочитаемое название устройства, с которого пользователь регистрируется (например, "iPhone 12", "Windows PC"), для удобства отображения в интерфейсе управления сессиями
string platform = 9; // Платформа устройства, с которого пользователь регистрируется (например, "iOS", "Android", "Web"), для аналитики и оптимизации работы сессий на разных платформах
string app_version = 10; // Версия приложения, с которого пользователь регистрируется, для аналитики и оптимизации работы сессий на разных версиях приложения
}
message RegisterResponse {
string user_id = 1; // UUID нового пользователя, который был зарегистрирован
TokenPair tokens = 2; // Пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями
DeviceSession session = 3; // Данные о сессии, которая была создана для нового пользователя на устройстве, с которого он регистрировался
}
message LoginWithPasswordRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string login = 2; // Имя пользователя, электронная почта или номер телефона, которые пользователь использует для входа в систему
string password = 3; // Пароль пользователя, который будет использоваться для аутентификации при входе в систему
string device_id = 4; // UUID устройства, с которого пользователь входит в систему, для отслеживания и управления сессиями на разных устройствах
string device_name = 5; // Человекочитаемое название устройства, с которого пользователь входит в систему (например, "iPhone 12", "Windows PC"), для удобства отображения в интерфейсе управления сессиями
string platform = 6; // Платформа устройства, с которого пользователь входит в систему (например, "iOS", "Android", "Web"), для аналитики и оптимизации работы сессий на разных платформах
string app_version = 7; // Версия приложения, с которого пользователь входит в систему, для аналитики и оптимизации работы сессий на разных версиях приложения
}
message LoginWithPasswordResponse {
oneof result {
TokenPair tokens = 1; // Пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями, если вход выполнен успешно
LoginChallenge second_factor_required = 2; // Данные о вызове второго фактора аутентификации, если он требуется для входа в систему
}
DeviceSession session = 3; // Данные о сессии, которая была создана для пользователя на устройстве, с которого он входит в систему (может быть полезно для отображения информации о текущей сессии в интерфейсе управления сессиями)
}
message VerifySecondFactorRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string login_challenge_id = 2; // UUID вызова второго фактора аутентификации, который был возвращен при попытке входа в систему
string totp_code = 3; // TOTP-код, который пользователь сгенерировал в своем приложении для аутентификации (например, Google Authenticator), для подтверждения второго фактора аутентификации
string recovery_code = 4; // Код восстановления, который пользователь получил при настройке второго фактора аутентификации, для подтверждения второго фактора аутентификации в случае, если TOTP-коды недоступны
}
message VerifySecondFactorResponse {
TokenPair tokens = 1; // Пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями, если второй фактор аутентификации был успешно подтвержден
DeviceSession session = 2; // Данные о сессии, которая была создана для пользователя на устройстве, с которого он входит в систему (может быть полезно для отображения информации о текущей сессии в интерфейсе управления сессиями)
}
message RefreshSessionRequest{
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string refresh_token = 2; // Токен обновления, который был выдан при аутентификации и может быть использован для получения новой пары токенов доступа и обнов
}
message RefreshSessionResponse{
TokenPair tokens = 1; // Новая пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями, если токен обновления был успешно подтвержден
DeviceSession session = 2; // Данные о сессии, которая была обновлена для пользователя на устройстве, с которого он входит в систему (может быть полезно для отображения информации о текущей сессии в интерфейсе управления сессиями)
bool family_rotated = 3; // Флаг, указывающий, была ли выполнена ротация всей семьи токенов (т.е. были ли отозваны все другие активные сессии пользователя), что может быть полезно для безопасности и управления сессиями
}
message LogoutSessionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string session_id = 2; // UUID сессии, которую пользователь хочет завершить (например, текущая сессия или другая активная сессия на другом устройстве)
}
message LogoutSessionResponse {
bool success = 1; // Флаг, указывающий, была ли сессия успешно завершена
}
message RevokeSessionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string session_id = 2; // UUID сессии, которую пользователь хочет отозвать (например, текущая сессия или другая активная сессия на другом устройстве)
string reason = 3; // Причина отзыва сессии, которая может быть полезна для аудита и безопасности (например, "user_logout", "password_change", "suspicious_activity")
}
message RevokeSessionResponse {
DeviceSession session = 1; // Данные о сессии, которая была отозвана, включая ее статус и метаданные, что может быть полезно для отображения информации о сессиях в интерфейсе управления сессиями
}
message LockSessionRequest{
glifa.common.v1.RequestMeta meta = 1;
string session_id = 2;
string reason = 3;
}
message LockSessionResponse{
DeviceSession session = 1;
}
message UnlockSessionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string session_id = 2; // UUID сессии, которую пользователь хочет разблок
oneof proof {
string password = 3; // Пароль пользователя, который будет использоваться для подтверждения личности при разблокировке сессии
string challenge_id = 4; // UUID вызова аутентификационного челленджа, который был отправлен пользователю для подтверждения личности при разблокировке сессии
}
string code = 5; // Код из аутентификационного челленджа, который пользователь получил и должен предоставить для подтверждения личности при разблокировке сессии
}
message UnlockSessionResponse {
DeviceSession session = 1; // Данные о сессии, которая была разблокирована, включая ее статус и метаданные, что может быть полезно для отображения информации о сессиях в интерфейсе управления сессиями
TokenPair tokens = 2; // Пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями, если разблокировка сессии была успешно подтверждена
}
message ValidateAccessTokenRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string access_token = 2; // Токен доступа, который нужно проверить на валидность и получить связанную с ним информацию о сессии и правах доступа
}
message ValidateAccessTokenResponse {
bool valid = 1; // Флаг, указывающий, является ли токен доступа валидным (т.е. не истекшим, не отозванным и правильно подписанным)
string user_id = 2; // UUID пользователя, которому принадлежит этот токен доступа, если он валиден
string session_id = 3; // UUID сессии, с которой связан этот ток
string device_id = 4; // UUID устройства, с которого был выдан этот токен доступа, если он валиден
uint64 token_version = 5; // Версия токена, которая может быть полезна для управления ротацией токенов и обеспечения безопасности
google.protobuf.Timestamp expires_at = 6; // Временная метка истечения срока действия токена доступа, которая может быть полезна для управления сессиями и обеспечения безопасности
DeviceSessionStatus session_status = 7; // Статус сессии, с которой связан этот токен доступа (например, "active", "locked", "revoked"), который может быть полезен для управления сессиями и обеспечения безопасности
glifa.common.v1.SubjectContext subject = 8; // Контекст субъекта, связанный с этим токеном доступа, который может включать информацию о ролях и правах доступа пользователя для авторизации при доступе к ресурсам системы
}
message GetSessionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string session_id = 2; // UUID сессии, которую пользователь хочет получить
}
message GetSessionResponse {
DeviceSession session = 1; // Данные о запрошенной сессии, включая ее статус и метаданные, что может быть полезно для отображения информации о сессиях в интерфейсе управления сессиями
}
message ListSessionsRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string user_id = 2; // UUID пользователя, для которого нужно получить список сессий
}
message ListSessionsResponse {
repeated DeviceSession sessions = 1; // Список сессий, связанных с указанным пользователем, включая их статус и метаданные, что может быть полезно для отображения информации о сессиях в интерфейсе управления сессиями
}
message CreateQrLoginRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string device_id = 2; // UUID устройства, с которого пользователь инициирует QR-вход, для отслеживания и управления сессиями на разных устройствах
string device_name = 3; // Человекочитаемое название устройства, с которого пользователь инициирует QR-вход (например, "iPhone 12", "Windows PC"), для удобства отображения в интерфейсе управления сессиями
string platform = 4; // Платформа устройства, с которого пользователь инициирует QR-вход (например, "iOS", "Android", "Web"), для аналитики и оптимизации работы сессий на разных
string app_version = 5; // Версия приложения, с которого пользователь инициирует QR-вход, для аналитики и оптимизации работы сессий на разных версиях приложения
}
message CreateQrLoginResponse{
QrLoginRequest request = 1; // Данные о созданном QR-запросе, включая его UUID и время истечения срока действия, которые могут быть использованы для отображения QR-кода и управления процессом QR-входа
string qr_payload = 2; // Строка, которая может быть сериализована в QR-код и содержит информацию, необходимую для выполнения QR-входа (например, UUID запроса и URL для обмена данными между устройствами)
}
message ApproveQrLoginRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string request_id = 2; // UUID QR-запроса, который пользователь хочет одобрить для выполнения QR-входа
}
message ApproveQrLoginResponse {
QrLoginRequest request = 1; // Данные о QR-запросе, который был одобрен, включая его UUID и время истечения срока действия, которые могут быть использованы для управления процессом QR-входа
}
message ExchangeQrLoginRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string request_id = 2; // UUID QR-запроса, который был одобрен и для которого пользователь хочет получить токены доступа и обновления для выполнения QR-входа
string proof = 3; // Доказательство, которое может быть предоставлено пользователем для подтверждения своей личности при обмене QR-запроса на токены доступа и обновления (например, код из аутентификационного челленджа или другой механизм подтверждения)
}
message ExchangeQrLoginResponse {
TokenPair tokens = 1; // Пара токенов доступа и обновления, которая может быть использована для аутентификации и управления сессиями, если обмен QR-запроса был успешно подтвержден
DeviceSession session = 2; // Данные о сессии, которая была создана для пользователя на устройстве, с которого он выполняет QR-вход (может быть полезно для отображения информации о текущей сессии в интерфейсе управления сессиями)
}
message SendAuthChallengeRequest{
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string target = 2; // Цель, на которую должен быть отправлен аутентификационный челлендж (например, электронная почта или номер телефона пользователя)
AuthChallengePurpose purpose = 3; // Цель аутентификационного челленджа, которая может быть полезна для определения типа и содержания челленджа (например, "login", "unlock_session", "verify_identity")
AuthChallengeDeliveryChannel delivery_channel = 4; // Канал доставки аутентификационного челленджа, который может быть полезен для оптимизации процесса доставки и обеспечения безопасности (например, "email", "sms", "push_notification")
}
message SendAuthChallengeResponse{
AuthChallenge challenge = 1; // Данные о созданном аутентификационном челлендже, включая его UUID, код и время истечения срока действия, которые могут быть использованы для подтверждения личности пользователя при выполнении различных действий в системе
}
message VerifyAuthChallengeRequest{
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string challenge_id = 2; // UUID аутентификационного челленджа, который был отправлен пользователю и который он предоставляет для подтверждения своей личности
string code = 3; // Код из аутентификационного челленджа, который пользователь получил и должен предоставить для подтверждения своей личности
}
message VerifyAuthChallengeResponse{
AuthChallenge challenge = 1; // Данные о аутентификационном челлендже, который был успешно подтвержден, включая его UUID и время истечения срока действия, которые могут быть использованы для управления процессом подтверждения личности пользователя при выполнении различных действий в системе
bool verified = 2; // Флаг, указывающий, был ли аутентификационный челлендж успешно подтвержден, что может быть полезно для управления процессом подтверждения личности пользователя при выполнении различных действий в системе
}
message ListSecurityEventsRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string user_id = 2; // UUID пользователя, для которого нужно получить список событий безопасности
glifa.common.v1.PageRequest page = 3; // Параметры пагинации (номер страницы и размер страницы)
}
message ListSecurityEventsResponse {
repeated SecurityEvent events = 1; // Список событий безопасности, связанных с указанным пользователем, включая их тип, время и метаданные, что может быть полезно для отображения информации о безопасности в интерфейсе управления сессиями и обеспечения безопасности
glifa.common.v1.PageResponse page = 2; // Информация о пагинации (номер страницы, размер страницы, общее количество элементов) для списка событий безопасности, что может быть полезно для отображения информации о безопасности в интерфейсе управления сессиями и обеспечения безопасности
}

View File

@@ -0,0 +1,150 @@
syntax = "proto3";
package glifa.auth.v1;
import "google/protobuf/timestamp.proto";
option go_package = "glifa/contracts/gen/go/glifa/auth/v1;authv1";
enum DeviceSessionStatus{
DEVICE_SESSION_STATUS_UNSPECIFIED = 0; // Неопределенный статус сессии устройства
DEVICE_SESSION_STATUS_ACTIVE = 1; // Сессия устройства активна и используется
DEVICE_SESSION_STATUS_LOCKED = 2; // Сессия устройства заблокирована (например, из-за подозрительной активности)
DEVICE_SESSION_STATUS_REQUIRES_2FA = 3; // Сессия устройства требует двухфакторной аутентификации для продолжения
DEVICE_SESSION_STATUS_REQUIRES_REAUTH = 4; // Сессия устройства требует повторной аутентификации (например, после длительного периода неактивности)
DEVICE_SESSION_STATUS_REVOKED = 5; // Сессия устройства отозвана (например, из-за нарушения безопасности)
DEVICE_SESSION_STATUS_EXPIRED = 6; // Сессия устройства истекла (например, после определенного периода времени)
DEVICE_SESSION_STATUS_COMPROMISED = 7; // Сессия устройства скомпрометирована (например, обнаружена утечка учетных данных)
}
enum AuthChallengePurpose {
AUTH_CHALLENGE_PURPOSE_UNSPECIFIED = 0; // Неопределенная цель аутентификационного вызова
AUTH_CHALLENGE_PURPOSE_LOGIN = 1; // Вызов для аутентификации при входе в систему
AUTH_CHALLENGE_PURPOSE_PASSWORD_RESET = 2; // Вызов для аутентификации при сбросе пароля
AUTH_CHALLENGE_PURPOSE_EMAIL_VERIFICATION = 3; // Вызов для аутентификации при подтверждении электронной почты
AUTH_CHALLENGE_PURPOSE_PHONE_VERIFICATION = 4; // Вызов для аутентификации при подтверждении номера телефона
AUTH_CHALLENGE_PURPOSE_SESSION_UNLOCK = 5; // Вызов для аутентификации при разблокировке сессии
AUTH_CHALLENGE_PURPOSE_REAUTH = 6; // Вызов для аутентификации при повторной аутентификации (например, после длительного периода неактивности)
AUTH_CHALLENGE_PURPOSE_QR_APPROVAL = 7; // Вызов для аутентификации при одобрении входа через QR-код на другом устройстве
}
enum AuthChallengeDeliveryChannel {
AUTH_CHALLENGE_DELIVERY_CHANNEL_UNSPECIFIED = 0; // Неопределенный канал доставки аутентификационного вызова
AUTH_CHALLENGE_DELIVERY_CHANNEL_EMAIL = 1; // Канал доставки - электронная почта
AUTH_CHALLENGE_DELIVERY_CHANNEL_SMS = 2; // Канал доставки - SMS
AUTH_CHALLENGE_DELIVERY_CHANNEL_TOTP = 3; // Канал доставки - TOTP (например, Google Authenticator)
AUTH_CHALLENGE_DELIVERY_CHANNEL_INTERNAL = 4; // Канал доставки - внутренний (например, push-уведомление в мобильном приложении)
}
enum AuthChallengeType {
AUTH_CHALLENGE_TYPE_UNSPECIFIED = 0; // Неопределенный тип аутентификационного вызова
AUTH_CHALLENGE_TYPE_CODE = 1; // Вызов с кодом подтверждения (например, 6-значный код из SMS или TOTP)
AUTH_CHALLENGE_TYPE_LINK = 2; // Вызов с ссылкой для подтверждения (например, magic link в электронной почте)
AUTH_CHALLENGE_TYPE_TOTP = 3; // Вызов с TOTP (например, код из Google Authenticator)
AUTH_CHALLENGE_TYPE_APPROVAL = 4; // Вызов с запросом на одобрение (например, push-уведомление для одобрения входа на другом устройстве)
}
enum AuthChallengeStatus {
AUTH_CHALLENGE_STATUS_UNSPECIFIED = 0; // Неопределенный статус аутентификационного вызова
AUTH_CHALLENGE_STATUS_PENDING = 1; // Вызов создан и ожидает подтверждения пользователем
AUTH_CHALLENGE_STATUS_VERIFIED = 2; // Вызов успешно подтвержден пользователем
AUTH_CHALLENGE_STATUS_CONSUMED = 3; // Вызов уже был использован для подтверждения и больше не действителен
AUTH_CHALLENGE_STATUS_EXPIRED = 4; // Вызов истек и больше не действителен (например, после определенного периода времени)
AUTH_CHALLENGE_STATUS_BLOCKED = 5; // Вызов заблокирован (например, из-за подозрительной активности)
}
enum QrLoginRequestStatus {
QR_LOGIN_REQUEST_STATUS_UNSPECIFIED = 0; // Неопределенный статус запроса на вход через QR-код
QR_LOGIN_REQUEST_STATUS_PENDING = 1; // Запрос на вход через QR-код создан и ожидает сканирования пользователем
QR_LOGIN_REQUEST_STATUS_APPROVED = 2; // Запрос на вход через QR-код одобрен пользователем (например, через мобильное приложение)
QR_LOGIN_REQUEST_STATUS_CONSUMED = 3; // Запрос на вход через QR-код уже был использован для входа и больше не действителен
QR_LOGIN_REQUEST_STATUS_EXPIRED = 4; // Запрос на вход через QR-код истек и больше не действителен (например, после определенного периода времени)
QR_LOGIN_REQUEST_STATUS_REJECTED = 5; // Запрос на вход через QR-код отклонен пользователем (например, через мобильное приложение)
}
enum SecurityEventType {
SECURITY_EVENT_TYPE_UNSPECIFIED = 0; // Неопределенный тип события безопасности
SECURITY_EVENT_TYPE_LOGIN_SUCCESS = 1; // Событие успешного входа в систему
SECURITY_EVENT_TYPE_LOGIN_FAILED = 2; // Событие неудачного входа в систему (например, из-за неправильного пароля)
SECURITY_EVENT_TYPE_CHALLENGE_SEND = 3; // Событие отправки аутентификационного вызова пользователю (например, отправка SMS с кодом подтверждения)
SECURITY_EVENT_TYPE_CHALLENGE_VERIFIED = 4; // Событие успешного подтверждения аутентификационного вызова пользователем (например, пользователь ввел правильный код подтверждения)
SECURITY_EVENT_TYPE_TWO_FACTOR_ENABLED = 5; // Событие включения двухфакторной аутентификации пользователем
SECURITY_EVENT_TYPE_TWO_FACTOR_DISABLED = 6; // Событие отключения двухфакторной аутентификации пользователем
SECURITY_EVENT_TYPE_SESSION_CREATED = 7; // Событие создания новой сессии пользователя
SECURITY_EVENT_TYPE_SESSION_LOCKED = 8; // Событие блокировки сессии пользователя (например, из-за подозрительной активности)
SECURITY_EVENT_TYPE_SESSION_UNLOCKED = 9; // Событие разблокировки сессии пользователя (например, после успешной аутентификации)
SECURITY_EVENT_TYPE_SESSION_REVOKED = 10; // Событие отзыва сессии пользователя (например, из-за нарушения безопасности)
SECURITY_EVENT_TYPE_SESSION_COMPROMISED = 11; // Событие компрометации сессии пользователя (например, обнаружена утечка учетных данных)
SECURITY_EVENT_TYPE_QR_APPROVED = 12; // Событие одобрения входа через QR-код на другом устройстве
SECURITY_EVENT_TYPE_QR_CONSUMED = 13; // Событие использования запроса на вход через QR-код для входа в систему
SECURITY_EVENT_TYPE_QR_EXPIRED = 14; // Событие истечения срока действия запроса на вход через QR-код
}
message DeviceSession {
string id = 1; // UUID сессии устройства
string user_id = 2; // UUID пользователя, которому принадлежит сессия устройства
string device_id = 3; // UUID устройства, с которого была создана сесс
string device_name = 4; // Человеко-читаемое имя устройства (например, "iPhone 12 Pro")
string platform = 5; // Платформа устройства (например, "iOS", "Android", "Web")
string app_version = 6; // Версия приложения, с которого была создана сессия устройства
DeviceSessionStatus status = 7; // Статус сессии устройства
string last_ip = 8; // Последний IP-адрес, с которого была активна сессия устройства
string user_agent = 9; // User-Agent устройства, с которого была создана сессия
google.protobuf.Timestamp last_seen_at = 10; // Время последней активности сессии устройства
google.protobuf.Timestamp soft_lock_at = 11; // Время, когда сессия устройства была мягко заблокирована (например, из-за подозрительной активности, но еще не отозвана)
google.protobuf.Timestamp expires_at = 12; // Время истечения срока действия сессии устройства (например, после определенного периода времени неактивности)
google.protobuf.Timestamp created_at = 13; // Время создания сессии устройства
google.protobuf.Timestamp updated_at = 14; // Время последнего обновления сессии устройства
}
message TokenPair{
string access_token = 1; // JWT access token для аутентификации API-запросов
google.protobuf.Timestamp access_token_expires_at = 2; // Время истечения срока действия access token
string refresh_token = 3; // JWT refresh token для получения нового access token после истечения срока действия
google.protobuf.Timestamp refresh_token_expires_at = 4; // Время истечения срока действия refresh token (например, через 30 дней)
string session_id = 5; // UUID сессии, для которой был выдан токен
string user_id = 6; // UUID пользователя, которому принадлежит сессия и токен
}
message LoginChallenge{
string challenge_id = 1; // UUID аутентификационного вызова, который может быть использован для отслеживания и управления процессом аутентификации
google.protobuf.Timestamp expires_at = 2; // Временная метка, указывающая, когда этот аутентификационный вызов истекает и больше не может быть использован для подтверждения входа
}
message AuthChallenge {
string id = 1; // UUID аутентификационного вызова
string target = 2; // Цель аутентификационного вызова (например, "login", "password_reset")
AuthChallengePurpose purpose = 3; // Цель аутентификационного вызова (например, "login", "password_reset")
AuthChallengeDeliveryChannel delivery_channel = 4; // Канал доставки аутентификационного вызова (например, "email", "sms")
AuthChallengeType challenge_type = 5; // Тип аутентификационного вызова (например, "code", "link")
AuthChallengeStatus status = 6; // Статус аутентификационного вызова (например, "pending", "verified")
uint32 attempt_count = 7; // Количество попыток подтверждения аутентификационного вызова
uint32 resend_count = 8; // Количество повторных отправок аутентификационного вызова
uint32 max_attempts = 9; // Максимально допустимое количество попыток подтверждения аутентификационного вызова (например, 5)
google.protobuf.Timestamp expires_at = 10; // Время истечения срока действия аутентификационного вызова (например, через 10 минут)
google.protobuf.Timestamp consumed_at = 11; // Время, когда аутентификационный вызов был успешно подтвержден и использован
google.protobuf.Timestamp created_at = 12; // Время создания аутентификационного вызова
google.protobuf.Timestamp updated_at = 13; // Время последнего обновления аутентификационного вызова (например, при каждой попытке подтверждения или повторной отправке)
}
message QrLoginRequest {
string request_id = 1; // UUID запроса на вход через QR-код
string nonce = 2; // Случайная строка для обеспечения безопасности QR-кода
QrLoginRequestStatus status = 3; // Статус запроса на вход через QR-код (например, "pending", "approved")
google.protobuf.Timestamp expires_at = 4; // Время истечения срока действия запроса на вход через QR-код (например, через 5 минут)
google.protobuf.Timestamp approved_at = 5; // Время, когда запрос на вход через QR-код был одобрен пользователем (например, через мобильное приложение)
google.protobuf.Timestamp consumed_at = 6; // Время, когда запрос на вход через QR-код был использован для входа в систему
google.protobuf.Timestamp created_at = 7; // Время создания запроса на вход через QR-код
}
message SecurityEvent {
string id = 1; // UUID события безопасности
string user_id = 2; // UUID пользователя, которому относится событие безопасности
string session_id = 3; // UUID сессии, если событие безопасности связано с конкретной сессией пользователя
SecurityEventType event_type = 4; // Тип события безопасности (например, "login_success", "challenge_verified")
string ip_address = 5; // IP-адрес, с которого произошло событие безопасности
string user_agent = 6; // User-Agent, с которого произошло событие безопасности
string details_json = 7; // Дополнительные детали события безопасности в формате JSON (например, информация о вызове аутентификационного вызова, который был подтвержден)
google.protobuf.Timestamp created_at = 8; // Время создания события безопасности
}

View File

@@ -0,0 +1,146 @@
syntax = "proto3";
package glifa.channel.v1;
import "google/protobuf/struct.proto";
import "glifa/common/v1/types.proto";
import "glifa/channel/v1/types.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/gen/go/glifa/channel/v1;channelv1";
service ChannelService{
rpc CreateChannel(CreateChannelRequest) returns (CreateChannelResponse);
rpc GetChannel(GetChannelRequest) returns (GetChannelResponse);
rpc Subscribe(SubscribeRequest) returns (SubscribeResponse);
rpc Unsubscribe(UnsubscribeRequest) returns (UnsubscribeResponse);
rpc CreatePost(CreatePostRequest) returns (CreatePostResponse);
rpc EditPost(EditPostRequest) returns (EditPostResponse);
rpc DeletePost(DeletePostRequest) returns (DeletePostResponse);
rpc GetPost(GetPostRequest) returns (GetPostResponse);
rpc GetFeed(GetFeedRequest) returns (GetFeedResponse);
rpc UpdateReadOffset(UpdateReadOffsetRequest) returns (UpdateReadOffsetResponse);
rpc GetReadOffset(GetReadOffsetRequest) returns (GetReadOffsetResponse);
}
message CreateChannelRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string owner_user_id = 2; // UUID пользователя, который создает канал
string handle = 3; // Уникальный идентификатор канала (например, "general", "random")
string title = 4; // Название канала
string description = 5; // Описание канала
bool is_private = 6; // Флаг, указывающий, является ли канал приватным (только по приглашениям)
}
message CreateChannelResponse {
Channel channel = 1; // Данные созданного канала
}
message GetChannelRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string owner_user_id = 2; // UUID пользователя, который создал канал
string handle = 3; // Уникальный идентификатор канала (например, "general", "random")
string title = 4; // Название канала
string description = 5; // Описание канала
bool is_private = 6; // Флаг, указывающий, является ли канал приватным (только по приглашениям)
}
message GetChannelResponse {
Channel channel = 1; // Данные запрошенного канала
}
message SubscribeRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, в который пользователь хочет подписаться
string user_id = 3; // UUID пользователя, который хочет подписаться на канал
}
message SubscribeResponse {
ChannelSubscriber subscriber = 1; // Данные о новом подписчике канала
}
message UnsubscribeRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, из которого пользователь хочет отписаться
string user_id = 3; // UUID пользователя, который хочет отписаться от канала
}
message UnsubscribeResponse {
bool success = 1; // Флаг, указывающий, была ли операция отписки успешной
}
message CreatePostRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, в котором пользователь хочет создать пост
string client_post_id = 3; // Идентификатор поста, сгенерированный на клиенте (для обеспечения идемпотентности при повторной отправке)
glifa.common.v1.MessageContentType message_type = 4; // Тип контента поста (например, "text", "image", "file")
string text = 5; // Текст поста (если message_type == "text")
string file_id = 6; // UUID файла, прикрепленного к посту (если message_type == "file")
google.protobuf.Struct metadata = 7; // Дополнительные метаданные поста в виде произвольной JSON-структуры (например, для хранения информации о медиа-контенте)
}
message CreatePostResponse {
ChannelPost post = 1; // Данные созданного поста
}
message EditPostRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string post_id = 2; // UUID поста, который пользователь хочет отредактировать
string text = 3; // Новый текст поста (если message_type == "text")
google.protobuf.Struct metadata = 4; // Новые дополнительные метаданные поста в виде произвольной JSON-структуры (например, для обновления информации о медиа-контенте)
}
message EditPostResponse {
ChannelPost post = 1; // Данные отредактированного поста
}
message DeletePostRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string post_id = 2; // UUID поста, который пользователь хочет удалить
}
message DeletePostResponse {
bool success = 1; // Флаг, указывающий, была ли операция удаления успешной
}
message GetPostRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string post_id = 2; // UUID поста, который пользователь хочет получить
}
message GetPostResponse {
ChannelPost post = 1; // Данные запрошенного поста
}
message GetFeedRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, для которого пользователь хочет получить ленту постов
glifa.common.v1.PageRequest page = 3; // Параметры пагинации (номер страницы и размер страницы)
}
message GetFeedResponse {
repeated ChannelPost items = 1; // Список постов в запрошенной странице ленты
glifa.common.v1.PageResponse page = 2; // Информация о пагинации (номер страницы, размер страницы, общее количество элементов)
}
message UpdateReadOffsetRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, для которого пользователь хочет обновить оффсет прочтения
string read_post_seq = 3; // Максимальный последовательный номер поста, который пользователь прочитал в канале (включительно)
}
message UpdateReadOffsetResponse {
ChannelReadOffset offset = 1; // Данные обновленного оффсета прочтения пользователя в канале
}
message GetReadOffsetRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса (например, для аутентификации и трассировки)
string channel_id = 2; // UUID канала, для которого пользователь хочет получить оффсет прочтения
string user_id = 3; // UUID пользователя, для которого нужно получить оффсет прочтения
}
message GetReadOffsetResponse {
ChannelReadOffset offset = 1; // Данные оффсета прочтения пользователя в канале
}

View File

@@ -0,0 +1,53 @@
syntax = "proto3";
package glifa.channel.v1;
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/get/go/channel/v1;channelv1";
message Channel{
string id = 1; // UUID канала
string handler = 2; // Идентификатор обработчика канала (например, "websocket", "mqtt")
string title = 3; // Название канала
string description = 4; // Описание канала
string owner_user_id = 5; // UUID пользователя, который создал канал
uint64 last_post_seq = 6; // Последовательный номер последнего поста в канале (для генерации новых последовательных номеров)
string last_post_id = 7; // UUID последнего поста в канале (для оптимистичной блокировки при добавлении новых постов)
bool is_private = 8; // Флаг, указывающий, является ли канал приватным (только по приглашениям)
google.protobuf.Timestamp created_at = 9; // Время создания канала
google.protobuf.Timestamp updated_at = 10; // Время последнего обновления канала (например, при изменении названия или описания)
}
message ChannelSubscriber{
string channel_id = 1; // UUID канала, на который подписан пользователь
string user_id = 2; // UUID пользователя, который подписан на канал
google.protobuf.Timestamp subscribed_at = 3; // Время подписки пользователя на канал
}
message ChannelPost{
string id = 1; // UUID поста
string channel_id = 2; // UUID канала, в котором опубликован пост
string post_seq = 3; // Последовательный номер поста в канале (для упорядочивания постов)
string client_post_id = 4; // Идентификатор поста, сгенерированный на клиенте (для обеспечения идемпотентности при повторной отправке)
string author_user_id = 5; // UUID пользователя, который создал пост
glifa.common.v1.MessageContentType message_type = 6; // Тип контента поста (например, "text", "image", "file")
string text = 7; // Текст поста (если message_type == "text")
string file_id = 8; // UUID файла, прикрепленного к посту (если message_type == "file")
google.protobuf.Struct metadata = 9; // Дополнительные метаданные поста в виде произвольной JSON-структуры (например, для хранения информации о медиа-контент
bool is_edited = 10; // Флаг, указывающий, был ли пост отредактирован после создания
uint32 edit_version = 11; // Версия редактирования поста, которая увеличивается при каждом редактировании (для оптимистичной блокировки при редактировании)
google.protobuf.Timestamp deleted_at = 12; // Время удаления поста (если пост был удален)
google.protobuf.Timestamp created_at = 13; // Время создания поста
google.protobuf.Timestamp updated_at = 14; // Время последнего обновления поста
}
message ChannelReadOffset{
string channel_id = 1; // UUID канала, для которого сохраняется смещение прочтения
string user_id = 2; // UUID пользователя, для которого сохраняется смещение прочтения
string read_post_seq = 3; // Последовательный номер последнего прочитанного поста в канале (для определения новых постов, которые пользователь еще не прочитал)
google.protobuf.Timestamp updated_at = 4; // Время последнего обновления смещения прочтения (например, при открытии канала пользователем)
}

View File

@@ -0,0 +1,26 @@
syntax = "proto3";
package glifa.common.v1;
option go_package = "glifa/contracts/gen/go/glifa/common/v1;commonv1";
message SubjectContext {
string user_id = 1; // UUID пользователя, которому принадлежат права
string device_id = 2; // UUID устройства, с которого пришел запрос (если есть)
string session_id = 3; // UUID сессии, если пользователь авторизован
repeated string global_roles = 4; // Глобальные роли пользователя (например, "admin", "moderator")
repeated string global_permissions = 5; // Глобальные права пользователя (например, "read_all", "write_all")
}
message PermissionCheck {
string resource_type = 1; // Тип ресурса (например, "user", "device", "session")
string resource_id = 2; // UUID ресурса, к которому запрашиваются права
string permission = 3; // Запрашиваемое право (например, "read", "write", "delete")
}
message PermissionDecision {
string permission = 1; // Запрашиваемое право (например, "read", "write", "delete")
bool allowed = 2; // Разрешено ли запрашиваемое право
string reason = 3; // Причина решения (например, "user_is_owner", "user_has_role_admin")
}

View File

@@ -0,0 +1,40 @@
syntax = "proto3";
package glifa.common.v1;
option go_package = "glifa/contracts/gen/go/glifa/common/v1;commonv1";
// --- Общие перечисления ---
enum SortDirection {
SORT_DIRECTION_UNSPECIFIED = 0; // Не указано
SORT_DIRECTION_ASC = 1; // По возрастанию
SORT_DIRECTION_DESC = 2; // По убыванию
}
enum Visibility {
VISIBILITY_UNSPECIFIED = 0; // Не указано
VISIBILITY_PUBLIC = 1; // Публичный ресурс, доступный всем
VISIBILITY_PRIVATE = 2; // Приватный ресурс, доступный только владельцу
VISIBILITY_INTERNAL = 3; // Внутренний ресурс, доступный только внутри системы
}
enum MessageContentType {
MESSAGE_CONTENT_TYPE_UNSPECIFIED = 0; // Не указано
MESSAGE_CONTENT_TYPE_TEXT = 1; // Текстовое сообщение
MESSAGE_CONTENT_TYPE_IMAGE = 2; // Изображение
MESSAGE_CONTENT_TYPE_VIDEO = 3; // Видео
MESSAGE_CONTENT_TYPE_AUDIO = 4; // Аудио
MESSAGE_CONTENT_TYPE_FILE = 5; // Файл
MESSAGE_CONTENT_TYPE_SYSTEM = 6; // Системное сообщение (например, уведомление о входе пользователя)
}
enum EncryptionMode {
ENCRYPTION_MODE_UNSPECIFIED = 0; // Не указано
ENCRYPTION_MODE_NONE = 1; // Без шифрования
ENCRYPTION_MODE_SERVER = 2; // Шифрование на стороне сервера
ENCRYPTION_MODE_E2EE = 3; // End-to-End шифрование
}

View File

@@ -0,0 +1,64 @@
syntax = "proto3";
package glifa.common.v1;
import "google/protobuf/timestamp.proto";
option go_package = "glifa/contracts/gen/go/glifa/common/v1;commonv1";
// --- Общие структуры ---
message Empty {}
message RequestMeta {
string request_id = 1; // UUID4 для трассировки запроса
string trace_id = 2; // UUID4 для распределенного трейсинга
string correlation_id = 3; // UUID4 для корреляции логов
string idempotency_key = 4; // UUID4 для идемпотентности операций
string actor_user_id = 5; // UUID пользователя, инициировавшего запрос (если есть)
string actor_device_id = 6; // UUID устройства, с которого пришел запрос (
string actor_session_id = 7; // UUID сессии, если пользователь авторизован
string client_ip = 8; // IP-адрес клиента, от которого пришел запрос
string user_agent = 9; // User-Agent клиента
string locale = 10; // Локаль клиента (например, "en-US")
}
message PageRequest {
uint32 limit = 1; // Количество элементов на странице
string cursor = 2; // Курсор для пагинации (например, ID последнего элемента на предыдущей странице)
}
message PageResponse {
string next_cursor = 1; // Курсор для следующей страницы (например, ID последнего элемента на текущей странице)
bool has_more = 2; // Флаг, указывающий, есть ли еще страницы
}
message StringValue {
string value = 1;
}
message BoolValue {
bool value = 1;
}
message Int64Value {
int64 value = 1;
}
message ErrorDetail {
string code = 1; // Код ошибки (например, "USER_NOT_FOUND")
string message = 2; // Человеко-читаемое сообщение об ошибке
map<string, string> fields = 3; // Дополнительные данные об ошибке
}
message ResourceRef{
string id = 1; // UUID ресурса
string type = 2; // Тип ресурса (например, "user", "device", "session")
}
message AuditStamp {
google.protobuf.Timestamp created_at = 1; // Время создания ресурса
ResourceRef created_by = 2; // Ссылка на ресурс, который создал этот ресурс
google.protobuf.Timestamp updated_at = 3; // Время последнего обновления ресурса
ResourceRef updated_by = 4; // Ссылка на ресурс, который последний обновил этот ресурс
}

View File

@@ -0,0 +1,187 @@
syntax = "proto3";
package glifa.core.v1;
import "glifa/common/v1/types.proto";
import "glifa/common/v1/authz.proto";
import "glifa/core/v1/types.proto";
import "google/protobuf/struct.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/gen/go/core/v1;corev1";
service CoreService {
rpc CreateDirectChat(CreateDirectChatRequest) returns (CreateDirectChatResponse);
rpc CreateGroupChat(CreateGroupChatRequest) returns (CreateGroupChatResponse);
rpc AddChatMember(AddChatMemberRequest) returns (AddChatMemberResponse);
rpc RemoveChatMember(RemoveChatMemberRequest) returns (RemoveChatMemberResponse);
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse);
rpc EditMessage(EditMessageRequest) returns (EditMessageResponse);
rpc DeleteMessage(DeleteMessageRequest) returns (DeleteMessageResponse);
rpc GetChat(GetChatRequest) returns (GetChatResponse);
rpc GetMessage(GetMessageRequest) returns (GetMessageResponse);
rpc GetHistory(GetHistoryRequest) returns (GetHistoryResponse);
rpc UpdateReadCursor(UpdateReadCursorRequest) returns (UpdateReadCursorResponse);
rpc GetReadCursor(GetReadCursorRequest) returns (GetReadCursorResponse);
rpc GetUserProfile(GetUserProfileRequest) returns (GetUserProfileResponse);
rpc SearchUserProfiles(SearchUserProfilesRequest) returns (SearchUserProfilesResponse);
rpc CheckPermissions(CheckPermissionsRequest) returns (CheckPermissionsResponse);
}
message CreateDirectChatRequest {
glifa.common.v1.RequestMeta meta = 1;
string initiator_user_id = 2; // UUID пользователя, который инициирует создание чата
string peer_user_id = 3; // UUID другого пользователя, с которым будет создан прямой чат
}
message CreateDirectChatResponse {
Chat chat = 1; // Информация о созданном чате
}
message CreateGroupChatRequest {
glifa.common.v1.RequestMeta meta = 1;
string created_by_user_id = 2; // UUID пользователя, который инициирует создание чата
string title = 3; // Название группового чата
repeated string member_user_ids = 4; // Список UUID пользователей, которые будут добавлены в групповой чат (может быть пустым, тогда чат будет создан без участников, кроме создателя)
}
message CreateGroupChatResponse {
Chat chat = 1; // Информация о созданном чате
}
message AddChatMemberRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, в который нужно добавить участника
string user_id = 3; // UUID пользователя, которого нужно добавить в чат
}
message AddChatMemberResponse {
ChatMember member = 1; // Информация о добавленном участнике чата
}
message RemoveChatMemberRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, из которого нужно удалить участника
string user_id = 3; // UUID пользователя, которого нужно удалить из чата
}
message RemoveChatMemberResponse {
bool success = 1; // Флаг, указывающий, был ли участник успешно удален из чата
}
message SendMessageRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, в который нужно отправить сообщение
string client_message_id = 3; // Идентификатор сообщения, сгенерированный на клиенте (для обеспечения идемпотентности при повторной отправке)
glifa.common.v1.MessageContentType message_type = 4; // Тип контента сообщения (например, "text", "image", "file")
string text = 5; // Текст сообщения (если message_type == "text")
string file_id = 6; // UUID файла, прикрепленного к сообщению (если message_type == "file")
string reply_to_message_id = 7; // UUID сообщения, на которое был дан ответ (если это
glifa.common.v1.EncryptionMode encryption_mode = 8; // Режим шифрования сообщения (например, "none", "client_side")
google.protobuf.Struct metadata = 9; // Дополнительные метаданные сообщения в виде произвольной JSON-структуры (например, для хранения информации о медиа-контенте)
}
message SendMessageResponse {
ChatMessage message = 1; // Информация о созданном сообщении
MessageSendStatus status = 2; // Статус отправки сообщения (например, "sent", "delivered", "read")
}
message EditMessageRequest {
glifa.common.v1.RequestMeta meta = 1;
string message_id = 2; // UUID сообщения, которое нужно отредактировать
string text = 3; // Новый текст сообщения (если message_type == "text")
google.protobuf.Struct metadata = 4; // Новые дополнительные метаданные сообщения в виде произвольной JSON-структуры (например, для обновления информации о медиа-контенте)
}
message EditMessageResponse {
ChatMessage message = 1; // Информация об отредактированном сообщении
}
message DeleteMessageRequest {
glifa.common.v1.RequestMeta meta = 1;
string message_id = 2; // UUID сообщения, которое нужно удалить
}
message DeleteMessageResponse {
bool success = 1; // Флаг, указывающий, было ли сообщение успешно удалено
}
message GetChatRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, информацию о котором нужно получить
}
message GetChatResponse {
Chat chat = 1; // Информация о запрошенном чате
repeated ChatMember members = 2; // Список участников чата
}
message GetMessageRequest {
glifa.common.v1.RequestMeta meta = 1;
string message_id = 2; // UUID сообщения, информацию о котором нужно получить
}
message GetMessageResponse {
ChatMessage message = 1; // Информация о запрошенном сообщении
}
message GetHistoryRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, историю которого нужно получить
glifa.common.v1.PageRequest page = 3; // Параметры пагинации для получения истории сообщений
}
message GetHistoryResponse {
repeated ChatMessage messages = 1; // Список сообщений в запрошенной истории
glifa.common.v1.PageResponse page = 2; // Информация о пагинации (номер страницы, размер страницы, общее количество сообщений)
}
message UpdateReadCursorRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, для которого нужно обновить курсор прочтения
uint64 read_chat_seq = 3; // Последовательный номер сообщения, до которого пользователь прочитал чат (включительно)
}
message UpdateReadCursorResponse {
ChatReadCursor cursor = 1; // Информация об обновленном курсоре прочтения
}
message GetReadCursorRequest {
glifa.common.v1.RequestMeta meta = 1;
string chat_id = 2; // UUID чата, для которого нужно получить курсор прочтения
string user_id = 3; // UUID пользователя, для которого нужно получить курсор прочтения
}
message GetReadCursorResponse {
ChatReadCursor cursor = 1; // Информация о курсоре прочтения, включая последний прочитанный последовательный номер сообщения в чате
}
message GetUserProfileRequest {
glifa.common.v1.RequestMeta meta = 1;
string user_id = 2; // UUID пользователя, профиль которого нужно получить
}
message GetUserProfileResponse {
UserProfile profile = 1; // Информация о запрошенном профиле пользователя
}
message SearchUserProfilesRequest {
glifa.common.v1.RequestMeta meta = 1;
string query = 2; // Строка поиска, которая может соответствовать имени пользователя, отображаемому имени или биографии
glifa.common.v1.PageRequest page = 3; // Параметры пагинации для получения результатов поиска
}
message SearchUserProfilesResponse {
repeated UserProfile items = 1; // Список профилей пользователей, которые соответствуют строке поиска
glifa.common.v1.PageResponse page = 2; // Информация о пагинации (номер страницы, размер страницы, общее количество результатов)
}
message CheckPermissionsRequest {
glifa.common.v1.RequestMeta meta = 1;
glifa.common.v1.SubjectContext subject = 2; // Контекст субъекта, для которого нужно проверить права (например, идентификатор пользователя, его роли и т.д.)
repeated glifa.common.v1.PermissionCheck checks = 3; // Список прав, которые нужно проверить для данного субъекта (например, "read" право на ресурс "chat" с
}
message CheckPermissionsResponse {
repeated glifa.common.v1.PermissionDecision decisions = 1; // Список решений по каждому запрашиваемому праву, указывающий, разрешено ли это право для данного субъекта и причину решения
}

View File

@@ -0,0 +1,93 @@
syntax = "proto3";
package glifa.core.v1;
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/gen/go/core/v1;corev1";
enum ChatType{
CHAT_TYPE_UNSPECIFIED = 0;
CHAT_TYPE_DIRECT = 1; // Прямой чат между двумя пользователями
CHAT_TYPE_GROUP = 2; // Групповой чат с несколькими участниками
}
enum ChatMemberStatus {
CHAT_MEMBER_STATUS_UNSPECIFIED = 0;
CHAT_MEMBER_STATUS_ACTIVE = 1; // Участник активно участвует в чате
CHAT_MEMBER_STATUS_LEFT = 2; // Участник покинул чат
CHAT_MEMBER_STATUS_REMOVED = 3; // Участник был удален из чата
CHAT_MEMBER_STATUS_BANNED = 4; // Участник был заблокирован в чате
}
enum MessageSendStatus{
MESSAGE_SEND_STATUS_UNSPECIFIED = 0;
MESSAGE_SEND_STATUS_ACCEPTED = 1; // Сообщение принято в обработку
MESSAGE_SEND_STATUS_DEDUPLICATED = 2; // Сообщение является дубликатом (например, повторная отправка с тем же client_message_id)
}
message UserProfile{
string user_id = 1; // UUID пользователя
string username = 2; // Уникальное имя пользователя (например, "john_doe")
string display_name = 3; // Отображаемое имя пользователя (например, "John Doe")
string bio = 4; // Биография пользователя
string avatar_media_object_id = 5; // UUID медиа-объекта, который используется в качестве аватара пользователя
google.protobuf.Timestamp created_at = 6; // Время создания профиля пользователя
google.protobuf.Timestamp updated_at = 7; // Время последнего обновления профиля пользователя
}
message Chat {
string id = 1; // UUID чата
ChatType type = 2; // Тип чата (прямой или групповой)
string title = 3; // Название чата (для группового чата)
string created_by_user_id = 4; // UUID пользователя, который создал чат
uint64 last_chat_seq = 5; // Последовательный номер последнего сообщения в чате (начинается с 0, увеличивается на 1 для каждого нового сообщения)
string last_message_id = 6; // UUID последнего сообщения в чате
google.protobuf.Timestamp created_at = 7; // Время создания чата
google.protobuf.Timestamp updated_at = 8; // Время последнего обновления чата
}
message ChatMember {
string chat_id = 1; // UUID чата, к которому относится этот участник
string user_id = 2; // UUID пользователя, который является участником чата
ChatMemberStatus status = 3; // Статус участника в чате (активный, покинувший, удаленный, заблокированный)
google.protobuf.Timestamp joined_at = 4; // Время, когда пользователь присоединился к чату
google.protobuf.Timestamp updated_at = 5; // Время последнего обновления статуса участника в чате
}
message ChatRole{
string id = 1; // UUID роли в чате
string chat_id = 2; // UUID чата, к которому относится эта роль
string key = 3; // Уникальный ключ роли (например, "admin", "member")
string title = 4; // Человекочитаемое название роли (например, "Администратор", "Участник")
bool builtin = 5; // Является ли роль встроенной (например, "admin" и "member" могут быть встроенными ролями, которые нельзя удалить)
}
message ChatMessage{
string id = 1; // UUID сообщения
string chat_id = 2; // UUID чата, к которому относится это сообщение
uint64 chat_seq = 3; // Последовательный номер сообщения в рамках чата (начинается с 1 и увеличивается на 1 для каждого нового сообщения в этом чате)
string client_message_id = 4; // Уникальный идентификатор сообщения, сгенерированный на клиенте (например, для обеспечения идемпотентности при отправке сообщений)
string sender_user_id = 5; // UUID пользователя, который отправил сообщение
string sender_device_session_id = 6; // UUID сессии устройства, с которого было отправлено сообщение
glifa.common.v1.MessageContentType message_type = 7; // Тип содержимого сообщения (например, text, image, file)
string text = 8; // Текст сообщения (используется, если message_type == text)
string file_name = 9; // Имя файла (используется, если message_type == file)
string reply_to_message_id = 10; // UUID сообщения, на которое данное сообщение является ответом (может быть пустым, если это не ответ на другое сообщение)
glifa.common.v1.EncryptionMode encryption_mode = 11; // Режим шифрования сообщения (например, none, client_side)
google.protobuf.Struct metadata = 12; // Дополнительные метаданные сообщения в виде
bool is_edited = 13; // Флаг, указывающий, было ли сообщение отредактировано после отправки
uint32 edit_version = 14; // Версия редактирования сообщения (увеличивается на 1 при каждом редактировании)
google.protobuf.Timestamp deleted_at = 15; // Время удаления сообщения (устанавливается, если сообщение было удалено)
google.protobuf.Timestamp created_at = 16; // Время создания сообщения
google.protobuf.Timestamp updated_at = 17; // Время последнего обновления сообщения (
}
message ChatReadCursor{
string chat_id = 1; // UUID чата
string user_id = 2; // UUID пользователя
uint64 read_chat_seq = 3; // Последовательный номер сообщения, до которого пользователь прочитал чат (включительно)
google.protobuf.Timestamp updated_at = 4; // Время последнего обновления курсора
}

View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package glifa.edge.v1;
import "glifa/common/v1/types.proto";
option go_package = "glifa/contracts/gen/go/glifa/edge/v1;edgev1";
service EdgeGagewayService {
rpc Health(HealthRequest) returns (HealthResponse);
rpc Readiness(ReadinessRequest) returns (ReadinessResponse);
}
message HealthRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
}
message HealthResponse {
string status = 1; // Статус здоровья сервиса, например, "healthy", "degraded", "unhealthy"
}
message ReadinessRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
}
message ReadinessResponse {
string status = 1; // Статус готовности сервиса, например, "ready", "not_ready"
repeated string checks = 2; // Список проверок, которые были выполнены для определения готовности сервиса, и их результаты (например, "database: ok", "cache: ok", "external_api: timeout")
}

View File

@@ -0,0 +1,82 @@
syntax = "proto3";
package glifa.events.v1;
import "google/protobuf/timestamp.proto";
option go_package = "glifa/contracts/gen/go/glifa/events/v1;eventsv1";
message AuthUserCreated{
string user_id = 1; // UUID нового пользователя
string username = 2; // Имя пользователя
string email = 3; // Электронная почта пользователя
string phone = 4; // Номер телефона пользователя
google.protobuf.Timestamp created_at = 5; // Время создания пользователя
}
message AuthUserUpdated{
string user_id = 1; // UUID пользователя
string username = 2; // Новое имя пользователя (если изменилось)
string display_name = 3; // Новое отображаемое имя пользователя (если изменилось)
string avatar_media_object_id = 4; // UUID нового аватара пользователя (если изменился)
google.protobuf.Timestamp updated_at = 5; // Время обновления пользователя
}
message AuthUserBlocked{
string user_id = 1; // UUID заблокированного пользователя
string reason = 2; // Причина блокировки пользователя
google.protobuf.Timestamp blocked_at = 3; // Время блокировки пользователя
}
message AuthSessionCreated{
string session_id = 1; // UUID новой сессии
string user_id = 2; // UUID пользователя, которому принадлежит сессия
string device_id = 3; // UUID устройства, с которого была создана сессия
string status = 4; // Статус сессии (например, "active", "inactive")
google.protobuf.Timestamp created_at = 5; // Время создания сессии
}
message AuthSessionLocked{
string session_id = 1; // UUID заблокированной сессии
string user_id = 2; // UUID пользователя, которому принадлежит сессия
string reason = 3; // Причина блокировки сессии
google.protobuf.Timestamp locked_at = 4; // Время блокировки сессии
}
message AuthSessionUnlocked{
string session_id = 1; // UUID разблокированной сессии
string user_id = 2; // UUID пользователя, которому принадлежит сессия
google.protobuf.Timestamp unlocked_at = 3; // Время разблокировки сессии
}
message AuthSessionRevoked{
string session_id = 1; // UUID отозванной сессии
string user_id = 2; // UUID пользователя, которому принадлежит сессия
string reason = 3; // Причина отзыва сессии
google.protobuf.Timestamp revoked_at = 4; // Время отзыва сессии
}
message AuthSessionCompromised{
string session_id = 1; // UUID скомпрометированной сессии
string user_id = 2; // UUID пользователя, которому принадлежит сессия
string reason = 3; // Причина компрометации сессии
google.protobuf.Timestamp compromised_at = 4; // Время компрометации сессии
}
message AuthQrRequestCreated{
string request_id = 1; // UUID нового QR-запроса
google.protobuf.Timestamp expires_at = 2; // Время истечения срока действия QR-запроса
}
message AuthQrRequestApproved{
string request_id = 1; // UUID одобренного QR-запроса
string approving_user_id = 2; // UUID пользователя, который одобрил QR-запрос
string approving_session_id = 3; // UUID сессии, с которой был одобрен QR-запрос
google.protobuf.Timestamp approved_at = 4; // Время одобрения QR-запроса
}
message AuthQrRequestExpired{
string request_id = 1; // UUID истекшего QR-запроса
google.protobuf.Timestamp expired_at = 2; // Время истечения срока действия QR-запроса
}

View File

@@ -0,0 +1,55 @@
syntax = "proto3";
package glifa.events.v1;
import "google/protobuf/timestamp.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/gen/go/glifa/events/v1;eventsv1";
message ChannelCreated {
string channel_id = 1; // UUID канала, который был создан
string handle = 2; // Уникальный идентификатор канала (например, "general", "random")
string title = 3; // Название канала
string owner_user_id = 4; // UUID пользователя, который создал канал
google.protobuf.Timestamp created_at = 5; // Время создания канала
}
message ChannelSubscriberAdded {
string channel_id = 1; // UUID канала, в который был добавлен подписчик
string user_id = 2; // UUID пользователя, который был добавлен в канал
google.protobuf.Timestamp added_at = 3; // Время добавления подписчика в канал
}
message ChannelSubscriberRemoved {
string channel_id = 1; // UUID канала, из которого был удален подписчик
string user_id = 2; // UUID пользователя, который был удален из канала
google.protobuf.Timestamp removed_at = 3; // Время удаления подписчика из канала
}
message ChannelPostCreated {
string post_id = 1; // UUID созданного поста
string channel_id = 2; // UUID канала, в котором был создан пост
uint64 post_seq = 3; // Последовательный номер поста в рамках канала (начинается с 1 и увеличивается на 1 для каждого нового поста в канале)
string client_post_id = 4; // Идентификатор поста, сгенерированный на клиенте (для обеспечения идемпотентности при повторной отправке)
string author_user_id = 5; // UUID пользователя, который создал пост
glifa.common.v1.MessageContentType message_type = 6; // Тип контента поста (например, "text", "image", "file")
string text = 7; // Текст поста (если message_type == "text")
string file_id = 8; // UUID файла, прикрепленного к посту (если message_type == "file")
google.protobuf.Timestamp created_at = 9; // Время создания поста
}
message ChannelPostEdited {
string post_id = 1; // UUID отредактированного поста
string channel_id = 2; // UUID канала, в котором был создан пост
string edit_version = 3; // Версия редактирования поста (начинается с 1 и увеличивается на 1 для каждого редактирования поста)
string text = 4; // Новый текст поста (если message_type == "text")
google.protobuf.Timestamp updated_at = 5; // Время редактирования поста
}
message ChannelPostDeleted {
string post_id = 1; // UUID удаленного поста
string channel_id = 2; // UUID канала, в котором был создан пост
google.protobuf.Timestamp deleted_at = 3; // Время удаления поста
}

View File

@@ -0,0 +1,78 @@
syntax = "proto3";
package glifa.events.v1;
import "google/protobuf/timestamp.proto";
import "glifa/common/v1/enums.proto";
option go_package = "glifa/contracts/gen/go/glifa/events/v1;eventsv1";
message CoreUserProfileCreated {
string user_id = 1; // UUID пользователя, для которого создан профиль
string username = 2; // Имя пользователя
string display_name = 3; // Отображаемое имя пользователя
google.protobuf.Timestamp created_at = 4; // Время создания профиля пользователя
}
message CoreUserProfileUpdated {
string user_id = 1; // UUID пользователя, чей профиль был обновлен
string display_name = 2; // Новое отображаемое имя пользователя (если изменилось)
string bio = 3; // Новая биография пользователя (если изменилось)
string avatar_media_object_id = 4; // UUID нового аватара пользователя (если изменился)
google.protobuf.Timestamp updated_at = 5; // Время обновления профиля пользователя
}
message CoreChatMemberAdded {
string chat_id = 1; // UUID чата, в который был добавлен участник
string user_id = 2; // UUID пользователя, который был добавлен в чат
google.protobuf.Timestamp added_at = 4; // Время добавления участника в чат
}
message CoreChatMemberRemoved {
string chat_id = 1; // UUID чата, из которого был удален участник
string user_id = 2; // UUID пользователя, который был удален из чата
google.protobuf.Timestamp removed_at = 4; // Время удаления участника из чата
}
message CoreChatRoleAssigned {
string chat_id = 1; // UUID чата, в котором была назначена роль
string user_id = 2; // UUID пользователя, которому была назначена роль
string role_key = 3; // Ключ роли, которая была назначена пользователю (например, "admin", "moderator")
google.protobuf.Timestamp assigned_at = 4; // Время назначения роли пользователю в ч
}
message CoreMessageCreated {
string message_id = 1; // UUID созданного сообщения
string chat_id = 2; // UUID чата, в котором было создано сообщение
string chat_seq = 3; // Последовательный номер сообщения в рамках чата (начинается с 1 и увеличивается на 1 для каждого нового сообщения в чате)
string client_message_id = 4; // Идентификатор сообщения, сгенерированный на клиенте (для обеспечения идемпотентности при повторной отправке)
string sender_user_id = 5; // UUID пользователя, который отправил сообщение
string sender_session_id = 6; // UUID сессии, с которой было отправлено сообщение
glifa.common.v1.MessageContentType message_type = 7; // Тип контента сообщения (например, "text", "image", "file")
glifa.common.v1.EncryptionMode encryption_mode = 8; // Режим шифрования сообщения (например, "none", "end-to-end")
string text = 9; // Текст сообщения (если message_type == "text")
string file_id = 10; // UUID файла, прикрепленного к сообщению (если message_type == "file")
string reply_to_message_id = 11; // UUID сообщения, на которое был дан ответ (если это сообщение является ответом)
google.protobuf.Timestamp created_at = 12; // Время создания сообщения
}
message CoreMessageEdited {
string message_id = 1; // UUID отредактированного сообщения
string chat_id = 2; // UUID чата, в котором было отредактировано сообщение
string edit_version = 3; // Версия редактирования сообщения (начинается с 1 и увеличивается на 1 для каждого нового редактирования)
string text = 4; // Новый текст сообщения (если message_type == "text")
google.protobuf.Timestamp updated_at = 5; // Время редактирования сообщения
}
message CoreMessageDeleted {
string message_id = 1; // UUID удаленного сообщения
string chat_id = 2; // UUID чата, в котором было удалено сообщение
google.protobuf.Timestamp deleted_at = 3; // Время удаления сообщения
}
message CoreMessageReadUpdated {
string chat_id = 1; // UUID чата, в котором было обновлено состояние прочтения сообщений
string user_id = 2; // UUID пользователя, который прочитал сообщения
uint64 read_chat_seq = 3; // Максимальный последовательный номер сообщения, который пользователь прочитал в чате (включительно)
google.protobuf.Timestamp updated_at = 4; // Время обновления состояния прочтения
}

View File

@@ -0,0 +1,24 @@
syntax = "proto3";
package glifa.events.v1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
option go_package = "glifa/contracts/gen/go/glifa/events/v1;eventsv1";
message DurableEventEventlope {
string event_id = 1; // UUID события
string event_type = 2; // Тип события (например, "user.created", "
uint32 event_version = 3; // Версия схемы данных события
string producer = 4; // Идентификатор системы, которая сгенерировала событие
string aggregate_type = 5; // Тип агрегата, к которому относится событие (например, "user", "order")
string aggregate_id = 6; // UUID агрегата, к которому относится событие
string partition_key = 7; // Ключ для партиционирования (например, "user_id" или "order_id")
google.protobuf.Timestamp occurred_at = 8; // Время возникновения события
string trace_id = 9; // UUID для распределенного трейсинга
string correlation_id = 10; // UUID для корреляции логов
string idempotency_key = 11; // UUID для идемпотентности операций
google.protobuf.Any payload = 12; // Данные события в виде сериализованного protobuf-сообщения (может быть любым типом, в зависимости от event_type)
}

View File

@@ -0,0 +1,39 @@
syntax = "proto3";
package glifa.events.v1;
import "google/protobuf/timestamp.proto";
option go_package = "glifa/contracts/gen/go/glifa/events/v1;eventsv1";
message MediaUploadInitiated {
string upload_intent_id = 1; // UUID намерения загрузки, который будет использоваться для идентификации процесса загрузки
string owner_user_id = 2; // UUID пользователя, который инициализировал загрузку
google.protobuf.Timestamp initiated_at = 3; // Время инициализации загрузки медиа
}
message MediaUploadFinalized {
string upload_intent_id = 1; // UUID намерения загрузки, который был использован для идентификации процесса загрузки
string media_object_id = 2; // UUID созданного медиа-объекта после успешной загрузки
google.protobuf.Timestamp finalized_at = 3; // Время финализации загрузки медиа
}
message MediaObjectActivated {
string media_object_id = 1; // UUID медиа-объекта, который был активирован
string owner_user_id = 2; // UUID пользователя, который активировал медиа-объект
string visibility = 3; // Видимость медиа-объекта (например, "public", "private", "unlisted")
google.protobuf.Timestamp activated_at = 4; // Время активации медиа-объекта (когда он стал доступен для использования)
}
message MediaObjectQuarantined {
string media_object_id = 1; // UUID медиа-объекта, который был помещен в карантин
string reason = 2; // Причина помещения медиа-объекта в карантин (например, "inappropriate_content", "copyright_violation")
google.protobuf.Timestamp quarantined_at = 3; // Время помещения медиа-объекта в карантин
}
message MediaVariantCreated {
string media_variant_id = 1; // UUID созданного варианта медиа-объекта
string media_object_id = 2; // UUID медиа-объекта, для которого был создан вариант
string variant_kind = 3; // Тип варианта (например, "thumbnail", "preview", "full")
google.protobuf.Timestamp created_at = 4; // Время создания варианта медиа-объекта
}

View File

@@ -0,0 +1,107 @@
syntax = "proto3";
package glifa.media.v1;
import "glifa/common/v1/types.proto";
import "glifa/media/v1/types.proto";
option go_package = "glifa/contracts/gen/go/glifa/media/v1;mediav1";
service MediaService {
rpc InitiateUpload(InitiateUploadRequest) returns (InitiateUploadResponse);
rpc PresignPartUpload(PresignPartUploadRequest) returns (PresignPartUploadResponse);
rpc CompletePart(CompletePartRequest) returns (CompletePartResponse);
rpc FinalizeUpload(FinalizeUploadRequest) returns (FinalizeUploadResponse);
rpc AbortUpload(AbortUploadRequest) returns (AbortUploadResponse);
rpc GetMediaObject(GetMediaObjectRequest) returns (GetMediaObjectResponse);
rpc CreateAccessGrant(CreateAccessGrantRequest) returns (CreateAccessGrantResponse);
rpc ResolveDownload(ResolveDownloadRequest) returns (ResolveDownloadResponse);
}
message InitiateUploadRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string file_name = 2; // Исходное имя файла, который будет загружен
string declared_mime_type = 3; // MIME-тип файла, который будет загружен (например, "image/jpeg", "video/mp4")
uint64 expected_size = 4; // Ожидаемый размер файла в байтах, который будет загружен
bool multipart = 5; // Флаг, указывающий, будет ли загрузка выполняться в несколько частей (multipart upload)
MediaVisibility visibility = 6; // Видимость медиа-объекта (публичный или приватный)
}
message InitiateUploadResponse {
UploadIntent upload_intent = 1; // Намерение загрузки, содержащее информацию о процессе загрузки и его статусе
}
message PresignPartUploadRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string upload_intent_id = 2; // UUID намерения загрузки, к которому относится эта часть
int32 part_number = 3; // Номер части в последовательности загрузки (начинается с 1)
}
message PresignPartUploadResponse {
string url = 1; // Предварительно подписанный URL для загрузки части файла в хранилище
map<string, string> headers = 2; // Дополнительные заголовки, которые должны быть включены в запрос загрузки части (например, для аутентификации или указания типа контента)
}
message CompletePartRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string upload_intent_id = 2; // UUID намерения загрузки, к которому относится эта часть
int32 part_number = 3; // Номер части в последовательности загрузки (начинается с 1)
string etag = 4; // ETag, возвращаемый хранилищем после успешной загрузки части, который будет использоваться для финализации загрузки
uint64 size = 5; // Размер части в байтах
}
message CompletePartResponse {
UploadPart part = 1; // Информация о загруженной части, включая номер части, ETag и размер
}
message FinalizeUploadRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string upload_intent_id = 2; // UUID намерения загрузки, который будет финализирован
string checksum = 3; // Контрольная сумма (например, MD5 или SHA-256) всего файла, который был загружен, для проверки целостности данных
}
message FinalizeUploadResponse {
UploadIntent upload_intent = 1; // Намерение загрузки с обновленным статусом, указывающим, что загрузка была успешно завершена
MediaObject media_object = 2; // Информация о созданном медиа-объекте, включая его UUID, размер, MIME-тип и т.д.
}
message AbortUploadRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string upload_intent_id = 2; // UUID намерения загрузки, который будет прерван
}
message AbortUploadResponse {
bool success = 1; // Флаг, указывающий, была ли операция прерывания успешной
}
message GetMediaObjectRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string media_object_id = 2; // UUID медиа-объекта, который пользователь хочет получить
}
message GetMediaObjectResponse {
MediaObject media_object = 1; // Информация о запрошенном медиа-объекте, включая его UUID, размер, MIME-тип, статус и т.д.
}
message CreateAccessGrantRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string media_object_id = 2; // UUID медиа-объекта, для которого создается грант доступа
string subject_user_id = 3; // UUID пользователя, которому предоставляется доступ к медиа-объекту
bool single_use = 4; // Флаг, указывающий, является ли грант доступа одноразовым (может быть использован только один раз для доступа к медиа-объекту)
}
message CreateAccessGrantResponse {
MediaAccessGrant grant = 1; // Информация о созданном гранте доступа, включая его UUID, связанный медиа-объект, субъект доступа и т.д.
}
message ResolveDownloadRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string media_object_id = 2; // UUID медиа-объекта, который пользователь хочет скачать
string access_grant_id = 3; // UUID гранта доступа, который будет использоваться для авторизации доступа к медиа-объекту при скачивании
}
message ResolveDownloadResponse {
string url = 1; // Предварительно подписанный URL для скачивания файла медиа-объекта из хранилища
map<string, string> headers = 2; // Дополнительные заголовки, которые должны быть включены в запрос скачивания файла (например, для аутентификации или указания типа контента)
string method = 3; // HTTP-метод, который должен быть использован для скачивания файла (например, "GET", "POST")
}

View File

@@ -0,0 +1,80 @@
syntax = "proto3";
package glifa.media.v1;
import "google/protobuf/timestamp.proto";
option go_package = "glifa/contracts/gen/go/glifa/media/v1;mediav1";
enum UploadIntentStatus{
UPLOAD_INTENT_STATUS_UNSPECIFIED = 0; // Неопределенный статус намерения загрузки
UPLOAD_INTENT_STATUS_INITIATED = 1; // Намерение загрузки было инициализировано, но загрузка еще не началась
UPLOAD_INTENT_STATUS_UPLOADING = 2; // Процесс загрузки медиа-объекта начался, но еще не завершился
UPLOAD_INTENT_STATUS_FINALIZED = 3; // Процесс загрузки медиа-объекта успешно завершился, и медиа-объект был создан
UPLOAD_INTENT_STATUS_ABORTED = 4; // Процесс загрузки был прерван или отменен до его завершения
UPLOAD_INTENT_STATUS_EXPIRED = 5; // Намерение загрузки истекло, и загрузка не может быть завершена
}
enum MediaObjectStatus {
MEDIA_OBJECT_STATUS_UNSPECIFIED = 0; // Неопределенный статус медиа-объекта
MEDIA_OBJECT_STATUS_PENDING = 1; // Медиа-объект находится в ожидании обработки (например, конвертации или проверки)
MEDIA_OBJECT_STATUS_ACTIVE = 2; // Медиа-объект активен и доступен для использования
MEDIA_OBJECT_STATUS_QUARANTINED = 3; // Медиа-объект помещен в карантин из-за подозрения на нарушение правил (например, неподобающий контент)
MEDIA_OBJECT_STATUS_DELETED = 4; // Медиа-объект удален и больше не доступен
}
enum MediaVisibility {
MEDIA_VISIBILITY_UNSPECIFIED = 0; // Неопределенная видимость медиа-объекта
MEDIA_VISIBILITY_PUBLIC = 1; // Медиа-объект публичный и доступен всем пользователям
MEDIA_VISIBILITY_PRIVATE = 2; // Медиа-объект приватный и доступен только владельцу
}
message UploadIntent {
string id = 1; // UUID намерения загрузки, который будет использоваться для идентификации процесса загрузки
string owner_user_id = 2; // UUID пользователя, который инициализировал
string file_name = 3; // Исходное имя файла, который будет загружен
string declared_mime_type = 4; // MIME-тип файла, который будет загружен (например, "image/jpeg", "video/mp4")
uint64 expected_size = 5; // Ожидаемый размер файла в байтах, который будет загружен
bool multipart = 6; // Флаг, указывающий, будет ли загрузка выполняться в несколько частей (multipart upload)
UploadIntentStatus status = 7; // Текущий статус намерения загрузки
google.protobuf.Timestamp expires_at = 8; // Временная метка, указывающая, когда намерение загрузки истекает и больше не может быть использовано для загрузки файла
google.protobuf.Timestamp created_at = 9; // Временная метка создания намерения загрузки
google.protobuf.Timestamp updated_at = 10; // Временная метка последнего обновления намерения загрузки
}
message UploadPart {
string upload_intent_id = 1; // UUID намерения загрузки, к которому относится эта часть
int32 part_number = 2; // Номер части в последовательности загрузки (начинается с 1)
string etag = 3; // ETag, возвращаемый хранилищем после успешной загрузки части, который будет использоваться для финализации загрузки
uint64 size = 4; // Размер части в байтах
google.protobuf.Timestamp completed_at = 5; // Временная метка, указывающая, когда эта часть была успешно загружена
}
message MediaObject {
string id = 1; // UUID медиа-объекта, который будет использоваться для идентификации и доступа к медиа-объекту
string owner_user_id = 2; // UUID пользователя, которому принадлежит этот медиа-объект
string object_key = 3; // Ключ объекта в хранилище, который указывает на местоположение файла медиа-объекта
string checksum = 4; // Контрольная сумма (например, MD5 или SHA-256) файла медиа-объекта, которая может использоваться для проверки целостности данных
uint64 size = 5; // Размер файла медиа-объекта в бай
string detected_mime_type = 6; // MIME-тип, определенный после загрузки и анализа файла медиа-объекта
MediaVisibility visibility = 7; // Видимость медиа-объекта (публичный или приватный)
MediaObjectStatus status = 8; // Текущий статус медиа-объекта (например, ожидает обработки, активен, в карантине, удален)
string encryption_key_ref = 9; // Ссылка на ключ шифрования, если медиа-объект зашифрован
string link_resource_type = 10; // Тип ресурса, с которым связан этот медиа-объект (например, "post", "profile_picture", "document")
string link_resource_id = 11; // UUID ресурса, с которым связан этот медиа-объект (например, идентификатор поста, идентификатор профиля пользователя, идентификатор документа)
google.protobuf.Timestamp created_at = 12; // Временная метка создания медиа-объекта
google.protobuf.Timestamp updated_at = 13; // Временная метка последнего обновления медиа-объекта
}
message MediaAccessGrant{
string id = 1; // UUID разрешения доступа, который будет использоваться для идентификации и управления разрешением доступа
string media_object_id = 2; // UUID медиа-объекта, к
string subject_user_id = 3; // UUID пользователя, которому предоставлено разрешение доступа к медиа-объекту
bool single_use = 4; // Флаг, указывающий, является ли это разрешение одноразовым (single-use), которое может быть использовано только один раз для доступа к медиа-объекту
google.protobuf.Timestamp expires_at = 5; // Временная метка, указывающая, когда разрешение доступа истекает и больше не может быть использовано для доступа к медиа-объекту
google.protobuf.Timestamp consumed_at = 6; // Временная метка, указывающая, когда это разрешение доступа было использовано для доступа к медиа-объекту (для одноразовых разрешений)
google.protobuf.Timestamp created_at = 7; // Временная метка создания разрешения доступа
}

View File

@@ -0,0 +1,76 @@
syntax = "proto3";
package glifa.ws.v1;
import "glifa/common/v1/types.proto";
import "glifa/ws/v1/types.proto";
option go_package = "glifa/contracts/gen/go/glifa/ws/v1;wsv1";
service WsGatewayService {
rpc RegisterConnection(RegisterConnectionRequest) returns (RegisterConnectionResponse);
rpc UnregisterConnection(UnregisterConnectionRequest) returns (UnregisterConnectionResponse);
rpc PublishEnvelope(PublishEnvelopeRequest) returns (PublishEnvelopeResponse);
rpc PublishPresence(PublishPresenceRequest) returns (PublishPresenceResponse);
rpc PublishTyping(PublishTypingRequest) returns (PublishTypingResponse);
rpc ListUserConnections(ListUserConnectionsRequest) returns (ListUserConnectionsResponse);
}
message RegisterConnectionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string access_token = 2; // Токен доступа, который будет использоваться для аутентификации и авторизации соединения
string connection_id = 3; // Уникальный идентификатор соединения, который может быть сгенерирован клиентом или сервером для отслеживания этого соединения
string node_id = 4; // Идентификатор узла, к которому подключается это соединение, если используется распределенная архитектура с несколькими узлами
}
message RegisterConnectionResponse {
ConnectionInfo connection = 1; // Информация о зарегистрированном соединении, включая его статус и метаданные
}
message UnregisterConnectionRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string connection_id = 2; // Уникальный идентификатор соединения, которое должно быть удалено или разорвано
}
message UnregisterConnectionResponse {
bool success = 1; // Флаг, указывающий, было ли соединение успешно удалено или разорвано
}
message PublishEnvelopeRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
repeated string target_user_ids = 2; // Список UUID пользователей, которые являются целевыми получателями этого сообщения, и которым должно быть доставлено это сообщение
repeated string target_session_ids = 3; // Список UUID сессий, которые являются целевыми получателями этого сообщения, и которым должно быть доставлено это сообщение
repeated string target_channel_ids = 4; // Список UUID каналов или тем, на которые подписаны получатели, которым должно быть доставлено это сообщение
RealtimeEnvelope envelope = 5; // Конверт в реальном времени, который содержит данные и метаданные сообщения, которое должно быть доставлено получателям
}
message PublishEnvelopeResponse {
uint32 accepted_targets = 1; // Количество целевых получателей, которым было принято это сообщение для доставки (например, количество пользователей, сессий или каналов, которым было отправлено это сообщение)
}
message PublishPresenceRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
PresenceState presence = 2; // Состояние присутствия пользователя, которое должно быть опубликовано и доставлено подписчикам
}
message PublishPresenceResponse {
bool success = 1; // Флаг, указывающий, было ли состояние присутствия успешно опубликовано и доставлено подписчикам
}
message PublishTypingRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
TypingState typing = 2; // Состояние печати пользователя, которое должно быть опубликовано и доставлено подписчикам
}
message PublishTypingResponse {
bool success = 1; // Флаг, указывающий, было ли состояние печати успешно опубликовано и доставлено подписчикам
}
message ListUserConnectionsRequest {
glifa.common.v1.RequestMeta meta = 1; // Метаданные запроса, такие как идентификатор корреляции, язык и т.д.
string user_id = 2; // UUID пользователя, для которого нужно получить список активных соединений
}
message ListUserConnectionsResponse {
repeated ConnectionInfo items = 1; // Список активных соединений, связанных с указанным пользователем, включая их статус и метаданные
}

View File

@@ -0,0 +1,56 @@
syntax = "proto3";
package glifa.ws.v1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
option go_package = "glifa/contracts/gen/go/glifa/ws/v1;wsv1";
enum ConnectionStatus {
CONNECTION_STATUS_UNSPECIFIED = 0; // Неопределенный статус соединения
CONNECTION_STATUS_CONNECTED = 1; // Соединение установлено и активно
CONNECTION_STATUS_DRAINING = 2; // Соединение находится в процессе завершения, и новые сообщения не принимаются, но существующие сообщения могут быть доставлены
CONNECTION_STATUS_DISCONNECTED = 3; // Соединение было разорвано или потеряно
}
enum RealtimeEnvelopeKind {
REALTIME_ENVELOPE_KIND_UNSPECIFIED = 0; // Неопределенный тип конверта в реальном времени
REALTIME_ENVELOPE_KIND_DURABLE = 1; // Конверт в реальном времени, который гарантирует доставку сообщения получателю, даже если он временно недоступен (например, из-за отключения от сети)
REALTIME_ENVELOPE_KIND_EPHEMERAL = 2; // Конверт в реальном времени, который не гарантирует доставку сообщения получателю, если он временно недоступен (например, из-за отключения от сети), и может быть потерян в таких случаях
}
message ConnectionInfo {
string connection_id = 1; // Уникальный идентификатор соединения, который может использоваться для отслеживания и управления соединением
string user_id = 2; // UUID пользователя, которому принадлежит это соединение
string session_id = 3; // UUID сессии, которая связана с этим соединением
string device_id = 4; // UUID устройства, с которого установлено это соединение
string node_id = 5; // Идентификатор узла, к которому подключено это соединение, если используется распределенная архитектура с несколькими узлами
ConnectionStatus status = 6; // Текущий статус соединения (например, подключено, в процессе завершения, отключено)
google.protobuf.Timestamp connected_at = 7; // Временная метка, указывающая, когда это соединение было установлено
google.protobuf.Timestamp last_seen_at = 8; // Временная метка, указывающая, когда это соединение в последний раз было активно или получало сообщения
repeated string subscriptions = 9; // Список подписок, на которые подписано это соединение, например, идентификаторы каналов или тем, на которые оно подписано для получения сообщений
}
message RealtimeEnvelope {
string envelope_id = 1; // Уникальный идентификатор конверта в реальном времени, который может использоваться для отслеживания и управления сообщениями
RealtimeEnvelopeKind kind = 2; // Тип конверта в реальном времени, который определяет гарантии доставки сообщения (например, долговременный или эфемерный)
string topic = 3; // Тема или канал, на который это сообщение предназначено, и на который подписаны получатели, которые должны получить это сообщение
string aggregate_id = 4; // Идентификатор агрегата, который может использоваться для группировки связанных сообщений вместе (например, все сообщения, относящиеся к одному чату или разговору)
string event_type = 5; // Тип события, который описывает содержание или действие, связанное с этим сообщением (например, "message.created", "user.typing", "notification.new")
string event_version = 6; // Версия схемы события, которая может использоваться для управления изменениями в структуре данных события с течением времени
google.protobuf.Timestamp occurred_at = 7; // Временная метка, указывающая, когда это событие произошло или было создано, что может использоваться для упорядочивания сообщений и управления временем жизни сообщений
google.protobuf.Any payload = 8; // Полезная нагрузка сообщения, которая может содержать любые данные, связанные с этим событием, и может быть сериализована в формате JSON
}
message PresenceState{
string user_id = 1; // UUID пользователя, чье присутствие отслеживается
bool online = 2; // Статус присутствия пользователя (true - онлайн, false - офлайн)
google.protobuf.Timestamp last_seen_at = 3; // Временная метка, указывающая, когда пользователь в последний раз был онлайн или активен
}
message TypingState {
string chat_id = 1; // UUID чата или канала, в котором пользователь печатает
string user_id = 2; // UUID пользователя, который печатает
string session_id = 3; // UUID сессии пользователя, который печатает
google.protobuf.Timestamp expires_at = 4; // Временная метка, указывающая, когда статус печати должен истечь (например, если пользователь перестал печатать и не отправил сообщение в течение определенного времени)
}