refactor(infra): centralize protobuf definitions in shared proto/ directory

CLN-07: Copied .proto sources from chat-server and stream-server
to proto/{common,chat,stream}/. Original copies remain until builds
are updated to use the shared directory.
This commit is contained in:
senke 2026-02-22 17:45:11 +01:00
parent fc318d5aa0
commit 73d6cb2bee
4 changed files with 876 additions and 0 deletions

34
proto/README.md Normal file
View file

@ -0,0 +1,34 @@
# Centralized Protobuf Definitions (CLN-07)
This directory contains the **canonical source** of all `.proto` files for the Veza monorepo.
## Structure
```
proto/
├── common/
│ └── auth.proto # Shared auth service (ValidateToken, GetUserInfo, etc.)
├── stream/
│ └── stream.proto # Stream service (veza-stream-server)
├── chat/
│ └── chat.proto # Chat service (veza-chat-server)
└── README.md
```
## Intent
- **Single source of truth**: All protobuf definitions live here. Edit these files when changing API contracts.
- **Generated code stays in place**: Go/Rust generated code remains in `veza-backend-api`, `veza-chat-server`, and `veza-stream-server`. Build scripts in those projects should use this directory as the `--proto_path` when invoking `protoc`.
- **Shared common types**: `common/auth.proto` is imported by both `chat.proto` and `stream.proto`.
## Consumers
| Consumer | Proto files used | Generated output location |
|---------------------|-------------------------|----------------------------------|
| veza-chat-server | chat.proto, common/auth.proto | (existing generated dirs) |
| veza-stream-server | stream.proto, common/auth.proto | (existing generated dirs) |
| veza-backend-api | All (if applicable) | (existing generated dirs) |
## Migration note
The original `.proto` files were duplicated in `veza-chat-server/proto/` and `veza-stream-server/proto/`. Those copies can be removed or symlinked to this directory once build pipelines are updated to use `proto/` as the source.

320
proto/chat/chat.proto Normal file
View file

@ -0,0 +1,320 @@
syntax = "proto3";
package veza.chat;
option go_package = "veza-backend-api/proto/chat";
import "common/auth.proto";
// Service Chat pour communication avec le module Rust
service ChatService {
// Gestion des salles
rpc CreateRoom(CreateRoomRequest) returns (CreateRoomResponse);
rpc JoinRoom(JoinRoomRequest) returns (JoinRoomResponse);
rpc LeaveRoom(LeaveRoomRequest) returns (LeaveRoomResponse);
rpc GetRoomInfo(GetRoomInfoRequest) returns (Room);
rpc ListRooms(ListRoomsRequest) returns (ListRoomsResponse);
// Gestion des messages
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse);
rpc GetMessageHistory(GetMessageHistoryRequest) returns (GetMessageHistoryResponse);
rpc DeleteMessage(DeleteMessageRequest) returns (DeleteMessageResponse);
// Messages directs
rpc SendDirectMessage(SendDirectMessageRequest) returns (SendDirectMessageResponse);
rpc GetDirectMessages(GetDirectMessagesRequest) returns (GetDirectMessagesResponse);
// Modération
rpc MuteUser(MuteUserRequest) returns (MuteUserResponse);
rpc BanUser(BanUserRequest) returns (BanUserResponse);
rpc ModerateMessage(ModerateMessageRequest) returns (ModerateMessageResponse);
// Statistiques temps réel
rpc GetRoomStats(GetRoomStatsRequest) returns (RoomStats);
rpc GetUserActivity(GetUserActivityRequest) returns (UserActivity);
}
// Messages pour les salles
message CreateRoomRequest {
string name = 1;
string description = 2;
RoomType type = 3;
RoomVisibility visibility = 4;
int64 created_by = 5;
string auth_token = 6;
}
message CreateRoomResponse {
Room room = 1;
string error = 2;
}
message JoinRoomRequest {
string room_id = 1;
int64 user_id = 2;
string auth_token = 3;
}
message JoinRoomResponse {
bool success = 1;
RoomMember member = 2;
string error = 3;
}
message LeaveRoomRequest {
string room_id = 1;
int64 user_id = 2;
string auth_token = 3;
}
message LeaveRoomResponse {
bool success = 1;
string error = 2;
}
message GetRoomInfoRequest {
string room_id = 1;
string auth_token = 2;
}
message ListRoomsRequest {
RoomVisibility visibility = 1;
int32 page = 2;
int32 limit = 3;
string auth_token = 4;
}
message ListRoomsResponse {
repeated Room rooms = 1;
int32 total = 2;
string error = 3;
}
// Messages pour les messages
message SendMessageRequest {
string room_id = 1;
int64 sender_id = 2;
string content = 3;
MessageType type = 4;
string auth_token = 5;
string reply_to = 6; // ID du message parent
}
message SendMessageResponse {
Message message = 1;
string error = 2;
}
message GetMessageHistoryRequest {
string room_id = 1;
int32 limit = 2;
string before_id = 3; // pagination
string auth_token = 4;
}
message GetMessageHistoryResponse {
repeated Message messages = 1;
bool has_more = 2;
string error = 3;
}
message DeleteMessageRequest {
string message_id = 1;
int64 user_id = 2;
string auth_token = 3;
}
message DeleteMessageResponse {
bool success = 1;
string error = 2;
}
// Messages directs
message SendDirectMessageRequest {
int64 sender_id = 1;
int64 recipient_id = 2;
string content = 3;
MessageType type = 4;
string auth_token = 5;
}
message SendDirectMessageResponse {
DirectMessage message = 1;
string error = 2;
}
message GetDirectMessagesRequest {
int64 user_id = 1;
int64 other_user_id = 2;
int32 limit = 3;
string before_id = 4;
string auth_token = 5;
}
message GetDirectMessagesResponse {
repeated DirectMessage messages = 1;
bool has_more = 2;
string error = 3;
}
// Modération
message MuteUserRequest {
string room_id = 1;
int64 user_id = 2;
int64 moderator_id = 3;
int64 duration_seconds = 4;
string reason = 5;
string auth_token = 6;
}
message MuteUserResponse {
bool success = 1;
string error = 2;
}
message BanUserRequest {
string room_id = 1;
int64 user_id = 2;
int64 moderator_id = 3;
string reason = 4;
string auth_token = 5;
}
message BanUserResponse {
bool success = 1;
string error = 2;
}
message ModerateMessageRequest {
string message_id = 1;
int64 moderator_id = 2;
ModerationAction action = 3;
string reason = 4;
string auth_token = 5;
}
message ModerateMessageResponse {
bool success = 1;
string error = 2;
}
// Statistiques
message GetRoomStatsRequest {
string room_id = 1;
string auth_token = 2;
}
message GetUserActivityRequest {
int64 user_id = 1;
string auth_token = 2;
}
// Types de données
message Room {
string id = 1;
string name = 2;
string description = 3;
RoomType type = 4;
RoomVisibility visibility = 5;
int64 created_by = 6;
int64 created_at = 7;
int32 member_count = 8;
int32 online_count = 9;
bool is_active = 10;
}
message RoomMember {
int64 user_id = 1;
string username = 2;
RoomRole role = 3;
int64 joined_at = 4;
bool is_online = 5;
int64 last_seen = 6;
}
message Message {
string id = 1;
string room_id = 2;
int64 sender_id = 3;
string sender_username = 4;
string content = 5;
MessageType type = 6;
int64 created_at = 7;
int64 updated_at = 8;
bool is_edited = 9;
bool is_deleted = 10;
string reply_to = 11;
repeated MessageReaction reactions = 12;
}
message DirectMessage {
string id = 1;
int64 sender_id = 2;
int64 recipient_id = 3;
string content = 4;
MessageType type = 5;
int64 created_at = 6;
bool is_read = 7;
bool is_deleted = 8;
}
message MessageReaction {
string emoji = 1;
repeated int64 user_ids = 2;
int32 count = 3;
}
message RoomStats {
string room_id = 1;
int32 total_members = 2;
int32 online_members = 3;
int32 messages_today = 4;
int32 total_messages = 5;
repeated int64 active_users = 6;
}
message UserActivity {
int64 user_id = 1;
int32 rooms_joined = 2;
int32 messages_sent = 3;
int64 last_activity = 4;
bool is_online = 5;
string current_status = 6;
}
// Énumérations
enum RoomType {
PUBLIC = 0;
PRIVATE = 1;
DIRECT = 2;
PREMIUM = 3;
}
enum RoomVisibility {
OPEN = 0;
INVITE_ONLY = 1;
HIDDEN = 2;
}
enum RoomRole {
MEMBER = 0;
MODERATOR = 1;
ADMIN = 2;
OWNER = 3;
}
enum MessageType {
TEXT = 0;
IMAGE = 1;
FILE = 2;
AUDIO = 3;
VIDEO = 4;
SYSTEM = 5;
}
enum ModerationAction {
WARN = 0;
DELETE = 1;
EDIT = 2;
FLAG = 3;
}

89
proto/common/auth.proto Normal file
View file

@ -0,0 +1,89 @@
syntax = "proto3";
package veza.common.auth;
option go_package = "veza-backend-api/proto/common/auth";
// Service d'authentification partagé
service AuthService {
// Valider un JWT token
rpc ValidateToken(ValidateTokenRequest) returns (ValidateTokenResponse);
// Obtenir les informations utilisateur
rpc GetUserInfo(GetUserInfoRequest) returns (GetUserInfoResponse);
// Vérifier les permissions
rpc CheckPermissions(CheckPermissionsRequest) returns (CheckPermissionsResponse);
// Révoquer un token
rpc RevokeToken(RevokeTokenRequest) returns (RevokeTokenResponse);
}
// Messages de requête/réponse
message ValidateTokenRequest {
string token = 1;
string service = 2; // service qui fait la demande (chat, stream)
}
message ValidateTokenResponse {
bool valid = 1;
UserClaims user = 2;
string error = 3;
}
message GetUserInfoRequest {
int64 user_id = 1;
string token = 2;
}
message GetUserInfoResponse {
UserInfo user = 1;
string error = 2;
}
message CheckPermissionsRequest {
int64 user_id = 1;
string resource = 2; // "chat.room", "stream.channel"
string action = 3; // "read", "write", "moderate"
string resource_id = 4;
}
message CheckPermissionsResponse {
bool allowed = 1;
repeated string permissions = 2;
string error = 3;
}
message RevokeTokenRequest {
string token = 1;
string reason = 2;
}
message RevokeTokenResponse {
bool success = 1;
string error = 2;
}
// Types de données
message UserClaims {
int64 user_id = 1;
string username = 2;
string email = 3;
string role = 4;
bool is_active = 5;
int64 issued_at = 6;
int64 expires_at = 7;
}
message UserInfo {
int64 id = 1;
string username = 2;
string email = 3;
string first_name = 4;
string last_name = 5;
string role = 6;
bool is_active = 7;
bool is_verified = 8;
int64 created_at = 9;
int64 last_login_at = 10;
}

433
proto/stream/stream.proto Normal file
View file

@ -0,0 +1,433 @@
syntax = "proto3";
package veza.stream;
option go_package = "veza-backend-api/proto/stream";
import "common/auth.proto";
// Service Stream pour communication avec le module Rust
service StreamService {
// Gestion des streams
rpc CreateStream(CreateStreamRequest) returns (CreateStreamResponse);
rpc StartStream(StartStreamRequest) returns (StartStreamResponse);
rpc StopStream(StopStreamRequest) returns (StopStreamResponse);
rpc GetStreamInfo(GetStreamInfoRequest) returns (Stream);
rpc ListActiveStreams(ListActiveStreamsRequest) returns (ListActiveStreamsResponse);
// Gestion des auditeurs
rpc JoinStream(JoinStreamRequest) returns (JoinStreamResponse);
rpc LeaveStream(LeaveStreamRequest) returns (LeaveStreamResponse);
rpc GetListeners(GetListenersRequest) returns (GetListenersResponse);
// Contrôle audio
rpc ChangeQuality(ChangeQualityRequest) returns (ChangeQualityResponse);
rpc GetAudioMetrics(GetAudioMetricsRequest) returns (AudioMetrics);
rpc SetVolume(SetVolumeRequest) returns (SetVolumeResponse);
// Recording
rpc StartRecording(StartRecordingRequest) returns (StartRecordingResponse);
rpc StopRecording(StopRecordingRequest) returns (StopRecordingResponse);
rpc GetRecordings(GetRecordingsRequest) returns (GetRecordingsResponse);
// Analytics
rpc GetStreamAnalytics(GetStreamAnalyticsRequest) returns (StreamAnalytics);
rpc GetUserListeningHistory(GetUserListeningHistoryRequest) returns (UserListeningHistory);
// Notifications temps réel
rpc SubscribeToStreamEvents(SubscribeToStreamEventsRequest) returns (stream StreamEvent);
}
// Messages pour la gestion des streams
message CreateStreamRequest {
string title = 1;
string description = 2;
StreamCategory category = 3;
StreamVisibility visibility = 4;
int64 streamer_id = 5;
StreamQuality default_quality = 6;
string auth_token = 7;
}
message CreateStreamResponse {
Stream stream = 1;
string stream_key = 2;
string rtmp_url = 3;
string error = 4;
}
message StartStreamRequest {
string stream_id = 1;
int64 streamer_id = 2;
StreamConfig config = 3;
string auth_token = 4;
}
message StartStreamResponse {
bool success = 1;
string stream_url = 2;
repeated string hls_urls = 3; // URLs pour différentes qualités
string error = 4;
}
message StopStreamRequest {
string stream_id = 1;
int64 streamer_id = 2;
string auth_token = 3;
}
message StopStreamResponse {
bool success = 1;
StreamSummary summary = 2;
string error = 3;
}
message GetStreamInfoRequest {
string stream_id = 1;
string auth_token = 2;
}
message ListActiveStreamsRequest {
StreamCategory category = 1;
int32 page = 2;
int32 limit = 3;
StreamSortBy sort_by = 4;
string auth_token = 5;
}
message ListActiveStreamsResponse {
repeated Stream streams = 1;
int32 total = 2;
string error = 3;
}
// Messages pour les auditeurs
message JoinStreamRequest {
string stream_id = 1;
int64 user_id = 2;
StreamQuality preferred_quality = 3;
string auth_token = 4;
}
message JoinStreamResponse {
bool success = 1;
string stream_url = 2;
StreamQuality actual_quality = 3;
int32 buffer_duration = 4; // en millisecondes
string error = 5;
}
message LeaveStreamRequest {
string stream_id = 1;
int64 user_id = 2;
string auth_token = 3;
}
message LeaveStreamResponse {
bool success = 1;
int64 listen_duration = 2; // en secondes
string error = 3;
}
message GetListenersRequest {
string stream_id = 1;
string auth_token = 2;
}
message GetListenersResponse {
repeated StreamListener listeners = 1;
int32 total_count = 2;
string error = 3;
}
// Messages pour le contrôle audio
message ChangeQualityRequest {
string stream_id = 1;
int64 user_id = 2;
StreamQuality quality = 3;
string auth_token = 4;
}
message ChangeQualityResponse {
bool success = 1;
string new_stream_url = 2;
string error = 3;
}
message GetAudioMetricsRequest {
string stream_id = 1;
string auth_token = 2;
}
message SetVolumeRequest {
string stream_id = 1;
int64 user_id = 2;
int32 volume = 3; // 0-100
string auth_token = 4;
}
message SetVolumeResponse {
bool success = 1;
string error = 2;
}
// Messages pour le recording
message StartRecordingRequest {
string stream_id = 1;
int64 streamer_id = 2;
RecordingConfig config = 3;
string auth_token = 4;
}
message StartRecordingResponse {
bool success = 1;
string recording_id = 2;
string error = 3;
}
message StopRecordingRequest {
string stream_id = 1;
string recording_id = 2;
int64 streamer_id = 3;
string auth_token = 4;
}
message StopRecordingResponse {
bool success = 1;
Recording recording = 2;
string error = 3;
}
message GetRecordingsRequest {
int64 streamer_id = 1;
int32 page = 2;
int32 limit = 3;
string auth_token = 4;
}
message GetRecordingsResponse {
repeated Recording recordings = 1;
int32 total = 2;
string error = 3;
}
// Messages pour les analytics
message GetStreamAnalyticsRequest {
string stream_id = 1;
int64 start_time = 2;
int64 end_time = 3;
string auth_token = 4;
}
message GetUserListeningHistoryRequest {
int64 user_id = 1;
int32 limit = 2;
string auth_token = 3;
}
message SubscribeToStreamEventsRequest {
string stream_id = 1;
repeated StreamEventType event_types = 2;
string auth_token = 3;
}
// Types de données
message Stream {
string id = 1;
string title = 2;
string description = 3;
StreamCategory category = 4;
StreamVisibility visibility = 5;
int64 streamer_id = 6;
string streamer_username = 7;
StreamStatus status = 8;
StreamQuality current_quality = 9;
int32 listener_count = 10;
int64 created_at = 11;
int64 started_at = 12;
int64 duration = 13; // en secondes
bool is_recording = 14;
StreamMetadata metadata = 15;
}
message StreamConfig {
StreamQuality quality = 1;
int32 bitrate = 2; // kbps
int32 sample_rate = 3; // Hz
AudioCodec codec = 4;
bool enable_recording = 5;
bool enable_chat = 6;
int32 max_listeners = 7;
}
message StreamListener {
int64 user_id = 1;
string username = 2;
StreamQuality current_quality = 3;
int64 joined_at = 4;
int64 listen_duration = 5;
bool is_active = 6;
string location = 7; // géolocalisation
}
message StreamSummary {
string stream_id = 1;
int64 total_duration = 2;
int32 max_listeners = 3;
int32 unique_listeners = 4;
int64 total_listen_time = 5;
float average_listen_duration = 6;
}
message AudioMetrics {
string stream_id = 1;
int32 current_bitrate = 2;
int32 buffer_health = 3; // %
float latency = 4; // millisecondes
int32 dropped_frames = 5;
QualityStats quality_stats = 6;
int64 measured_at = 7;
}
message QualityStats {
map<string, int32> quality_distribution = 1; // qualité -> nombre d'auditeurs
float average_buffer_duration = 2;
int32 rebuffer_events = 3;
}
message Recording {
string id = 1;
string stream_id = 2;
string title = 3;
int64 duration = 4;
int64 file_size = 5; // bytes
StreamQuality quality = 6;
AudioCodec codec = 7;
string file_url = 8;
string thumbnail_url = 9;
int64 created_at = 10;
RecordingStatus status = 11;
}
message RecordingConfig {
StreamQuality quality = 1;
AudioCodec codec = 2;
bool auto_upload = 3;
string title = 4;
}
message StreamAnalytics {
string stream_id = 1;
int64 start_time = 2;
int64 end_time = 3;
int32 unique_listeners = 4;
int32 max_concurrent = 5;
int64 total_listen_time = 6;
float average_session_duration = 7;
map<string, int32> geographic_distribution = 8;
repeated ListenerActivity hourly_activity = 9;
}
message ListenerActivity {
int64 timestamp = 1;
int32 listener_count = 2;
int32 new_listeners = 3;
int32 listeners_left = 4;
}
message UserListeningHistory {
int64 user_id = 1;
repeated ListeningSession sessions = 2;
int64 total_listen_time = 3;
int32 streams_listened = 4;
}
message ListeningSession {
string stream_id = 1;
string stream_title = 2;
string streamer_username = 3;
int64 started_at = 4;
int64 duration = 5;
StreamQuality quality = 6;
}
message StreamMetadata {
string current_track = 1;
string artist = 2;
string album = 3;
string genre = 4;
map<string, string> custom_fields = 5;
}
message StreamEvent {
string stream_id = 1;
StreamEventType type = 2;
int64 timestamp = 3;
string data = 4; // JSON data
}
// Énumérations
enum StreamCategory {
MUSIC = 0;
TALK = 1;
PODCAST = 2;
GAMING = 3;
NEWS = 4;
EDUCATION = 5;
ENTERTAINMENT = 6;
OTHER = 7;
}
enum StreamVisibility {
PUBLIC_STREAM = 0;
UNLISTED = 1;
PRIVATE_STREAM = 2;
PREMIUM_ONLY = 3;
}
enum StreamStatus {
CREATED = 0;
LIVE = 1;
PAUSED = 2;
ENDED = 3;
ERROR = 4;
}
enum StreamQuality {
AUTO = 0;
LOW = 1; // 64 kbps
MEDIUM = 2; // 128 kbps
HIGH = 3; // 256 kbps
ULTRA = 4; // 320 kbps
}
enum AudioCodec {
MP3 = 0;
AAC = 1;
OPUS = 2;
FLAC = 3;
}
enum StreamSortBy {
LISTENERS = 0;
RECENT = 1;
POPULAR = 2;
TITLE = 3;
}
enum RecordingStatus {
RECORDING = 0;
PROCESSING = 1;
COMPLETED = 2;
FAILED = 3;
}
enum StreamEventType {
LISTENER_JOINED = 0;
LISTENER_LEFT = 1;
QUALITY_CHANGED = 2;
METADATA_UPDATED = 3;
STREAM_PAUSED = 4;
STREAM_RESUMED = 5;
ERROR_OCCURRED = 6;
}