veza/veza-common
senke 172581ff02 chore(cleanup): remove orphan code + archive disabled workflows + .playwright-mcp
Triple cleanup, landed together because they share the same cleanup
branch intent and touch non-overlapping trees.

1. 38× tracked .playwright-mcp/*.yml stage-deleted
   MCP session recordings that had been inadvertently committed.
   .gitignore already covers .playwright-mcp/ (post-audit J2 block
   added in d12b901de). Working tree copies removed separately.

2. 19× disabled CI workflows moved to docs/archive/workflows/
   Legacy .yml.disabled files in .github/workflows/ were 1676 LOC of
   dead config (backend-ci, cd, staging-validation, accessibility,
   chromatic, visual-regression, storybook-audit, contract-testing,
   zap-dast, container-scan, semgrep, sast, mutation-testing,
   rust-mutation, load-test-nightly, flaky-report, openapi-lint,
   commitlint, performance). Preserved in docs/archive/workflows/
   for historical reference; `.github/workflows/` now only lists the
   5 actually-running pipelines.

3. Orphan code removed (0 consumers confirmed via grep)
   - veza-backend-api/internal/repository/user_repository.go
     In-memory UserRepository mock, never imported anywhere.
   - proto/chat/chat.proto
     Chat server Rust deleted 2026-02-22 (commit 279a10d31); proto
     file was orphan spec. Chat lives 100% in Go backend now.
   - veza-common/src/types/chat.rs (Conversation, Message, MessageType,
     Attachment, Reaction)
   - veza-common/src/types/websocket.rs (WebSocketMessage,
     PresenceStatus, CallType — depended on chat::MessageType)
   - veza-common/src/types/mod.rs updated: removed `pub mod chat;`,
     `pub mod websocket;`, and their re-exports.
   Only `veza_common::logging` is consumed by veza-stream-server
   (verified with `grep -r "veza_common::"`). `cargo check` on
   veza-common passes post-removal.

Refs: AUDIT_REPORT.md §8.2 "Code mort / orphelin" + §9.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:33:40 +02:00
..
src chore(cleanup): remove orphan code + archive disabled workflows + .playwright-mcp 2026-04-20 20:33:40 +02:00
tests adding initial veza-common 2025-12-03 22:24:14 +01:00
AUDIT_REPORT.md refonte: backend-api go first; phase 1 2025-12-12 21:34:34 -05:00
Cargo.toml fix(release): v1.0.1 — Conformité complète ROADMAP checklist 2026-03-03 20:17:54 +01:00
README.md adding initial veza-common 2025-12-03 22:24:14 +01:00

Veza Common Library

Bibliothèque commune pour tous les services Veza. Cette bibliothèque fournit des types partagés, des utilitaires et des configurations communes utilisées par tous les services du projet Veza.

Installation

Ajoutez cette dépendance à votre Cargo.toml:

[dependencies]
veza-common = { path = "../veza-common" }

Modules

Types (types)

Types de données partagés pour tous les services.

User

use veza_common::types::User;

let user = User::new(1, "john_doe".to_string(), "john@example.com".to_string());
assert!(user.validate().is_ok());

Track

use veza_common::types::Track;
use uuid::Uuid;

let track_id = Uuid::new_v4();
let track = Track::new(
    track_id,
    "Song Title".to_string(),
    "Artist Name".to_string(),
    180 // duration in seconds
);
assert_eq!(track.formatted_duration(), "3:00");

Playlist

use veza_common::types::Playlist;
use uuid::Uuid;

let playlist_id = Uuid::new_v4();
let owner_id = Uuid::new_v4();
let mut playlist = Playlist::new(playlist_id, "My Playlist".to_string(), owner_id);

let track_id = Uuid::new_v4();
playlist.add_track(track_id);
assert_eq!(playlist.track_count(), 1);

API Response

use veza_common::types::ApiResponse;

// Success response
let response = ApiResponse::success("data".to_string());
assert!(response.success);

// Error response
let error_response = ApiResponse::<String>::error("Error message".to_string());
assert!(!error_response.success);

Error Handling (error)

Types d'erreurs standardisés avec codes HTTP et messages.

use veza_common::error::{CommonError, CommonResult};

fn example_function() -> CommonResult<i32> {
    // Return success
    Ok(42)
    
    // Or error
    // Err(CommonError::NotFound("Resource not found".to_string()))
}

// Error codes
let error = CommonError::ValidationError("Invalid input".to_string());
assert_eq!(error.code(), "VALIDATION_ERROR");
assert_eq!(error.http_status_code(), 400);

Configuration (config)

Types de configuration pour Database et Redis.

DatabaseConfig

use veza_common::config::DatabaseConfig;
use std::time::Duration;

let config = DatabaseConfig::new(
    "postgresql://user:password@localhost:5432/mydb".to_string(),
    10 // max_connections
);

// Validate configuration
assert!(config.validate().is_ok());

// Extract information
let host = config.host(); // Some("localhost")
let port = config.port(); // Some(5432)
let db_name = config.database_name(); // Some("mydb")

RedisConfig

use veza_common::config::RedisConfig;

let config = RedisConfig::new("redis://localhost:6379".to_string());

// Validate configuration
assert!(config.validate().is_ok());

// Check SSL
let is_ssl = config.is_ssl(); // false for redis://, true for rediss://

// Extract information
let host = config.host(); // Some("localhost")
let port = config.port(); // Some(6379)

Utilities (utils)

Validation

use veza_common::utils::validation::*;

// Email validation
assert!(validate_email("test@example.com"));
assert!(!validate_email("invalid-email"));

// Username validation
assert!(validate_username("user123"));
assert!(!validate_username("ab")); // Too short

// Password validation
assert!(validate_password("Password123"));
assert!(!validate_password("short")); // Too short

// With Result return
let result = validate_email_result("test@example.com");
assert!(result.is_ok());

Serialization

use veza_common::utils::serialization::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct MyStruct {
    name: String,
    value: i32,
}

let data = MyStruct {
    name: "test".to_string(),
    value: 42,
};

// Serialize to JSON
let json = to_json(&data).unwrap();

// Deserialize from JSON
let deserialized: MyStruct = from_json(&json).unwrap();
assert_eq!(data, deserialized);

// Pretty print
let pretty = to_json_pretty(&data).unwrap();

Date Utilities

use veza_common::utils::date::*;
use chrono::{DateTime, Utc, Duration};

// Format timestamp
let timestamp = 1609459200; // 2021-01-01 00:00:00 UTC
let formatted = format_timestamp(timestamp);

// Parse date
let date_str = "2021-01-01T00:00:00Z";
let dt: DateTime<Utc> = parse_date(date_str).unwrap();

// Relative time
let now = Utc::now();
let past = now - Duration::hours(2);
let relative = format_relative_time(&past, &now); // "2 hours ago"

// Current timestamp
let ts = current_timestamp();

Logging

use veza_common::utils::logging::*;
use std::collections::HashMap;

// Simple logging
log_info("api", "Service started");
log_error("api", "Connection failed", None);

// Request logging
log_request("api", "GET", "/users");

// Request with context
let mut context = HashMap::new();
context.insert("user_id".to_string(), "123".to_string());
log_request_with_context("api", "POST", "/users", &context);

// Structured logging
let entry = StructuredLogEntry::new("api", "INFO", "User created")
    .with_context("user_id".to_string(), "123".to_string());
let json = entry.to_json();

General Utilities

use veza_common::utils::*;

// Generate UUID
let uuid = generate_uuid();

// Format duration
let formatted = format_duration(125); // "2:05"

// Format file size
let size = format_file_size(1024); // "1.00 KB"

Exemples d'Usage Complets

Exemple 1: Créer et valider un utilisateur

use veza_common::types::User;
use veza_common::utils::validation::validate_email_result;

fn create_user(username: String, email: String) -> Result<User, String> {
    // Validate email
    validate_email_result(&email)?;
    
    // Create user
    let user = User::new(1, username, email);
    
    // Validate user data
    user.validate()?;
    
    Ok(user)
}

Exemple 2: Configuration de base de données

use veza_common::config::DatabaseConfig;
use veza_common::error::CommonResult;

fn setup_database() -> CommonResult<DatabaseConfig> {
    let config = DatabaseConfig::new(
        std::env::var("DATABASE_URL")
            .unwrap_or_else(|_| "postgresql://localhost/mydb".to_string()),
        20
    );
    
    // Validate configuration
    config.validate()?;
    
    Ok(config)
}

Exemple 3: API Response avec pagination

use veza_common::types::{ApiResponse, PaginatedResponse};

fn get_users(page: u32, limit: u32) -> ApiResponse<PaginatedResponse<User>> {
    let items = vec![/* ... */];
    let total = 100;
    
    let paginated = PaginatedResponse::new(items, total, page, limit);
    ApiResponse::success(paginated)
}

Exemple 4: Gestion d'erreurs

use veza_common::error::{CommonError, CommonResult};

fn process_request(data: &str) -> CommonResult<String> {
    if data.is_empty() {
        return Err(CommonError::ValidationError(
            "Data cannot be empty".to_string()
        ));
    }
    
    // Process data...
    Ok("processed".to_string())
}

Tests

La bibliothèque inclut une infrastructure de tests complète dans tests/common_tests.rs avec:

  • Fixtures: Fonctions pour créer des données de test
  • Helpers: Fonctions utilitaires pour les tests
  • Exemples: Tests d'intégration complets

Exécuter les tests:

cargo test

Documentation API

Pour générer la documentation complète:

cargo doc --open

Structure du Projet

veza-common/
├── src/
│   ├── lib.rs          # Module principal
│   ├── types/          # Types partagés (User, Track, Playlist)
│   ├── error.rs        # Gestion d'erreurs
│   ├── config/         # Configurations (Database, Redis)
│   └── utils/          # Utilitaires
│       ├── validation.rs
│       ├── serialization.rs
│       ├── date.rs
│       └── logging.rs
├── tests/
│   └── common_tests.rs # Tests d'intégration
└── Cargo.toml

Licence

MIT

Contribution

Les contributions sont les bienvenues ! Veuillez suivre les standards de code définis dans ORIGIN_CODE_STANDARDS.md.