`{
    "schemes": {{ marshal .Schemes }},
    "swagger": "2.0",
    "info": {
        "description": "{{escape .Description}}",
        "title": "{{.Title}}",
        "termsOfService": "http://swagger.io/terms/",
        "contact": {
            "name": "API Support",
            "url": "http://www.veza.app/support",
            "email": "support@veza.app"
        },
        "license": {
            "name": "Apache 2.0",
            "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
        },
        "version": "{{.Version}}"
    },
    "host": "{{.Host}}",
    "basePath": "{{.BasePath}}",
    "paths": {
        "/api/v1/marketplace/download/{product_id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get a secure download URL for a purchased product",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Marketplace"
                ],
                "summary": "Get download URL",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Product ID",
                        "name": "product_id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "object",
                            "additionalProperties": {
                                "type": "string"
                            }
                        }
                    },
                    "403": {
                        "description": "No license",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/api/v1/marketplace/orders": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Purchase products",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Marketplace"
                ],
                "summary": "Create a new order",
                "parameters": [
                    {
                        "description": "Order items",
                        "name": "order",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.CreateOrderRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Order"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/api/v1/marketplace/products": {
            "get": {
                "description": "List marketplace products with filters",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Marketplace"
                ],
                "summary": "List products",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Product status",
                        "name": "status",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "description": "Seller ID",
                        "name": "seller_id",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Product"
                            }
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Create a product (Track, Pack, Service) for sale",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Marketplace"
                ],
                "summary": "Create a new product",
                "parameters": [
                    {
                        "description": "Product info",
                        "name": "product",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.CreateProductRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Product"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/check-username": {
            "get": {
                "description": "Check if a username is already taken",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Check Username Availability",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Username to check",
                        "name": "username",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "available": {
                                                    "type": "boolean"
                                                },
                                                "username": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Missing Username",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/login": {
            "post": {
                "description": "Authenticate user and return access/refresh tokens",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "User Login",
                "parameters": [
                    {
                        "description": "Login Credentials",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.LoginRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.LoginResponse"
                        }
                    },
                    "400": {
                        "description": "Validation or Bad Request",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Invalid credentials",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/logout": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Revoke refresh token and current session",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Logout",
                "parameters": [
                    {
                        "description": "Refresh Token to revoke",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "object",
                            "properties": {
                                "refresh_token": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success message",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/me": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get profile information of the currently logged-in user",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Get Current User",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "email": {
                                                    "type": "string"
                                                },
                                                "id": {
                                                    "type": "string"
                                                },
                                                "role": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/refresh": {
            "post": {
                "description": "Get a new access token using a refresh token",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Refresh Token",
                "parameters": [
                    {
                        "description": "Refresh Token",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.RefreshRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.TokenResponse"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Invalid/Expired Refresh Token",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/register": {
            "post": {
                "description": "Register a new user account",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "User Registration",
                "parameters": [
                    {
                        "description": "Registration Data",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.RegisterRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.RegisterResponse"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "409": {
                        "description": "User already exists",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/resend-verification": {
            "post": {
                "description": "Resend the email verification link",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Resend Verification Email",
                "parameters": [
                    {
                        "description": "Email",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_dto.ResendVerificationRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success message",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/auth/verify-email": {
            "post": {
                "description": "Verify user email address using a token",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Auth"
                ],
                "summary": "Verify Email",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Verification Token",
                        "name": "token",
                        "in": "query",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success message",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "400": {
                        "description": "Invalid Token",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/chat/token": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Generate a short-lived token for chat authentication",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Chat"
                ],
                "summary": "Get Chat Token",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "token": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/playlists": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get a paginated list of playlists",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Get Playlists",
                "parameters": [
                    {
                        "type": "integer",
                        "default": 1,
                        "description": "Page number",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "default": 20,
                        "description": "Items per page",
                        "name": "limit",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "description": "Filter by User ID",
                        "name": "user_id",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "pagination": {
                                                    "type": "object"
                                                },
                                                "playlists": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Create a new playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Create Playlist",
                "parameters": [
                    {
                        "description": "Playlist Metadata",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.CreatePlaylistRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "playlist": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/playlists/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get detailed information about a playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Get Playlist by ID",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "playlist": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Invalid ID",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Playlist not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            },
            "put": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Update playlist metadata",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Update Playlist",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Playlist Metadata",
                        "name": "playlist",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.UpdatePlaylistRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "playlist": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Playlist not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            },
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Permanently delete a playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Delete Playlist",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Playlist not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/playlists/{id}/tracks": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Add a track to the playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Add Track to Playlist",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Track ID (in body)",
                        "name": "trackId",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "type": "object",
                            "properties": {
                                "track_id": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Track already present or invalid ID",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Playlist or Track not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/playlists/{id}/tracks/reorder": {
            "put": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Reorder tracks in the playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Reorder Tracks",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "New Track Order",
                        "name": "order",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.ReorderTracksRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/playlists/{id}/tracks/{trackId}": {
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Remove a track from the playlist",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Playlist"
                ],
                "summary": "Remove Track from Playlist",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Playlist ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Track ID",
                        "name": "trackId",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "404": {
                        "description": "Playlist or Track not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks": {
            "get": {
                "description": "Get a paginated list of tracks with filters",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "List Tracks",
                "parameters": [
                    {
                        "type": "integer",
                        "default": 1,
                        "description": "Page number",
                        "name": "page",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "default": 20,
                        "description": "Items per page",
                        "name": "limit",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "description": "Filter by User ID",
                        "name": "user_id",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "description": "Filter by Genre",
                        "name": "genre",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "description": "Filter by Format",
                        "name": "format",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "default": "created_at",
                        "description": "Sort field",
                        "name": "sort_by",
                        "in": "query"
                    },
                    {
                        "type": "string",
                        "default": "desc",
                        "description": "Sort order (asc/desc)",
                        "name": "sort_order",
                        "in": "query"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "pagination": {
                                                    "type": "object"
                                                },
                                                "tracks": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            },
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Upload a new track (audio file)",
                "consumes": [
                    "multipart/form-data"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Upload Track",
                "parameters": [
                    {
                        "type": "file",
                        "description": "Audio File (MP3, WAV, FLAC, OGG)",
                        "name": "file",
                        "in": "formData",
                        "required": true
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "track": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "No file or validation error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Quota exceeded",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/batch/delete": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Delete multiple tracks at once",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Batch Delete Tracks",
                "parameters": [
                    {
                        "description": "List of Track IDs",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_core_track.BatchDeleteRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "deleted": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    }
                                                },
                                                "failed": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/chunk": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Upload a single chunk of a file",
                "consumes": [
                    "multipart/form-data"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Upload Chunk",
                "parameters": [
                    {
                        "type": "file",
                        "description": "Chunk Data",
                        "name": "chunk",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Upload ID",
                        "name": "upload_id",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "description": "Chunk Number",
                        "name": "chunk_number",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "description": "Total Chunks",
                        "name": "total_chunks",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "integer",
                        "format": "int64",
                        "description": "Total Size",
                        "name": "total_size",
                        "in": "formData",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Filename",
                        "name": "filename",
                        "in": "formData",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                },
                                                "progress": {
                                                    "type": "number",
                                                    "format": "float64"
                                                },
                                                "received_chunks": {
                                                    "type": "integer"
                                                },
                                                "upload_id": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/complete": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Finish upload session and assemble file",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Complete Chunked Upload",
                "parameters": [
                    {
                        "description": "Upload ID",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_core_track.CompleteChunkedUploadRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "md5": {
                                                    "type": "string"
                                                },
                                                "message": {
                                                    "type": "string"
                                                },
                                                "track": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation or Assemblage Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/initiate": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Start a new chunked upload session",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Initiate Chunked Upload",
                "parameters": [
                    {
                        "description": "Upload Metadata",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_core_track.InitiateChunkedUploadRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                },
                                                "upload_id": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/quota/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get remaining upload quota for the user",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Get Upload Quota",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User ID (optional, defaults to current user)",
                        "name": "id",
                        "in": "path"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "quota": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/resume/{uploadId}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get state of an interrupted upload",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Resume Upload",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Upload ID",
                        "name": "uploadId",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "chunks_received": {
                                                    "type": "integer"
                                                },
                                                "upload_id": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "404": {
                        "description": "Upload session not found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/{id}": {
            "get": {
                "description": "Get detailed information about a track",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Get Track by ID",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Track ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "track": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Invalid ID",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Track not found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            },
            "put": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Update track metadata",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Update Track",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Track ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Track Metadata",
                        "name": "track",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_core_track.UpdateTrackRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "track": {
                                                    "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Track not found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            },
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Permanently delete a track",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Delete Track",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Track ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Track not found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/tracks/{id}/status": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Get the processing status of an uploaded track",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "Track"
                ],
                "summary": "Get Upload Status",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Track ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "progress": {
                                                    "type": "integer"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Invalid ID",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    },
                    "404": {
                        "description": "Track not found",
                        "schema": {
                            "$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
                        }
                    }
                }
            }
        },
        "/users/by-username/{username}": {
            "get": {
                "description": "Get public profile information for a user by username",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "User"
                ],
                "summary": "Get Profile by Username",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Username",
                        "name": "username",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "profile": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Missing username",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "User not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/users/{id}": {
            "get": {
                "description": "Get public profile information for a user",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "User"
                ],
                "summary": "Get Profile by ID",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "profile": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Invalid ID",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "404": {
                        "description": "User not found",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            },
            "put": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Update user profile details",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "User"
                ],
                "summary": "Update Profile",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Profile Data",
                        "name": "profile",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.UpdateProfileRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "profile": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Validation Error",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        },
        "/users/{id}/completion": {
            "get": {
                "description": "Get profile completion percentage and missing fields",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "User"
                ],
                "summary": "Get Profile Completion",
                "parameters": [
                    {
                        "type": "string",
                        "description": "User ID",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/definitions/internal_handlers.APIResponse"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object"
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "400": {
                        "description": "Invalid ID",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    },
                    "403": {
                        "description": "Forbidden",
                        "schema": {
                            "$ref": "#/definitions/internal_handlers.APIResponse"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "internal_core_track.BatchDeleteRequest": {
            "type": "object",
            "required": [
                "track_ids"
            ],
            "properties": {
                "track_ids": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "internal_core_track.CompleteChunkedUploadRequest": {
            "type": "object",
            "required": [
                "upload_id"
            ],
            "properties": {
                "upload_id": {
                    "type": "string"
                }
            }
        },
        "internal_core_track.InitiateChunkedUploadRequest": {
            "type": "object",
            "required": [
                "filename",
                "total_chunks",
                "total_size"
            ],
            "properties": {
                "filename": {
                    "type": "string"
                },
                "total_chunks": {
                    "type": "integer",
                    "minimum": 1
                },
                "total_size": {
                    "type": "integer",
                    "minimum": 1
                }
            }
        },
        "internal_core_track.UpdateTrackRequest": {
            "type": "object",
            "properties": {
                "album": {
                    "type": "string"
                },
                "artist": {
                    "type": "string"
                },
                "genre": {
                    "type": "string"
                },
                "is_public": {
                    "type": "boolean"
                },
                "title": {
                    "type": "string"
                },
                "year": {
                    "type": "integer"
                }
            }
        },
        "internal_handlers.APIResponse": {
            "type": "object",
            "properties": {
                "data": {},
                "error": {},
                "success": {
                    "type": "boolean"
                }
            }
        },
        "internal_handlers.CreateOrderRequest": {
            "type": "object",
            "required": [
                "items"
            ],
            "properties": {
                "items": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                        "type": "object",
                        "required": [
                            "product_id"
                        ],
                        "properties": {
                            "product_id": {
                                "type": "string"
                            }
                        }
                    }
                }
            }
        },
        "internal_handlers.CreatePlaylistRequest": {
            "type": "object",
            "required": [
                "title"
            ],
            "properties": {
                "description": {
                    "type": "string"
                },
                "is_public": {
                    "type": "boolean"
                },
                "title": {
                    "type": "string",
                    "maxLength": 200,
                    "minLength": 1
                }
            }
        },
        "internal_handlers.CreateProductRequest": {
            "type": "object",
            "required": [
                "price",
                "product_type",
                "title"
            ],
            "properties": {
                "description": {
                    "type": "string",
                    "maxLength": 2000
                },
                "license_type": {
                    "type": "string",
                    "enum": [
                        "standard",
                        "exclusive",
                        "commercial"
                    ]
                },
                "price": {
                    "type": "number",
                    "minimum": 0
                },
                "product_type": {
                    "type": "string",
                    "enum": [
                        "track",
                        "pack",
                        "service"
                    ]
                },
                "title": {
                    "type": "string",
                    "maxLength": 200,
                    "minLength": 3
                },
                "track_id": {
                    "description": "UUID string",
                    "type": "string"
                }
            }
        },
        "internal_handlers.ReorderTracksRequest": {
            "type": "object",
            "required": [
                "track_ids"
            ],
            "properties": {
                "track_ids": {
                    "description": "Changed to []uuid.UUID",
                    "type": "array",
                    "minItems": 1,
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "internal_handlers.UpdatePlaylistRequest": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "is_public": {
                    "type": "boolean"
                },
                "title": {
                    "type": "string",
                    "maxLength": 200,
                    "minLength": 1
                }
            }
        },
        "internal_handlers.UpdateProfileRequest": {
            "type": "object",
            "properties": {
                "bio": {
                    "type": "string",
                    "maxLength": 500
                },
                "birthdate": {
                    "type": "string"
                },
                "first_name": {
                    "type": "string",
                    "maxLength": 100
                },
                "gender": {
                    "type": "string",
                    "enum": [
                        "Male",
                        "Female",
                        "Other",
                        "Prefer not to say"
                    ]
                },
                "last_name": {
                    "type": "string",
                    "maxLength": 100
                },
                "location": {
                    "type": "string",
                    "maxLength": 100
                },
                "username": {
                    "type": "string",
                    "maxLength": 30,
                    "minLength": 3
                }
            }
        },
        "veza-backend-api_internal_core_marketplace.LicenseType": {
            "type": "string",
            "enum": [
                "basic",
                "premium",
                "exclusive"
            ],
            "x-enum-varnames": [
                "LicenseBasic",
                "LicensePremium",
                "LicenseExclusive"
            ]
        },
        "veza-backend-api_internal_core_marketplace.Order": {
            "type": "object",
            "properties": {
                "buyer_id": {
                    "type": "string"
                },
                "created_at": {
                    "type": "string"
                },
                "currency": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "items": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.OrderItem"
                    }
                },
                "payment_intent": {
                    "description": "Stripe PaymentIntent ID",
                    "type": "string"
                },
                "status": {
                    "description": "pending, paid, failed, refunded",
                    "type": "string"
                },
                "total_amount": {
                    "type": "number"
                },
                "updated_at": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_core_marketplace.OrderItem": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "string"
                },
                "order_id": {
                    "type": "string"
                },
                "price": {
                    "type": "number"
                },
                "product_id": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_core_marketplace.Product": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "currency": {
                    "type": "string"
                },
                "description": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "license_type": {
                    "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.LicenseType"
                },
                "price": {
                    "type": "number"
                },
                "product_type": {
                    "description": "\"track\", \"pack\", \"service\"",
                    "type": "string"
                },
                "seller_id": {
                    "type": "string"
                },
                "status": {
                    "$ref": "#/definitions/veza-backend-api_internal_core_marketplace.ProductStatus"
                },
                "title": {
                    "type": "string"
                },
                "track_id": {
                    "description": "Liaison optionnelle avec un Track (si ProductType == \"track\")",
                    "type": "string"
                },
                "updated_at": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_core_marketplace.ProductStatus": {
            "type": "string",
            "enum": [
                "draft",
                "active",
                "archived"
            ],
            "x-enum-varnames": [
                "ProductStatusDraft",
                "ProductStatusActive",
                "ProductStatusArchived"
            ]
        },
        "veza-backend-api_internal_dto.LoginRequest": {
            "type": "object",
            "required": [
                "email",
                "password"
            ],
            "properties": {
                "email": {
                    "type": "string"
                },
                "password": {
                    "type": "string"
                },
                "remember_me": {
                    "type": "boolean"
                }
            }
        },
        "veza-backend-api_internal_dto.LoginResponse": {
            "type": "object",
            "properties": {
                "token": {
                    "$ref": "#/definitions/veza-backend-api_internal_dto.TokenResponse"
                },
                "user": {
                    "$ref": "#/definitions/veza-backend-api_internal_dto.UserResponse"
                }
            }
        },
        "veza-backend-api_internal_dto.RefreshRequest": {
            "type": "object",
            "required": [
                "refresh_token"
            ],
            "properties": {
                "refresh_token": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_dto.RegisterRequest": {
            "type": "object",
            "required": [
                "email",
                "password",
                "password_confirm"
            ],
            "properties": {
                "email": {
                    "type": "string"
                },
                "password": {
                    "type": "string",
                    "minLength": 12
                },
                "password_confirm": {
                    "type": "string"
                },
                "username": {
                    "type": "string",
                    "maxLength": 50,
                    "minLength": 3
                }
            }
        },
        "veza-backend-api_internal_dto.RegisterResponse": {
            "type": "object",
            "properties": {
                "token": {
                    "$ref": "#/definitions/veza-backend-api_internal_dto.TokenResponse"
                },
                "user": {
                    "$ref": "#/definitions/veza-backend-api_internal_dto.UserResponse"
                }
            }
        },
        "veza-backend-api_internal_dto.ResendVerificationRequest": {
            "type": "object",
            "required": [
                "email"
            ],
            "properties": {
                "email": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_dto.TokenResponse": {
            "type": "object",
            "properties": {
                "access_token": {
                    "type": "string"
                },
                "expires_in": {
                    "type": "integer"
                },
                "refresh_token": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_dto.UserResponse": {
            "type": "object",
            "properties": {
                "email": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "username": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_models.Playlist": {
            "type": "object",
            "properties": {
                "collaborators": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/veza-backend-api_internal_models.PlaylistCollaborator"
                    }
                },
                "cover_url": {
                    "type": "string"
                },
                "created_at": {
                    "type": "string"
                },
                "description": {
                    "type": "string"
                },
                "follower_count": {
                    "type": "integer"
                },
                "id": {
                    "type": "string"
                },
                "is_public": {
                    "type": "boolean"
                },
                "title": {
                    "type": "string"
                },
                "track_count": {
                    "type": "integer"
                },
                "tracks": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/veza-backend-api_internal_models.PlaylistTrack"
                    }
                },
                "updated_at": {
                    "type": "string"
                },
                "user_id": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_models.PlaylistCollaborator": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "permission": {
                    "$ref": "#/definitions/veza-backend-api_internal_models.PlaylistPermission"
                },
                "playlist_id": {
                    "type": "string"
                },
                "updated_at": {
                    "type": "string"
                },
                "user": {
                    "$ref": "#/definitions/veza-backend-api_internal_models.User"
                },
                "user_id": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_models.PlaylistPermission": {
            "type": "string",
            "enum": [
                "read",
                "write",
                "admin"
            ],
            "x-enum-varnames": [
                "PlaylistPermissionRead",
                "PlaylistPermissionWrite",
                "PlaylistPermissionAdmin"
            ]
        },
        "veza-backend-api_internal_models.PlaylistTrack": {
            "type": "object",
            "properties": {
                "added_at": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "playlist_id": {
                    "type": "string"
                },
                "position": {
                    "type": "integer"
                },
                "track": {
                    "$ref": "#/definitions/veza-backend-api_internal_models.Track"
                },
                "track_id": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_models.Track": {
            "type": "object",
            "properties": {
                "album": {
                    "type": "string"
                },
                "artist": {
                    "type": "string"
                },
                "bitrate": {
                    "description": "kbps",
                    "type": "integer"
                },
                "cover_art_path": {
                    "type": "string"
                },
                "created_at": {
                    "type": "string"
                },
                "duration": {
                    "description": "seconds",
                    "type": "integer"
                },
                "file_path": {
                    "type": "string"
                },
                "file_size": {
                    "description": "bytes",
                    "type": "integer"
                },
                "format": {
                    "description": "mp3, flac, wav, etc.",
                    "type": "string"
                },
                "genre": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "is_public": {
                    "type": "boolean"
                },
                "like_count": {
                    "type": "integer"
                },
                "play_count": {
                    "type": "integer"
                },
                "sample_rate": {
                    "description": "Hz",
                    "type": "integer"
                },
                "status": {
                    "$ref": "#/definitions/veza-backend-api_internal_models.TrackStatus"
                },
                "status_message": {
                    "type": "string"
                },
                "stream_manifest_url": {
                    "type": "string"
                },
                "stream_status": {
                    "description": "pending, processing, ready, error",
                    "type": "string"
                },
                "title": {
                    "type": "string"
                },
                "updated_at": {
                    "type": "string"
                },
                "user_id": {
                    "type": "string"
                },
                "waveform_path": {
                    "type": "string"
                },
                "year": {
                    "type": "integer"
                }
            }
        },
        "veza-backend-api_internal_models.TrackStatus": {
            "type": "string",
            "enum": [
                "uploading",
                "processing",
                "completed",
                "failed"
            ],
            "x-enum-varnames": [
                "TrackStatusUploading",
                "TrackStatusProcessing",
                "TrackStatusCompleted",
                "TrackStatusFailed"
            ]
        },
        "veza-backend-api_internal_models.User": {
            "type": "object",
            "properties": {
                "avatar": {
                    "type": "string"
                },
                "bio": {
                    "type": "string"
                },
                "birthdate": {
                    "type": "string"
                },
                "created_at": {
                    "type": "string"
                },
                "email": {
                    "type": "string"
                },
                "first_name": {
                    "type": "string"
                },
                "gender": {
                    "type": "string"
                },
                "id": {
                    "type": "string"
                },
                "is_active": {
                    "type": "boolean"
                },
                "is_admin": {
                    "type": "boolean"
                },
                "is_public": {
                    "type": "boolean"
                },
                "is_verified": {
                    "type": "boolean"
                },
                "last_login_at": {
                    "type": "string"
                },
                "last_name": {
                    "type": "string"
                },
                "location": {
                    "type": "string"
                },
                "password": {
                    "description": "Virtual field for input",
                    "type": "string"
                },
                "role": {
                    "type": "string"
                },
                "slug": {
                    "type": "string"
                },
                "token_version": {
                    "type": "integer"
                },
                "updated_at": {
                    "type": "string"
                },
                "username": {
                    "type": "string"
                },
                "username_changed_at": {
                    "type": "string"
                }
            }
        },
        "veza-backend-api_internal_response.APIResponse": {
            "type": "object",
            "properties": {
                "data": {},
                "error": {},
                "success": {
                    "type": "boolean"
                }
            }
        }
    },
    "securityDefinitions": {
        "BearerAuth": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}`1.2.0"1.2.0"localhost:8080"localhost:8080"/api/v1"/api/v1"Veza Backend API"Veza Backend API"Backend API for Veza platform."Backend API for Veza platform.""swagger"{{"{{"}}"}}" Package docs Code generated by swaggo/swag. DO NOT EDIT SwaggerInfo holds exported Swagger Info so clients can modify it/home/senke/git/talas/veza/veza-backend-api/go.modveza-backend-apigo1.23.8v0.0.0-20240417053706-3d75831295e8v1.6.2v0.0.0-20170520113014-b970184f4d9ev1.9.0v0.40.0v1.9.1v10.16.0v5.3.0v1.6.0v1.5.3v1.5.1v1.10.9v1.5.0github.com/prometheus/client_golangv1.22.0github.com/prometheus/client_modelv0.6.2v1.10.0v9.16.0v1.0.0github.com/stretchr/testifyv1.11.1v1.0.1v1.6.1v1.16.6v0.33.0v1.27.0golang.org/x/cryptov0.37.0v0.30.0golang.org/x/timev0.12.0v2.2.1v1.30.0v0.3.0// indirectgithub.com/Azure/go-ansitermv0.0.0-20210617225240-d185dfc1b5a1v1.2.1github.com/Microsoft/go-winiov1.1.1v0.0.0-20170810143723-de5bf2ad4578github.com/beorn7/perksv1.0.1-0.20190219062509-6c824513baccgithub.com/bytedance/sonicv4.2.1v2.3.0github.com/chenzhuoyu/base64xv0.0.0-20221115062448-fe3a3abad311github.com/containerd/containerdv1.7.18v0.1.0v0.2.1v0.3.1github.com/davecgh/go-spewv0.0.0-20200823014737-9f7001d12a5fv0.6.0github.com/docker/dockerv27.1.1+incompatiblegithub.com/docker/go-connectionsv0.5.0v1.0.4v1.4.2v1.4.1v1.2.2github.com/go-ole/go-olev1.2.6v0.19.5v0.19.6v0.20.4v0.19.15v0.14.1v0.18.1github.com/goccy/go-jsonv0.10.2github.com/gogo/protobufv1.3.2v0.0.0-20240606120523-5a60cdf6a761v5.6.0v2.2.2v1.1.5github.com/json-iterator/gov1.1.12v1.18.0github.com/klauspost/cpuid/v2v2.2.4v1.2.4github.com/lufia/plan9statsv0.0.0-20211012122336-39d0f177ccd0v1.8.7github.com/mailru/easyjsonv0.7.6v0.0.19v1.14.22github.com/moby/docker-image-specv1.3.1github.com/modern-go/concurrentv0.0.0-20180306012644-bacd9c7ef1ddgithub.com/modern-go/reflect2v1.0.2v0.0.0-20191010083416-a7dc8b61c822github.com/opencontainers/image-specv1.1.0v2.0.8v0.9.1github.com/pmezard/go-difflibgithub.com/power-devops/perfstatv0.0.0-20210106213030-5aafc221ea8cgithub.com/prometheus/commonv0.63.0v0.16.1github.com/shirou/gopsutil/v3v3.23.12github.com/shoenig/go-m1cpuv0.1.6v1.9.3v0.5.2v0.3.12v0.6.1github.com/twitchyliquid64/golang-asmv0.15.1v1.2.11github.com/yusufpapurcu/wmiv1.2.3v0.49.0v1.24.0golang.org/x/archgolang.org/x/imagev0.0.0-20191009234506-e7c1f5e7dbb8golang.org/x/modv0.25.0golang.org/x/netv0.39.0golang.org/x/syncv0.16.0golang.org/x/sysv0.35.0golang.org/x/textv0.24.0golang.org/x/toolsv0.32.0google.golang.org/protobufv1.36.8v2.4.0v3.0.1/home/senke/git/talas/veza/veza-backend-api/internal/home/senke/git/talas/veza/veza-backend-api/internal/api/home/senke/git/talas/veza/veza-backend-api/internal/api/admin/home/senke/git/talas/veza/veza-backend-api/internal/api/admin/service.goNewServiceroleGetDashboardStatsGetUsersGetAnalyticsGetCategoriesuserIDmodelsadminveza-backend-api/internal/models"veza-backend-api/internal/models"SELECT role FROM users WHERE id = $1"SELECT role FROM users WHERE id = $1"false"admin"super_admin"super_admin"DashboardStatsTotalUsersdb:"total_users" json:"total_users"ActiveUsersdb:"active_users" json:"active_users"TotalTracksdb:"total_tracks" json:"total_tracks"PublicTracksdb:"public_tracks" json:"public_tracks"TotalSharedResourcesdb:"total_shared_resources" json:"total_shared_resources"TotalListingsdb:"total_listings" json:"total_listings"ActiveListingsdb:"active_listings" json:"active_listings"TotalOffersdb:"total_offers" json:"total_offers"PendingOffersdb:"pending_offers" json:"pending_offers"TotalMessagesdb:"total_messages" json:"total_messages"TotalRoomsdb:"total_rooms" json:"total_rooms"TotalProductsdb:"total_products" json:"total_products"TotalCategoriesdb:"total_categories" json:"total_categories"SELECT COUNT(*) FROM users WHERE is_active = true"SELECT COUNT(*) FROM users WHERE is_active = true"SELECT COUNT(*) FROM tracks"SELECT COUNT(*) FROM tracks"SELECT COUNT(*) FROM listings WHERE status = 'open'"SELECT COUNT(*) FROM listings WHERE status = 'open'"UserAnalyticsdb:"user_id" json:"user_id"db:"username" json:"username"db:"email" json:"email"db:"role" json:"role"db:"tracks_count" json:"tracks_count"ResourcesCountdb:"resources_count" json:"resources_count"ListingsCountdb:"listings_count" json:"listings_count"MessagesCountdb:"messages_count" json:"messages_count"ProductsCountdb:"products_count" json:"products_count"RegistrationDatedb:"registration_date" json:"registration_date"LastActivitydb:"last_activity" json:"last_activity,omitempty"db:"is_active" json:"is_active"StorageUseddb:"storage_used" json:"storage_used,omitempty"AdminContentAnalyticsMonthlyCountdb:"month" json:"month"db:"count" json:"count"TagCountdb:"tag" json:"tag"UploaderStatsTotalUploadsdb:"total_uploads" json:"total_uploads"TotalDownloadsdb:"total_downloads" json:"total_downloads"CategoryStatsCategoryIDdb:"category_id" json:"category_id"CategoryNamedb:"category_name" json:"category_name"ProductCountdb:"product_count" json:"product_count"UserCountdb:"user_count" json:"user_count"TracksByMonthjson:"tracks_by_month"ResourcesByMonthjson:"resources_by_month"UsersByMonthjson:"users_by_month"PopularTagsjson:"popular_tags"TopUploadersjson:"top_uploaders"json:"category_stats,omitempty" Récupérer les statistiques Ignorer l'erreur pour l'instant TODO: Implement based on doc_admin_handler.md TODO: Implement categories/home/senke/git/talas/veza/veza-backend-api/internal/api/chat/home/senke/git/talas/veza/veza-backend-api/internal/api/chat/handler.gochat Package chat - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/collaboration/home/senke/git/talas/veza/veza-backend-api/internal/api/collaboration/handler.gocollaboration Package collaboration - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/contest/home/senke/git/talas/veza/veza-backend-api/internal/api/contest/handler.gocontest Package contest - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/education/home/senke/git/talas/veza/veza-backend-api/internal/api/education/handlers.goAddExerciseRequestAddLessonRequestAddTutorialCommentRequestAddTutorialStepRequestCreateCourseRequestCreateTutorialRequestSetupRoutesUpdateCourseRequestUpdateProgressRequestUpdateTutorialRequestcourseManagertutorialManagercourseexistsCourseManagerCourseCourseLevelLessonCourseIDjson:"course_id"json:"title"VideoURLjson:"video_url"json:"duration"json:"order"IsFreejson:"is_free"ExerciseExerciseTypeLessonIDjson:"lesson_id"Solutionjson:"solution"Pointsjson:"points"TimeLimitjson:"time_limit"json:"is_required"json:"score"MaxScorejson:"max_score"IsPassedjson:"is_passed"json:"issued_at"json:"expires_at"Instructorjson:"instructor"Pricejson:"price"Currencyjson:"currency"json:"thumbnail"Lessonsjson:"lessons"Exercisesjson:"exercises"json:"certificates"json:"tags"IsPublishedjson:"is_published"CourseProgressjson:"progress"CompletedLessonsjson:"completed_lessons"CurrentLessonjson:"current_lesson"TimeSpentjson:"time_spent"LastAccessedjson:"last_accessed"IsCompletedjson:"is_completed"json:"completed_at"coursesprogressCreateCourseGetCourseListCoursesUpdateCourseDeleteCourseAddLessonAddExerciseGetUserProgressUpdateUserProgressIssueCertificateTutorialManagerTutorialVideoQualityjson:"author"Qualityjson:"quality"Viewsjson:"views"Dislikesjson:"dislikes"Ratingjson:"rating"TutorialStepTutorialIDjson:"tutorial_id"TutorialCommentIsHelpfuljson:"is_helpful"tutorialsstepsCreateTutorialGetTutorialListTutorialsUpdateTutorialDeleteTutorialAddTutorialStepGetTutorialStepsAddTutorialCommentGetTutorialCommentsIncrementViewsLikeTutorialDislikeTutorialupdateTutorialRatingSearchTutorialscourseIDisPublishedisFreeupdateslessonexerciselessonIDmaxScoremaxScoreStrscorescoreStrtutorialtutorialIDauthoreducationstrconv"strconv"veza-backend-api/internal/common"veza-backend-api/internal/common"veza-backend-api/internal/core/education"veza-backend-api/internal/core/education"veza-backend-api/internal/response"veza-backend-api/internal/response"json:"title" binding:"required"json:"description" binding:"required"json:"instructor" binding:"required"json:"category" binding:"required"json:"level" binding:"required"json:"duration" binding:"required"json:"language" binding:"required"`json:"title" binding:"required"``json:"description" binding:"required"``json:"instructor" binding:"required"``json:"category" binding:"required"``json:"level" binding:"required"``json:"duration" binding:"required"``json:"price"``json:"language" binding:"required"``json:"tags"``json:"title"``json:"description"``json:"instructor"``json:"category"``json:"level"``json:"duration"``json:"language"``json:"is_published"`json:"author" binding:"required"json:"video_url" binding:"required"json:"quality" binding:"required"`json:"author" binding:"required"``json:"video_url" binding:"required"``json:"thumbnail"``json:"quality" binding:"required"``json:"is_free"``json:"author"``json:"video_url"``json:"quality"`json:"content" binding:"required"json:"order" binding:"required"`json:"content" binding:"required"``json:"order" binding:"required"`json:"solution" binding:"required"json:"type" binding:"required"json:"points" binding:"required"`json:"solution" binding:"required"``json:"type" binding:"required"``json:"points" binding:"required"``json:"time_limit"``json:"is_required"`json:"progress" binding:"required"`json:"progress" binding:"required"``json:"completed_lessons"``json:"current_lesson"``json:"score"``json:"time_spent"``json:"timestamp"`json:"rating" binding:"min=1,max=5"`json:"rating" binding:"min=1,max=5"`GetUserIDFromContextStatusUnauthorized401Utilisateur non authentifié"Utilisateur non authentifié"StatusBadRequest400Données de requête invalides"Données de requête invalides"Échec de création du cours"Échec de création du cours"StatusInternalServerError500Cours créé avec succès"Cours créé avec succès"course_id"course_id"ID de cours requis"ID de cours requis"Échec de récupération du cours"Échec de récupération du cours"StatusNotFound404Cours non trouvé"Cours non trouvé"Cours récupéré avec succès"Cours récupéré avec succès""category""level"is_published"is_published"is_free"is_free"Échec de récupération des cours"Échec de récupération des cours"Cours récupérés avec succès"Cours récupérés avec succès""title""description"instructor"instructor""duration"price"price""language""tags"Échec de mise à jour du cours"Échec de mise à jour du cours"Cours mis à jour avec succès"Cours mis à jour avec succès"Échec de suppression du cours"Échec de suppression du cours"Cours supprimé avec succès"Cours supprimé avec succès"Échec d'ajout de leçon"Échec d'ajout de leçon"Leçon ajoutée avec succès"Leçon ajoutée avec succès"lesson_id"lesson_id"ID de cours et de leçon requis"ID de cours et de leçon requis"Échec d'ajout d'exercice"Échec d'ajout d'exercice"Exercice ajouté avec succès"Exercice ajouté avec succès"Échec de récupération de la progression"Échec de récupération de la progression"Progression non trouvée"Progression non trouvée"Progression récupérée avec succès"Progression récupérée avec succès"Échec de mise à jour de la progression"Échec de mise à jour de la progression"Progression mise à jour avec succès"Progression mise à jour avec succès""score"max_score"max_score"Tous les paramètres sont requis"Tous les paramètres sont requis"Score invalide"Score invalide"Score maximum invalide"Score maximum invalide"Échec d'émission du certificat"Échec d'émission du certificat"Certificat émis avec succès"Certificat émis avec succès"Échec de création du tutoriel"Échec de création du tutoriel"Tutoriel créé avec succès"Tutoriel créé avec succès"tutorial_id"tutorial_id"ID de tutoriel requis"ID de tutoriel requis"Échec de récupération du tutoriel"Échec de récupération du tutoriel"Tutoriel non trouvé"Tutoriel non trouvé"Échec d'incrémentation des vues"Échec d'incrémentation des vues"Tutoriel récupéré avec succès"Tutoriel récupéré avec succès""author"Échec de récupération des tutoriels"Échec de récupération des tutoriels"Tutoriels récupérés avec succès"Tutoriels récupérés avec succès""q"Terme de recherche requis"Terme de recherche requis"Échec de recherche des tutoriels"Échec de recherche des tutoriels"Recherche de tutoriels terminée"Recherche de tutoriels terminée"video_url"video_url"thumbnail"thumbnail"quality"quality"Échec de mise à jour du tutoriel"Échec de mise à jour du tutoriel"Tutoriel mis à jour avec succès"Tutoriel mis à jour avec succès"Échec de suppression du tutoriel"Échec de suppression du tutoriel"Tutoriel supprimé avec succès"Tutoriel supprimé avec succès"Échec d'ajout d'étape de tutoriel"Échec d'ajout d'étape de tutoriel"Étape de tutoriel ajoutée avec succès"Étape de tutoriel ajoutée avec succès"Échec de récupération des étapes"Échec de récupération des étapes"Étapes récupérées avec succès"Étapes récupérées avec succès"GetUsernameFromContextUtilisateur anonyme"Utilisateur anonyme"Échec d'ajout de commentaire"Échec d'ajout de commentaire"Commentaire ajouté avec succès"Commentaire ajouté avec succès"Échec de récupération des commentaires"Échec de récupération des commentaires"Commentaires récupérés avec succès"Commentaires récupérés avec succès"Échec d'ajout de like"Échec d'ajout de like"Like ajouté avec succès"Like ajouté avec succès"Échec d'ajout de dislike"Échec d'ajout de dislike"Dislike ajouté avec succès"Dislike ajouté avec succès" Handler gère les requêtes HTTP pour l'éducation NewHandler crée un nouveau handler d'éducation Request/Response structures COURSES HANDLERS CreateCourse crée un nouveau cours GetCourse récupère un cours par son ID ListCourses liste tous les cours disponibles UpdateCourse met à jour un cours DeleteCourse supprime un cours AddLesson ajoute une leçon à un cours AddExercise ajoute un exercice à un cours GetUserProgress récupère la progression d'un utilisateur UpdateUserProgress met à jour la progression d'un utilisateur IssueCertificate émet un certificat Récupérer les paramètres de la requête TUTORIALS HANDLERS CreateTutorial crée un nouveau tutoriel GetTutorial récupère un tutoriel par son ID Incrémenter les vues ListTutorials liste tous les tutoriels disponibles SearchTutorials recherche des tutoriels UpdateTutorial met à jour un tutoriel DeleteTutorial supprime un tutoriel AddTutorialStep ajoute une étape à un tutoriel GetTutorialSteps récupère les étapes d'un tutoriel AddTutorialComment ajoute un commentaire à un tutoriel GetTutorialComments récupère les commentaires d'un tutoriel LikeTutorial ajoute un like à un tutoriel DislikeTutorial ajoute un dislike à un tutoriel/home/senke/git/talas/veza/veza-backend-api/internal/api/education/routes.goauthMiddlewareedujwtSecretveza-backend-api/internal/middleware"veza-backend-api/internal/middleware"/education"/education"/courses"/courses"/create"/create"/list"/list"/:course_id"/:course_id"/:course_id/lessons"/:course_id/lessons"/:course_id/lessons/:lesson_id/exercises"/:course_id/lessons/:lesson_id/exercises"/:course_id/progress"/:course_id/progress"/:course_id/certificate"/:course_id/certificate"/tutorials"/tutorials"/search"/search"/:tutorial_id"/:tutorial_id"/:tutorial_id/steps"/:tutorial_id/steps"/:tutorial_id/comments"/:tutorial_id/comments"/:tutorial_id/like"/:tutorial_id/like"/:tutorial_id/dislike"/:tutorial_id/dislike" SetupRoutes configure les routes d'éducation Added authMiddleware parameter Groupe de routes pour l'éducation Routes des cours Changed to authMiddleware.RequireAuth() Routes des tutoriels Routes publiques (sans authentification) Routes protégées (avec authentification)/home/senke/git/talas/veza/veza-backend-api/internal/api/graphql/home/senke/git/talas/veza/veza-backend-api/internal/api/graphql/handler.gographql Package graphql - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/grpc/home/senke/git/talas/veza/veza-backend-api/internal/api/grpc/handler.gogrpc Package grpc - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/handlers/home/senke/git/talas/veza/veza-backend-api/internal/api/handlers/rbac_handlers.goInitRBACHandlersNewRBACHandlersRBACHandlersRBACHandlersInstancerbacServiceRBACServiceCreateRoleGetRoleByIDAssignRoleToUserRemoveRoleFromUserGetUserRolesGetUserPermissionsGetAllRolesGetRoleroleIDrolespermissionshasPermissionpermissionservices"github.com/google/uuid"veza-backend-api/internal/services"veza-backend-api/internal/services"json:"name" binding:"required"json:"permissions"`json:"name" binding:"required"``json:"permissions"`"error"json:"is_system"Failed to create role"Failed to create role"StatusCreated201"success""role""id"Invalid role ID"Invalid role ID"Failed to get role"Failed to get role"Role not found"Role not found"StatusOKFailed to get roles"Failed to get roles""roles"user_id"user_id"Invalid user ID"Invalid user ID"RoleIDjson:"role_id" binding:"required"`json:"role_id" binding:"required"`Failed to assign role to user"Failed to assign role to user""message"Role assigned to user successfully"Role assigned to user successfully"role_id"role_id"Failed to remove role from user"Failed to remove role from user"Role removed from user successfully"Role removed from user successfully"Failed to get user roles"Failed to get user roles"Failed to get user permissions"Failed to get user permissions""permissions""resource""action"Resource and action are required"Resource and action are required"Failed to check permission"Failed to check permission"has_permission"has_permission"json:"resource" binding:"required"json:"action" binding:"required"`json:"resource" binding:"required"``json:"action" binding:"required"`Failed to create permission"Failed to create permission""permission" RBACHandlers handles RBAC-related API endpoints NewRBACHandlers creates new RBAC handlers InitRBACHandlers initializes RBAC handlers Store handlers globally for route registration RBACHandlersInstance holds the global RBAC handlers instance CreateRole creates a new role GetRole gets a role by ID GetAllRoles gets all roles AssignRoleToUser assigns a role to a user RemoveRoleFromUser removes a role from a user GetUserRoles gets all roles for a user GetUserPermissions gets all permissions for a user CheckPermission checks if a user has a specific permission CreatePermission creates a new permission/home/senke/git/talas/veza/veza-backend-api/internal/api/listing/home/senke/git/talas/veza/veza-backend-api/internal/api/listing/handler.golisting Package listing - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/message/home/senke/git/talas/veza/veza-backend-api/internal/api/message/handler.go Package message - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/offer/home/senke/git/talas/veza/veza-backend-api/internal/api/offer/handler.gooffer Package offer - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/production_challenge/home/senke/git/talas/veza/veza-backend-api/internal/api/production_challenge/handler.goproduction_challenge Package production_challenge - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/room/home/senke/git/talas/veza/veza-backend-api/internal/api/room/handler.goroom Package room - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/router.goincludeStackTracecreateGroupmarketHandlermarketServicestorageServiceuploadDirloginGrouppasswordGroupauthGroupauthServiceemailServiceemailValidatoremailVerificationServicepasswordResetServicepasswordServicepasswordValidatorrefreshTokenServicechunkServicechunksDirinternalDeprecatedlikeServiceredisClientstreamServicetrackHandlertrackServicetrackUploadServicev1InternalprofileHandlerusersuploadGrouptracksuploadConfiguploadValidatorchatHandlerchatServiceplaylistHandlerplaylistServiceplaylistswebhookHandlerwebhookServicewebhookWorkerwebhookshealthHandlerrabbitMQEventBusbuildTimechatServerURLgitCommitstatusHandlerstreamServerURLuploadHandlerdeprecationMWhealthCheckHandlerlivenessHandlerreadinessHandlerv1PublicauditauditHandlerconversationsmessageReporoomHandlerroomReporoomServicesessionHandlersessionsuploadsauthcoremarketplacerepositoriestrackcorevalidators"github.com/redis/go-redis/v9"veza-backend-api/internal/handlers"veza-backend-api/internal/handlers"veza-backend-api/internal/repositories"veza-backend-api/internal/repositories""github.com/swaggo/files""github.com/swaggo/gin-swagger"veza-backend-api/internal/core/auth"veza-backend-api/internal/core/auth"veza-backend-api/internal/core/marketplace"veza-backend-api/internal/core/marketplace"veza-backend-api/internal/core/track"veza-backend-api/internal/core/track"veza-backend-api/internal/validators"veza-backend-api/internal/validators"veza-backend-api/internal/workers"veza-backend-api/internal/workers"RequestLoggerSentryRecoverSecurityHeadersEnvDevelopmentDEBUG"DEBUG"CORSCORS origins not configured - strict mode enabled: ALL CORS requests will be rejected."CORS origins not configured - strict mode enabled: ALL CORS requests will be rejected."Config is nil - CORS middleware applied in strict mode (reject all origins)."Config is nil - CORS middleware applied in strict mode (reject all origins)."RequestID/swagger/*any"/swagger/*any"uploads/tracks"uploads/tracks"TrackStorageServicelocalPathuseS3s3ServiceretryDelaySetS3ServiceGetDownloadURLSaveTracksaveToS3saveLocallydeleteFromS3deleteLocallygetContentTypeFromExtensionGenerateTrackKeyNewTrackStorageServiceStorageServiceCreateProductGetProductListProductsCreateOrderProcessPaymentWebhookGetUserLicensesMarketplaceHandlerMarketplaceServiceNewOrderItemProductIDOrderItemgorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"OrderIDgorm:"type:uuid;not null" json:"order_id"gorm:"type:uuid;not null" json:"product_id"gorm:"not null;type:decimal(10,2)" json:"price"BuyerIDgorm:"type:uuid;not null" json:"buyer_id"TotalAmountgorm:"not null;type:decimal(10,2)" json:"total_amount"gorm:"default:'EUR'" json:"currency"gorm:"default:'pending'" json:"status"PaymentIntentjson:"payment_intent,omitempty"gorm:"foreignKey:OrderID" json:"items"gorm:"autoCreateTime" json:"created_at"gorm:"autoUpdateTime" json:"updated_at"ProductStatusLicenseTypeSellerIDgorm:"type:uuid;not null" json:"seller_id"gorm:"not null;size:255" json:"title"gorm:"type:text" json:"description"gorm:"default:'EUR';size:3" json:"currency"gorm:"default:'draft'" json:"status"ProductTypegorm:"not null" json:"product_type"gorm:"type:uuid" json:"track_id,omitempty"gorm:"size:50" json:"license_type,omitempty"gorm:"type:uuid;not null" json:"track_id"gorm:"not null" json:"type"Rightsgorm:"type:jsonb" json:"rights"DownloadsLeftgorm:"default:3" json:"downloads_left"json:"expires_at,omitempty"CommonHandlerValidateVarValidateRequestRespondWithSuccessRespondWithErrorRespondWithValidationErrorRespondWithPaginatedDataBindAndValidateJSONGetPaginationParamsValidatePaginationLogRequestLogResponseSetRequestIDValidateRequiredFieldsSanitizeStringParseJSONSafeMarshalJSONGetClientIPRateLimitKeyservicecommonHandlerNewMarketplaceHandler/marketplace"/marketplace"/products"/products"/orders"/orders"/download/:product_id"/download/:product_id"EmailValidatorValidateFormatIsUniqueNewEmailValidatorPasswordValidatorNewPasswordValidatorPasswordServiceGetUserByEmailGeneratePasswordResetTokenResetPasswordValidatePasswordChangePasswordGenerateJWTUpdatePasswordNewPasswordServicePasswordResetServiceGenerateTokenStoreTokenMarkTokenAsUsedInvalidateOldTokensNewPasswordResetServiceNewJWTServicefailed to initialize JWT service: %w"failed to initialize JWT service: %w"RefreshTokenServiceRevokeRevokeAllHashTokenNewRefreshTokenServiceEmailVerificationServiceNewEmailVerificationServiceEmailServicesmtpHostsmtpPortsmtpUsersmtpPassfromEmailfromNameSendVerificationEmailSendVerificationEmailWithUserIDVerifyEmailTokenResendVerificationEmailgenerateVerificationTokenstoreVerificationTokensendEmailbuildVerificationEmailHTMLSendPasswordResetEmailbuildPasswordResetEmailNewEmailServiceNewSessionServiceAuthServicejobWorkerGetUserByUsernameLoginVerifyEmailLogoutInvalidateAllUserSessionsAdminVerifyUserAdminBlockUserRequestPasswordResetValidateAccessTokenUpdateLastLoginNewAuthService/auth"/auth"/register"/register"/login"/login"/refresh"/refresh"/verify-email"/verify-email"/resend-verification"/resend-verification"ResendVerification/check-username"/check-username"CheckUsername/password"/password"/reset-request"/reset-request"/reset"/reset"/logout"/logout"/me"/me"GetMe/chunks"/chunks"TrackServicemaxFileSizeValidateTrackFileUploadTrackcopyFileAsyncupdateTrackStatuscleanupFailedUploadCreateTrackFromPathCheckUserQuotaGetUserQuotaListTracksGetTrackByIDUpdateTrackUpdateStreamStatusGetTrackStatsBatchDeleteTracksdeleteTrackFilesBatchUpdateTracksNewTrackServiceTrackUploadServiceGetUploadProgressUpdateUploadStatuscalculateProgressNewTrackUploadServiceTrackChunkServiceUploadStateStoreChunkUploadInfoChunkInfoChunkNumberjson:"chunk_number"json:"md5"json:"file_path"Receivedjson:"received"UploadIDjson:"upload_id"TotalChunksjson:"total_chunks"TotalSizejson:"total_size"json:"filename"Chunksjson:"chunks"ReceivedMD5json:"received_md5,omitempty"DeleteStateSetStatecleanupIntervalmaxUploadAgeInitiateChunkedUploadSaveChunkGetUploadInfoCompleteChunkedUploadGetUploadStateCleanupUploadstartDiskCleanupCleanupOrphanedChunksNewTrackChunkServiceTrackLikeServiceLikeTrackUnlikeTrackIsLikedGetTrackLikesCountGetUserLikedTracksGetUserLikedTracksCountNewTrackLikeServiceStreamServiceCircuitBreakerHTTPClientcircuitBreakerDoWithContextbaseURLStartProcessingNewStreamServiceTrackHandlerTrackSearchServiceSearchTracksTrackShareServiceCreateShareGetShareByTokenRevokeShareTrackVersionServiceCreateVersionGetVersionByNumberListVersionsDeleteVersionTrackHistoryServiceRecordHistoryGetHistoryGetHistoryByUserGetHistoryByActionsearchServiceshareServiceversionServicehistoryServiceSetUploadValidatorSetPermissionServiceSetSearchServiceSetShareServiceSetVersionServiceSetHistoryServicegetUserIDrespondWithErrorGetUploadStatusUploadChunkmapTrackErrorgetErrorStatusCodeGetUploadQuotaResumeUploadGetTrackLikesDownloadTrackGetSharedTrackHandleStreamCallbackGetTrackHistoryNewTrackHandler/internal"/internal"DeprecationWarning/tracks/:id/stream-ready"/tracks/:id/stream-ready"/api/v1/internal"/api/v1/internal"GormUserRepositoryUpdateLastLoginAtIncrementTokenVersionNewGormUserRepositoryNewUserServiceWithDBProfileHandlerGetProfileCompletionNewProfileHandler/users"/users"/:id"/:id"/by-username/:username"/by-username/:username"/:id/completion"/:id/completion"UploadConfigMaxAudioSizeMaxImageSizeMaxVideoSizeAllowedAudioTypesAllowedImageTypesAllowedVideoTypesClamAVEnabledClamAVAddressQuarantineDirDefaultUploadConfigNewUploadValidatorUpload validator created with ClamAV unavailable - uploads will be rejected"Upload validator created with ClamAV unavailable - uploads will be rejected"/tracks"/tracks"/:id/stats"/:id/stats"/:id/history"/:id/history"/:id/download"/:id/download"/shared/:token"/shared/:token"/:id/status"/:id/status"/initiate"/initiate"/chunk"/chunk"/complete"/complete"/quota/:id"/quota/:id"/resume/:uploadId"/resume/:uploadId"/batch/delete"/batch/delete"/batch/update"/batch/update"/:id/like"/:id/like"/:id/likes"/:id/likes"/:id/share"/:id/share"/share/:id"/share/:id"ChatServiceNewChatServiceChatHandlerGetTokenNewChatHandler/chat"/chat"/token"/token"NewPlaylistRepositoryNewPlaylistTrackRepositoryNewPlaylistCollaboratorRepositoryNewPlaylistServicePlaylistHandlerPlaylistAnalyticsServiceGetPlaylistStatsIncrementPlaylistPlaysplaylistAnalyticsServiceSetPlaylistAnalyticsServiceDuplicatePlaylistGetRecommendationsNewPlaylistHandler/playlists"/playlists"/:id/tracks"/:id/tracks"/:id/tracks/:track_id"/:id/tracks/:track_id"/:id/tracks/reorder"/:id/tracks/reorder"WebhookServiceRegisterWebhookDeliverWebhookgenerateSignatureVerifySignatureTriggerEventListWebhooksGetWebhookDeleteWebhookNewWebhookServiceWebhookWorkerWebhookJobWebhookgorm:"type:uuid;primaryKey" json:"id"gorm:"type:uuid;not null;index" json:"user_id"gorm:"not null" json:"url"gorm:"type:text[]" json:"events"gorm:"default:true" json:"active"gorm:"not null" json:"secret,omitempty"logFailedDeliveryCleanupOldFailuresRequeueFailedNewWebhookWorker100WebhookHandlerGetWebhookStatsTestWebhookNewWebhookHandler/webhooks"/webhooks"/stats"/stats"/:id/test"/:id/test"HealthHandlerReadinessLivenesscheckDatabasecheckRedischeckRabbitMQNewHealthHandlerSimpleHealthCheck/health"/health"/healthz"/healthz"/readyz"/readyz"/metrics"/metrics"PrometheusMetrics/metrics/aggregated"/metrics/aggregated"/system/metrics"/system/metrics"SystemMetricsAPP_VERSION"APP_VERSION""v1.0.0"GIT_COMMIT"GIT_COMMIT""unknown"BUILD_TIME"BUILD_TIME"StatusHandlerGetStatuscheckChatServercheckStreamServerGetSystemInfoNewStatusHandler/status"/status"NewAuditServiceUploadHandlerUploadFileuhDeleteUploadGetUploadStatsValidateFileTypeGetUploadLimitsUploadProgressBatchUploadNewUploadHandler/upload/limits"/upload/limits"/upload/validate-type"/upload/validate-type""/"SessionHandlershLogoutAllGetSessionsNewSessionHandlerAuditHandlerahGetAuditLogNewAuditHandler/sessions"/sessions"/logout-all"/logout-all"/:session_id"/:session_id"/uploads"/uploads"/batch"/batch"/:id/progress"/:id/progress"/audit"/audit"/logs"/logs"/activity"/activity"/suspicious"/suspicious"/ip/:ip"/ip/:ip"/logs/:id"/logs/:id"/cleanup"/cleanup"RoomRepositoryAddMemberRemoveMemberGetMembersByRoomIDNewRoomRepositoryChatMessageRepositoryGetConversationMessagesNewChatMessageRepositoryRoomServiceGetUserRoomsGetRoomHistoryNewRoomServiceRoomHandlerRoomServiceInterfaceCreateRoomRequestjson:"name" binding:"required,min=1,max=255"json:"type" binding:"required,oneof=public private direct"RoomResponseParticipantsjson:"participants"ChatMessageResponseConversationIDjson:"conversation_id"SenderIDjson:"sender_id"json:"message_type"NewRoomHandler/conversations"/conversations"/:id/members"/:id/members"/admin"/admin"/audit/logs"/audit/logs"/audit/stats"/audit/stats"/audit/suspicious"/audit/suspicious" Single handlers import swaggerFiles "github.com/swaggo/files" // Uncommented ginSwagger "github.com/swaggo/gin-swagger" // Uncommented Add missing imports. swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" APIRouter gère la configuration des routes de l'API NewAPIRouter crée une nouvelle instance de APIRouter Setup configure toutes les routes de l'API Middlewares globaux Utilisation du structured logger Prometheus Metrics Sentry error tracking MOD-P2-005: Security headers (HSTS, CSP, etc.) MOD-P1-005: Determine if stack traces should be included in logs Stack traces only in dev/DEBUG mode (not in production) Include if: APP_ENV=development OR LOG_LEVEL=DEBUG SECURITY: CORS configuration - use config.CORSOrigins strictly (P0-SECURITY) No fallback to CORSDefault() to avoid wildcard in production MOD-P0-001: Apply CORS middleware even if CORSOrigins is empty (strict mode - reject all origins) The middleware itself handles empty list correctly (rejects all origins) Fallback: if config is nil, apply CORS with empty list (strict mode) Global Timeout middleware (PR-6) MOD-P0-003: Removed duplicate timeout middleware registration Rate limiting via config.RateLimiter si disponible, sinon utiliser SimpleRateLimiter Swagger Documentation Routes core publiques (health, metrics, upload info) Setup internal routes (both legacy and modern) before v1 group These need to be on the root router, not under /api/v1 Groupe API v1 (nouveau frontend React) Routes core protégées (sessions, uploads, audit, admin, conversations) Réactivation des routes User et Track pour Phase 1 Réactivation des routes Chat pour Phase 4 Réactivation des routes Playlists pour Phase 5 Réactivation des routes Webhooks Marketplace Routes (v1.2.0) Méthodes de configuration des routes par module setupMarketplaceRoutes configure les routes de la marketplace Storage service (reused from tracks logic) Marketplace service Public routes Protected routes GO-012: Create product requires creator/premium/admin role setupAuthRoutes configure les routes d'authentification avec toutes les dépendances 1. Instanciation des dépendances 2. Service Auth complet Passer le JobWorker 3. Handlers Apply rate limiting to login endpoint (PR-3) Password reset routes (public) Protected routes (authentification JWT requise) Changed to RequireAuth() setupInternalRoutes configure les routes internal (legacy and modern) These routes must be on the root router, not under /api/v1 Create track handler for internal routes Deprecated /internal routes (legacy, on root router) New /api/v1/internal routes (modern, on root router) setupUserRoutes configure les routes utilisateur MOD-P1-003: Set permission service for admin check in ownership verification setupTrackRoutes configure les routes de gestion des tracks MOD-P1-001: Set upload validator for ClamAV scan before persistence GO-012: Upload track requires creator/premium/admin role Upload Batch operations Social Sharing Note: Internal routes are now set up in setupInternalRoutes() to avoid path prefix issues when setupTrackRoutes is called with a RouterGroup setupChatRoutes configure les routes de chat setupPlaylistRoutes configure les routes pour les playlists Protected routes for playlists Playlist Tracks setupWebhookRoutes configure les routes pour les webhooks Queue size Workers Max retries Start worker in background setupCorePublicRoutes configure les routes publiques core (health, metrics, upload info) Health check handlers Deprecated Public Core Routes - apply deprecation middleware only to specific routes Use a wrapper function to apply middleware to individual routes Wrap handlers with deprecation middleware for legacy routes only New /api/v1 Public Core Routes Status endpoint (comprehensive health check) Get build info from environment or defaults Upload info endpoints (public, already in /api/v1) MOD-P1-001-REFINEMENT: Permettre démarrage même si ClamAV down Créer un validateur minimal pour permettre les endpoints info setupCoreProtectedRoutes configure les routes protégées core (sessions, uploads, audit, admin, conversations) Middleware d'authentification pour routes protégées Services nécessaires Créer un validateur minimal pour permettre les routes d'upload (qui rejetteront) Handlers Routes de session Routes d'upload avec rate limiting spécifique Routes d'audit Routes de conversations (chat rooms) New Updated constructor Routes administrateur (avec authentification + permissions admin) Audit logs (disponibles)HealthCheckjson:"duration_ms,omitempty"Thresholdjson:"threshold_ms,omitempty"RoomMembergorm:"type:uuid;not null" json:"room_id"gorm:"column:sender_id;type:uuid;not null" json:"user_id"gorm:"not null;type:text" json:"content"gorm:"column:message_type;not null;default:'text'" json:"type"gorm:"column:reply_to_id;type:uuid" json:"parent_id,omitempty"gorm:"default:false" json:"is_edited"gorm:"default:false" json:"is_deleted"gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"-"gorm:"foreignKey:ParentID;constraint:OnDelete:SET NULL" json:"-"gorm:"size:255" json:"name"gorm:"column:room_type;not null;default:'public'" json:"type"gorm:"default:false" json:"is_private"gorm:"column:creator_id;type:uuid;not null" json:"created_by"Creatorgorm:"foreignKey:CreatedBy;constraint:OnDelete:CASCADE" json:"-"gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"members,omitempty"gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"messages,omitempty"gorm:"type:uuid;not null" json:"user_id"gorm:"not null;default:'member'" json:"role"JoinedAtgorm:"autoCreateTime" json:"joined_at"rmBatchUpdateResultBatchUpdateErrorjson:"track_id"Updatedjson:"updated"json:"failed"ValidationErrorjson:"field"json:"latency_ms,omitempty"TrackStatsUniqueListenersjson:"unique_listeners"CompletionRatejson:"completion_rate"json:"views,omitempty"json:"likes,omitempty"json:"comments,omitempty"TotalPlayTimejson:"total_play_time,omitempty"Downloadsjson:"downloads,omitempty"UpdateTrackParamsjson:"artist"json:"album"json:"genre"json:"year"json:"is_public"PlaylistStatsPlaysjson:"plays"json:"shares"json:"track_count"UploadStateChunksReceivedjson:"chunks_received"LastChunkjson:"last_chunk"ReceivedCountjson:"received_count"S3ServiceDeleteFileGetPresignedURLAppErrorjson:"field,omitempty"PasswordStrengthWebhookFailuregorm:"type:uuid;primaryKey"WebhookIDgorm:"type:uuid;not null;index" json:"webhook_id"gorm:"not null" json:"event"gorm:"not null" json:"error"gorm:"default:0" json:"retries"gorm:"not null" json:"created_at"db:"id"db:"email"db:"username"TrackHistoryActionTrackHistorygorm:"type:uuid;not null;index:idx_track_history_track_id" json:"track_id" db:"track_id"gorm:"not null;type:uuid;index:idx_track_history_user_id" json:"user_id" db:"user_id"gorm:"not null;size:50;index:idx_track_history_action" json:"action" db:"action"OldValuegorm:"type:text" json:"old_value,omitempty" db:"old_value"gorm:"type:text" json:"new_value,omitempty" db:"new_value"gorm:"autoCreateTime;index:idx_track_history_created_at" json:"created_at" db:"created_at"BatchDeleteResultBatchDeleteErrorjson:"deleted"json:"track_id" db:"track_id"json:"status" db:"status"json:"progress" db:"progress"json:"message,omitempty" db:"message"json:"stream_status,omitempty" db:"stream_status"json:"stream_manifest_url,omitempty" db:"stream_manifest_url"RecordHistoryParamsChatTokenResponseWSUrljson:"ws_url"TrackListParamsSortOrderCreateVersionParamsPaginationDatajson:"page"TotalPagesjson:"total_pages"HasNextjson:"has_next"HasPreviousjson:"has_previous"NextCursorjson:"next_cursor,omitempty"PreviousCursorjson:"previous_cursor,omitempty"TrackSearchParamsTagModeMinDurationMaxDurationMinBPMMaxBPMMinDateMaxDateChatMessagegorm:"column:room_id;type:uuid;not null" json:"conversation_id"gorm:"type:uuid;not null" json:"sender_id"gorm:"type:text;not null" json:"content"gorm:"type:varchar(50);not null" json:"message_type"ParentMessageIDgorm:"type:uuid" json:"parent_message_id,omitempty"ReplyToIDgorm:"type:uuid" json:"reply_to_id,omitempty"IsPinnedgorm:"default:false;not null" json:"is_pinned"gorm:"default:false;not null" json:"is_edited"gorm:"default:false;not null" json:"is_deleted"EditedAtjson:"edited_at,omitempty"gorm:"type:varchar(50);not null" json:"status"gorm:"type:jsonb" json:"metadata,omitempty"UserQuotajson:"tracks_count"TracksLimitjson:"tracks_limit"json:"storage_used"StorageLimitjson:"storage_limit"/home/senke/git/talas/veza/veza-backend-api/internal/api/search/home/senke/git/talas/veza/veza-backend-api/internal/api/search/handler.go Package search - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/shared_resources/home/senke/git/talas/veza/veza-backend-api/internal/api/shared_resources/handler.goshared_resources Package shared_resources - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/sound_design_contest/home/senke/git/talas/veza/veza-backend-api/internal/api/sound_design_contest/handler.gosound_design_contest Package sound_design_contest - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/tag/home/senke/git/talas/veza/veza-backend-api/internal/api/tag/handler.go Package tag - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/track/home/senke/git/talas/veza/veza-backend-api/internal/api/track/handler.gotrack Package track - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/user/home/senke/git/talas/veza/veza-backend-api/internal/api/user/handler.goAccountStatusAudioSettingsCreateUserRequestNewRouteGroupRouteGroupUpdateUserRequestUserActivityUserContentUserDataExportUserInteractionUserPreferencesRequestUserPreferencesResponseUserResponseGetUserPreferencesUpdateUserPreferencesDeleteAccountRecoverAccountExportUserDataRequestDataDeletionGetAccountStatusUpdateMeGetUsersExceptMeSearchUsersGetUserAvatarGetPreferencesUpdatePreferencesExportDatafilteredUsersidStrpreferencesexportDataUser ID not found"User ID not found"json:"first_name,omitempty"json:"last_name,omitempty"json:"bio,omitempty"json:"avatar,omitempty"json:"is_active"json:"is_verified"json:"last_login_at,omitempty"User not found"User not found"json:"is_active,omitempty"json:"is_verified,omitempty"json:"role,omitempty"BindAndValidateBadRequestCurrentPasswordjson:"current_password" binding:"required"NewPasswordjson:"new_password" binding:"required,min=8"`json:"current_password" binding:"required"``json:"new_password" binding:"required,min=8"`"page""1""limit""20""search"InternalServerErrorFailed to retrieve users"Failed to retrieve users""data"pagination"pagination""total"total_pages"total_pages"Query parameter 'q' is required"Query parameter 'q' is required"Failed to search users"Failed to search users"No avatar found"No avatar found"StatusFound302Desktopjson:"desktop"NewFollowersjson:"new_followers"TrackCommentsjson:"track_comments"DirectMessagesjson:"direct_messages"ShowEmailjson:"show_email"ShowActivityjson:"show_activity"AllowDMjson:"allow_dm"TrackVisibilityjson:"track_visibility"AutoPlayjson:"auto_play"json:"volume"Crossfadejson:"crossfade"Themejson:"theme"json:"audio"Failed to get preferences"Failed to get preferences"json:"theme,omitempty"json:"language,omitempty"json:"audio,omitempty"json:"password" binding:"required"json:"reason"ConfirmTextjson:"confirm_text" binding:"required"`json:"password" binding:"required"``json:"reason"``json:"confirm_text" binding:"required"`"DELETE"Confirmation text must be 'DELETE'"Confirmation text must be 'DELETE'"json:"email" binding:"required,email"`json:"email" binding:"required,email"`json:"details"TargetIDjson:"target_id"json:"profile"Activityjson:"activity"Interactionsjson:"interactions"ExportedAtjson:"exported_at"Failed to export user data"Failed to export user data"json:"deleted_at,omitempty"DeletionReasonjson:"deletion_reason,omitempty"RecoveryDeadlinejson:"recovery_deadline,omitempty"Failed to get account status"Failed to get account status" veza-backend-api/internal/api/user/handler.go Added import GetMe récupère le profil de l'utilisateur connecté UpdateMe met à jour le profil de l'utilisateur connecté ChangePassword change le mot de passe de l'utilisateur GetUsers liste tous les utilisateurs GetUsersExceptMe liste tous les utilisateurs sauf l'utilisateur connecté Ajouter le filtre pour exclure l'utilisateur actuel Filtrer l'utilisateur connecté Direct comparison of uuid.UUID -1 car on exclut l'utilisateur connecté SearchUsers recherche des utilisateurs ✅ Correct way to handle sql.NullString Rediriger vers l'URL de l'avatar ou servir le fichier GetPreferences récupère les préférences de l'utilisateur connecté UpdatePreferences met à jour les préférences de l'utilisateur connecté DeleteAccount supprime le compte de l'utilisateur (soft delete) Vérifier le texte de confirmation RecoverAccount récupère un compte supprimé ExportData exporte les données de l'utilisateur (RGPD) RequestDataDeletion demande la suppression définitive des données (RGPD) GetAccountStatus récupère le statut du comptejson:"username" binding:"required,min=3,max=50"json:"password" binding:"required,min=8"db:"id" json:"id"db:"password_hash" json:"-"db:"first_name" json:"first_name,omitempty"db:"last_name" json:"last_name,omitempty"db:"bio" json:"bio,omitempty"db:"avatar" json:"avatar,omitempty"db:"is_verified" json:"is_verified"db:"last_login_at" json:"last_login_at,omitempty"db:"created_at" json:"created_at"db:"updated_at" json:"updated_at"rgregisterPublicRoutesregisterProtectedRoutes/home/senke/git/talas/veza/veza-backend-api/internal/api/user/routes.go/:id/avatar"/:id/avatar"/recover"/recover"/me/password"/me/password"/me/preferences"/me/preferences"/me/status"/me/status"/me/export"/me/export"/me/request-deletion"/me/request-deletion"/except-me"/except-me" RouteGroup représente un groupe de routes pour le module utilisateur Added authMiddleware NewRouteGroup crée une nouvelle instance de RouteGroup Assign authMiddleware Register enregistre toutes les routes du module utilisateur Groupe principal des utilisateurs Routes publiques Routes protégées registerPublicRoutes enregistre les routes publiques GET /api/v1/users - Liste des utilisateurs GET /api/v1/users/:id/avatar - Avatar d'un utilisateur POST /api/v1/users/recover - Récupérer un compte supprimé registerProtectedRoutes enregistre les routes protégées GET /api/v1/users/me - Informations de l'utilisateur connecté PUT /api/v1/users/me - Mise à jour des informations de l'utilisateur PUT /api/v1/users/me/password - Changement de mot de passe GET /api/v1/users/me/preferences - Récupérer les préférences PUT /api/v1/users/me/preferences - Mettre à jour les préférences DELETE /api/v1/users/me - Supprimer le compte GET /api/v1/users/me/status - Statut du compte GET /api/v1/users/me/export - Exporter les données (RGPD) POST /api/v1/users/me/request-deletion - Demander suppression définitive GET /api/v1/users/except-me - Liste des utilisateurs sauf l'utilisateur connecté GET /api/v1/users/search - Recherche d'utilisateurs SetupRoutes configure les routes du module utilisateur (pour la compatibilité) func SetupRoutes(router *gin.RouterGroup, handler *Handler, jwtSecret string) { 	rg := NewRouteGroup(handler, jwtSecret) 	rg.Register(router) }/home/senke/git/talas/veza/veza-backend-api/internal/api/user/service.goargIndexbaseQuerycountQuerylimitClauseorderClausewhereClausepasswordHashsetPartsrowsAffectedcurrentHashcurrentPasswordnewPasswordactiveUsersnewUsersThisMonthtotalUsersverifiedUsersaudioJSONnotificationsJSONprivacyJSONreasonrecoveryDeadlinedeletedAtupdateQueryactivityexportinteractionsprofile"database/sql""strings"veza-backend-api/internal/utils"veza-backend-api/internal/utils"
		SELECT id, email, first_name, last_name, username, avatar, bio, 
			   role, is_active, is_verified, last_login_at, created_at, updated_at
		FROM users
	`
		SELECT id, email, first_name, last_name, username, avatar, bio, 
			   role, is_active, is_verified, last_login_at, created_at, updated_at
		FROM users
	`SELECT COUNT(*) FROM users"SELECT COUNT(*) FROM users" WHERE (
			email ILIKE $` WHERE (
			email ILIKE $` OR 
			first_name ILIKE $` OR 
			first_name ILIKE $` OR 
			last_name ILIKE $` OR 
			last_name ILIKE $` OR 
			username ILIKE $` OR 
			username ILIKE $`
		)`
		)`%"%"failed to count users: %w"failed to count users: %w" ORDER BY created_at DESC" ORDER BY created_at DESC" LIMIT $%d OFFSET $%d" LIMIT $%d OFFSET $%d"failed to query users: %w"failed to query users: %w"failed to scan user: %w"failed to scan user: %w"
		SELECT id, email, first_name, last_name, username, avatar, bio,
			   role, is_active, is_verified, last_login_at, created_at, updated_at
		FROM users 
		WHERE id = $1 AND is_active = true
	`
		SELECT id, email, first_name, last_name, username, avatar, bio,
			   role, is_active, is_verified, last_login_at, created_at, updated_at
		FROM users 
		WHERE id = $1 AND is_active = true
	`user not found"user not found"failed to get user: %w"failed to get user: %w"
		SELECT id, email, password_hash, first_name, last_name, username, 
			   avatar, bio, role, is_active, is_verified, last_login_at, 
			   created_at, updated_at
		FROM users 
		WHERE email = $1
	`
		SELECT id, email, password_hash, first_name, last_name, username, 
			   avatar, bio, role, is_active, is_verified, last_login_at, 
			   created_at, updated_at
		FROM users 
		WHERE email = $1
	`HashPasswordfailed to hash password: %w"failed to hash password: %w""user"
		INSERT INTO users (email, password_hash, first_name, last_name, username, role, is_active, is_verified, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, true, false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
		RETURNING id, email, first_name, last_name, username, role, is_active, is_verified, created_at, updated_at
	`
		INSERT INTO users (email, password_hash, first_name, last_name, username, role, is_active, is_verified, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, true, false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
		RETURNING id, email, first_name, last_name, username, role, is_active, is_verified, created_at, updated_at
	`"unique"email already exists"email already exists"failed to create user: %w"failed to create user: %w"updated_at = CURRENT_TIMESTAMP"updated_at = CURRENT_TIMESTAMP"first_name = $%d"first_name = $%d"last_name = $%d"last_name = $%d"username = $%d"username = $%d"avatar = $%d"avatar = $%d"bio = $%d"bio = $%d"is_active = $%d"is_active = $%d"is_verified = $%d"is_verified = $%d"role = $%d"role = $%d"
		UPDATE users 
		SET %s
		WHERE id = $%d
		RETURNING id, email, first_name, last_name, username, avatar, bio,
				  role, is_active, is_verified, last_login_at, created_at, updated_at
	`
		UPDATE users 
		SET %s
		WHERE id = $%d
		RETURNING id, email, first_name, last_name, username, avatar, bio,
				  role, is_active, is_verified, last_login_at, created_at, updated_at
	`, ", "failed to update user: %w"failed to update user: %w"
		UPDATE users 
		SET is_active = false, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1 AND is_active = true
	`
		UPDATE users 
		SET is_active = false, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1 AND is_active = true
	`failed to delete user: %w"failed to delete user: %w"failed to get rows affected: %w"failed to get rows affected: %w"
		UPDATE users 
		SET last_login_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`
		UPDATE users 
		SET last_login_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`failed to update last login: %w"failed to update last login: %w"SELECT password_hash FROM users WHERE id = $1"SELECT password_hash FROM users WHERE id = $1"failed to get user password: %w"failed to get user password: %w"CheckPasswordHashcurrent password is incorrect"current password is incorrect"failed to hash new password: %w"failed to hash new password: %w"
		UPDATE users 
		SET password_hash = $1, updated_at = CURRENT_TIMESTAMP
		WHERE id = $2
	`
		UPDATE users 
		SET password_hash = $1, updated_at = CURRENT_TIMESTAMP
		WHERE id = $2
	`failed to update password: %w"failed to update password: %w"failed to get total users: %w"failed to get total users: %w"total_users"total_users"SELECT COUNT(*) FROM users WHERE is_active = true AND is_verified = true"SELECT COUNT(*) FROM users WHERE is_active = true AND is_verified = true"failed to get verified users: %w"failed to get verified users: %w"verified_users"verified_users"
		SELECT COUNT(*) FROM users 
		WHERE is_active = true AND last_login_at > CURRENT_TIMESTAMP - INTERVAL '30 days'
	`
		SELECT COUNT(*) FROM users 
		WHERE is_active = true AND last_login_at > CURRENT_TIMESTAMP - INTERVAL '30 days'
	`failed to get active users: %w"failed to get active users: %w"active_users"active_users"
		SELECT COUNT(*) FROM users 
		WHERE is_active = true AND created_at >= date_trunc('month', CURRENT_TIMESTAMP)
	`
		SELECT COUNT(*) FROM users 
		WHERE is_active = true AND created_at >= date_trunc('month', CURRENT_TIMESTAMP)
	`failed to get new users this month: %w"failed to get new users this month: %w"new_users_this_month"new_users_this_month"
		SELECT user_id, theme, language, timezone, 
		       COALESCE(notifications, '{}') as notifications,
		       COALESCE(privacy, '{}') as privacy,
		       COALESCE(audio, '{}') as audio,
		       updated_at
		FROM user_preferences 
		WHERE user_id = $1
	`
		SELECT user_id, theme, language, timezone, 
		       COALESCE(notifications, '{}') as notifications,
		       COALESCE(privacy, '{}') as privacy,
		       COALESCE(audio, '{}') as audio,
		       updated_at
		FROM user_preferences 
		WHERE user_id = $1
	`light"light"en"en""UTC"public"public""high"0.80.800000000000000044413602879701896397/4503599627370496failed to get user preferences: %w"failed to get user preferences: %w"
		INSERT INTO user_preferences (user_id, theme, language, timezone, notifications, privacy, audio, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
		ON CONFLICT (user_id) DO UPDATE SET
			theme = EXCLUDED.theme,
			language = EXCLUDED.language,
			timezone = EXCLUDED.timezone,
			notifications = EXCLUDED.notifications,
			privacy = EXCLUDED.privacy,
			audio = EXCLUDED.audio,
			updated_at = EXCLUDED.updated_at
	`
		INSERT INTO user_preferences (user_id, theme, language, timezone, notifications, privacy, audio, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
		ON CONFLICT (user_id) DO UPDATE SET
			theme = EXCLUDED.theme,
			language = EXCLUDED.language,
			timezone = EXCLUDED.timezone,
			notifications = EXCLUDED.notifications,
			privacy = EXCLUDED.privacy,
			audio = EXCLUDED.audio,
			updated_at = EXCLUDED.updated_at
	`{}"{}"failed to update user preferences: %w"failed to update user preferences: %w"invalid password"invalid password"72036000000000002592000000000000
		UPDATE users 
		SET is_active = false, deleted_at = CURRENT_TIMESTAMP, 
		    deletion_reason = $2, recovery_deadline = $3, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`
		UPDATE users 
		SET is_active = false, deleted_at = CURRENT_TIMESTAMP, 
		    deletion_reason = $2, recovery_deadline = $3, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`failed to delete account: %w"failed to delete account: %w"
		SELECT id, password_hash, deleted_at, recovery_deadline
		FROM users 
		WHERE email = $1 AND deleted_at IS NOT NULL
	`
		SELECT id, password_hash, deleted_at, recovery_deadline
		FROM users 
		WHERE email = $1 AND deleted_at IS NOT NULL
	`no deleted account found for this email"no deleted account found for this email"failed to find account: %w"failed to find account: %w"recovery period has expired"recovery period has expired"
		UPDATE users 
		SET is_active = true, deleted_at = NULL, deletion_reason = NULL, 
		    recovery_deadline = NULL, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`
		UPDATE users 
		SET is_active = true, deleted_at = NULL, deletion_reason = NULL, 
		    recovery_deadline = NULL, updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`failed to recover account: %w"failed to recover account: %w"failed to get user profile: %w"failed to get user profile: %w"login"login"User login"User login"profile_update"profile_update"Profile updated"Profile updated""track"Sample Track"Sample Track"/tracks/1"/tracks/1""like"
		INSERT INTO data_deletion_requests (user_id, reason, status, requested_at)
		VALUES ($1, $2, 'pending', CURRENT_TIMESTAMP)
	`
		INSERT INTO data_deletion_requests (user_id, reason, status, requested_at)
		VALUES ($1, $2, 'pending', CURRENT_TIMESTAMP)
	`failed to create deletion request: %w"failed to create deletion request: %w"
		SELECT id, is_active, is_verified, created_at, deleted_at, 
		       COALESCE(deletion_reason, '') as deletion_reason,
		       recovery_deadline
		FROM users 
		WHERE id = $1
	`
		SELECT id, is_active, is_verified, created_at, deleted_at, 
		       COALESCE(deletion_reason, '') as deletion_reason,
		       recovery_deadline
		FROM users 
		WHERE id = $1
	`failed to get account status: %w"failed to get account status: %w"deleted"deleted"suspended"suspended""active" veza-backend-api/internal/api/user/service.go Service handles user business logic NewService creates a new user service GetUsers retrieves users with pagination and optional search Build the query with optional search Get total count Get users GetUserByID retrieves a user by ID GetUserByEmail retrieves a user by email (includes password hash for auth) CreateUser creates a new user Hash the password Set default role if not provided UpdateUser updates an existing user Build dynamic update query Add user ID as the last argument DeleteUser soft deletes a user (sets is_active to false) UpdateLastLogin updates the user's last login timestamp ChangePassword updates a user's password First, get the current password hash Verify current password Hash new password Update password GetUserStats returns basic user statistics Total users Verified users Active users (logged in within last 30 days) New users this month GetUserPreferences récupère les préférences d'un utilisateur Retourner les préférences par défaut TODO: Parse JSON strings to structs (simplified for now) UpdateUserPreferences met à jour les préférences d'un utilisateur Récupérer les préférences actuelles Appliquer les mises à jour Sauvegarder en base (upsert) TODO: Serialize structs to JSON (simplified for now) DeleteAccount supprime le compte d'un utilisateur (soft delete) Vérifier le mot de passe Marquer le compte comme supprimé avec période de grâce de 30 jours Vérifier l'utilisateur et son statut Vérifier que la période de récupération n'est pas expirée Réactiver le compte ExportUserData exporte toutes les données d'un utilisateur (RGPD) Récupérer le profil Récupérer les préférences Récupérer l'activité (simplifié) Récupérer le contenu (simplifié) Récupérer les interactions (simplifié) RequestDataDeletion demande la suppression définitive des données Créer une demande de suppression définitive Déterminer le statut/home/senke/git/talas/veza/veza-backend-api/internal/api/user/types.go`db:"id" json:"id"``db:"username" json:"username"``db:"email" json:"email"``db:"password_hash" json:"-"``db:"first_name" json:"first_name,omitempty"``db:"last_name" json:"last_name,omitempty"``db:"bio" json:"bio,omitempty"``db:"avatar" json:"avatar,omitempty"``db:"role" json:"role"``db:"is_active" json:"is_active"``db:"is_verified" json:"is_verified"``db:"last_login_at" json:"last_login_at,omitempty"``db:"created_at" json:"created_at"``db:"updated_at" json:"updated_at"``json:"id"``json:"username"``json:"email"``json:"first_name,omitempty"``json:"last_name,omitempty"``json:"bio,omitempty"``json:"avatar,omitempty"``json:"role"``json:"is_active"``json:"is_verified"``json:"last_login_at,omitempty"``json:"created_at"``json:"updated_at"``json:"username" binding:"required,min=3,max=50"``json:"password" binding:"required,min=8"``json:"role,omitempty"``json:"username,omitempty"``json:"email,omitempty"``json:"is_active,omitempty"``json:"is_verified,omitempty"``json:"theme,omitempty"``json:"language,omitempty"``json:"timezone,omitempty"``json:"notifications,omitempty"``json:"privacy,omitempty"``json:"audio,omitempty"``json:"user_id"``json:"theme"``json:"timezone"``json:"notifications"``json:"privacy"``json:"audio"``json:"push"``json:"desktop"``json:"new_followers"``json:"track_comments"``json:"direct_messages"``json:"mentions"``json:"likes"``json:"show_email"``json:"show_activity"``json:"allow_dm"``json:"track_visibility"``json:"profile_visibility"``json:"auto_play"``json:"volume"``json:"crossfade"``json:"status"``json:"deleted_at,omitempty"``json:"deletion_reason,omitempty"``json:"recovery_deadline,omitempty"``json:"profile"``json:"preferences"``json:"activity"``json:"content"``json:"interactions"``json:"exported_at"``json:"type"``json:"details"``json:"ip_address"``json:"user_agent"``json:"url"``json:"target_id"` User represents a user with password (for auth) Never serialize password UserResponse represents user data without sensitive information CreateUserRequest represents a request to create a new user UpdateUserRequest represents a request to update user data UserPreferencesRequest représente une requête de mise à jour des préférences UserPreferencesResponse représente les préférences utilisateur NotificationSettings paramètres de notification PrivacySettings paramètres de confidentialité public, followers, private public, registered, private AudioSettings paramètres audio low, medium, high, lossless 0-1 secondes AccountStatus statut du compte active, suspended, deleted, pending_deletion UserDataExport export des données utilisateur (RGPD) UserActivity activité utilisateur UserContent contenu utilisateur UserInteraction interaction utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/api/voting_system/home/senke/git/talas/veza/veza-backend-api/internal/api/voting_system/handler.govoting_system Package voting_system - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/api/websocket/home/senke/git/talas/veza/veza-backend-api/internal/api/websocket/handler.go Package websocket - TO BE IMPLEMENTED/home/senke/git/talas/veza/veza-backend-api/internal/common/home/senke/git/talas/veza/veza-backend-api/internal/common/context.goErrorCodeBadRequestErrorCodeConflictErrorCodeForbiddenErrorCodeInternalServerErrorErrorCodeNotFoundErrorCodeUnauthorizedMaxJSONBodySizePaginationMetaSetUserIDInContextSetUsernameInContextUserIDContextKeyUsernameContextKeyhandleBindingErrormsgForTag"username" GetUserIDFromContext retrieves user ID from gin context Return uuid.Nil for non-existent UUID SetUserIDInContext sets user ID in gin context GetUsernameFromContext retrieves username from gin context SetUsernameInContext sets username in gin contextjson:"success"PerPagejson:"per_page"/home/senke/git/talas/veza/veza-backend-api/internal/common/types.go`json:"success"``json:"data,omitempty"``json:"error,omitempty"``json:"message,omitempty"``json:"page"``json:"per_page"``json:"total"``json:"total_pages"`BAD_REQUEST"BAD_REQUEST"UNAUTHORIZED"UNAUTHORIZED"FORBIDDEN"FORBIDDEN"NOT_FOUND"NOT_FOUND"CONFLICT"CONFLICT"INTERNAL_SERVER_ERROR"INTERNAL_SERVER_ERROR" Common types and utilities used across the application Response represents a standard API response PaginationMeta contains pagination metadata ErrorCode represents application error codes/home/senke/git/talas/veza/veza-backend-api/internal/common/validation.govalidationErrorsjsonSyntaxErrorjsonUnmarshalTypeErrormaxBytesErrorio"encoding/json""errors""io""github.com/go-playground/validator/v10"1024010485760Request body too large: maximum size is %d bytes"Request body too large: maximum size is %d bytes"MaxBytesReaderValidation failed"Validation failed"MaxBytesErrorInvalid JSON syntax at offset %d: %s"Invalid JSON syntax at offset %d: %s"Invalid type for field '%s': expected %s"Invalid type for field '%s': expected %s"Request body is empty or invalid JSON"Request body is empty or invalid JSON"Incomplete or malformed JSON"Incomplete or malformed JSON"unknown field"unknown field"Unknown fields in JSON payload"Unknown fields in JSON payload"Invalid request body format"Invalid request body format""required"This field is required"This field is required""email"Invalid email format"Invalid email format""min"Must be at least %s characters long"Must be at least %s characters long""max"Must be at most %s characters long"Must be at most %s characters long""uuid"Invalid UUID format"Invalid UUID format"Failed validation on tag: %s"Failed validation on tag: %s" MaxJSONBodySize définit la taille maximale du body JSON (10MB par défaut) 10MB BindAndValidateJSON lie et valide les données JSON de la requête de manière robuste MOD-P1-002: Helper centralisé pour bind + validate + format d'erreur standard Utilisable par tous les handlers (pas seulement ceux avec CommonHandler) Comportement:   - Vérifie la taille du body (max 10MB)   - Parse le JSON avec ShouldBindJSON (Gin)   - Valide avec le validator centralisé (go-playground/validator)   - Retourne false si erreur (erreur déjà envoyée au client avec code 400) Usage:	var req MyRequest	if !common.BindAndValidateJSON(c, &req) {	    return // Erreur déjà envoyée au client	} 1. Vérifier la taille du body 2. Limiter la lecture du body pour éviter les attaques par body trop gros 3. Parser le JSON avec ShouldBindJSON 4. Valider avec le validator centralisé (go-playground/validator) Convertir en format standardisé BindAndValidate binds the request body to the given object and validates it. DEPRECATED: Utiliser BindAndValidateJSON à la place pour une validation complète If binding or validation fails, it sends a standardized error response and returns false. Returns true if successful. handleBindingError gère les erreurs de binding JSON MOD-P1-002: Gestion d'erreurs améliorée pour JSON malformé Body trop gros JSON syntaxiquement invalide Type incorrect pour un champ Body vide JSON incomplet Erreurs de validation Gin (binding tags) Erreur générique/home/senke/git/talas/veza/veza-backend-api/internal/config/home/senke/git/talas/veza/veza-backend-api/internal/config/config.goConfigDefaultsConfigValidatorDefaultSecretKeysDetectEnvironmentEnvConfigEnvProductionEnvSecretsProviderEnvStagingEnvTestEnvVarDocGetAllEnvVarDocsLoadEnvFilesMaskConfigValueMaskSecretNewConfigDefaultsNewConfigReloaderNewConfigValidatorNewConfigWatcherNewEnvSecretsProviderNewTestConfigNormalizeEnvironmentReloadableResetEnvWithMultipleEnvenvVarsDocsfilteredRedisLoggergetCORSOriginsgetEnvBoolgetEnvDurationgetEnvFloat64getEnvIntgetEnvStringSliceinitDatabaseWithRetryinitRedisisValidEnvironmentvalidEnvironmentsenvFilesappPortcorsOriginsdatabaseURLlogLevelrateLimitLimitrateLimitWindowsecretKeysendpointLimiterConfigendpointLimitsrateLimiterConfigredisURLdbConfigretryIntervalfloatValuetrimmedpartoriginserr3err2allowedLevelseventbusveza-backend-api/internal/email"veza-backend-api/internal/email"veza-backend-api/internal/eventbus"veza-backend-api/internal/eventbus"RATE_LIMIT_LIMIT"RATE_LIMIT_LIMIT"RATE_LIMIT_WINDOW"RATE_LIMIT_WINDOW"LOG_LEVEL"LOG_LEVEL"INFO"INFO"APP_PORT"APP_PORT"JWT_SECRET"JWT_SECRET"JWT_ISSUER"JWT_ISSUER"veza-api"veza-api"JWT_AUDIENCE"JWT_AUDIENCE"veza-app"veza-app"CHAT_JWT_SECRET"CHAT_JWT_SECRET"REDIS_URL"REDIS_URL"redis://localhost:6379"redis://localhost:6379"REDIS_ENABLE"REDIS_ENABLE"UPLOAD_DIR"UPLOAD_DIR""uploads"STREAM_SERVER_URL"STREAM_SERVER_URL"http://localhost:8082"http://localhost:8082"CHAT_SERVER_URL"CHAT_SERVER_URL"http://localhost:8081"http://localhost:8081"SENTRY_DSN"SENTRY_DSN"SENTRY_SAMPLE_RATE_ERRORS"SENTRY_SAMPLE_RATE_ERRORS"1.0SENTRY_SAMPLE_RATE_TRANSACTIONS"SENTRY_SAMPLE_RATE_TRANSACTIONS"0.10.100000000000000005553602879701896397/36028797018963968AUTH_RATE_LIMIT_LOGIN_ATTEMPTS"AUTH_RATE_LIMIT_LOGIN_ATTEMPTS"AUTH_RATE_LIMIT_LOGIN_WINDOW"AUTH_RATE_LIMIT_LOGIN_WINDOW"HANDLER_TIMEOUT"HANDLER_TIMEOUT"DB_MAX_RETRIES"DB_MAX_RETRIES"DB_RETRY_INTERVAL"DB_RETRY_INTERVAL"5000000000RABBITMQ_URL"RABBITMQ_URL"amqp://guest:guest@localhost:5672/"amqp://guest:guest@localhost:5672/"RABBITMQ_MAX_RETRIES"RABBITMQ_MAX_RETRIES"RABBITMQ_RETRY_INTERVAL"RABBITMQ_RETRY_INTERVAL"RABBITMQ_ENABLE"RABBITMQ_ENABLE"Configuration validation failed"Configuration validation failed""env"invalid configuration: %w"invalid configuration: %w"CORS_ALLOWED_ORIGINS is empty in production. Strict mode enabled: ALL CORS requests will be rejected."CORS_ALLOWED_ORIGINS is empty in production. Strict mode enabled: ALL CORS requests will be rejected."Failed to initialize Redis"Failed to initialize Redis"Redis désactivé par configuration (REDIS_ENABLE=false)"Redis désactivé par configuration (REDIS_ENABLE=false)"Failed to initialize database"Failed to initialize database"NewRabbitMQEventBusWithRetryEventBusUnavailableErrorRabbitMQ EventBus est indisponible mais le service démarre en mode dégradé."RabbitMQ EventBus est indisponible mais le service démarre en mode dégradé."Impossible de se connecter à RabbitMQ après plusieurs tentatives. Le service ne peut pas démarrer."Impossible de se connecter à RabbitMQ après plusieurs tentatives. Le service ne peut pas démarrer."Failed to initialize RabbitMQ EventBus"Failed to initialize RabbitMQ EventBus"Failed to initialize services"Failed to initialize services"Failed to initialize middlewares"Failed to initialize middlewares"NewErrorMetricsLoadSMTPConfigFromEnvNewSMTPEmailSenderNewJobServiceNewJobWorkerCONFIG_WATCH"CONFIG_WATCH""false""true"Failed to create config watcher"Failed to create config watcher".env".env".env.".env."Failed to start watching config files"Failed to start watching config files"Config watcher started"Config watcher started""files"NewTOTPServiceNewCacheServiceNewPlaylistServiceWithDBNewPermissionService1000veza:rate_limit"veza:rate_limit"NewRateLimiterNewSimpleRateLimiterveza:endpoint_limit"veza:endpoint_limit"DefaultEndpointLimits60000000000NewEndpointLimiterNewAuthMiddlewaremaint_notifications"maint_notifications"Redis internal"Redis internal"300000000000AppEnvDBHostDBPortDBPassword"development"failed to load environment files: %w"failed to load environment files: %w"CORS_ALLOWED_ORIGINS"CORS_ALLOWED_ORIGINS"*"*"veza_db"veza_db"required environment variable %s is not set"required environment variable %s is not set",","staginghttp://localhost:3000"http://localhost:3000"http://127.0.0.1:3000"http://127.0.0.1:3000"http://localhost:5173"http://localhost:5173"http://127.0.0.1:5173"http://127.0.0.1:5173"CORS_ALLOWED_ORIGINS is required in production environment. Empty CORS origins will reject all CORS requests, making the service inaccessible from frontend. Please set CORS_ALLOWED_ORIGINS with explicit origins (e.g., CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com)"CORS_ALLOWED_ORIGINS is required in production environment. Empty CORS origins will reject all CORS requests, making the service inaccessible from frontend. Please set CORS_ALLOWED_ORIGINS with explicit origins (e.g., CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com)"CORS wildcard '*' is not allowed in production environment. Please specify explicit origins in CORS_ALLOWED_ORIGINS"CORS wildcard '*' is not allowed in production environment. Please specify explicit origins in CORS_ALLOWED_ORIGINS"LOG_LEVEL=DEBUG is not allowed in production environment for security reasons"LOG_LEVEL=DEBUG is not allowed in production environment for security reasons"CORS wildcard '*' detected in development environment. This is acceptable for dev but should never be used in production"CORS wildcard '*' detected in development environment. This is acceptable for dev but should never be used in production"ValidatePortValidateURLValidateEnumValidateSecretLengthValidatePositiveIntAPP_PORT validation failed: %w"APP_PORT validation failed: %w"JWT_SECRET validation failed: %w"JWT_SECRET validation failed: %w"DATABASE_URL is required"DATABASE_URL is required""postgres"postgresql"postgresql""sqlite"DATABASE_URL validation failed: must start with postgres://, postgresql://, or sqlite://"DATABASE_URL validation failed: must start with postgres://, postgresql://, or sqlite://"REDIS_URL is required"REDIS_URL is required""redis"rediss"rediss"REDIS_URL validation failed: must start with redis:// or rediss://"REDIS_URL validation failed: must start with redis:// or rediss://"WARN"WARN""ERROR"LOG_LEVEL validation failed: %w"LOG_LEVEL validation failed: %w"RATE_LIMIT_LIMIT validation failed: %w"RATE_LIMIT_LIMIT validation failed: %w"RATE_LIMIT_WINDOW validation failed: %w"RATE_LIMIT_WINDOW validation failed: %w"Configuration initialized successfully"Configuration initialized successfully"app_port"app_port"jwt_secret"jwt_secret"jwt_issuer"jwt_issuer"jwt_audience"jwt_audience"chat_jwt_secret"chat_jwt_secret"database_url"database_url"redis_url"redis_url"rabbitmq_url"rabbitmq_url"cors_origins"cors_origins"rate_limit_limit"rate_limit_limit"rate_limit_window"rate_limit_window"auth_rate_limit_login_attempts"auth_rate_limit_login_attempts"auth_rate_limit_login_window"auth_rate_limit_login_window"handler_timeout"handler_timeout"log_level"log_level"sentry_dsn"sentry_dsn" Import the eventbus package Config contient toute la configuration de l'application Base de données Redis Services Middlewares Rate limiter simple (T0015) Logger Metrics (T0020) Secrets Provider (T0037) Config Watcher (T0040) Configuration Environnement: development, test, production (P0-SECURITY) Port pour le serveur HTTP (T0031) T0204: Issuer claim validation (P1-SECURITY) T0204: Audience claim validation (P1-SECURITY) Secret pour les tokens WebSocket Chat Enable/Disable Redis Répertoire d'upload URL du serveur de streaming URL du serveur de chat Liste des origines CORS autorisées Sentry configuration DSN Sentry pour error tracking Environnement Sentry (dev, staging, prod) Sample rate pour les erreurs (0.0-1.0) Sample rate pour les transactions (0.0-1.0) Limite de requêtes pour le rate limiter simple Fenêtre de temps en secondes pour le rate limiter simple Max login attempts (PR-3) Login rate limit window in minutes (PR-3) Global handler timeout (PR-6) Niveau de log (T0027) RabbitMQ Ajout de l'instance de l'EventBus Email & Jobs NewConfig crée une nouvelle configuration Déterminer l'environnement avec détection automatique améliorée (T0032, T0039) Charger les fichiers .env selon l'environnement (T0032) Charge dans l'ordre: .env.{env}, .env Les variables d'environnement système ont priorité En cas d'erreur, continuer quand même (peut-être que les fichiers .env n'existent pas) Les variables d'environnement système seront utilisées Initialiser le logger SECURITY: Charger les origines CORS avec defaults sécurisés selon l'environnement (P0-SECURITY) Charger la configuration du rate limiter simple 100 requêtes par défaut 60 secondes (1 minute) par défaut Charger le niveau de log depuis les variables d'environnement (T0027) Valeurs possibles: DEBUG, INFO, WARN, ERROR Par défaut: INFO Charger le port depuis les variables d'environnement (T0031) Configuration depuis les variables d'environnement SECURITY: JWT_SECRET est REQUIS - pas de valeur par défaut pour éviter les failles de sécurité Store environment for validation (P0-SECURITY) Fallback to main JWT secret if not set SECURITY: DATABASE_URL est REQUIS - contient des credentials sensibles Utiliser l'environnement détecté Default: 5 attempts Default: 1 minute Default: 30 seconds 5 tentatives par défaut 5 secondes par défaut Configuration RabbitMQ 3 tentatives par défaut 2 secondes par défaut Activé par défaut Initialiser le SecretsProvider (T0037) SECURITY: Valider la configuration selon l'environnement (P0-SECURITY) Warn if CORS is strict/empty in production (MOD-P0-002) Initialiser Redis Initialiser la base de données avec retry Initialiser RabbitMQ avec retry En mode dégradé, l'erreur n'est pas fatale au démarrage du service Si le service est censé être enabled et qu'il est injoignable après retries Retourner l'erreur fatale Initialiser les middlewares Initialiser les métriques d'erreurs (T0020) Initialiser la configuration SMTP Initialiser le JobService Initialiser le JobWorker queueSize workers maxRetries emailSender Logger la configuration avec masquage des secrets (T0037) Initialiser le ConfigWatcher si activé (T0040) Le watcher peut être activé via une variable d'environnement CONFIG_WATCH=true Surveiller les fichiers .env GetConfigReloader retourne le ConfigReloader pour cette configuration (T0034) initServices initialise tous les services Service de session Service d'audit Service TOTP Validateur d'upload Service de cache Service de playlist Service de permissions JWT Service User Service initMiddlewares initialise tous les middlewares Rate limiter global (avec Redis) Simple rate limiter (T0015) - sans dépendance Redis Rate limiter par endpoint Override defaults with config (PR-3) Middleware d'authentification NOTE: Les handlers ne sont plus initialisés dans Config pour éviter les imports cycliques. Les handlers doivent être créés dans main.go ou dans les routes selon les besoins. SetupRoutes a été supprimé pour casser le cycle d'import config <-> api. Utiliser directement api.SetupRoutes() dans cmd/modern-server/main.go SetupMiddleware configure les middlewares globaux DÉPRÉCIÉ : Cette méthode est conservée pour compatibilité mais ne fait plus rien Les middlewares globaux sont maintenant configurés dans internal/api/router.go via APIRouter.Setup() TODO: Améliorer la configuration CORS dans api/router.go pour utiliser c.CORSOrigins depuis la config No-op : Les middlewares sont configurés dans api/router.go Cette méthode existe uniquement pour compatibilité avec cmd/main.go (legacy) qui sera désactivé dans le Chantier 1 - Étape 2 initRedis initialise la connexion Redis Configurer un logger filtré pour Redis pour éviter les warnings "maint_notifications" Test de connexion filteredRedisLogger est un wrapper pour filtrer les logs de Redis Ignorer ce warning spécifique en mode auto-discovery initDatabaseWithRetry initialise la connexion à la base de données avec des tentatives de retry Utiliser la fonction de connexion avec retry du package database EnvConfig représente la configuration de base chargée depuis les variables d'environnement Cette struct est utilisée par la fonction Load() pour charger la configuration de base Load charge et valide les variables d'environnement avec valeurs par défaut Déterminer l'environnement (T0032) Charger les origines CORS depuis les variables d'environnement Database, JWTSecret are required getEnv récupère une variable d'environnement avec une valeur par défaut SECURITY: Removed debug fmt.Printf to avoid leaking config info in production (P0-SECURITY) getEnvRequired récupère une variable d'environnement requise (retourne erreur si absente) getEnvInt récupère une variable d'environnement entière avec une valeur par défaut getEnvBool récupère une variable d'environnement booléenne avec une valeur par défaut getEnvDuration récupère une variable d'environnement durée avec une valeur par défaut getEnvFloat64 récupère une variable d'environnement float64 avec une valeur par défaut getEnvStringSlice récupère une variable d'environnement comme une slice de strings Format attendu: "value1,value2,value3" (séparées par des virgules) Séparer par virgule et nettoyer les espaces getCORSOrigins charge les origines CORS avec defaults sécurisés selon l'environnement (P0-SECURITY) - development: defaults permissifs (localhost uniquement) si CORS_ALLOWED_ORIGINS non défini - test: liste vide ou configurée explicitement - production: CORS_ALLOWED_ORIGINS comportement:   - si défini: utiliser   - si absent/vide: liste vide (STRICT, reject all) Si CORS_ALLOWED_ORIGINS est défini, l'utiliser Defaults selon l'environnement Production: defaults to empty (Strict Mode) MOD-P0-002: "si CORS_ALLOWED_ORIGINS vide, appliquer un comportement strict par défaut (reject toutes origines)" Test: liste vide par défaut (peut être configurée explicitement) Development/Staging: defaults permissifs pour localhost Fallback: development-like ValidateForEnvironment valide la configuration selon l'environnement (P0-SECURITY) En production: validation stricte (CORS requis, pas de wildcard, etc.) En development: validation permissive avec warnings D'abord, validation de base (port, secrets, URLs, etc.) Validations spécifiques selon l'environnement PRODUCTION: Validation stricte 1. MOD-P0-001: CORS_ALLOWED_ORIGINS MUST be configured in production (fail-fast) Empty CORS origins means strict mode (reject all), which makes the service inaccessible from frontend 2. CORS_ALLOWED_ORIGINS ne doit PAS contenir "*" (wildcard interdit en prod) 3. LogLevel ne doit pas être DEBUG en production TEST: Validation adaptée aux tests CORS peut être vide ou configuré explicitement Pas de validation stricte sur les secrets (peuvent être des valeurs de test) DEVELOPMENT/STAGING: Validation permissive avec warnings Si CORS contient "*", logger un warning mais ne pas bloquer Validate valide la configuration (T0031, T0036) Vérifie que toutes les valeurs de configuration sont valides avant le démarrage de l'application Utilise ConfigValidator pour une validation stricte selon les règles de schéma (T0036) Valider le port (1-65535) avec ConfigValidator (T0036) Valider JWT secret (minimum 32 caractères pour sécurité) avec ConfigValidator (T0036) Valider DatabaseURL (requis) avec ConfigValidator (T0036) Valider le format de DatabaseURL avec ConfigValidator (T0036) Support postgres, postgresql, et sqlite Valider RedisURL (requis) avec ConfigValidator (T0036) Valider le format de RedisURL avec ConfigValidator (T0036) Support redis et rediss (Redis avec SSL) Valider LogLevel avec ValidateEnum (T0036) Valider RateLimitLimit et RateLimitWindow avec ValidatePositiveInt (T0036) logConfigInitialized log la configuration initialisée avec masquage des secrets (T0037) MOD-P0-002: Always mask secrets in logs, even in DEBUG mode Close ferme toutes les connexions (T0040) Arrêter le ConfigWatcher si actif (T0040)WithJWTSecretWithDatabaseURLWithRedisURLWithCORSOriginsWithRateLimitWithLogLevel/home/senke/git/talas/veza/veza-backend-api/internal/config/defaults.gowindowSeconds ConfigDefaults permet de construire une config avec des valeurs par défaut (T0038) NewConfigDefaults crée un nouveau builder de defaults (T0038) WithPort définit le port par défaut (T0038) WithEnv définit l'environnement par défaut (T0038) WithJWTSecret définit le secret JWT par défaut (T0038) WithDatabaseURL définit l'URL de la base de données par défaut (T0038) WithRedisURL définit l'URL Redis par défaut (T0038) WithCORSOrigins définit les origines CORS par défaut (T0038) WithRateLimit définit les limites de rate limiting par défaut (T0038) WithLogLevel définit le niveau de log par défaut (T0038) WithLogger définit le logger par défaut (T0038) Build construit une Config avec les valeurs par défaut (T0038) Note: appEnv n'est pas dans Config, mais peut être utilisé ailleurs Merge fusionne les valeurs par défaut avec une config existante (override) (T0038)/home/senke/git/talas/veza/veza-backend-api/internal/config/docs.go"sort""string"Environment mode (development, production, test)"Environment mode (development, production, test)""int"Port for HTTP server (1-65535)"Port for HTTP server (1-65535)"Secret key for JWT token signing and validation (minimum 32 characters)"Secret key for JWT token signing and validation (minimum 32 characters)"your-super-secret-jwt-key-minimum-32-characters-long"your-super-secret-jwt-key-minimum-32-characters-long"postgresql://veza:password@localhost:5432/veza_db"postgresql://veza:password@localhost:5432/veza_db"PostgreSQL database connection URL (must start with postgres://, postgresql://, or sqlite://)"PostgreSQL database connection URL (must start with postgres://, postgresql://, or sqlite://)"postgresql://user:password@localhost:5432/veza_db"postgresql://user:password@localhost:5432/veza_db"Database host address"Database host address"Database port number"Database port number"Database username"Database username"Database password (required)"Database password (required)"your-secure-database-password"your-secure-database-password"Database name"Database name"Redis connection URL (must start with redis:// or rediss://)"Redis connection URL (must start with redis:// or rediss://)"Comma-separated list of allowed CORS origins (use * for all origins)"Comma-separated list of allowed CORS origins (use * for all origins)"http://localhost:3000,https://app.veza.com"http://localhost:3000,https://app.veza.com""100"Maximum number of requests allowed per time window for rate limiting"Maximum number of requests allowed per time window for rate limiting""60"Time window in seconds for rate limiting"Time window in seconds for rate limiting"Logging level (DEBUG, INFO, WARN, ERROR)"Logging level (DEBUG, INFO, WARN, ERROR)"# Configuration Variables

"# Configuration Variables\n\n"This document lists all environment variables used by the Veza backend API.

"This document lists all environment variables used by the Veza backend API.\n\n"## Overview

"## Overview\n\n"Variables can be set in:
"Variables can be set in:\n"- System environment variables (highest priority)
"- System environment variables (highest priority)\n"- `.env.{APP_ENV}` file (e.g., `.env.development`, `.env.production`)
"- `.env.{APP_ENV}` file (e.g., `.env.development`, `.env.production`)\n"- `.env` file (fallback)

"- `.env` file (fallback)\n\n"---

"---\n\n"## %s

"## %s\n\n"**Type**: `%s`

"**Type**: `%s`\n\n"**Required**: ✅ Yes

"**Required**: ✅ Yes\n\n"**Required**: ❌ No

"**Required**: ❌ No\n\n"**Default**: `%s`

"**Default**: `%s`\n\n"**Description**: %s

"**Description**: %s\n\n"**Example**:
```bash
export %s=%s
```

"**Example**:\n```bash\nexport %s=%s\n```\n\n" EnvVarDoc représente la documentation d'une variable d'environnement (T0033) envVarsDocs contient la documentation de toutes les variables d'environnement (T0033) GenerateConfigDocs génère la documentation markdown pour toutes les variables d'environnement (T0033) GetAllEnvVarDocs retourne la map complète de documentation (utile pour les tests et l'introspection) Retourner une copie pour éviter les modifications externes/home/senke/git/talas/veza/veza-backend-api/internal/config/env_detection.gohostnameLowervalidEnvenvLowernormalized"staging""test"NODE_ENV"NODE_ENV"GO_ENV"GO_ENV"prod"prod"stage"stage"dev"dev"stg"stg""local" EnvDevelopment représente l'environnement de développement (T0039) EnvStaging représente l'environnement de staging (T0039) EnvProduction représente l'environnement de production (T0039) EnvTest représente l'environnement de test (T0039) DetectEnvironment détecte l'environnement actuel avec fallback intelligent (T0039) Priorité: APP_ENV > NODE_ENV > GO_ENV > hostname > development 1. APP_ENV (priorité) 2. NODE_ENV (compatibilité) 3. GO_ENV (compatibilité Go) 4. Fallback: détection par hostname (production si contient "prod") 5. Fallback par défaut: development isValidEnvironment vérifie qu'un environnement est valide (T0039) NormalizeEnvironment normalise le nom d'environnement (T0039) Convertit les alias courants (dev, prod, stage, etc.) en noms canoniques Mappings courants Si déjà valide, retourner tel quel Fallback/home/senke/git/talas/veza/veza-backend-api/internal/config/env_loader.goenvFilefailed to load %s: %w"failed to load %s: %w" LoadEnvFiles charge les fichiers .env selon l'environnement (T0032) Les variables d'environnement système ont toujours priorité (godotenv ne surcharge pas les variables existantes) Charger .env.{env} si existe (ex: .env.development, .env.production, .env.test) Charger .env en fallback (ignore si n'existe pas) Note: godotenv.Load() ne retourne pas d'erreur si le fichier n'existe pas/home/senke/git/talas/veza/veza-backend-api/internal/config/reloader.gonewLevelStrnewLimitnewWindownewWindowSecondslogging"sync"veza-backend-api/internal/logging"veza-backend-api/internal/logging""go.uber.org/zap/zapcore"Log level reloaded from environment"Log level reloaded from environment"old_level"old_level"new_level"new_level"parsed_level"parsed_level"Rate limits reloaded from environment"Rate limits reloaded from environment"new_limit"new_limit"new_window_seconds"new_window_seconds"Some configurations failed to reload"Some configurations failed to reload"error_count"error_count"All configurations reloaded successfully"All configurations reloaded successfully"`json:"log_level"``json:"rate_limit_limit"``json:"rate_limit_window"` Reloadable représente une configuration qui peut être rechargée (T0034) ConfigReloader gère le rechargement de configurations à chaud (T0034) Service de logging pour changement de niveau dynamique NewConfigReloader crée un nouveau ConfigReloader (T0034) Sera initialisé lors du premier reload si nécessaire SetLoggingService définit le service de logging pour permettre le changement dynamique de niveau ReloadLogLevel recharge le niveau de log depuis les variables d'environnement (T0034) Récupérer le nouveau niveau depuis les variables d'environnement Parser le niveau Si le logger zap est accessible directement et utilise AtomicLevel On peut changer le niveau dynamiquement Essayer de changer le niveau via l'AtomicLevel si disponible Note: Le logger zap doit être créé avec AtomicLevel pour permettre le changement dynamique Pour l'instant, on log juste le changement et on met à jour la config ReloadRateLimits recharge les limites de rate limiting depuis les variables d'environnement (T0034) Récupérer les nouvelles limites depuis les variables d'environnement Si le simple rate limiter existe, mettre à jour ses limites Mettre à jour les limites directement dans le rate limiter Mettre à jour la config ReloadAll recharge toutes les configurations reloadable (T0034) Recharger le niveau de log Recharger les limites de rate limiting Retourner la première erreur GetCurrentConfig retourne la configuration actuelle (en lecture seule) ReloadableConfig représente la partie de la configuration qui peut être rechargée Note: getEnv et getEnvInt sont définis dans config.go/home/senke/git/talas/veza/veza-backend-api/internal/config/secrets.gokeysMapsecret %s not found"secret %s not found"****"****"DATABASE_PASSWORD"DATABASE_PASSWORD"REDIS_PASSWORD"REDIS_PASSWORD"AWS_SECRET_ACCESS_KEY"AWS_SECRET_ACCESS_KEY"AWS_ACCESS_KEY_ID"AWS_ACCESS_KEY_ID"STRIPE_SECRET_KEY"STRIPE_SECRET_KEY"STRIPE_WEBHOOK_SECRET"STRIPE_WEBHOOK_SECRET"SMTP_PASSWORD"SMTP_PASSWORD"OAUTH_CLIENT_SECRET"OAUTH_CLIENT_SECRET" SecretsProvider définit l'interface pour les fournisseurs de secrets (T0037) EnvSecretsProvider récupère les secrets depuis les variables d'environnement (T0037) NewEnvSecretsProvider crée un nouveau fournisseur de secrets depuis l'environnement GetSecret récupère un secret depuis les variables d'environnement (T0037) IsSecret vérifie si une clé est un secret (T0037) MaskSecret masque un secret pour l'affichage dans les logs (T0037) Masque les 4 premiers et 4 derniers caractères, remplace le reste par "****" MaskConfigValue masque une valeur si c'est un secret (T0037) DefaultSecretKeys retourne la liste des clés considérées comme secrets (T0037) Contains password in connection string May contain password in connection string May contain sensitive information/home/senke/git/talas/veza/veza-backend-api/internal/config/testutils.gooldValuetestVarsenvVarsoldValuestesting"testing""go.uber.org/zap/zaptest"test-jwt-secret-key-minimum-32-characters-long"test-jwt-secret-key-minimum-32-characters-long"postgres://test:test@localhost:5432/test_db"postgres://test:test@localhost:5432/test_db"redis://localhost:6379/0"redis://localhost:6379/0" NewTestConfig crée une configuration de test avec valeurs par défaut (T0035) Cette fonction facilite la création de configurations de test sans nécessiter une base de données ou Redis réels, parfait pour les tests unitaires Créer un logger de test WithEnv définit temporairement une variable d'environnement pour les tests (T0035) Retourne une fonction de cleanup qui restaure la valeur originale (ou unset si elle n'existait pas)	reset := WithEnv("TEST_VAR", "test_value")	defer reset()	// ... test code ... ResetEnv réinitialise toutes les variables d'environnement de test couramment utilisées (T0035) Cette fonction nettoie les variables d'environnement après les tests pour éviter les interférences entre tests WithMultipleEnv définit temporairement plusieurs variables d'environnement pour les tests (T0035) Retourne une fonction de cleanup qui restaure toutes les valeurs originales	reset := WithMultipleEnv(map[string]string{	  "APP_ENV": "test",	  "LOG_LEVEL": "DEBUG",	}) Sauvegarder les valeurs actuelles Définir les nouvelles valeurs Retourner la fonction de cleanup/home/senke/git/talas/veza/veza-backend-api/internal/config/validator.goexpectedSchemeparsedURLurlStrallowedValuenet/url"net/url"65535port must be between 1 and 65535, got %d"port must be between 1 and 65535, got %d"URL cannot be empty"URL cannot be empty"invalid URL format: %w"invalid URL format: %w"URL must have scheme %s, got %s"URL must have scheme %s, got %s"value '%s' is not allowed. Allowed values: %s"value '%s' is not allowed. Allowed values: %s"secret must be at least %d characters, got %d"secret must be at least %d characters, got %d"%s must be positive, got %d"%s must be positive, got %d" ConfigValidator valide la configuration selon des règles strictes (T0036) NewConfigValidator crée un nouveau validateur ValidatePort valide qu'un port est dans la plage valide (1-65535) ValidateURL valide qu'une URL a le schéma attendu ValidateEnum valide qu'une valeur fait partie des valeurs autorisées ValidateSecretLength valide qu'un secret a une longueur minimale ValidatePositiveInt valide qu'un entier est positif/home/senke/git/talas/veza/veza-backend-api/internal/config/watcher.gofileNamedebounceTimer"github.com/fsnotify/fsnotify"failed to create watcher: %w"failed to create watcher: %w"Millisecond1000000500000000Failed to resolve absolute path"Failed to resolve absolute path""file"Failed to watch file"Failed to watch file"Watching config file"Watching config file"Config file changed"Config file changed""op"Config file changed, reloading"Config file changed, reloading"Failed to reload config"Failed to reload config"Config reloaded successfully"Config reloaded successfully"Watcher error"Watcher error" ConfigWatcher surveille les fichiers de configuration pour changements (T0040) Ensures stopChan is closed only once NewConfigWatcher crée un nouveau watcher de configuration (T0040) Initialize sync.Once Watch surveille les fichiers .env pour changements (T0040) Ajouter les fichiers à surveiller Résoudre le chemin absolu pour éviter les problèmes de chemins relatifs watchLoop boucle principale de surveillance avec debouncing (T0040) Ignorer les opérations autres que Write et Create Arrêter le timer précédent si existant Démarrer un nouveau timer de debounce Goroutine pour attendre le debounce et relancer Arrêter le timer si actif Stop arrête la surveillance proprement (T0040) GetWatchedFiles retourne la liste des fichiers surveillés (T0040)/home/senke/git/talas/veza/veza-backend-api/internal/core/home/senke/git/talas/veza/veza-backend-api/internal/core/auth/home/senke/git/talas/veza/veza-backend-api/internal/core/auth/handler.goNewAuthHandlererrorMsgexpiresInipAddresssessionReqauthHeaderuserIDInterfacedtoveza-backend-api/internal/dto"veza-backend-api/internal/dto"RegisterRequestjson:"username" binding:"omitempty,min=3,max=50" validate:"omitempty,min=3,max=50,username"json:"email" binding:"required,email" validate:"required,email"json:"password" binding:"required,min=12" validate:"required,min=12"PasswordConfirmjson:"password_confirm" binding:"required,eqfield=Password" validate:"required,eqfield=Password""Password"Le mot de passe doit contenir au moins 12 caractères"Le mot de passe doit contenir au moins 12 caractères""PasswordConfirm"eqfield"eqfield"Les mots de passe ne correspondent pas"Les mots de passe ne correspondent pas""Email"Format d'email invalide"Format d'email invalide"Le mot de passe est requis"Le mot de passe est requis"L'email est requis"L'email est requis"La confirmation du mot de passe est requise"La confirmation du mot de passe est requise"Invalid registration request"Invalid registration request"error_message"error_message"Received registration request"Received registration request""req"already exists"already exists"StatusConflict409"validation""invalid"Failed to create user"Failed to create user"RegisterResponseTokenResponseLoginRequestjson:"password" binding:"required" validate:"required"RememberMejson:"remember_me"email not verified"email not verified"StatusForbidden403invalid credentials"invalid credentials"Invalid credentials"Invalid credentials"Failed to authenticate"Failed to authenticate"User-Agent"User-Agent""Unknown"9021607776000000000000Failed to create session after login"Failed to create session after login"ip_address"ip_address"LoginResponseRefreshRequestjson:"refresh_token" binding:"required" validate:"required"invalid refresh token"invalid refresh token"not found"not found""expired"token version mismatch"token version mismatch"Invalid refresh token"Invalid refresh token"Failed to refresh token"Failed to refresh token"900Username is required"Username is required""available""Unauthorized"Invalid user ID type in context"Invalid user ID type in context"json:"refresh_token" binding:"required"`json:"refresh_token" binding:"required"`Refresh token is required"Refresh token is required"Failed to logout (revoke token)"Failed to logout (revoke token)""Authorization"Bearer "Bearer "Failed to revoke session on logout"Failed to revoke session on logout"Logged out successfully"Logged out successfully""token"Token required"Token required"Email verified successfully"Email verified successfully"email already verified"email already verified"Verification email sent if account exists"Verification email sent if account exists" AuthHandler gère les requêtes d'authentification pour T0151 Changed to *AuthService (from the current package) NewAuthHandler crée une nouvelle instance d'AuthHandler Changed to *AuthService Register gère l'inscription d'un nouvel utilisateur MOD-P2-003: Utiliser AppError au lieu de gin.H Login gère la connexion d'un utilisateur MOD-P2-003: Utiliser AppError au lieu de gin.H (403 -> ErrCodeForbidden) Refresh gère le rafraîchissement d'un access token CheckUsername vérifie la disponibilité d'un nom d'utilisateur GetMe retourne les informations de l'utilisateur connecté Logout déconnecte l'utilisateur VerifyEmail gère la vérification de l'email ResendVerification gère la demande de renvoi d'email de vérification GetUserByUsername gets a user by username/home/senke/git/talas/veza/veza-backend-api/internal/core/auth/service.goerrMsghashedPasswordpasswordStrengthaccessTokenrefreshTokenTTLrememberMeclaimsnewAccessTokennewRefreshTokenresetURLtemplateData"gorm.io/gorm"username = ?"username = ?"Attempting to register new user"Attempting to register new user"Registration failed: invalid email"Registration failed: invalid email"invalid email: "invalid email: "Registration failed: weak password"Registration failed: weak password"weak password: "weak password: "Failed to hash password"Failed to hash password"users_email_key"users_email_key"idx_users_email"idx_users_email"Registration failed: email already exists"Registration failed: email already exists"ErrUserAlreadyExistsusers_username_key"users_username_key"idx_users_username"idx_users_username"Registration failed: username already exists"Registration failed: username already exists"username already exists"username already exists"users_slug_key"users_slug_key"idx_users_slug"idx_users_slug"Registration failed: slug collision"Registration failed: slug collision"slug"slug"username unavailable (slug collision)"username unavailable (slug collision)"unique constraint"unique constraint"duplicate key"duplicate key"Registration failed: unique constraint violation"Registration failed: unique constraint violation"Failed to create user in database"Failed to create user in database"Failed to generate email verification token"Failed to generate email verification token"failed to generate verification token: %w"failed to generate verification token: %w"Failed to store email verification token"Failed to store email verification token"failed to store verification token: %w"failed to store verification token: %w"Sending verification email"Sending verification email"User registered successfully"User registered successfully"Attempting login"Attempting login"email = ?"email = ?"Login failed: user not found"Login failed: user not found"Database error during login"Database error during login"Login failed: invalid password"Login failed: invalid password"Login failed: email not verified"Login failed: email not verified"Failed to generate access token"Failed to generate access token"failed to generate access token: %w"failed to generate access token: %w"Failed to generate refresh token"Failed to generate refresh token"failed to generate refresh token: %w"failed to generate refresh token: %w"Failed to store refresh token"Failed to store refresh token"failed to store refresh token: %w"failed to store refresh token: %w"User logged in successfully"User logged in successfully"Invalid refresh token format"Invalid refresh token format"Token is not a refresh token"Token is not a refresh token"invalid token type"invalid token type"Refresh token invalid or revoked"Refresh token invalid or revoked"invalid or revoked refresh token"invalid or revoked refresh token"User not found for refresh token"User not found for refresh token"Failed to generate new access token"Failed to generate new access token"Failed to generate new refresh token"Failed to generate new refresh token"Failed to rotate refresh token"Failed to rotate refresh token"Email verification failed"Email verification failed"id = ?"id = ?"is_verified"is_verified"Failed to update user verification status"Failed to update user verification status"Failed to invalidate old verification tokens"Failed to invalidate old verification tokens"Failed to invalidate old tokens"Failed to invalidate old tokens"Resending verification email"Resending verification email"Invalid refresh token during logout"Invalid refresh token during logout"User ID mismatch for logout request"User ID mismatch for logout request"requested_user_id"requested_user_id"token_user_id"token_user_id"user ID mismatch"user ID mismatch"Failed to revoke refresh token during logout"Failed to revoke refresh token during logout"User logged out successfully"User logged out successfully"Failed to revoke all refresh tokens"Failed to revoke all refresh tokens"Failed to revoke user sessions"Failed to revoke user sessions"Revoked user sessions"Revoked user sessions""count"All user sessions invalidated"All user sessions invalidated"User verified by admin"User verified by admin"User blocked by admin"User blocked by admin"Failed to invalidate old password reset tokens"Failed to invalidate old password reset tokens"Failed to generate password reset token"Failed to generate password reset token"failed to generate reset token: %w"failed to generate reset token: %w"Failed to store password reset token"Failed to store password reset token"failed to store reset token: %w"failed to store reset token: %w"FRONTEND_URL"FRONTEND_URL"%s/reset-password?token=%s"%s/reset-password?token=%s""Username"ResetURL"ResetURL"Reset your Veza password"Reset your Veza password"password_reset"password_reset"Password reset email job enqueued"Password reset email job enqueued"Job worker not available, using direct email service"Job worker not available, using direct email service"Failed to send password reset email"Failed to send password reset email"Password reset requested successfully"Password reset requested successfully"token_preview"token_preview"..."..."Password reset token verification failed"Password reset token verification failed"invalid or expired token: %w"invalid or expired token: %w"Password validation failed during reset"Password validation failed during reset"invalid password: %w"invalid password: %w"Failed to update password during reset"Failed to update password during reset"Failed to mark password reset token as used"Failed to mark password reset token as used"Failed to revoke refresh tokens after password reset"Failed to revoke refresh tokens after password reset"Password reset completed successfully"Password reset completed successfully"invalid current password"invalid current password"password_hash"password_hash"Failed to revoke refresh tokens after password change"Failed to revoke refresh tokens after password change"Password changed successfully"Password changed successfully"last_login_at"last_login_at" Added import for services Import the validators package Changed to pointer Added for password reset Job worker pour envoi d'emails asynchrones Job worker pour emails asynchrones GetUserByUsername récupère un utilisateur par son nom d'utilisateur Refresh est un alias pour RefreshToken Valider l'email Valider le mot de passe Vérifiez également si la force n'est pas suffisante Si l'erreur est nil mais pas valide, utilisez les détails de la force Hacher le mot de passe Créer l'utilisateur dans la base de données Générer un nouvel UUID IsVerified: false par défaut PostgreSQL error code 23505 is unique_violation We check for specific constraint names if possible, or fallback to generic "duplicate" We can return the same error or a more specific one if needed In a real robust system, we would retry with a suffix here For now, fail explicitly so the user knows Fallback for generic unique constraint Générer le token de vérification d'email Stocker le token Envoyer l'email de vérification (simulation pour l'instant) Générer les tokens JWT Assurez-vous que ce champ existe dans models.JWTConfig Stocker le refresh token en base Valider le refresh token Ne pas retourner d'erreur pour ne pas bloquer le logout côté UI MIGRATION UUID: userID migré vers uuid.UUID Return nil to prevent email enumeration - always return success Invalidate old tokens for this user Continue anyway, not critical Generate new reset token Store token in database Send password reset email via job worker (asynchrone) Construire l'URL de reset Préparer les données du template Enqueue le job d'email avec template Fallback sur l'ancien système si job worker non disponible Verify the reset token Validate password strength Update password using PasswordService Mark token as used Log but don't fail - password is already updated Invalidate all user sessions (revoke refresh tokens) Don't fail - password is already updated min returns the minimum of two integers (helper function)/home/senke/git/talas/veza/veza-backend-api/internal/core/collaboration/home/senke/git/talas/veza/veza-backend-api/internal/core/collaboration/collaboration.go Core collaboration functionality for the application/home/senke/git/talas/veza/veza-backend-api/internal/core/education/home/senke/git/talas/veza/veza-backend-api/internal/core/education/course.goCourseLevelAdvancedCourseLevelBeginnerCourseLevelExpertCourseLevelIntermediateExerciseTypeAudioExerciseTypeCodeExerciseTypeEssayExerciseTypeProjectExerciseTypeQuizNewCourseManagerNewTutorialManagerVideoQuality4KVideoQuality8KVideoQualityHDcontainsSubstringvideoURLexerciseIDexerciseTypesolutiontimeLimitprogressKeycompletedLessonscurrentLessontimeSpentuserProgresscertificateIDisPassed`json:"currency"``json:"lessons"``json:"exercises"``json:"certificates"`beginner"beginner"intermediate"intermediate"advanced"advanced"expert"expert"`json:"course_id"``json:"order"``json:"lesson_id"``json:"solution"``json:"points"`quiz"quiz"project"project"audio"audio""code"essay"essay"`json:"max_score"``json:"is_passed"``json:"issued_at"``json:"expires_at"``json:"progress"``json:"last_accessed"``json:"is_completed"``json:"completed_at"`"EUR"Cours créé"Cours créé"cours non trouvé: %s"cours non trouvé: %s"Cours mis à jour"Cours mis à jour"Cours supprimé"Cours supprimé"Leçon ajoutée"Leçon ajoutée"Exercice ajouté"Exercice ajouté"exercise_id"exercise_id"%s_%s"%s_%s"progression non trouvée pour l'utilisateur %s dans le cours %s"progression non trouvée pour l'utilisateur %s dans le cours %s"Progression utilisateur mise à jour"Progression utilisateur mise à jour""progress"0.70.699999999999999955593152519739159347/4503599627370496Certificat émis"Certificat émis"certificate_id"certificate_id"is_passed"is_passed" Course représente un cours de formation CourseLevel définit le niveau de difficulté d'un cours Lesson représente une leçon dans un cours Exercise représente un exercice pratique ExerciseType définit le type d'exercice Certificate représente un certificat de formation CourseProgress représente la progression d'un utilisateur dans un cours 0.0 à 1.0 CourseManager gère les cours et formations NewCourseManager crée un nouveau gestionnaire de cours Appliquer les filtres si fournis GetUserProgress récupère la progression d'un utilisateur dans un cours IssueCertificate émet un certificat pour un utilisateur 70% pour réussir Valide 2 ans Ajouter le certificat au cours/home/senke/git/talas/veza/veza-backend-api/internal/core/education/tutorial.gostepIDcommentIDratingratedCommentstotalRatingsubstr`json:"views"``json:"dislikes"``json:"rating"`"hd"4k"4k"8k"8k"`json:"tutorial_id"``json:"is_helpful"`0.0Tutoriel créé"Tutoriel créé"tutoriel non trouvé: %s"tutoriel non trouvé: %s"Tutoriel mis à jour"Tutoriel mis à jour"Tutoriel supprimé"Tutoriel supprimé"Étape de tutoriel ajoutée"Étape de tutoriel ajoutée"step_id"step_id"Commentaire ajouté"Commentaire ajouté"comment_id"comment_id"Vues incrémentées"Vues incrémentées"views"views"Like ajouté"Like ajouté"likes"likes"Dislike ajouté"Dislike ajouté"dislikes"dislikes"%%%s%%"%%%s%%" Tutorial représente un tutoriel vidéo VideoQuality définit la qualité de la vidéo TutorialStep représente une étape dans un tutoriel TutorialComment représente un commentaire sur un tutoriel 1-5 étoiles TutorialManager gère les tutoriels vidéo NewTutorialManager crée un nouveau gestionnaire de tutoriels GetTutorialSteps récupère toutes les étapes d'un tutoriel Mettre à jour la note moyenne du tutoriel GetTutorialComments récupère tous les commentaires d'un tutoriel IncrementViews incrémente le nombre de vues d'un tutoriel updateTutorialRating met à jour la note moyenne d'un tutoriel SearchTutorials recherche des tutoriels par mots-clés Recherche LIKE Vérifier si le tutoriel correspond à la recherche Vérifier les tags contains vérifie si une chaîne contient une sous-chaîne (insensible à la casse) containsSubstring vérifie si une chaîne contient une sous-chaîne/home/senke/git/talas/veza/veza-backend-api/internal/core/marketplace/home/senke/git/talas/veza/veza-backend-api/internal/core/marketplace/models.goErrInsufficientFundsErrInvalidSellerErrNoLicenseErrOrderFailedErrProductNotFoundErrTrackNotFoundLicenseBasicLicenseExclusiveLicensePremiumProductStatusActiveProductStatusArchivedProductStatusDraft"basic"premium"premium"exclusive"exclusive"draft"draft"archived"archived"`gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"``gorm:"type:uuid;not null" json:"seller_id"``gorm:"not null;size:255" json:"title"``gorm:"type:text" json:"description"``gorm:"not null;type:decimal(10,2)" json:"price"``gorm:"default:'EUR';size:3" json:"currency"``gorm:"default:'draft'" json:"status"``gorm:"not null" json:"product_type"``gorm:"type:uuid" json:"track_id,omitempty"``gorm:"size:50" json:"license_type,omitempty"``gorm:"autoCreateTime" json:"created_at"``gorm:"autoUpdateTime" json:"updated_at"``gorm:"index" json:"-"``gorm:"type:uuid;not null" json:"buyer_id"``gorm:"type:uuid;not null" json:"track_id"``gorm:"type:uuid;not null" json:"product_id"``gorm:"type:uuid;not null" json:"order_id"``gorm:"not null" json:"type"``gorm:"type:jsonb" json:"rights"``gorm:"default:3" json:"downloads_left"``json:"expires_at,omitempty"``gorm:"not null;type:decimal(10,2)" json:"total_amount"``gorm:"default:'EUR'" json:"currency"``gorm:"default:'pending'" json:"status"``json:"payment_intent,omitempty"``gorm:"foreignKey:OrderID" json:"items"` LicenseType définit le type de licence (Basic, Premium, Exclusive) ProductStatus définit le statut d'un produit (Draft, Active, Archived) Product représente un produit vendable sur la marketplace (Track, Sample Pack, Service) "track", "pack", "service" Liaison optionnelle avec un Track (si ProductType == "track") License représente une licence achetée par un utilisateur pour un Track Détails des droits (JSON) Order représente une commande/transaction pending, paid, failed, refunded Stripe PaymentIntent ID OrderItem représente une ligne dans une commande/home/senke/git/talas/veza/veza-backend-api/internal/core/marketplace/service.goproductbuyerIDpayloadproductIDsellerIDproductslicenseorderItemsproductsToLicensetotalAmountlicensesproduct not found"product not found"insufficient funds"insufficient funds"order failed processing"order failed processing"seller does not own the track"seller does not own the track"track not found"track not found"no valid license found"no valid license found"Failed to create product"Failed to create product"Product created successfully"Product created successfully"product_id"product_id"seller_id"seller_id""status"status = ?"status = ?"seller_id = ?"seller_id = ?"product %s not found"product %s not found"product %s is not active"product %s is not active""pending"completed"completed"simulated_payment_"simulated_payment_"{"streaming": true, "download": true}`{"streaming": true, "download": true}`Failed to create order"Failed to create order"buyer_id"buyer_id"Order created and processed successfully"Order created and processed successfully"order_id"order_id"buyer_id = ? AND product_id = ? AND downloads_left > 0"buyer_id = ? AND product_id = ? AND downloads_left > 0"buyer_id = ?"buyer_id = ?" NewOrderItem represents an item to be ordered StorageService defines the interface for file retrieval GetDownloadURL returns a signed URL or relative path for the file MarketplaceService définit l'interface pour les opérations de la marketplace Product Management Purchasing Fulfillment Service implémente MarketplaceService NewService creates a new Marketplace service instance CreateProduct creates a new product listing Validates that the seller owns the track 1. Validate Track existence and ownership if linked Verify ownership 2. Create Product GetProduct retrieves a product by ID ListProducts retrieves products based on filters CreateOrder initiates a purchase transaction Transactional: Order -> Items -> Payment(Simulated) -> Licenses 1. Validate products and calculate total 2. Create Order (PENDING) Default for MVP 3. Simulate Payment (Immediate Success for MVP) In real scenario, we would pause here or interact with Stripe 4. Generate Licenses Default rights Default limit ProcessPaymentWebhook handles payment confirmation MVP: Not implemented yet GetDownloadURL checks license and returns signed URL for the asset 1. Check for valid license 2. Get Track info 3. Generate URL 4. Decrement downloads left (Optional based on business rules) In strict mode we might want to decrement here s.db.Model(&license).Update("downloads_left", gorm.Expr("downloads_left - 1")) GetUserLicenses returns all licenses owned by a user/home/senke/git/talas/veza/veza-backend-api/internal/core/social/home/senke/git/talas/veza/veza-backend-api/internal/core/social/models.goActivityCommentActivityFollowActivityLikeActivityPostActivityPurchaseActivityTypeFeedItemPostTypePostTypeActivityPostTypeReleasePostTypeSharePostTypeStatusSocialServicesocialshare"share""release""activity"gorm:"type:text" json:"content"gorm:"default:'status'" json:"type"gorm:"type:uuid" json:"playlist_id,omitempty"gorm:"default:0" json:"like_count"CommentCountgorm:"default:0" json:"comment_count"gorm:"autoCreateTime;index" json:"created_at"`gorm:"type:uuid;not null;index" json:"user_id"``gorm:"type:text" json:"content"``gorm:"default:'status'" json:"type"``gorm:"type:uuid" json:"playlist_id,omitempty"``gorm:"default:0" json:"like_count"``gorm:"default:0" json:"comment_count"``gorm:"autoCreateTime;index" json:"created_at"`gorm:"type:uuid;not null;index" json:"target_id"TargetTypegorm:"not null" json:"target_type"`gorm:"type:uuid;not null;index" json:"target_id"``gorm:"not null" json:"target_type"``gorm:"type:text;not null" json:"content"`"post""comment""follow"purchase"purchase"ActorIDjson:"actor_id"json:"target_type"ActorNamejson:"actor_name,omitempty"ActorAvatarjson:"actor_avatar,omitempty"`json:"actor_id"``json:"target_type"``json:"content,omitempty"``json:"actor_name,omitempty"``json:"actor_avatar,omitempty"` PostType définit le type de post Pour les activités automatiques (ex: achat) Post représente une publication sociale d'un utilisateur Attachments (Optionnel) Metrics (Cached) Like représente une interaction "J'aime" Polymorphisme via TargetType + TargetID "post", "track", "playlist" Comment représente un commentaire ActivityType définit le type d'activité Nouveau FeedItem représente un élément agrégé pour le flux d'actualité Embedded objectsCreatePostGetGlobalFeedGetUserFeedToggleLikeAddCommentCreateActivityPost/home/senke/git/talas/veza/veza-backend-api/internal/core/social/service.gotargetIDtargetTypemetatrackIDplaylistIDfeedpostslikedtrackIDStrtrack_id"track_id"playlist_id"playlist_id"Failed to create post"Failed to create post"created_at desc"created_at desc"none"none"playlist"playlist"post:%s"post:%s"user_id = ?"user_id = ?"user_wall"user_wall"user_id = ? AND target_id = ? AND target_type = ?"user_id = ? AND target_id = ? AND target_type = ?"ToggleLike: failed to delete like: %w"ToggleLike: failed to delete like: %w"like_count"like_count"like_count - 1"like_count - 1"ToggleLike: failed to decrement like_count: %w"ToggleLike: failed to decrement like_count: %w"ToggleLike: post not found: %w"ToggleLike: post not found: %w"ToggleLike: failed to check post existence: %w"ToggleLike: failed to check post existence: %w"ToggleLike: failed to create like: %w"ToggleLike: failed to create like: %w"like_count + 1"like_count + 1"ToggleLike: failed to increment like_count: %w"ToggleLike: failed to increment like_count: %w"ToggleLike: failed to check like existence: %w"ToggleLike: failed to check like existence: %w"post not found"post not found"AddComment: failed to validate post: %w"AddComment: failed to validate post: %w"AddComment: failed to create comment: %w"AddComment: failed to create comment: %w"comment_count"comment_count"comment_count + 1"comment_count + 1"AddComment: failed to increment comment_count: %w"AddComment: failed to increment comment_count: %w" SocialService gère les interactions sociales Interactions Internal Service implémente SocialService NewService crée une nouvelle instance du service social CreatePost crée une nouvelle publication Handle attachments GetGlobalFeed récupère un flux d'activité global Spécial pour les activités automatiques Ou autre logique plus fine GetUserFeed récupère le flux d'un utilisateur ToggleLike ajoute ou supprime un like Transactionnelle : SELECT like + DELETE/CREATE + UPDATE compteur dans une seule transaction 1. VÉRIFICATION : Like existe déjà ? (SELECT dans la transaction) 2a. Mode UNLIKE : Like existe, on le supprime 3a. Décrémenter le compteur si c'est un post (dans la transaction) 2b. Mode LIKE : Like n'existe pas, on le crée Vérifier d'abord que la ressource existe (pour les posts) 3b. Incrémenter le compteur si c'est un post (dans la transaction) Rollback automatique si erreur AddComment ajoute un commentaire Transactionnelle : CREATE comment + UPDATE compteur dans une seule transaction 1. VALIDATION : Post existe ? (SELECT dans la transaction si targetType == "post") 2. CRÉATION : Commentaire (INSERT dans la transaction) 3. MISE À JOUR : Compteur (UPDATE dans la transaction) 4. RETOUR nil = commit automatique CreateActivityPost crée un post automatique pour une activité (ex: Achat)/home/senke/git/talas/veza/veza-backend-api/internal/core/track/home/senke/git/talas/veza/veza-backend-api/internal/core/track/handler.goBatchDeleteRequestBatchUpdateRequestCompleteChunkedUploadRequestCreateShareRequestErrInvalidTrackFormatErrNetworkErrorErrStorageErrorErrStorageQuotaExceededErrTrackQuotaExceededErrTrackTooLargeInitiateChunkedUploadRequestMaxStoragePerUserMaxTracksPerUserStreamCallbackRequestUpdateTrackRequestUploadChunkRequestgetContentTypeerrCodehttpStatusvalidationResulterrorMessagefileHeaderuploadIDreceivedChunkscreateCancelcreateCtxfinalFilenamefinalPathquotaCancelquotaCtxtotalSizeuploadInfoauthenticatedUserIDquotauserIDParamgenrelimitIntpageIntsortBysortOrdertotalPagesuserIDStrhasRoleisAdmintrackUUIDsisLikedparsedLimitlimitStrparsedOffsetoffsetStrpageStrtagsStrminDurationminDurationStrmaxDurationmaxDurationStrminBPMminBPMStrmaxBPMmaxBPMStrminDatemaxDateshareTokenshareIDshareIDStrapperrorsveza-backend-api/internal/errors"veza-backend-api/internal/errors"RespondWithAppErrorNewUnauthorizedErrorunauthorized"unauthorized"ErrCodeValidation2000ErrCodeUnauthorized1004ErrCodeForbidden1003ErrCodeNotFound30009000no file provided"no file provided"clamav_unavailable"clamav_unavailable"StatusServiceUnavailable503Virus scanning service is temporarily unavailable"Virus scanning service is temporarily unavailable"Uploads are disabled for security reasons until the scanning service is restored"Uploads are disabled for security reasons until the scanning service is restored"SERVICE_UNAVAILABLE"SERVICE_UNAVAILABLE"clamav_infected"clamav_infected"422File rejected: virus detected"File rejected: virus detected""details"VIRUS_DETECTED"VIRUS_DETECTED"clamav_scan_error"clamav_scan_error"Virus scan failed"Virus scan failed"Unable to complete virus scan. Upload rejected for security."Unable to complete virus scan. Upload rejected for security."SCAN_ERROR"SCAN_ERROR""Location"/api/v1/tracks/%s/status"/api/v1/tracks/%s/status"RespondSuccessStatusAccepted202status_url"status_url"Upload initiated, file is being saved in background"Upload initiated, file is being saved in background"track id is required"track id is required"invalid track id"invalid track id"failed to get upload progress"failed to get upload progress"json:"total_chunks" binding:"required,min=1" validate:"required,min=1"json:"total_size" binding:"required,min=1" validate:"required,min=1"json:"filename" binding:"required" validate:"required"`json:"total_chunks" binding:"required,min=1" validate:"required,min=1"``json:"total_size" binding:"required,min=1" validate:"required,min=1"``json:"filename" binding:"required" validate:"required"`upload_id"upload_id"upload initiated successfully"upload initiated successfully"form:"upload_id" binding:"required"form:"chunk_number" binding:"required,min=1"form:"total_chunks" binding:"required,min=1"form:"total_size" binding:"required,min=1"form:"filename" binding:"required"`form:"upload_id" binding:"required"``form:"chunk_number" binding:"required,min=1"``form:"total_chunks" binding:"required,min=1"``form:"total_size" binding:"required,min=1"``form:"filename" binding:"required"`"chunk"no chunk file provided"no chunk file provided"chunk uploaded successfully"chunk uploaded successfully"received_chunks"received_chunks"total_chunks"total_chunks"json:"upload_id" binding:"required" validate:"required,uuid"`json:"upload_id" binding:"required" validate:"required,uuid"`.mp3".mp3"%s_%s%s"%s_%s%s"failed to create directory"failed to create directory".".""M4A""AAC"TrackStatusUploadinguploadingUpload completed, MD5: %s"Upload completed, MD5: %s"Failed to update track upload status after completion"Failed to update track upload status after completion"upload completed successfully"upload completed successfully""md5"unknown error"unknown error"invalid track format"invalid track format"invalid file format"invalid file format"Invalid file format. Allowed formats: MP3, FLAC, WAV, OGG"Invalid file format. Allowed formats: MP3, FLAC, WAV, OGG"file size exceeds"file size exceeds"too large"too large"File size exceeds maximum allowed size of 100MB"File size exceeds maximum allowed size of 100MB"file is empty"file is empty"The uploaded file is empty"The uploaded file is empty"track quota exceeded"track quota exceeded"You have reached the maximum number of tracks allowed"You have reached the maximum number of tracks allowed"storage quota exceeded"storage quota exceeded"You have reached your storage quota. Please delete some tracks to free up space"You have reached your storage quota. Please delete some tracks to free up space"network error"network error""timeout""connection"Network error occurred. Please try again"Network error occurred. Please try again"storage error"storage error"failed to save file"failed to save file"Failed to save file. Please try again"Failed to save file. Please try again"failed to create upload directory"failed to create upload directory"Failed to prepare storage. Please try again later"Failed to prepare storage. Please try again later"An error occurred during upload. Please try again"An error occurred during upload. Please try again""empty"quota exceeded"quota exceeded"failed to save"failed to save""me"invalid user id"invalid user id"forbidden: you can only view your own quota"forbidden: you can only view your own quota"failed to get quota"failed to get quota""quota"uploadId"uploadId"upload_id is required"upload_id is required"upload not found"upload not found"forbidden: you can only resume your own uploads"forbidden: you can only resume your own uploads"total_size"total_size""filename"chunks_received"chunks_received"received_count"received_count"last_chunk"last_chunk"created_at"created_at"updated_at"updated_at""genre""format"sort_by"sort_by"sort_order"sort_order""desc"failed to list tracks"failed to list tracks""tracks"failed to get track"failed to get track"json:"title" binding:"omitempty,min=1,max=255" validate:"omitempty,min=1,max=255"json:"artist" binding:"omitempty,max=255" validate:"omitempty,max=255"json:"album" binding:"omitempty,max=255" validate:"omitempty,max=255"json:"genre" binding:"omitempty,max=100" validate:"omitempty,max=100"json:"year" binding:"omitempty,min=1900,max=2100" validate:"omitempty,min=1900,max=2100"`json:"title" binding:"omitempty,min=1,max=255" validate:"omitempty,min=1,max=255"``json:"artist" binding:"omitempty,max=255" validate:"omitempty,max=255"``json:"album" binding:"omitempty,max=255" validate:"omitempty,max=255"``json:"genre" binding:"omitempty,max=100" validate:"omitempty,max=100"``json:"year" binding:"omitempty,min=1900,max=2100" validate:"omitempty,min=1900,max=2100"``json:"is_public"`is_admin"is_admin"forbidden"forbidden"cannot be"cannot be"failed to update track"failed to update track"failed to delete track"failed to delete track"track deleted successfully"track deleted successfully"TrackIDsjson:"track_ids" binding:"required" validate:"required,min=1,dive,uuid"`json:"track_ids" binding:"required" validate:"required,min=1,dive,uuid"`batch size exceeds maximum"batch size exceeds maximum"failed to delete tracks"failed to delete tracks""failed"json:"updates" binding:"required" validate:"required,min=1"`json:"updates" binding:"required" validate:"required,min=1"`cannot be empty"cannot be empty"invalid value"invalid value"exceeds maximum length"exceeds maximum length"must be between"must be between"failed to update tracks"failed to update tracks"updated"updated"track liked"track liked"track unliked"track unliked"is_liked"is_liked"user id is required"user id is required""offset"search service not available"search service not available"tag_mode"tag_mode""OR"min_duration"min_duration"max_duration"max_duration"min_bpm"min_bpm"max_bpm"max_bpm"min_date"min_date"max_date"max_date"failed to search tracks"failed to search tracks"share_token"share_token"share service not available"share service not available"ErrShareNotFoundinvalid share token"invalid share token"ErrShareExpiredshare link expired"share link expired"failed to validate share token"failed to validate share token"download"download"download not allowed"download not allowed"IsNotExisttrack file not found"track file not found"Content-Type"Content-Type"Content-Disposition"Content-Disposition"attachment; filename="%s""attachment; filename=\"%s\""json:"permissions" binding:"required" validate:"required,oneof=read write admin"`json:"permissions" binding:"required" validate:"required,oneof=read write admin"`failed to create share"failed to create share"share token is required"share token is required"share id is required"share id is required"invalid share id"invalid share id"share not found"share not found"failed to revoke share"failed to revoke share"share revoked"share revoked"json:"status" binding:"required" validate:"required,oneof=completed failed processing"ManifestURLjson:"manifest_url" validate:"omitempty,url"`json:"status" binding:"required" validate:"required,oneof=completed failed processing"``json:"manifest_url" validate:"omitempty,url"``json:"error"`failed to update stream status"failed to update stream status"status updated"status updated"StatusNotImplemented501Not implemented"Not implemented""MP3"audio/mpeg"audio/mpeg""FLAC"audio/flac"audio/flac"WAV"WAV"audio/wav"audio/wav""OGG"audio/ogg"audio/ogg"audio/aac"audio/aac"application/octet-stream"application/octet-stream" Added zap TrackHandler gère les opérations sur les tracks MOD-P1-003: Added for admin check MOD-P1-001: Added for ClamAV scan before persistence NewTrackHandler crée un nouveau handler de tracks SetUploadValidator définit le validateur d'upload (pour injection de dépendance) SetPermissionService définit le service de permissions (pour injection de dépendance) MOD-P1-003: Added for admin check in ownership verification SetSearchService définit le service de recherche (pour injection de dépendance) SetShareService définit le service de partage (pour injection de dépendance) SetVersionService définit le service de versioning (pour injection de dépendance) SetHistoryService définit le service d'historique (pour injection de dépendance) getUserID récupère l'ID utilisateur du contexte de manière sécurisée (fail-secure) MOD-P1-RES-003: Remplace c.MustGet() pour éviter les panics Retourne false si user_id est absent ou invalide (répond déjà avec 401) MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Unauthorized respondWithError est un helper pour migrer vers RespondWithAppError MOD-P1-RES-001: Helper pour standardiser les réponses d'erreur UploadTrack gère l'upload d'un fichier audio @Summary      Upload Track @Description  Upload a new track (audio file) @Tags         Track @Accept       multipart/form-data @Produce      json @Security     BearerAuth @Param        file formData file true "Audio File (MP3, WAV, FLAC, OGG)" @Success      201  {object}  response.APIResponse{data=object{track=models.Track}} @Failure      400  {object}  response.APIResponse "No file or validation error" @Failure      401  {object}  response.APIResponse "Unauthorized" @Failure      403  {object}  response.APIResponse "Quota exceeded" @Failure      500  {object}  response.APIResponse "Internal Error" @Router       /tracks [post] MOD-P1-RES-003: Utiliser helper fail-secure au lieu de c.MustGet() Erreur déjà envoyée par getUserID MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.BadRequest MOD-P1-001: Scanner le fichier avec ClamAV AVANT toute persistance MOD-P1-004: Ajouter timeout context pour opération I/O (ClamAV scan) MOD-P1-001: Détecter le type d'erreur ClamAV et retourner code HTTP approprié Autre erreur de validation MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Error Upload track (validation et quota sont vérifiés dans le service) MOD-P1-001: Le scan ClamAV a été fait ci-dessus, maintenant on peut persister MOD-P2-008: UploadTrack crée le Track immédiatement et lance la copie en goroutine MOD-P1-004: Ajouter timeout context pour opération DB critique (upload track) Upload peut prendre du temps Mapper les erreurs vers des messages utilisateur spécifiques MOD-P2-008: Sémantique asynchrone - retourner 202 Accepted avec track_id La copie fichier se fait en arrière-plan, le client peut poller GetUploadStatus MOD-P2-008: Déclencher le traitement du streaming après la copie (sera fait quand Status=Processing) On ne peut pas le faire ici car le fichier n'existe pas encore Ce sera fait dans un job séparé ou via un hook quand Status passe à Processing GetUploadStatus récupère le statut d'upload d'un track @Summary      Get Upload Status @Description  Get the processing status of an uploaded track @Accept       json @Param        id   path      string  true  "Track ID" @Success      200  {object}  response.APIResponse{data=object{progress=int}} @Failure      400  {object}  response.APIResponse "Invalid ID" @Failure      404  {object}  response.APIResponse "Track not found" @Router       /tracks/{id}/status [get] MIGRATION UUID: ID est maintenant un UUID Le trackID doit être un int64 pour le moment car models.Track n'a pas encore migré l'ID? Attends, j'ai migré models.Track ID vers UUID dans l'étape 1. Donc trackID est UUID. Vérifier que l'utilisateur est authentifié (userID non utilisé dans cette fonction) Récupérer la progression TODO(P2-GO-004): trackUploadService attend int64 - Migration UUID partielle à compléter Je dois mettre à jour trackUploadService. Pour l'instant, je ne peux pas compiler si je passe UUID. Je vais supposer que trackUploadService a été migré ou que je dois le faire. Mais la tâche ne mentionnait pas de migrer trackUploadService. C'est le problème de dépendance en cascade. Je vais convertir en int64 si possible pour que ça compile, ou migrer le service. Mais Track.ID est UUID... OK, la migration UUID était "complète" pour les modèles principaux. Mais les services satellites comme TrackUploadService n'ont pas été migrés. C'est la dette technique identifiée dans le rapport. Pour que ça compile maintenant, je dois adapter TrackUploadService. TODO(P2-GO-004): Migration UUID partielle - trackUploadService nécessite migration vers UUID Ou mieux, je vais mettre à jour TrackUploadService après ce fichier. MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.InternalServerError MOD-P1-RES-001: Utiliser RespondSuccess au lieu de response.Success InitiateChunkedUploadRequest représente la requête pour initialiser un upload par chunks InitiateChunkedUpload initialise un nouvel upload par chunks @Summary      Initiate Chunked Upload @Description  Start a new chunked upload session @Param        request body InitiateChunkedUploadRequest true "Upload Metadata" @Success      200  {object}  response.APIResponse{data=object{upload_id=string,message=string}} @Failure      400  {object}  response.APIResponse "Validation Error" @Router       /tracks/initiate [post] MOD-P1-002: Utiliser helper centralisé pour bind + validate Erreur déjà envoyée au client Initialiser l'upload InitiateChunkedUpload retourne un string (uploadID) donc pas de souci d'int64 Note: InitiateChunkedUpload n'accepte pas de context (à migrer si nécessaire) UploadChunkRequest représente la requête pour uploader un chunk UploadChunk gère l'upload d'un chunk @Summary      Upload Chunk @Description  Upload a single chunk of a file @Param        chunk formData file true "Chunk Data" @Param        upload_id formData string true "Upload ID" @Param        chunk_number formData int true "Chunk Number" @Param        total_chunks formData int true "Total Chunks" @Param        total_size formData int64 true "Total Size" @Param        filename formData string true "Filename" @Success      200  {object}  response.APIResponse{data=object{message=string,upload_id=string,received_chunks=int,progress=float64}} @Router       /tracks/chunk [post] Sauvegarder le chunk CompleteChunkedUploadRequest représente la requête pour compléter un upload par chunks CompleteChunkedUpload assemble tous les chunks et crée le track final @Summary      Complete Chunked Upload @Description  Finish upload session and assemble file @Param        request body CompleteChunkedUploadRequest true "Upload ID" @Success      201  {object}  response.APIResponse{data=object{message=string,track=models.Track,md5=string}} @Failure      400  {object}  response.APIResponse "Validation or Assemblage Error" @Router       /tracks/complete [post] Récupérer les informations de l'upload pour obtenir le filename Générer un nom de fichier unique pour le fichier final Par défaut Assurer que le répertoire existe Assembler les chunks MOD-P1-004: Ajouter timeout context pour opération I/O (assemblage chunks) Assemblage peut prendre du temps Vérifier le quota avant de créer le track final MOD-P1-004: Ajouter timeout context pour opération DB (quota check) Nettoyer le fichier assemblé Déterminer le format Créer le track en base en utilisant CreateTrackFromPath MOD-P1-004: Ajouter timeout context pour opération DB critique (create track) Nettoyer le fichier en cas d'erreur Mettre à jour le message de statut avec le MD5 Log l'erreur mais ne pas faire échouer la requête Déclencher le traitement du streaming Log error h.trackUploadService.UpdateUploadStatus(c.Request.Context(), track.ID, models.TrackStatusProcessing, "Processing audio...") mapTrackError mappe les erreurs techniques vers des messages utilisateur Erreurs de validation Erreurs de quota Erreurs réseau Erreurs de stockage Erreur par défaut getErrorStatusCode retourne le code de statut HTTP approprié pour une erreur Erreurs de validation -> 400 Erreurs de quota -> 403 Erreurs réseau -> 503 (Service Unavailable) Erreurs de stockage -> 500 GetUploadQuota récupère les informations de quota d'upload pour un utilisateur @Summary      Get Upload Quota @Description  Get remaining upload quota for the user @Param        id   path      string  false "User ID (optional, defaults to current user)" @Success      200  {object}  response.APIResponse{data=object{quota=object}} @Failure      403  {object}  response.APIResponse "Forbidden" @Router       /tracks/quota/{id} [get] Récupérer l'ID utilisateur depuis l'URL ou depuis le contexte d'authentification Si "me" ou vide, utiliser l'utilisateur authentifié Parse UUID Vérifier que l'utilisateur peut accéder à ces informations (soit lui-même, soit admin) Un utilisateur ne peut voir que son propre quota (sauf admin, mais on simplifie pour l'instant) Récupérer le quota ResumeUpload récupère l'état d'un upload pour permettre la reprise @Summary      Resume Upload @Description  Get state of an interrupted upload @Param        uploadId path string true "Upload ID" @Success      200  {object}  response.APIResponse{data=object{upload_id=string,chunks_received=int}} @Failure      404  {object}  response.APIResponse "Upload session not found" @Router       /tracks/resume/{uploadId} [get] Récupérer l'état de l'upload Vérifier que l'upload appartient à l'utilisateur authentifié ListTracks gère la liste des tracks avec pagination, filtres et tri @Summary      List Tracks @Description  Get a paginated list of tracks with filters @Param        page       query     int     false  "Page number" default(1) @Param        limit      query     int     false  "Items per page" default(20) @Param        user_id    query     string  false  "Filter by User ID" @Param        genre      query     string  false  "Filter by Genre" @Param        format     query     string  false  "Filter by Format" @Param        sort_by    query     string  false  "Sort field" default(created_at) @Param        sort_order query     string  false  "Sort order (asc/desc)" default(desc) @Success      200  {object}  response.APIResponse{data=object{tracks=[]models.Track,pagination=object}} @Router       /tracks [get] Récupérer les paramètres de query Parser les paramètres Construire les paramètres Parser user_id si fourni Parser genre si fourni Parser format si fourni Appeler le service Calculer les métadonnées de pagination Masquer l'URL de stream pour les utilisateurs non authentifiés GetTrack gère la récupération d'un track par son ID @Summary      Get Track by ID @Description  Get detailed information about a track @Success      200  {object}  response.APIResponse{data=object{track=models.Track}} @Router       /tracks/{id} [get] MIGRATION UUID: TrackID is UUID UpdateTrackRequest représente la requête de mise à jour d'un track MOD-P1-002: Added validation tags for systematic input validation UpdateTrack gère la mise à jour d'un track @Summary      Update Track @Description  Update track metadata @Param        id      path      string              true  "Track ID" @Param        track   body      UpdateTrackRequest  true  "Track Metadata" @Success      200     {object}  response.APIResponse{data=object{track=models.Track}} @Failure      400     {object}  response.APIResponse "Validation Error" @Failure      401     {object}  response.APIResponse "Unauthorized" @Failure      403     {object}  response.APIResponse "Forbidden" @Failure      404     {object}  response.APIResponse "Track not found" @Router       /tracks/{id} [put] Convertir la requête en paramètres de service MOD-P1-003: Check if user is admin for ownership bypass Pass isAdmin via context Erreur de validation (title empty, year negative, etc.) DeleteTrack gère la suppression d'un track @Summary      Delete Track @Description  Permanently delete a track @Success      200  {object}  response.APIResponse{data=object{message=string}} @Router       /tracks/{id} [delete] MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de c.JSON MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.NotFound MOD-P1-RES-001: Utiliser RespondWithAppError au lieu de response.Forbidden BatchDeleteRequest représente la requête pour supprimer plusieurs tracks BatchDeleteTracks gère la suppression en lot de plusieurs tracks @Summary      Batch Delete Tracks @Description  Delete multiple tracks at once @Param        request body BatchDeleteRequest true "List of Track IDs" @Success      200  {object}  response.APIResponse{data=object{deleted=[]string,failed=object}} @Router       /tracks/batch/delete [post] Convertir les IDs en UUIDs Vérifier si c'est une erreur de taille de batch BatchUpdateRequest représente la requête pour mettre à jour plusieurs tracks BatchUpdateTracks gère la mise à jour en lot de plusieurs tracks Vérifier si c'est une erreur de validation LikeTrack gère l'ajout d'un like sur un track UnlikeTrack gère la suppression d'un like sur un track GetTrackLikes gère la récupération du nombre de likes d'un track Vérifier si l'utilisateur a liké ce track (optionnel) GetUserLikedTracks gère la récupération des tracks likés par un utilisateur Parse pagination parameters default SearchTracks gère la recherche avancée de tracks Parser page Parser limit Parser tags Parser min_duration Parser max_duration Parser min_bpm Parser max_bpm Parser genre Parser format Parser min_date Parser max_date Effectuer la recherche avec filtres combinés DownloadTrack gère le téléchargement d'un track Récupérer l'utilisateur s'il est authentifié Récupérer le track Vérifier les permissions via share token si présent Vérifier que le share correspond au track Vérifier la permission download Vérifier les permissions normales (public ou owner) Vérifier que le fichier existe Servir le fichier avec les headers appropriés CreateShareRequest représente la requête pour créer un lien de partage CreateShare crée un nouveau lien de partage pour un track GetSharedTrack récupère un track via son token de partage RevokeShare révoque un lien de partage MIGRATION UUID: ShareID is UUID StreamCallbackRequest represents the request for stream status callback HandleStreamCallback handles the callback from stream server GetTrackStats stub GetTrackHistory stub getContentType retourne le Content-Type approprié pour un format audiojson:"total_play_time"json:"downloads"/home/senke/git/talas/veza/veza-backend-api/internal/core/track/service.goallowedExtallowedExtensionsheaderStrisValidExtisValidFormatbytesWrittencopyCtxtrackCountvalidSortFieldsadminValupdatedTrackmanifestURLPlayStatsplayStatsmaxBatchSizetrackIDstrackMapallowedFieldsfilteredUpdatesmultipartmime/multipart"mime/multipart"veza-backend-api/internal/types"veza-backend-api/internal/types"102400104857600107374182400track file too large"track file too large"%w: file size exceeds maximum allowed size of 100MB"%w: file size exceeds maximum allowed size of 100MB"%w: file is empty"%w: file is empty".flac".flac".wav".wav".ogg".ogg".m4a".m4a".aac".aac"%w: invalid file format. Allowed formats: MP3, FLAC, WAV, OGG"%w: invalid file format. Allowed formats: MP3, FLAC, WAV, OGG"failed to open file: %w"failed to open file: %w"failed to read file header: %w"failed to read file header: %w"file too small to validate"file too small to validate"ID3"ID3"0xFF2240xE0fLaC"fLaC"RIFF"RIFF"WAVE"WAVE"OggS"OggS""ftyp""mp4"%w: invalid audio file format"%w: invalid audio file format"%w: failed to create upload directory: %w"%w: failed to create upload directory: %w"%d_%d%s"%d_%d%s"Upload started"Upload started"failed to create track record: %w"failed to create track record: %w"Track upload initiated (async)"Track upload initiated (async)"file_size"file_size"TrackStatusFailedFailed to open uploaded file: %v"Failed to open uploaded file: %v"failed to open source file"failed to open source file"Failed to create destination file: %v"Failed to create destination file: %v"failed to create destination file"failed to create destination file"Failed to save file: %v"Failed to save file: %v"copy failed: %v"copy failed: %v"Upload cancelled: %v"Upload cancelled: %v"upload cancelled"upload cancelled"Incomplete copy: %d/%d bytes"Incomplete copy: %d/%d bytes"incomplete copy: %d/%d bytes"incomplete copy: %d/%d bytes"TrackStatusProcessingprocessingFile uploaded, processing..."File uploaded, processing..."Track file copied successfully (async)"Track file copied successfully (async)"bytes_written"bytes_written"file_path"file_path"status_message"status_message"Failed to update track status"Failed to update track status"Track status updated"Track status updated"Failed to cleanup file after upload failure"Failed to cleanup file after upload failure""reason"Cleaned up failed upload"Cleaned up failed upload"Upload completed"Upload completed"Track created from path"Track created from path"`json:"tracks_count"``json:"tracks_limit"``json:"storage_used"``json:"storage_limit"`creator_id = ?"creator_id = ?"failed to check track count: %w"failed to check track count: %w"COALESCE(SUM(file_size), 0)"COALESCE(SUM(file_size), 0)"failed to check storage usage: %w"failed to check storage usage: %w"failed to get track count: %w"failed to get track count: %w"failed to get storage usage: %w"failed to get storage usage: %w"TrackStatusCompletedgenre = ?"genre = ?"format = ?"format = ?"failed to count tracks: %w"failed to count tracks: %w"DESC"DESC"asc"asc"ASC"ASC"popularity"popularity"(play_count + like_count) %s"(play_count + like_count) %s"%s %s"%s %s""User"failed to list tracks: %w"failed to list tracks: %w"failed to get track: %w"failed to get track: %w"`json:"artist"``json:"album"``json:"genre"``json:"year"`title cannot be empty"title cannot be empty"artist"artist"album"album"year cannot be negative"year cannot be negative""year"is_public"is_public"failed to update track: %w"failed to update track: %w"Track updated"Track updated""updates"Failed to delete track file"Failed to delete track file"Failed to delete waveform file"Failed to delete waveform file"waveform_path"waveform_path"Failed to delete cover art file"Failed to delete cover art file"cover_art_path"cover_art_path"failed to delete track: %w"failed to delete track: %w"Track deleted"Track deleted"stream_status"stream_status"stream_manifest_url"stream_manifest_url""ready"Ready for streaming"Ready for streaming"Transcoding failed"Transcoding failed"failed to update stream status: %w"failed to update stream status: %w"Track stream status updated"Track stream status updated"manifest_url"manifest_url"`json:"comments"``json:"total_play_time"``json:"downloads"`track_id = ?"track_id = ?"failed to count likes: %w"failed to count likes: %w"TrackCommentgorm:"type:uuid;not null;index:idx_track_comments_track_id" json:"track_id" db:"track_id"gorm:"not null;type:uuid;index:idx_track_comments_user_id" json:"user_id" db:"user_id"gorm:"type:uuid;index:idx_track_comments_parent_id" json:"parent_id,omitempty" db:"parent_id"gorm:"type:text;not null" json:"content" db:"content"gorm:"default:0" json:"timestamp,omitempty" db:"timestamp"gorm:"default:false" json:"is_edited" db:"is_edited"gorm:"autoCreateTime;index:idx_track_comments_created_at" json:"created_at" db:"created_at"gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"user"gorm:"foreignKey:ParentID;constraint:OnDelete:CASCADE" json:"-"Repliesgorm:"foreignKey:ParentID;constraint:OnDelete:CASCADE" json:"replies,omitempty"failed to count comments: %w"failed to count comments: %w"TrackPlaygorm:"type:uuid;not null;index:idx_track_plays_track_id" json:"track_id" db:"track_id"gorm:"type:uuid;index:idx_track_plays_user_id" json:"user_id,omitempty" db:"user_id"PlayedAtgorm:"not null;index:idx_track_plays_played_at" json:"played_at" db:"played_at"gorm:"size:100" json:"device,omitempty" db:"device"gorm:"size:45" json:"ip_address,omitempty" db:"ip_address"gorm:"foreignKey:UserID;constraint:OnDelete:SET NULL" json:"-"COUNT(*) as views, COALESCE(SUM(duration), 0) as total_play_time"COUNT(*) as views, COALESCE(SUM(duration), 0) as total_play_time"failed to get play statistics: %w"failed to get play statistics: %w"track_id = ? AND permissions LIKE ?"track_id = ? AND permissions LIKE ?"%download%"%download%"COALESCE(SUM(access_count), 0)"COALESCE(SUM(access_count), 0)"failed to count downloads: %w"failed to count downloads: %w"Track stats retrieved"Track stats retrieved""comments"total_play_time"total_play_time"downloads"downloads"`json:"deleted"``json:"failed"``json:"track_id"`batch size exceeds maximum of %d tracks"batch size exceeds maximum of %d tracks"id IN ?"id IN ?"failed to fetch tracks: %w"failed to fetch tracks: %w"forbidden: track does not belong to user"forbidden: track does not belong to user"Failed to delete track files"Failed to delete track files"failed to delete from database: %v"failed to delete from database: %v"Track deleted in batch"Track deleted in batch"failed to delete track file %s: %w"failed to delete track file %s: %w"failed to delete waveform file %s: %w"failed to delete waveform file %s: %w"failed to delete cover art file %s: %w"failed to delete cover art file %s: %w"`json:"updated"`no valid fields to update"no valid fields to update"invalid value for is_public: must be boolean"invalid value for is_public: must be boolean"title exceeds maximum length of 255 characters"title exceeds maximum length of 255 characters"invalid value for title: must be string"invalid value for title: must be string"genre exceeds maximum length of 100 characters"genre exceeds maximum length of 100 characters"invalid value for %s: must be string"invalid value for %s: must be string"19002100year must be between 1900 and 2100"year must be between 1900 and 2100"invalid value for year: must be integer"invalid value for year: must be integer"failed to update: %v"failed to update: %v"Track updated in batch"Track updated in batch" Removed strconv MOD-P2-008: Ajouté pour timeout asynchrone Constantes pour les quotas utilisateur Nombre maximum de tracks par utilisateur 100GB par utilisateur Types d'erreurs spécifiques pour les tracks ErrInvalidTrackFormat est retourné quand le format du fichier est invalide ErrTrackTooLarge est retourné quand le fichier dépasse la taille maximale ErrTrackQuotaExceeded est retourné quand l'utilisateur a atteint son quota de tracks ErrStorageQuotaExceeded est retourné quand l'utilisateur a atteint son quota de stockage ErrTrackNotFound est retourné quand un track n'est pas trouvé ErrNetworkError est retourné en cas d'erreur réseau (timeout, connexion) ErrStorageError est retourné en cas d'erreur de stockage ErrForbidden est retourné quand l'utilisateur n'a pas la permission d'effectuer l'action TrackService gère les opérations sur les tracks NewTrackService crée un nouveau service de tracks 100MB ValidateTrackFile valide le format et la taille d'un fichier audio Valider la taille Valider l'extension Valider le type MIME en ouvrant le fichier Lire les premiers bytes pour vérifier le magic number Vérifier les magic numbers pour les formats audio MP3: ID3v2 (starts with "ID3") or MPEG frame sync (0xFF 0xFB/E/F) FLAC: "fLaC" WAV: "RIFF" followed by "WAVE" OGG: "OggS" M4A/AAC: "ftyp" avec "M4A" ou "mp4" UploadTrack upload un fichier audio et crée un enregistrement Track en base MOD-P2-008: Implémentation asynchrone - crée le Track immédiatement et lance la copie en goroutine Retourne le Track avec Status=Uploading, la copie se fait en arrière-plan Vérifier le quota utilisateur Valider le fichier Créer le répertoire d'upload s'il n'existe pas Générer un nom de fichier unique Déterminer le format depuis l'extension Extraire le titre depuis le nom de fichier (sans extension) MOD-P2-008: Créer l'enregistrement Track en base AVANT la copie (sémantique asynchrone) Le fichier n'existe pas encore, mais on crée l'enregistrement pour traçabilité FileID est NULL temporairement (sera mis à jour après création du fichier) NULL temporairement - sera mis à jour après création fichier Sera mis à jour lors du traitement asynchrone MOD-P2-008: Lancer la copie fichier en goroutine avec suivi (context + cancellation) La goroutine mettra à jour le Status quand terminé copyFileAsync copie le fichier de manière asynchrone et met à jour le Status du Track MOD-P2-008: Goroutine suivie avec context + cancellation + nettoyage en cas d'erreur Créer un contexte avec timeout pour la copie (5 minutes max) Ouvrir le fichier source Créer le fichier de destination Copier le fichier avec gestion d'erreurs Vérifier si le contexte a été annulé Continuer Vérifier que tous les bytes ont été copiés Copie réussie - mettre à jour le Status updateTrackStatus met à jour le Status et StatusMessage d'un Track MOD-P2-008: Helper pour mettre à jour le Status de manière thread-safe cleanupFailedUpload nettoie le fichier et le Track en cas d'échec MOD-P2-008: Nettoyage automatique en cas d'erreur Supprimer le fichier s'il existe CreateTrackFromPath crée un track à partir d'un fichier déjà sauvegardé UserQuota représente les informations de quota d'un utilisateur bytes CheckUserQuota vérifie si l'utilisateur peut uploader un fichier selon son quota MOD-P2-008: Utiliser creator_id (nom de colonne réel) au lieu de user_id GetUserQuota récupère les informations de quota d'un utilisateur TrackListParams représente les paramètres de filtrage et pagination pour la liste des tracks "created_at", "title", "popularity" "asc", "desc" ListTracks récupère une liste de tracks avec pagination, filtres et tri Créer la requête de base avec filtre sur le statut Appliquer les filtres Compter le total avant pagination Appliquer le tri Valider et appliquer SortBy Sécurité: valider que sortBy est un champ valide Pour "popularity", on utilise play_count + like_count Appliquer la pagination Maximum Exécuter la requête GetTrackByID récupère un track par son ID MOD-P1-003: Preload User pour éviter N+1 queries si User est accédé plus tard Changed trackID to uuid.UUID Updated query UpdateTrackParams représente les paramètres de mise à jour d'un track UpdateTrack met à jour les métadonnées d'un track Récupérer le track existant MOD-P1-003: Vérifier que l'utilisateur est propriétaire du track ou admin Check if user is admin (passed via context value) Construire les mises à jour Si aucune mise à jour n'est demandée Recharger le track pour obtenir les valeurs mises à jour Changed to zap.Any for uuid.UUID DeleteTrack supprime un track et son fichier physique Supprimer le fichier physique On continue même si la suppression du fichier échoue Supprimer les fichiers associés (waveform, cover art) Supprimer de la base de données GORM gérera automatiquement les relations en cascade grâce aux contraintes OnDelete:CASCADE UpdateStreamStatus updates the stream status and manifest URL of a track TrackStats représente les statistiques d'un track seconds GetTrackStats récupère les statistiques d'un track Vérifier que le track existe Count likes Count comments (excluding soft-deleted) Count views (total plays) and sum total play time Count downloads (sum of access_count from track_shares where permissions include 'download') Note: access_count is incremented when a share link with download permission is accessed BatchDeleteResult représente le résultat d'une suppression en lot Changed to uuid.UUID BatchDeleteError représente une erreur lors de la suppression d'un track BatchDeleteTracks supprime plusieurs tracks en une seule requête Changed trackIDs to []uuid.UUID Limiter le nombre de tracks à supprimer en une seule fois pour éviter les surcharges Récupérer tous les tracks en une seule requête Créer un map pour un accès rapide MOD-P1-003: Check if user is admin (passed via context value) Traiter chaque track MOD-P1-003: Vérifier l'ownership (admin peut bypass) Supprimer le track (réutiliser la logique de DeleteTrack) On continue même si la suppression des fichiers échoue deleteTrackFiles supprime les fichiers physiques d'un track (logique extraite de DeleteTrack) Supprimer le fichier principal Supprimer le fichier waveform Supprimer le fichier cover art Retourner la première erreur si il y en a, sinon nil BatchUpdateResult représente le résultat d'une mise à jour en lot BatchUpdateError représente une erreur lors de la mise à jour d'un track BatchUpdateTracks met à jour plusieurs tracks en une seule requête Limiter le nombre de tracks à mettre à jour en une seule fois Valider que les updates ne sont pas vides Liste des champs autorisés pour la mise à jour en lot Filtrer les champs autorisés et valider les valeurs Ignorer les champs non autorisés Validation spécifique selon le champ/home/senke/git/talas/veza/veza-backend-api/internal/database/home/senke/git/talas/veza/veza-backend-api/internal/database/chat_repository.goChatRepositoryCloseDBGetPoolStatsIsConnectionHealthyMeasureQueryNewChatRepositoryNewDBFromEnvConfigNewDatabaseNewPreparedStatementManagerNewSQLiteTestDBPreparedStatementManageraddIndexesbeforeIDmessagesroomIDmessageIDreactionemojiincludePrivateroomsuserID1userID2searchPatternsqlQuery
		INSERT INTO messages (room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
		RETURNING id
	`
		INSERT INTO messages (room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
		RETURNING id
	`
			SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
			FROM messages 
			WHERE room_id = $1 AND id < $2 AND is_deleted = false
			ORDER BY created_at DESC
			LIMIT $3 OFFSET $4
		`
			SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
			FROM messages 
			WHERE room_id = $1 AND id < $2 AND is_deleted = false
			ORDER BY created_at DESC
			LIMIT $3 OFFSET $4
		`
			SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
			FROM messages 
			WHERE room_id = $1 AND is_deleted = false
			ORDER BY created_at DESC
			LIMIT $2 OFFSET $3
		`
			SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
			FROM messages 
			WHERE room_id = $1 AND is_deleted = false
			ORDER BY created_at DESC
			LIMIT $2 OFFSET $3
		`
		SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
		FROM messages 
		WHERE id = $1
	`
		SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
		FROM messages 
		WHERE id = $1
	`
		UPDATE messages 
		SET content = $2, is_edited = $3, is_deleted = $4, updated_at = $5
		WHERE id = $1
	`
		UPDATE messages 
		SET content = $2, is_edited = $3, is_deleted = $4, updated_at = $5
		WHERE id = $1
	`
		INSERT INTO reactions (message_id, user_id, emoji, created_at)
		VALUES ($1, $2, $3, $4)
		RETURNING id
	`
		INSERT INTO reactions (message_id, user_id, emoji, created_at)
		VALUES ($1, $2, $3, $4)
		RETURNING id
	`DELETE FROM reactions WHERE message_id = $1 AND user_id = $2 AND emoji = $3`DELETE FROM reactions WHERE message_id = $1 AND user_id = $2 AND emoji = $3`
		INSERT INTO rooms (name, description, type, is_private, created_by, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
		RETURNING id
	`
		INSERT INTO rooms (name, description, type, is_private, created_by, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
		RETURNING id
	`
			SELECT DISTINCT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
			FROM rooms r
			LEFT JOIN room_members rm ON r.id = rm.room_id
			WHERE r.is_private = false OR rm.user_id = $1
			ORDER BY r.created_at DESC
		`
			SELECT DISTINCT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
			FROM rooms r
			LEFT JOIN room_members rm ON r.id = rm.room_id
			WHERE r.is_private = false OR rm.user_id = $1
			ORDER BY r.created_at DESC
		`
			SELECT id, name, description, type, is_private, created_by, created_at, updated_at
			FROM rooms 
			WHERE is_private = false
			ORDER BY created_at DESC
		`
			SELECT id, name, description, type, is_private, created_by, created_at, updated_at
			FROM rooms 
			WHERE is_private = false
			ORDER BY created_at DESC
		`
		SELECT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
		FROM rooms r
		JOIN room_members rm1 ON r.id = rm1.room_id
		JOIN room_members rm2 ON r.id = rm2.room_id
		WHERE r.type = 'dm' 
		AND rm1.user_id = $1 AND rm2.user_id = $2
		LIMIT 1
	`
		SELECT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
		FROM rooms r
		JOIN room_members rm1 ON r.id = rm1.room_id
		JOIN room_members rm2 ON r.id = rm2.room_id
		WHERE r.type = 'dm' 
		AND rm1.user_id = $1 AND rm2.user_id = $2
		LIMIT 1
	`
		INSERT INTO room_members (room_id, user_id, joined_at)
		VALUES ($1, $2, $3)
		ON CONFLICT (room_id, user_id) DO NOTHING
	`
		INSERT INTO room_members (room_id, user_id, joined_at)
		VALUES ($1, $2, $3)
		ON CONFLICT (room_id, user_id) DO NOTHING
	`DELETE FROM room_members WHERE room_id = $1 AND user_id = $2`DELETE FROM room_members WHERE room_id = $1 AND user_id = $2`SELECT COUNT(*) FROM room_members WHERE room_id = $1`SELECT COUNT(*) FROM room_members WHERE room_id = $1`
		SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
		FROM messages 
		WHERE room_id = $1 AND is_deleted = false AND content ILIKE $2
		ORDER BY created_at DESC
		LIMIT $3
	`
		SELECT id, room_id, user_id, content, type, parent_id, is_edited, is_deleted, created_at, updated_at
		FROM messages 
		WHERE room_id = $1 AND is_deleted = false AND content ILIKE $2
		ORDER BY created_at DESC
		LIMIT $3
	` ChatRepository provides access to chat data NewChatRepository creates a new chat repository CreateMessage creates a new message GetMessages retrieves messages for a room with pagination GetMessageByID retrieves a message by ID UpdateMessage updates a message CreateReaction creates a new reaction DeleteReaction removes a reaction CreateRoom creates a new room GetRooms retrieves available rooms for a user GetDirectMessageRoom retrieves or creates a DM room between two users AddUserToRoom adds a user to a room RemoveUserFromRoom removes a user from a room GetRoomUserCount gets the number of users in a room SearchMessages searches for messages in a roomstatementspsmGetStatementRefreshStatementRefreshAllStatements/home/senke/git/talas/veza/veza-backend-api/internal/database/database.gogormDBrollbackErrcommittedcheckQuerycontainsExtensionmigrationmigrationSQLcreateMigrationsTableconstraintsoauthIDrepo"gorm.io/driver/postgres""gorm.io/driver/sqlite"🔌 Tentative de connexion à la base de données PostgreSQL"🔌 Tentative de connexion à la base de données PostgreSQL"attempt"attempt"max_attempts"max_attempts""host""database"✅ Connexion à la base de données établie avec succès après tentatives"✅ Connexion à la base de données établie avec succès après tentatives"❌ Échec de connexion à la base de données"❌ Échec de connexion à la base de données"🔄 Nouvelle tentative dans quelques secondes..."🔄 Nouvelle tentative dans quelques secondes...""interval"échec de connexion à la base de données après %d tentatives: %w"échec de connexion à la base de données après %d tentatives: %w"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s"failed to open database: %w"failed to open database: %w"failed to ping database: %w"failed to ping database: %w"failed to initialize GORM: %w"failed to initialize GORM: %w"✅ Connexion à la base de données établie avec succès (connexion initiale)"✅ Connexion à la base de données établie avec succès (connexion initiale)"max_open_conns"max_open_conns"max_idle_conns"max_idle_conns"max_lifetime"max_lifetime"🔧 Initialisation de la base de données..."🔧 Initialisation de la base de données..."failed to run migrations: %w"failed to run migrations: %w"⚠️ Problèmes d'intégrité détectés"⚠️ Problèmes d'intégrité détectés"✅ Base de données initialisée avec succès"✅ Base de données initialisée avec succès"📦 Exécution des migrations..."📦 Exécution des migrations..."📦 Exécution des migrations SQL..."📦 Exécution des migrations SQL..."
		CREATE TABLE IF NOT EXISTS schema_migrations (
			id SERIAL PRIMARY KEY,
			version VARCHAR(50) NOT NULL UNIQUE,
			applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
		)
	`
		CREATE TABLE IF NOT EXISTS schema_migrations (
			id SERIAL PRIMARY KEY,
			version VARCHAR(50) NOT NULL UNIQUE,
			applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
		)
	`failed to create migrations table: %w"failed to create migrations table: %w"migrations/*.sql"migrations/*.sql"failed to list migration files: %w"failed to list migration files: %w"⚠️ Aucune migration trouvée dans le dossier migrations/"⚠️ Aucune migration trouvée dans le dossier migrations/"SELECT EXISTS(SELECT 1 FROM schema_migrations WHERE version = $1)"SELECT EXISTS(SELECT 1 FROM schema_migrations WHERE version = $1)"failed to check migration status: %w"failed to check migration status: %w"Migration déjà appliquée"Migration déjà appliquée""migration"Migration non trouvée, skip"Migration non trouvée, skip"CREATE EXTENSION"CREATE EXTENSION"Exécution migration avec extensions (hors transaction)"Exécution migration avec extensions (hors transaction)"failed to execute migration %s (extensions): %w"failed to execute migration %s (extensions): %w"failed to begin transaction for recording migration %s: %w"failed to begin transaction for recording migration %s: %w"INSERT INTO schema_migrations (version) VALUES ($1)"INSERT INTO schema_migrations (version) VALUES ($1)"failed to record migration %s: %w"failed to record migration %s: %w"failed to commit migration record transaction: %w"failed to commit migration record transaction: %w"failed to begin transaction for migration %s: %w"failed to begin transaction for migration %s: %w"Failed to rollback migration transaction"Failed to rollback migration transaction"Migration transaction rolled back automatically"Migration transaction rolled back automatically"failed to execute migration %s: %w"failed to execute migration %s: %w"failed to commit migration transaction for %s: %w"failed to commit migration transaction for %s: %w"Migration appliquée"Migration appliquée"✅ Toutes les migrations SQL ont été appliquées"✅ Toutes les migrations SQL ont été appliquées"failed to run GORM migrations: %w"failed to run GORM migrations: %w"✅ Migrations GORM appliquées (indexes additionnels)"✅ Migrations GORM appliquées (indexes additionnels)"🔍 Vérification de l'intégrité de la base de données..."🔍 Vérification de l'intégrité de la base de données...""users"user_sessions"user_sessions""rooms""messages"SELECT EXISTS (
			SELECT 1 FROM information_schema.tables 
			WHERE table_schema = 'public' AND table_name = $1
		)`SELECT EXISTS (
			SELECT 1 FROM information_schema.tables 
			WHERE table_schema = 'public' AND table_name = $1
		)`failed to check table %s: %w"failed to check table %s: %w"required table %s does not exist"required table %s does not exist"user_sessions_pkey"user_sessions_pkey"tracks_pkey"tracks_pkey"rooms_pkey"rooms_pkey"messages_pkey"messages_pkey"SELECT EXISTS (
			SELECT 1 FROM information_schema.table_constraints 
			WHERE table_name = $1 AND constraint_name = $2
		)`SELECT EXISTS (
			SELECT 1 FROM information_schema.table_constraints 
			WHERE table_name = $1 AND constraint_name = $2
		)`Impossible de vérifier la contrainte"Impossible de vérifier la contrainte""constraint"Contrainte manquante"Contrainte manquante""table"✅ Vérification d'intégrité terminée"✅ Vérification d'intégrité terminée"🔌 Fermeture de la connexion à la base de données"🔌 Fermeture de la connexion à la base de données"Erreur lors de la fermeture de la base de données"Erreur lors de la fermeture de la base de données"Timeout lors de la fermeture de la base de données"Timeout lors de la fermeture de la base de données"✅ Connexion à la base de données fermée avec succès"✅ Connexion à la base de données fermée avec succès"not implemented"not implemented"`json:"room_id"``json:"parent_id,omitempty"``json:"is_edited"``json:"is_deleted"``json:"message_id"``json:"emoji"``json:"name"``json:"is_private"``json:"created_by"`file::memory:?cache=shared"file::memory:?cache=shared"failed to open sqlite test database: %w"failed to open sqlite test database: %w" Added sqlite driver Config contient la configuration de la base de données Nombre maximal de tentatives de connexion Intervalle entre les tentatives Database représente la connexion principale à la base de données DB est un wrapper autour de sql.DB pour les repositories NewDatabaseWithRetry crée une nouvelle connexion à la base de données avec des tentatives de retry Au moins une tentative NewDatabase crée une nouvelle connexion à la base de données avec configuration Construire l'URL de connexion Ouvrir la connexion Configurer le pool de connexions optimisé Tester la connexion Initialiser GORM avec la même connexion Logger désactivé pour éviter les conflits avec zap On peut activer le logger GORM plus tard si nécessaire Initialize initialise la base de données avec les migrations Exécuter les migrations Vérifier l'intégrité des données RunMigrations exécute toutes les migrations en attente STRATÉGIE 100% SQL : Les migrations SQL sont exécutées EN PREMIER GORM n'est plus utilisé pour créer/modifier les tables Créer la table migrations si elle n'existe pas Découvir les fichiers de migration Exécuter chaque migration Vérifier si la migration a déjà été appliquée Lire le fichier de migration MOD-P1-002: Détecter si la migration contient CREATE EXTENSION (ne peut pas être dans transaction) MOD-P1-002: Exécuter migration avec rollback automatique en cas d'échec Extensions ne peuvent pas être dans une transaction PostgreSQL, exécuter directement Mais on doit quand même enregistrer dans schema_migrations de manière atomique Exécuter la migration directement (extensions) Enregistrer la migration dans une transaction séparée pour atomicité MOD-P1-002: Migration normale dans transaction avec rollback automatique garanti MOD-P1-002: Utiliser defer pour garantir rollback en cas d'erreur (même si panic) Exécuter la migration dans la transaction Enregistrer la migration comme appliquée dans la même transaction Commit transaction Exécuter les migrations GORM APRÈS les migrations SQL (uniquement pour les indexes additionnels sur users, pas pour créer/modifier les tables) VerifyIntegrity vérifie l'intégrité de base de la base de données Vérifier que les tables principales existent Vérifier quelques contraintes importantes Close ferme la connexion à la base de données de manière gracieuse Fermeture gracieuse : attendre que les requêtes en cours se terminent Fermer GORM d'abord GORM ferme automatiquement via sql.DB Fermer le pool de connexions Vérifier que la fermeture a réussi en utilisant le contexte Health vérifie la santé de la connexion à la base de données Stats retourne les statistiques de la base de données GetUserByOAuthID récupère un utilisateur par son OAuth ID et provider TODO: Implémenter OAuth user lookup CreateUser crée un nouvel utilisateur TODO: Implémenter avec vraie DB UpdateUser met à jour un utilisateur existant GetUserByID récupère un utilisateur par son ID Chat methods - using interfaces to avoid import cycles NewSQLiteTestDB crée une nouvelle connexion à une base de données SQLite en mémoire pour les tests. Pour les tests d'intégration, nous ne faisons pas d'AutoMigrate pour éviter les problèmes de DDL PostgreSQL. Les tests doivent mocker les interactions avec la base de données si nécessaire, ou s'appuyer sur des handlers qui ne touchent pas directement la base de données. Ou un logger de test silencieux Ouvrir une connexion GORM avec SQLite en mémoire Ne pas exécuter AutoMigrate pour éviter les erreurs de DDL PostgreSQL. Les tests qui nécessitent des données devront les insérer manuellement ou les handlers devront être mockés/testés sans réelle interaction DB./home/senke/git/talas/veza/veza-backend-api/internal/database/migrations.gomodelsToMigratefailed to migrate %T: %w"failed to migrate %T: %w"failed to add indexes: %w"failed to add indexes: %w" models n'est plus importé car AutoMigrate n'est plus utilisé (stratégie 100% SQL) RunMigrations exécute toutes les migrations GORM automatiques et ajoute les indexes personnalisés manquants. PostgreSQL active les foreign keys par défaut, pas besoin de PRAGMA Auto-migrate all models STRATÉGIE 100% SQL : Le schéma est géré exclusivement par les migrations SQL. GORM est utilisé uniquement pour mapper les modèles Go sur des tables existantes. Aucun modèle complexe n'est dans AutoMigrate pour éviter les bugs GORM + Postgres + soft delete + indexes. Tous les modèles sont gérés par SQL migrations: - users: migrations SQL existantes - tracks: 025_create_tracks.sql + 026_add_track_status.sql - playlists: 030_create_playlists.sql - playlist_tracks: 030_create_playlists.sql - rooms: 041_create_rooms.sql - room_members: 042_create_room_members.sql - messages: 043_create_messages.sql Add custom indexes addIndexes ajoute les indexes manquants sur les foreign keys et colonnes fréquemment utilisées NOTE: Avec la stratégie 100% SQL, la plupart des indexes sont gérés dans les migrations SQL. Cette fonction reste pour compatibilité mais ne fait plus rien. Tous les indexes sont maintenant gérés par les migrations SQL: - 001_create_users.sql: idx_users_email, idx_users_username, idx_users_slug - 025_create_tracks.sql: idx_tracks_user_id, idx_tracks_is_public, idx_tracks_created_at - 030_create_playlists.sql: idx_playlists_user_id, idx_playlist_tracks_* - 041_create_rooms.sql: idx_rooms_* - 042_create_room_members.sql: idx_room_members_* - 043_create_messages.sql: idx_messages_* Plus rien à faire ici - tous les indexes sont dans les migrations SQL/home/senke/git/talas/veza/veza-backend-api/internal/database/pool.godbnamesqlDBidlepingChanhost=%s user=%s password=%s dbname=%s port=%d sslmode=disable"host=%s user=%s password=%s dbname=%s port=%d sslmode=disable"failed to get underlying sql.DB: %w"failed to get underlying sql.DB: %w"database connection is nil"database connection is nil"UpdateDBConnectionsRecordDBQuerydatabase ping timeout after %v"database ping timeout after %v" NewDB crée une nouvelle connexion GORM avec pool de connexions optimisé Prend les paramètres de connexion individuels pour plus de flexibilité Configuration optimale du pool de connexions MaxOpenConns: Nombre maximum de connexions ouvertes (25 recommandé pour PostgreSQL) MaxIdleConns: Nombre maximum de connexions inactives (5 recommandé) ConnMaxLifetime: Durée maximale de vie d'une connexion (5 minutes) Cela permet de recycler les connexions et éviter les problèmes de timeout ConnMaxIdleTime: Durée maximale d'inactivité d'une connexion avant fermeture (1 minute) Test de la connexion NewDBFromEnvConfig crée une nouvelle connexion GORM à partir d'un EnvConfig Cette fonction facilite l'intégration avec le package config CloseDB ferme proprement la connexion à la base de données Fermeture gracieuse de toutes les connexions GetPoolStats retourne les statistiques du pool de connexions Met également à jour les métriques Prometheus (T0023) Mettre à jour les métriques Prometheus (T0023) open: nombre total de connexions ouvertes idle: nombre de connexions inactives (OpenConnections - InUse) in_use: nombre de connexions en cours d'utilisation MeasureQuery mesure la durée d'une requête DB et l'enregistre dans Prometheus Cette fonction helper peut être utilisée pour wrapper les opérations DB operation: type d'opération (SELECT, INSERT, UPDATE, DELETE, etc.) table: nom de la table (ou "unknown" si non disponible) fn: fonction à exécuter et mesurer Enregistrer la métrique indépendamment de l'erreur IsConnectionHealthy vérifie si la connexion à la base de données est saine Utiliser Ping avec un timeout personnalisé/home/senke/git/talas/veza/veza-backend-api/internal/database/prepared_statements.gonewStmtStatement already prepared"Statement already prepared""name"Failed to prepare statement"Failed to prepare statement""query"failed to prepare statement %s: %w"failed to prepare statement %s: %w"Statement prepared successfully"Statement prepared successfully"statement %s not found"statement %s not found"Initializing prepared statements..."Initializing prepared statements..."get_user_by_id"get_user_by_id"
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE id = $1 AND deleted_at IS NULL`
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE id = $1 AND deleted_at IS NULL`get_user_by_email"get_user_by_email"
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE email = $1 AND deleted_at IS NULL`
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE email = $1 AND deleted_at IS NULL`get_user_by_username"get_user_by_username"
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE username = $1 AND deleted_at IS NULL`
			SELECT id, username, email, password_hash, created_at, updated_at, deleted_at
			FROM users WHERE username = $1 AND deleted_at IS NULL`create_user"create_user"
			INSERT INTO users (username, email, password_hash, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5) RETURNING id`
			INSERT INTO users (username, email, password_hash, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5) RETURNING id`update_user"update_user"
			UPDATE users SET username = $2, email = $3, updated_at = $4
			WHERE id = $1 AND deleted_at IS NULL`
			UPDATE users SET username = $2, email = $3, updated_at = $4
			WHERE id = $1 AND deleted_at IS NULL`delete_user"delete_user"
			UPDATE users SET deleted_at = $2 WHERE id = $1`
			UPDATE users SET deleted_at = $2 WHERE id = $1`get_session_by_token"get_session_by_token"
			SELECT id, user_id, token, created_at, expires_at, ip_address, user_agent, is_valid
			FROM sessions WHERE token = $1 AND expires_at > $2 AND is_valid = true`
			SELECT id, user_id, token, created_at, expires_at, ip_address, user_agent, is_valid
			FROM sessions WHERE token = $1 AND expires_at > $2 AND is_valid = true`create_session"create_session"
			INSERT INTO sessions (user_id, token, created_at, expires_at, ip_address, user_agent)
			VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
			INSERT INTO sessions (user_id, token, created_at, expires_at, ip_address, user_agent)
			VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`revoke_session"revoke_session"
			UPDATE sessions SET is_valid = false, revoked_at = $2 WHERE token = $1`
			UPDATE sessions SET is_valid = false, revoked_at = $2 WHERE token = $1`revoke_user_sessions"revoke_user_sessions"
			UPDATE sessions SET is_valid = false, revoked_at = $2 
			WHERE user_id = $1 AND is_valid = true`
			UPDATE sessions SET is_valid = false, revoked_at = $2 
			WHERE user_id = $1 AND is_valid = true`cleanup_expired_sessions"cleanup_expired_sessions"
			DELETE FROM sessions WHERE expires_at < $1`
			DELETE FROM sessions WHERE expires_at < $1`get_messages_by_room"get_messages_by_room"
			SELECT m.id, m.room_id, m.user_id, m.content, m.type, m.parent_id, 
			       m.is_edited, m.is_deleted, m.created_at, m.updated_at,
			       u.username, u.email
			FROM messages m
			JOIN users u ON m.user_id = u.id
			WHERE m.room_id = $1 AND m.created_at < $2
			ORDER BY m.created_at DESC LIMIT $3`
			SELECT m.id, m.room_id, m.user_id, m.content, m.type, m.parent_id, 
			       m.is_edited, m.is_deleted, m.created_at, m.updated_at,
			       u.username, u.email
			FROM messages m
			JOIN users u ON m.user_id = u.id
			WHERE m.room_id = $1 AND m.created_at < $2
			ORDER BY m.created_at DESC LIMIT $3`create_message"create_message"
			INSERT INTO messages (room_id, user_id, content, type, parent_id, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id`
			INSERT INTO messages (room_id, user_id, content, type, parent_id, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id`update_message"update_message"
			UPDATE messages SET content = $2, is_edited = true, updated_at = $3
			WHERE id = $1 AND user_id = $4`
			UPDATE messages SET content = $2, is_edited = true, updated_at = $3
			WHERE id = $1 AND user_id = $4`delete_message"delete_message"
			UPDATE messages SET is_deleted = true, updated_at = $2 WHERE id = $1`
			UPDATE messages SET is_deleted = true, updated_at = $2 WHERE id = $1`get_track_by_id"get_track_by_id"
			SELECT id, user_id, title, artist, duration, file_path, file_size, 
			       mime_type, status, created_at, updated_at
			FROM tracks WHERE id = $1 AND status = 'active'`
			SELECT id, user_id, title, artist, duration, file_path, file_size, 
			       mime_type, status, created_at, updated_at
			FROM tracks WHERE id = $1 AND status = 'active'`get_user_tracks"get_user_tracks"
			SELECT id, user_id, title, artist, duration, file_path, file_size,
			       mime_type, status, created_at, updated_at
			FROM tracks WHERE user_id = $1 AND created_at < $2 AND status = 'active'
			ORDER BY created_at DESC LIMIT $3`
			SELECT id, user_id, title, artist, duration, file_path, file_size,
			       mime_type, status, created_at, updated_at
			FROM tracks WHERE user_id = $1 AND created_at < $2 AND status = 'active'
			ORDER BY created_at DESC LIMIT $3`create_track"create_track"
			INSERT INTO tracks (user_id, title, artist, duration, file_path, file_size, mime_type, status, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`
			INSERT INTO tracks (user_id, title, artist, duration, file_path, file_size, mime_type, status, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`update_track"update_track"
			UPDATE tracks SET title = $2, artist = $3, updated_at = $4
			WHERE id = $1 AND user_id = $5`
			UPDATE tracks SET title = $2, artist = $3, updated_at = $4
			WHERE id = $1 AND user_id = $5`delete_track"delete_track"
			UPDATE tracks SET status = 'deleted', updated_at = $2 WHERE id = $1`
			UPDATE tracks SET status = 'deleted', updated_at = $2 WHERE id = $1`get_room_by_id"get_room_by_id"
			SELECT id, name, description, type, is_private, created_by, created_at, updated_at
			FROM rooms WHERE id = $1`
			SELECT id, name, description, type, is_private, created_by, created_at, updated_at
			FROM rooms WHERE id = $1`get_user_rooms"get_user_rooms"
			SELECT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
			FROM rooms r
			JOIN room_users ru ON r.id = ru.room_id
			WHERE ru.user_id = $1 AND r.created_at < $2
			ORDER BY r.created_at DESC LIMIT $3`
			SELECT r.id, r.name, r.description, r.type, r.is_private, r.created_by, r.created_at, r.updated_at
			FROM rooms r
			JOIN room_users ru ON r.id = ru.room_id
			WHERE ru.user_id = $1 AND r.created_at < $2
			ORDER BY r.created_at DESC LIMIT $3`create_room"create_room"
			INSERT INTO rooms (name, description, type, is_private, created_by, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id`
			INSERT INTO rooms (name, description, type, is_private, created_by, created_at, updated_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id`add_user_to_room"add_user_to_room"
			INSERT INTO room_users (room_id, user_id, created_at)
			VALUES ($1, $2, $3) ON CONFLICT (room_id, user_id) DO NOTHING`
			INSERT INTO room_users (room_id, user_id, created_at)
			VALUES ($1, $2, $3) ON CONFLICT (room_id, user_id) DO NOTHING`remove_user_from_room"remove_user_from_room"
			DELETE FROM room_users WHERE room_id = $1 AND user_id = $2`
			DELETE FROM room_users WHERE room_id = $1 AND user_id = $2`create_audit_log"create_audit_log"
			INSERT INTO audit_logs (user_id, action, entity_type, entity_id, ip_address, user_agent, details, created_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`
			INSERT INTO audit_logs (user_id, action, entity_type, entity_id, ip_address, user_agent, details, created_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`get_audit_logs"get_audit_logs"
			SELECT id, user_id, action, entity_type, entity_id, ip_address, user_agent, details, created_at
			FROM audit_logs WHERE user_id = $1 AND created_at < $2
			ORDER BY created_at DESC LIMIT $3`
			SELECT id, user_id, action, entity_type, entity_id, ip_address, user_agent, details, created_at
			FROM audit_logs WHERE user_id = $1 AND created_at < $2
			ORDER BY created_at DESC LIMIT $3`search_tracks"search_tracks"
			SELECT id, user_id, title, artist, duration, file_path, file_size,
			       mime_type, status, created_at, updated_at,
			       ts_rank(to_tsvector('english', title || ' ' || artist), plainto_tsquery('english', $1)) as rank
			FROM tracks WHERE status = 'active' AND to_tsvector('english', title || ' ' || artist) @@ plainto_tsquery('english', $1)
			ORDER BY rank DESC, created_at DESC LIMIT $2`
			SELECT id, user_id, title, artist, duration, file_path, file_size,
			       mime_type, status, created_at, updated_at,
			       ts_rank(to_tsvector('english', title || ' ' || artist), plainto_tsquery('english', $1)) as rank
			FROM tracks WHERE status = 'active' AND to_tsvector('english', title || ' ' || artist) @@ plainto_tsquery('english', $1)
			ORDER BY rank DESC, created_at DESC LIMIT $2`search_messages"search_messages"
			SELECT m.id, m.room_id, m.user_id, m.content, m.type, m.created_at,
			       u.username, u.email,
			       ts_rank(to_tsvector('english', m.content), plainto_tsquery('english', $1)) as rank
			FROM messages m
			JOIN users u ON m.user_id = u.id
			WHERE m.room_id = $2 AND to_tsvector('english', m.content) @@ plainto_tsquery('english', $1)
			ORDER BY rank DESC, m.created_at DESC LIMIT $3`
			SELECT m.id, m.room_id, m.user_id, m.content, m.type, m.created_at,
			       u.username, u.email,
			       ts_rank(to_tsvector('english', m.content), plainto_tsquery('english', $1)) as rank
			FROM messages m
			JOIN users u ON m.user_id = u.id
			WHERE m.room_id = $2 AND to_tsvector('english', m.content) @@ plainto_tsquery('english', $1)
			ORDER BY rank DESC, m.created_at DESC LIMIT $3`All prepared statements initialized successfully"All prepared statements initialized successfully"Failed to close statement"Failed to close statement"All prepared statements closed"All prepared statements closed"total_statements"total_statements""statements"Failed to close old statement"Failed to close old statement"failed to refresh statement %s: %w"failed to refresh statement %s: %w"Statement refreshed"Statement refreshed"Failed to refresh statement"Failed to refresh statement"All statements refreshed"All statements refreshed"! Gestionnaire de requêtes préparées pour optimiser les performances!! Ce module implémente un cache de requêtes préparées pour améliorer! les performances et la sécurité des requêtes SQL fréquentes. PreparedStatement représente une requête préparée avec son nom PreparedStatementManager gère le cache des requêtes préparées NewPreparedStatementManager crée un nouveau gestionnaire de requêtes préparées Prepare prépare une requête SQL et la met en cache Vérifier si la requête est déjà préparée Préparer la requête Mettre en cache GetStatement récupère une requête préparée depuis le cache Execute exécute une requête préparée avec des arguments Query exécute une requête préparée et retourne des lignes QueryRow exécute une requête préparée et retourne une ligne Retourner une erreur dans le Row Initialize prépare toutes les requêtes fréquemment utilisées Requêtes utilisateur Requêtes de session Requêtes de messages Requêtes de tracks Requêtes de rooms Requêtes d'audit Requêtes de recherche Préparer toutes les requêtes Close ferme toutes les requêtes préparées Vider le cache GetStats retourne les statistiques des requêtes préparées RefreshStatement rafraîchit une requête préparée (utile après reconnexion DB) Fermer l'ancienne requête Préparer la nouvelle requête RefreshAllStatements rafraîchit toutes les requêtes préparées/home/senke/git/talas/veza/veza-backend-api/internal/dto/home/senke/git/talas/veza/veza-backend-api/internal/dto/login_request.goResendVerificationRequest`json:"email" binding:"required,email" validate:"required,email"``json:"password" binding:"required" validate:"required"``json:"remember_me"``json:"user"``json:"token"`/home/senke/git/talas/veza/veza-backend-api/internal/dto/refresh_request.go`json:"refresh_token" binding:"required" validate:"required"` RefreshRequest représente la requête de rafraîchissement de token T0172: DTO pour l'endpoint de refresh token/home/senke/git/talas/veza/veza-backend-api/internal/dto/register_request.go`json:"username" binding:"omitempty,min=3,max=50" validate:"omitempty,min=3,max=50,username"``json:"password" binding:"required,min=12" validate:"required,min=12"``json:"password_confirm" binding:"required,eqfield=Password" validate:"required,eqfield=Password"``json:"access_token"``json:"refresh_token"``json:"expires_in"`/home/senke/git/talas/veza/veza-backend-api/internal/dto/resend_verification_request.go/home/senke/git/talas/veza/veza-backend-api/internal/dto/validation.go`json:"field"``json:"message"``json:"value,omitempty"``json:"errors"` ValidationError représente une erreur de validation GO-013: Structure d'erreur de validation partagée pour éviter les cycles d'import ValidationErrors représente une liste d'erreurs de validation/home/senke/git/talas/veza/veza-backend-api/internal/email/home/senke/git/talas/veza/veza-backend-api/internal/email/sender.gosubjecttofromHeadersmtpnet/smtp"net/smtp"SMTP not configured, email would be sent"SMTP not configured, email would be sent""to""subject"ServerInfo%s <%s>"%s <%s>"From: %s
"From: %s\r\n"To: %s
"To: %s\r\n"Subject: %s
"Subject: %s\r\n"MIME-Version: 1.0
"MIME-Version: 1.0\r\n"Content-Type: text/html; charset=UTF-8
"Content-Type: text/html; charset=UTF-8\r\n"
"\r\n"%s"%s"From: %s
To: %s
Subject: %s
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

%s%s:%s"%s:%s"SendMailfailed to send email via SMTP: %w"failed to send email via SMTP: %w"Email sent successfully"Email sent successfully"SendTemplate not implemented directly, use EmailJob instead"SendTemplate not implemented directly, use EmailJob instead"SMTP_HOST"SMTP_HOST"SMTP_PORT"SMTP_PORT"MAILHOG_HOST"MAILHOG_HOST"MAILHOG_PORT"MAILHOG_PORT"1025"1025"SMTP_USERNAME"SMTP_USERNAME"SMTP_FROM"SMTP_FROM"SMTP_FROM_NAME"SMTP_FROM_NAME" EmailSender interface pour l'envoi d'emails SMTPConfig contient la configuration SMTP SMTPEmailSender implémente EmailSender avec SMTP réel NewSMTPEmailSender crée un nouveau sender SMTP Send envoie un email via SMTP Si pas de config SMTP, log seulement (dev mode) SMTP auth Email headers avec format correct Send email SendTemplate envoie un email avec un template Pour l'instant, cette méthode appelle Send avec le body généré L'implémentation complète avec template engine sera dans email_job.go Cette méthode sera utilisée par EmailJob qui gère le rendu des templates Pour l'instant, on délègue au template renderer LoadSMTPConfigFromEnv charge la config SMTP depuis les variables d'environnement En dev, fallback sur MailHog si pas de config MailHog default/home/senke/git/talas/veza/veza-backend-api/internal/errors/home/senke/git/talas/veza/veza-backend-api/internal/errors/codes.goErrCodeAlreadyExistsErrCodeConflictErrCodeDatabaseErrCodeInvalidCredentialsErrCodeInvalidFormatErrCodeOperationNotAllowedErrCodeOutOfRangeErrCodeQuotaExceededErrCodeRateLimitExceededErrCodeRequiredFieldErrCodeTokenExpiredErrCodeTokenInvalidFromValidatorErrorNewForbiddenErrorNewNotFoundErrorNewValidationErrorgetValidationMessage10011002200120022003300130024000400550009001 Authentication & Authorization (1000-1999) Validation (2000-2999) Resource (3000-3999) Business Logic (4000-4999) Rate Limiting (5000-5099) Internal (9000-9999)/home/senke/git/talas/veza/veza-backend-api/internal/errors/errors.go`json:"field,omitempty"`[%d] %s: %v"[%d] %s: %v"[%d] %s"[%d] %s"%s not found"%s not found" ErrorCode représente un code d'erreur standardisé de l'application AppError représente une erreur d'application avec un code standardisé Contexte additionnel (request_id, user_id, etc.) ErrorDetail représente un détail d'erreur pour une validation Error implémente l'interface error Unwrap retourne l'erreur causale pour le support des errors.Is/errors.As New crée une nouvelle AppError avec un code et un message Wrap enveloppe une erreur existante dans une AppError NewValidationError crée une nouvelle erreur de validation avec des détails NewNotFoundError crée une nouvelle erreur "not found" NewUnauthorizedError crée une nouvelle erreur d'autorisation NewForbiddenError crée une nouvelle erreur "forbidden"/home/senke/git/talas/veza/veza-backend-api/internal/errors/validation.go is required" is required" must be a valid email" must be a valid email" must be at least " must be at least " must be at most " must be at most ""len" must be exactly " must be exactly " characters" characters""gte" must be greater than or equal to " must be greater than or equal to ""lte" must be less than or equal to " must be less than or equal to ""gt" must be greater than " must be greater than ""lt" must be less than " must be less than ""url" must be a valid URL" must be a valid URL"alphanum"alphanum" must contain only alphanumeric characters" must contain only alphanumeric characters"alpha"alpha" must contain only alphabetic characters" must contain only alphabetic characters""numeric" must be numeric" must be numeric""oneof" must be one of: " must be one of: " is invalid" is invalid" FromValidatorError convertit une erreur de validation en AppError getValidationMessage génère un message d'erreur lisible à partir d'une FieldError/home/senke/git/talas/veza/veza-backend-api/internal/eventbus/home/senke/git/talas/veza/veza-backend-api/internal/eventbus/rabbitmq.goimmediatemandatoryroutingKeyautoAckconsumernoLocalnoWaittmpChannelamqp"github.com/rabbitmq/amqp091-go"📴 EventBus RabbitMQ désactivé par configuration."📴 EventBus RabbitMQ désactivé par configuration."🔄 Tentative de connexion à RabbitMQ"🔄 Tentative de connexion à RabbitMQ"✅ Connexion à RabbitMQ établie avec succès."✅ Connexion à RabbitMQ établie avec succès."failed to open RabbitMQ channel: %w"failed to open RabbitMQ channel: %w"❌ Échec de connexion à RabbitMQ"❌ Échec de connexion à RabbitMQ"🔄 Nouvelle tentative de connexion RabbitMQ dans quelques secondes..."🔄 Nouvelle tentative de connexion RabbitMQ dans quelques secondes..."❌ Échec de connexion à RabbitMQ après toutes les tentatives."❌ Échec de connexion à RabbitMQ après toutes les tentatives."failed to connect to RabbitMQ after %d attempts: %v"failed to connect to RabbitMQ after %d attempts: %v"⚠️ Tentative de publication sur EventBus désactivé"⚠️ Tentative de publication sur EventBus désactivé""exchange"routing_key"routing_key"EventBus is disabled"EventBus is disabled"⚠️ Tentative de consommation sur EventBus désactivé"⚠️ Tentative de consommation sur EventBus désactivé""queue""consumer"failed to close RabbitMQ channel: %w"failed to close RabbitMQ channel: %w"failed to close RabbitMQ connection: %w"failed to close RabbitMQ connection: %w"errors closing RabbitMQ: %v"errors closing RabbitMQ: %v"🔌 Connexion RabbitMQ fermée."🔌 Connexion RabbitMQ fermée."RabbitMQ EventBus est désactivé"RabbitMQ EventBus est désactivé"connexion RabbitMQ non établie ou fermée"connexion RabbitMQ non établie ou fermée"impossible d'ouvrir un canal RabbitMQ: %w"impossible d'ouvrir un canal RabbitMQ: %w" RabbitMQConfig contient la configuration pour RabbitMQ Si false, l'EventBus sera désactivé EventBusUnavailableError est retourné si l'EventBus est désactivé ou non disponible RabbitMQEventBus gère la connexion et les opérations RabbitMQ Indique si l'EventBus est actif NewRabbitMQEventBusWithRetry initialise une connexion RabbitMQ avec retry Si toutes les tentatives échouent, décider du mode dégradé ou fatal Publish envoie un message à un exchange RabbitMQ Consume démarre un consommateur RabbitMQ Close ferme la connexion et le canal RabbitMQ Health vérifie la santé de la connexion RabbitMQ Tenter d'ouvrir un canal temporaire pour vérifier l'état de la connexion Fermer le canal temporaire/home/senke/git/talas/veza/veza-backend-api/internal/features/home/senke/git/talas/veza/veza-backend-api/internal/features/features.go Package features - TO BE IMPLEMENTED Feature flags and feature management/home/senke/git/talas/veza/veza-backend-api/internal/handlers/home/senke/git/talas/veza/veza-backend-api/internal/handlers/analytics_handler.goAPIResponseAdaptBitrateRequestAddCollaboratorRequestAddCommentRequestAddMemberRequestAggregatedMetricsHandlerAnalyticsHandlerAvatarHandlerBitrateHandlerBroadcastMessageCommentHandlerConfigReloadHandlerCreateCommentRequestCreateOrderRequestCreatePlaylistRequestCreatePostRequestCreateProductRequestDashboardDataDuplicatePlaylistRequestGetUserIDUUIDHLSHandlerHealthResponseInitOAuthHandlersNewAggregatedMetricsHandlerNewAnalyticsHandlerNewAvatarHandlerNewBitrateHandlerNewCommentHandlerNewCommonHandlerNewConfigReloadHandlerNewHLSHandlerNewHealthHandlerSimpleNewNotificationHandlersNewPlaybackAnalyticsHandlerNewPlaybackAnalyticsHandlerFullNewPlaybackAnalyticsHandlerWithHeatmapNewPlaybackAnalyticsHandlerWithRateLimiterNewPlaybackWebSocketHandlerNewPlaylistExportHandlerNewRoleHandlerNewSearchHandlersNewSettingsHandlerNewSocialHandlerNotificationHandlersNotificationHandlersInstanceOAuthHandlersOAuthHandlersInstancePaginatedResponsePlaybackAnalyticsHandlerPlaybackWebSocketHandlerPlaylistExportHandlerRecordAnalyticsRequestRecordPlayRequestReorderTracksRequestRequestPasswordResetRequestResetPasswordRequestResponseDataRoleHandlerSearchHandlersSearchHandlersInstanceSettingsHandlerSocialHandlerStatusResponseSummaryDataTimeSeriesPointToggleLikeRequestTrendsDataUpdateCollaboratorPermissionRequestUpdateCommentRequestUpdatePlaylistRequestUploadRequestUploadResponseWebSocketMessagebToMbdailyStatgenerateRequestIDgetPlaylistErrorMessagegetPlaylistErrorStatusCodeisRetryableErrorisValidUsernamemapErrorCodeToHTTPStatusmapPlaylistErrorupgraderanalyticsServiceappErruidUUIDdeviceAnalyticsServiceRecordPlayGetPlaysOverTimeGetTopTracksstartDateStrendDateStrendDatestartDatetopTracksvalidIntervalsjson:"duration" binding:"required,min=1"json:"device,omitempty"`json:"duration" binding:"required,min=1"``json:"device,omitempty"`play recorded"play recorded""stats"invalid limit (must be between 1 and 100)"invalid limit (must be between 1 and 100)"start_date"start_date"RFC33392006-01-02T15:04:05Z07:00invalid start_date format (use RFC3339)"invalid start_date format (use RFC3339)"end_date"end_date"invalid end_date format (use RFC3339)"invalid end_date format (use RFC3339)"TopTrack-30day"day"hour"hour"week"week""month"invalid interval (must be: hour, day, week, month)"invalid interval (must be: hour, day, week, month)"PlayTimePointjson:"date""points"cannot access other user's stats"cannot access other user's stats" AnalyticsHandler gère les opérations d'analytics de lecture de tracks NewAnalyticsHandler crée un nouveau handler d'analytics RecordPlayRequest représente la requête pour enregistrer une lecture RecordPlay gère l'enregistrement d'une lecture de track Changed to uuid.Parse Récupérer user_id si authentifié (optionnel pour analytics anonymes) Récupérer IP address et device GetTrackStats gère la récupération des statistiques d'un track GetTopTracks gère la récupération des tracks les plus écoutés Parse limit Parse start_date (optionnel) Parse end_date (optionnel) GetPlaysOverTime gère la récupération des lectures sur une période Parse start_date (optionnel, défaut: 30 jours) Parse end_date (optionnel, défaut: maintenant) Parse interval (optionnel, défaut: day) GetUserStats gère la récupération des statistiques d'un utilisateur Vérifier que l'utilisateur peut accéder à ses propres statsPlaybackStatsTotalSessionsjson:"total_sessions"AveragePlayTimejson:"average_play_time"TotalPausesjson:"total_pauses"AveragePausesjson:"average_pauses"TotalSeeksjson:"total_seeks"AverageSeeksjson:"average_seeks"AverageCompletionjson:"average_completion"PlayTimeTrendjson:"play_time_trend"CompletionTrendjson:"completion_trend"SessionsTrendjson:"sessions_trend"TotalSessions7Daysjson:"total_sessions_7days"TotalSessions30Daysjson:"total_sessions_30days"Sessionsjson:"sessions"Trendsjson:"trends"TimeSeriesjson:"time_series"HLSServiceHLSTranscodeServiceoutputDirbitratesSetBitratesTranscodeTracktranscodeBitrategenerateMasterPlaylistgetPlaylistDurationcountSegmentscleanupTrackDirCleanupTrackDirHLSQueueServiceEnqueueWithIDDequeueMarkCompletedMarkFailedRetryJobGetJobGetPendingJobsCounttranscodeServicequeueServiceSetTranscodeServiceSetQueueServiceGetMasterPlaylistGetQualityPlaylistGetSegmentPathTriggerTranscodeTriggerTranscodeQueueGetStreamStatushlsServiceServeMasterPlaylistServeQualityPlaylistServeSegmentCommentServiceCreateCommentUpdateCommentGetRepliesDeleteCommentcommentServiceChecksjson:"checks"json:"track_id,omitempty"json:"details,omitempty"json:"request_id,omitempty"json:"context,omitempty"ReloadConfigGetConfigjson:"token" binding:"required"json:"autoplay"GetFeedjson:"content" binding:"required,min=1,max=5000"json:"attachments"OAuthServicegoogleConfiggithubConfigdiscordConfigInitializeConfigsGenerateStateTokenValidateStateTokenGetAuthURLHandleCallbackgetUserInfogetOrCreateUsersaveOAuthAccountgenerateJWToauthServiceGetOAuthProvidersohInitiateOAuthOAuthCallbackPlaybackAnalyticsServicecacheTTLSetBatchSizeRecordPlaybackRecordPlaybackBatchCalculateCompletionRateGetSessionsByDateRangeGetSessionsByDateRangePaginatedGetSessionsByDateRangePaginatedResultTrackCompletionUpdatePlaybackProgressreadPumpwritePumpclientsbroadcastWebSocketHandlersubscribeClientunsubscribeClientunregisterClientbroadcastMessagesBroadcastAnalyticsUpdateBroadcastStatsUpdateGetConnectedClientsCountGetTotalConnectedClientsCountjson:"title" binding:"required,min=3,max=200"json:"description" binding:"max=2000"json:"price" binding:"required,min=0,gt=0"json:"product_type" binding:"required,oneof=track pack service"json:"track_id,omitempty" binding:"omitempty,uuid"json:"license_type,omitempty" binding:"omitempty,oneof=standard exclusive commercial"json:"target_id" binding:"required,uuid"json:"target_type" binding:"required,oneof=post track playlist"json:"content" binding:"required,min=1,max=2000"json:"track_ids" binding:"required,min=1" validate:"required,min=1"RoleServiceGetRolesUpdateRoleDeleteRoleRevokeRoleFromUserroleServiceAssignRoleRevokeRoleEmailNotificationsjson:"email_notifications"PushNotificationsjson:"push_notifications"BrowserNotificationsjson:"browser_notifications"EmailOnFollowjson:"email_on_follow"EmailOnLikejson:"email_on_like"EmailOnCommentjson:"email_on_comment"EmailOnMessagejson:"email_on_message"EmailOnMentionjson:"email_on_mention"EmailMarketingjson:"email_marketing"json:"title" binding:"required,min=1,max=200" validate:"required,min=1,max=200"PlaybackHeatmapServiceGenerateHeatmapcalculateListenedZonescalculateSkipZonesgenerateHeatmapSegmentsGetHeatmapIntensityArrayPlaybackAnalyticsRateLimiterrequestsPerMinuterequestsWindowminRequestIntervaldailyQuotaweeklyQuotauserRequestsuserLastRequestuserDailyCountuserWeeklyCountCheckRateLimitRecordRequestGetQuotaInfogetQuotaCountscleanupLockedheatmapServicerateLimiterRecordAnalyticsGetDashboardcalculateTrendsgetStatsForDateRangecalculateTimeSeriesGetHeatmapvalidateAndSanitizeAnalyticsRequestGetSettingsUpdateSettingsvalidatePreferencesAllowSearchIndexingjson:"allow_search_indexing"BitrateAdaptationServiceBandwidthDetectionServicemaxSamplesMeasureBandwidthcalculateAverageGetAverageBandwidthRecommendBitrateClearSamplesbandwidthServiceAdaptBitratedetermineReasonadaptationServicejson:"first_name" binding:"omitempty,max=100" validate:"omitempty,max=100"json:"last_name" binding:"omitempty,max=100" validate:"omitempty,max=100"json:"username" binding:"omitempty,min=3,max=30" validate:"omitempty,min=3,max=30,username"json:"bio" binding:"omitempty,max=500" validate:"omitempty,max=500"json:"location" binding:"omitempty,max=100" validate:"omitempty,max=100"json:"birthdate" binding:"omitempty,datetime=2006-01-02" validate:"omitempty,datetime=2006-01-02"json:"gender" binding:"omitempty,oneof=Male Female Other 'Prefer not to say'" validate:"omitempty,oneof=Male Female Other 'Prefer not to say'"nhform:"track_id" binding:"required"form:"file_type" binding:"required,oneof=audio image video"form:"title" binding:"required,min=1,max=255"form:"artist" binding:"required,min=1,max=255"form:"duration" binding:"min=0"form:"metadata"ImageServiceValidateImageResizeImageEncodeJPEGProcessAvatarUploadToS3DeleteFromS3GenerateS3KeyimageServiceDeleteAvatarjson:"title,omitempty" binding:"omitempty,min=1,max=200" validate:"omitempty,min=1,max=200"json:"is_public,omitempty"PlayTimejson:"play_time" binding:"required,min=0"PauseCountjson:"pause_count" binding:"min=0"SeekCountjson:"seek_count" binding:"min=0"json:"completion_rate,omitempty"json:"started_at" binding:"required"EndedAtjson:"ended_at,omitempty"NewTitlejson:"new_title"NewDescriptionjson:"new_description,omitempty"SearchServiceerrorMetricstotalPlayTimetotalCompletionCurrentBitratejson:"current_bitrate" binding:"required" validate:"required"Bandwidthjson:"bandwidth" binding:"required" validate:"required"BufferLeveljson:"buffer_level" binding:"required" validate:"required"json:"file_name"json:"file_size"json:"file_type"json:"checksum"ExportPlaylistJSONExportPlaylistCSVjson:"permission" binding:"required,oneof=read write admin" validate:"required,oneof=read write admin"json:"user_id" binding:"required"Paginationjson:"pagination"SanitizedUptimeSecjson:"uptime_seconds"json:"services"json:"version"json:"git_commit"json:"build_time"json:"product_id" binding:"required"json:"items" binding:"required,min=1"json:"user_id" binding:"required" validate:"required"HLSTranscodeQueueQueueStatusgorm:"type:uuid;not null;index" json:"track_id"gorm:"foreignKey:TrackID" json:"track,omitempty"gorm:"not null;default:5" json:"priority"gorm:"type:varchar(20);not null;default:'pending';index" json:"status"gorm:"not null;default:0" json:"retry_count"gorm:"not null;default:3" json:"max_retries"gorm:"type:text" json:"error_message,omitempty"json:"started_at,omitempty"json:"completed_at,omitempty"PlaybackAnalyticsgorm:"type:uuid;not null;index:idx_playback_analytics_track_id" json:"track_id"gorm:"type:uuid;not null;index:idx_playback_analytics_user_id" json:"user_id"gorm:"not null;default:0" json:"play_time"gorm:"not null;default:0" json:"pause_count"gorm:"not null;default:0" json:"seek_count"gorm:"type:decimal(5,2);not null;default:0" json:"completion_rate"gorm:"not null" json:"started_at"gorm:"autoCreateTime;index:idx_playback_analytics_created_at" json:"created_at"PaginatedResultPageSizejson:"page_size"SkipZoneSkipCountBitrateAdaptationReasonListenedZoneListenCountSessionCountHeatmapSegmentjson:"start_time"json:"end_time"json:"listen_count"json:"skip_count"Intensityjson:"intensity"HeatmapDataTrackDurationjson:"track_duration"SegmentSizejson:"segment_size"json:"segments"MaxIntensityjson:"max_intensity"GeneratedAtjson:"generated_at"OAuthUserjson:"avatar"ProviderIDOAuthUserInfojson:"email" db:"email"json:"username" db:"username"OAuthStateStateTokendb:"state_token"db:"provider"db:"redirect_url"db:"expires_at"db:"created_at"RateLimitResultRetryAfterQuotaUsedQuotaLimitBitrateAnalyticsAdaptationTimePointTotalAdaptationsjson:"total_adaptations"Reasonsjson:"reasons"AdaptationsOverTimejson:"adaptations_over_time"AverageBandwidthjson:"average_bandwidth,omitempty"TrackResultUserResultPlaylistResultCoverjson:"cover"json:"tracks"json:"users"json:"playlists"/home/senke/git/talas/veza/veza-backend-api/internal/handlers/audit.goparsedHourshoursStractivitieshoursparsedRetentionretentionStrdeletedCountretentionDayslogIDlogIDStrUser not authenticated"User not authenticated"Invalid user ID type"Invalid user ID type"2006-01-02"2006-01-02"50Failed to search audit logs"Failed to search audit logs""logs"Invalid start_date format"Invalid start_date format"Invalid end_date format"Invalid end_date format"Failed to get audit stats"Failed to get audit stats"Failed to get user activity"Failed to get user activity""hours"168Failed to detect suspicious activity"Failed to detect suspicious activity""activities""ip"IP address parameter required"IP address parameter required"Failed to get IP activity"Failed to get IP activity"retention_days"retention_days"365Failed to cleanup old audit logs"Failed to cleanup old audit logs"Failed to cleanup old logs"Failed to cleanup old logs"Old audit logs cleaned up"Old audit logs cleaned up"deleted_count"deleted_count"Old audit logs cleaned up successfully"Old audit logs cleaned up successfully"Invalid log ID"Invalid log ID"Failed to get audit log"Failed to get audit log"log_id"log_id"Audit log not found"Audit log not found"Access denied"Access denied" AuditHandler gère les opérations sur les logs d'audit NewAuditHandler crée un nouveau handler d'audit SearchLogs recherche des logs d'audit Récupérer l'ID utilisateur depuis le contexte Parser les paramètres de recherche Par défaut, chercher les logs de l'utilisateur Paramètres optionnels Limite par défaut Effectuer la recherche GetStats récupère les statistiques d'audit Parser les paramètres de date 30 jours par défaut GetUserActivity récupère l'activité d'un utilisateur Parser le paramètre limit Récupérer l'activité DetectSuspiciousActivity détecte les activités suspectes Parser le paramètre hours 24 heures par défaut Détecter les activités suspectes GetIPActivity récupère l'activité d'une IP Récupérer l'IP depuis les paramètres Récupérer l'activité de l'IP CleanupOldLogs nettoie les anciens logs d'audit Parser le paramètre retention_days 90 jours par défaut Nettoyer les anciens logs GetAuditLog récupère un log d'audit spécifique Récupérer l'ID du log depuis les paramètres Rechercher le log spécifique Vérifier que le log appartient à l'utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/handlers/auth.gosessionCancelsessionCtxEmail not verified"Email not verified"3000000000Received registration request (Modern)"Received registration request (Modern)"IsUserAlreadyExistsErrorUser already exists"User already exists"IsInvalidEmailIsWeakPasswordPassword does not meet requirements"Password does not meet requirements"Registration failed"Registration failed"Failed to resend verification email"Failed to resend verification email" "veza-backend-api/internal/response" // Removed this import Login gère la connexion des utilisateurs @Summary      User Login @Description  Authenticate user and return access/refresh tokens @Tags         Auth @Param        request body dto.LoginRequest true "Login Credentials" @Success      200  {object}  dto.LoginResponse @Failure      400  {object}  handlers.APIResponse "Validation or Bad Request" @Failure      401  {object}  handlers.APIResponse "Invalid credentials" @Failure      500  {object}  handlers.APIResponse "Internal Error" @Router       /auth/login [post] req.RememberMe is a bool, not *bool, so no need to check for nil or indirect MOD-P1-004: Ajouter timeout context pour opération DB critique (login) MOD-P1-002: Utiliser RespondWithAppError au lieu de gin.H{"error"} MOD-P1-004: Ajouter timeout context pour opération DB (session) Register gère l'inscription des utilisateurs @Summary      User Registration @Description  Register a new user account @Param        request body dto.RegisterRequest true "Registration Data" @Success      201  {object}  dto.RegisterResponse @Failure      400  {object}  handlers.APIResponse "Validation Error" @Failure      409  {object}  handlers.APIResponse "User already exists" @Router       /auth/register [post] MOD-P1-004: Ajouter timeout context pour opération DB critique (register) @Summary      Refresh Token @Description  Get a new access token using a refresh token @Param        request body dto.RefreshRequest true "Refresh Token" @Success      200  {object}  dto.TokenResponse @Failure      401  {object}  handlers.APIResponse "Invalid/Expired Refresh Token" @Router       /auth/refresh [post] Use JWT config Logout gère la déconnexion des utilisateurs @Summary      Logout @Description  Revoke refresh token and current session @Param        request body object{refresh_token=string} true "Refresh Token to revoke" @Success      200  {object}  handlers.APIResponse "Success message" @Failure      401  {object}  handlers.APIResponse "Unauthorized" @Router       /auth/logout [post] Log the error but don't fail the request to prevent leaking info Log the error but don't fail the request @Summary      Verify Email @Description  Verify user email address using a token @Param        token query string true "Verification Token" @Failure      400  {object}  handlers.APIResponse "Invalid Token" @Router       /auth/verify-email [post] @Summary      Resend Verification Email @Description  Resend the email verification link @Param        request body dto.ResendVerificationRequest true "Email" @Router       /auth/resend-verification [post] @Summary      Check Username Availability @Description  Check if a username is already taken @Param        username query string true "Username to check" @Success      200  {object}  handlers.APIResponse{data=object{available=boolean,username=string}} @Failure      400  {object}  handlers.APIResponse "Missing Username" @Router       /auth/check-username [get] @Summary      Get Current User @Description  Get profile information of the currently logged-in user @Success      200  {object}  handlers.APIResponse{data=object{id=string,email=string,role=string}} @Router       /auth/me [get]/home/senke/git/talas/veza/veza-backend-api/internal/handlers/avatar_handler.goavatarURLresizedImages3Keyuser not authenticated"user not authenticated"cannot update other user's avatar"cannot update other user's avatar"avatar"avatar"failed to upload avatar"failed to upload avatar"failed to update avatar"failed to update avatar"avatar_url"avatar_url"cannot delete other user's avatar"cannot delete other user's avatar"failed to delete avatar"failed to delete avatar"avatar deleted"avatar deleted" AvatarHandler handles avatar-related operations NewAvatarHandler creates a new AvatarHandler instance UploadAvatar handles avatar upload T0221: Validates user_id, file format/size, processes image, uploads to S3, and updates DB Check that user_id corresponds to authenticated user Validate and process image Generate S3 key Upload to S3 (or local storage for now) Update avatar_url in DB DeleteAvatar handles avatar deletion T0222: Validates user_id, deletes file from S3, and sets avatar_url to NULL in DB Get current avatar_url from DB Delete file from S3 (or local storage) if exists Log error but continue (file may already be deleted) In production, you might want to use a logger here Set avatar_url to empty string (NULL in DB)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/bitrate_handler.gonewBitrateuserIDValanalytics`json:"current_bitrate" binding:"required" validate:"required"``json:"bandwidth" binding:"required" validate:"required"``json:"buffer_level" binding:"required" validate:"required"`ErrInvalidTrackIDErrInvalidUserIDErrInvalidBitrateErrInvalidBufferLevelrecommended_bitrate"recommended_bitrate""analytics" BitrateHandler gère les requêtes pour l'adaptation de bitrate T0349: Create Bitrate Adaptation Endpoint NewBitrateHandler crée un nouveau handler de bitrate AdaptBitrateRequest représente la requête pour adapter le bitrate AdaptBitrate gère la requête POST /api/v1/tracks/:id/bitrate/adapt Reçoit les métriques de streaming et retourne le bitrate recommandé Récupérer l'ID de l'utilisateur depuis le contexte (défini par le middleware d'authentification) Récupérer l'ID du track depuis les paramètres de l'URL Valider et parser le body de la requête Appeler le service d'adaptation de bitrate Le service retourne des erreurs de validation avec des messages spécifiques On peut distinguer les erreurs de validation des erreurs internes Retourner le bitrate recommandé GetAnalytics gère la requête GET /api/v1/tracks/:id/bitrate/analytics Retourne les statistiques d'adaptation de bitrate pour un track T0354: Create Bitrate Adaptation Analytics Endpoint Récupérer les analytics depuis le service Retourner les analytics/home/senke/git/talas/veza/veza-backend-api/internal/handlers/chat_handler.gouser_%s"user_%s"Failed to generate chat token"Failed to generate chat token"failed to generate token"failed to generate token" GetToken generates a JWT token for the chat service @Summary      Get Chat Token @Description  Generate a short-lived token for chat authentication @Tags         Chat @Success      200  {object}  APIResponse{data=object{token=string}} @Failure      401  {object}  APIResponse "Unauthorized" @Failure      500  {object}  APIResponse "Internal Error" @Router       /chat/token [get] Get username from DB/home/senke/git/talas/veza/veza-backend-api/internal/handlers/comment_handler.gocommentIDStrparentIDparentIDStrreplies`json:"content" binding:"required,min=1,max=5000"`ErrParentCommentNotFoundparent comment not found"parent comment not found"ErrParentTrackMismatchparent comment does not belong to the same track"parent comment does not belong to the same track"comment id is required"comment id is required"invalid comment id"invalid comment id"ErrCommentNotFoundcomment not found"comment not found"unauthorized: you can only edit your own comments"unauthorized: you can only edit your own comments"unauthorized: you can only delete your own comments"unauthorized: you can only delete your own comments"comment deleted successfully"comment deleted successfully"parent comment id is required"parent comment id is required"invalid parent comment id"invalid parent comment id""replies" CommentHandler gère les opérations sur les commentaires de tracks NewCommentHandler crée un nouveau handler de commentaires CreateCommentRequest représente la requête pour créer un commentaire Changed to *uuid.UUID UpdateCommentRequest représente la requête pour mettre à jour un commentaire CreateComment gère la création d'un commentaire sur un track Erreur déjà envoyée par GetUserIDUUID req.ParentID is already *uuid.UUID GetComments gère la récupération des commentaires d'un track UpdateComment gère la mise à jour d'un commentaire DeleteComment gère la suppression d'un commentaire Added false for isAdmin GetReplies gère la récupération des réponses d'un commentaire/home/senke/git/talas/veza/veza-backend-api/internal/handlers/common.goerrResponseresponseDatarequestIDcleaned`json:"request_id,omitempty"``json:"limit"``json:"has_next"``json:"has_previous"``json:"next_cursor,omitempty"``json:"previous_cursor,omitempty"``json:"pagination"`Handler error"Handler error"request_id"request_id""endpoint""list"Failed to bind JSON"Failed to bind JSON"Request body too large"Request body too large"content_length"content_length"max_size"max_size"Request body exceeds maximum size"Request body exceeds maximum size"Invalid JSON syntax"Invalid JSON syntax"Invalid JSON type"Invalid JSON type""field"type"type"Empty request body"Empty request body"Incomplete JSON"Incomplete JSON"Unknown fields in JSON"Unknown fields in JSON"JSON binding error (will be handled by validator)"JSON binding error (will be handled by validator)""cursor"Page must be greater than 0"Page must be greater than 0"ItoaLimit must be between 1 and 100"Limit must be between 1 and 100"Request received"Request received""method""path""operation"user_agent"user_agent"Response sent"Response sent"status_code"status_code"X-Request-ID"X-Request-ID"FormatIntFailed to parse JSON"Failed to parse JSON"Failed to marshal JSON"Failed to marshal JSON"X-Forwarded-For"X-Forwarded-For"X-Real-IP"X-Real-IP":user:":user:":ip:":ip:" ResponseData représente la structure standardisée des réponses API PaginationData représente les données de pagination PaginatedResponse représente une réponse paginée ValidationError et ValidationErrors sont maintenant dans internal/dto/validation.go pour éviter les cycles d'import. Utiliser dto.ValidationError et dto.ValidationErrors CommonHandler contient les dépendances communes aux handlers GO-013: Validator centralisé NewCommonHandler crée une nouvelle instance de CommonHandler GO-013: Initialise le validator centralisé ValidateRequest valide une requête avec le validator centralisé GO-013: Helper pour valider les requêtes et retourner des erreurs formatées RespondWithSuccess répond avec une réponse de succès Utiliser la structure unifiée APIResponse via RespondSuccess Si message est présent, on l'encapsule avec les données RespondWithError répond avec une erreur Utiliser la structure unifiée APIResponse On crée une structure d'erreur ad-hoc pour correspondre à l'interface attendue par APIResponse.Error (qui est interface{}) Ou mieux, on utilise RespondWithError qui attend un code, message et détails Note: RespondWithError est defined in error_response.go et attend (c, code, message, details...) Ici on a statusCode HTTP. RespondWithError attend un ErrorCode interne. C'est un conflit de signature. On va donc construire manuellement la réponse d'erreur unifiée. On pourrait ajouter err.Error() dans details, mais pour sécurité on évite d'exposer l'erreur brute sauf si nécessaire RespondWithValidationError répond avec des erreurs de validation GO-013: Utilise dto.ValidationError pour éviter les cycles d'import Adapter pour l'enveloppe unifiée Code 400 ou 422 RespondWithPaginatedData répond avec des données paginées Pour la pagination, on met tout dans Data BindJSON lie les données JSON de la requête à une structure DEPRECATED: Utiliser BindAndValidateJSON à la place pour une gestion d'erreurs robuste P0: JSON Hardening - Garantit qu'aucune erreur de parsing/validation ne passe silencieusement   - Vérifie la taille du body (max 10MB par défaut)   - Valide avec le validator centralisé   - Retourne une AppError avec code approprié (400 pour JSON malformé, 422 pour validation)	if appErr := h.BindAndValidateJSON(c, &req); appErr != nil {	    RespondWithAppError(c, appErr)	    return Analyser le type d'erreur pour retourner le bon code Body trop gros (dépassement de la limite) Erreur générique de binding (peut inclure des erreurs de validation Gin) On va laisser le validator gérer les erreurs de validation Si c'est une erreur de binding Gin (ex: unknown field), on la traite ici Pour les autres erreurs de binding, on considère que c'est une erreur de validation et on va laisser le validator s'en occuper 4. Valider avec le validator centralisé Convertir dto.ValidationError en errors.ErrorDetail GetUserIDFromContext extrait l'ID utilisateur du contexte GetUserIDUUID extrait l'ID utilisateur du contexte comme uuid.UUID (MOD-P1-001) WithTimeout crée un context avec timeout pour les opérations I/O critiques (MOD-P1-004) Utilise le timeout par défaut de 5s pour DB/Redis, ou le timeout fourni Default timeout pour DB/Redis GetPaginationParams extrait les paramètres de pagination de la requête ValidatePagination valide les paramètres de pagination GO-013: Utilise dto.ValidationError LogRequest log une requête entrante LogResponse log une réponse sortante SetRequestID middleware pour ajouter un ID de requête generateRequestID génère un ID de requête unique ValidateRequiredFields valide que les champs requis sont présents SanitizeString nettoie une chaîne de caractères Supprimer les caractères de contrôle et les espaces en début/fin Limiter la longueur ParseJSON parse du JSON de manière sécurisée SafeMarshalJSON sérialise en JSON de manière sécurisée GetClientIP obtient l'IP réelle du client Vérifier les headers de proxy RateLimitKey génère une clé pour le rate limiting/home/senke/git/talas/veza/veza-backend-api/internal/handlers/config_reload.gocurrentConfig"all"Log level reloaded successfully"Log level reloaded successfully"rate_limits"rate_limits"Rate limits reloaded successfully"Rate limits reloaded successfully"Invalid reload type. Use 'all', 'log_level', or 'rate_limits'"Invalid reload type. Use 'all', 'log_level', or 'rate_limits'"Failed to reload configuration"Failed to reload configuration""config" ConfigReloadHandler gère les endpoints de rechargement de configuration (T0034) NewConfigReloadHandler crée un nouveau handler pour le rechargement de configuration ReloadConfig gère le rechargement de toute la configuration (T0034) "all", "log_level", "rate_limits" Si pas de JSON valide, recharger tout par défaut Récupérer la configuration actuelle pour la réponse GetConfig gère la récupération de la configuration actuelle (T0034)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/error_response.goerrorData`json:"code"``json:"details,omitempty"``json:"context,omitempty"`10071008100510063003300442330055100StatusTooManyRequests42960007000StatusBadGateway50210000 ErrorResponse représente le format d'erreur standardisé selon ORIGIN_API_SPECIFICATION GO-014: Harmonisation format erreurs HTTP RespondWithAppError répond avec une AppError au format standardisé ORIGIN_API_SPECIFICATION GO-014: Harmonisation format erreurs HTTP selon ORIGIN_API_SPECIFICATION RespondWithError répond avec un code d'erreur et un message au format standardisé mapErrorCodeToHTTPStatus mappe les codes d'erreur ORIGIN vers les codes HTTP Invalid credentials, token expired/invalid, 2FA Insufficient permissions, account issues Validation Errors (2000-2999) Resource Errors (3000-3999) Not found, deleted Already exists, conflict Locked Quota exceeded Business Logic Errors (4000-4999) External Services (6000-6999) Internal Errors (9000-9999) Default/home/senke/git/talas/veza/veza-backend-api/internal/handlers/health.godbCheckrabbitMQCheckredisCheckhasOptionalServiceErrorpoolStatsstatsErrthreshold`json:"checks"``json:"duration_ms,omitempty"``json:"threshold_ms,omitempty"`"ok"rabbitmq"rabbitmq"degraded"degraded"slow"slow"not_ready"not_ready"Service is operational but some optional services are unavailable"Service is operational but some optional services are unavailable"Readiness probe: degraded mode"Readiness probe: degraded mode"checks"checks"alive"alive""timestamp"healthy"healthy""service""veza-backend-api"1e6100.0pool_connections"pool_connections"50.0Redis connection not configured"Redis connection not configured"RabbitMQ EventBus not configured"RabbitMQ EventBus not configured""disabled"RabbitMQ EventBus is disabled by configuration"RabbitMQ EventBus is disabled by configuration" HealthResponse représente la réponse du health check MOD-P1-006: Added for degraded status message HealthCheck représente le résultat d'un check individuel HealthHandler gère les health checks Typé avec le vrai type Redis Instance de l'EventBus RabbitMQ Env (development, production, etc.) NewHealthHandler crée un nouveau handler de health Type assertion for Redis Type assertion for RabbitMQ NewHealthHandlerSimple crée un nouveau handler de health simple (sans logger/redis) Pour compatibilité avec la spécification T0012 Check vérifie l'état de la base de données et retourne un status simple Cette méthode implémente la spécification T0012 Route /health - Stateless, sans dépendances externes Route /health simplifiée - toujours retourner {status: "ok"} Stateless, sans vérification de dépendances Health check endpoint (/health) Check database Check Redis Check RabbitMQ Déterminer le statut global Readiness check endpoint (/ready) Vérifier que la DB est accessible DB is critical in ALL environments MOD-P1-006: Redis and RabbitMQ are optional services DB is critical, but Redis/RabbitMQ can be down (degraded mode) Vérifier que Redis est accessible Vérifier que RabbitMQ est accessible (si activé) MOD-P1-006: Determine overall status - DB error = not_ready (critical service) - Redis/RabbitMQ error = degraded (optional services) - All OK = ready Skip database check (already handled above) MOD-P1-006: Log degraded status at warn level MOD-P1-006: Return 200 OK even if degraded (DB is OK, optional services down) Kubernetes will not kill the pod if readiness returns 200 Liveness check endpoint (/live) SimpleHealthCheck est une fonction simple pour le health check endpoint public checkDatabase vérifie la connexion à la base de données avec pool stats Utiliser IsConnectionHealthy avec timeout de 5 secondes 100ms threshold Récupérer les statistiques du pool On pourrait ajouter plus d'informations sur le pool ici Utiliser dans le futur pour plus de détails Convert to ms checkRedis vérifie la connexion à Redis 50ms threshold checkRabbitMQ vérifie la connexion à RabbitMQ (Event Bus) Vérifier si l'EventBus est configuré Vérifier si l'EventBus est activé via le champ booléen Tenter un Health Check réel/home/senke/git/talas/veza/veza-backend-api/internal/handlers/hls_handler.gobitratesegmentPathjobIDplaylist not found"playlist not found"application/vnd.apple.mpegurl"application/vnd.apple.mpegurl"Cache-Control"Cache-Control"no-cache"no-cache""bitrate""segment"segment not found"segment not found"video/mp2t"video/mp2t"public, max-age=3600"public, max-age=3600"stream not found"stream not found"forbidden: user does not own this track"forbidden: user does not own this track"job_id"job_id" "strconv" // Removed this import HLSHandler gère les requêtes pour servir les fichiers HLS NewHLSHandler crée un nouveau handler HLS ServeMasterPlaylist sert le master playlist pour un track ServeQualityPlaylist sert une quality playlist pour un track et bitrate ServeSegment sert un segment pour un track, bitrate et nom de segment GetStreamStatus retourne le statut d'un stream HLS pour un track TriggerTranscode déclenche le transcodage HLS d'un track via la queue (T0343)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/marketplace.gotrackUUIDproductIDStr`json:"title" binding:"required,min=3,max=200"``json:"description" binding:"max=2000"``json:"price" binding:"required,min=0,gt=0"``json:"product_type" binding:"required,oneof=track pack service"``json:"track_id,omitempty" binding:"omitempty,uuid"``json:"license_type,omitempty" binding:"omitempty,oneof=standard exclusive commercial"`Invalid track_id format"Invalid track_id format"You do not own this track"You do not own this track"Track not found"Track not found"`json:"product_id" binding:"required"``json:"items" binding:"required,min=1"`Invalid product_id: "Invalid product_id: "Invalid product_id"Invalid product_id"No valid license for this product"No valid license for this product"Track file not found"Track file not found"Failed to get download URL"Failed to get download URL"Failed to list products"Failed to list products" MarketplaceHandler gère les opérations de la marketplace NewMarketplaceHandler crée une nouvelle instance de MarketplaceHandler CreateProductRequest DTO pour la création de produit GO-013: Validation améliorée avec tags go-validator UUID string CreateProduct gère la création d'un produit @Summary Create a new product @Description Create a product (Track, Pack, Service) for sale @Tags Marketplace @Accept json @Produce json @Security BearerAuth @Param product body CreateProductRequest true "Product info" @Success 201 {object} marketplace.Product @Failure 400 {object} response.APIResponse "Validation Error" @Failure 401 {object} response.APIResponse "Unauthorized" @Router /api/v1/marketplace/products [post] Direct active for MVP CreateOrderRequest DTO pour la création de commande CreateOrder gère l'achat de produits @Summary Create a new order @Description Purchase products @Param order body CreateOrderRequest true "Order items" @Success 201 {object} marketplace.Order @Router /api/v1/marketplace/orders [post] GetDownloadURL récupère l'URL de téléchargement pour un achat @Summary Get download URL @Description Get a secure download URL for a purchased product @Param product_id path string true "Product ID" @Success 200 {object} map[string]string @Failure 403 {object} response.APIResponse "No license" @Failure 404 {object} response.APIResponse "Not Found" @Router /api/v1/marketplace/download/{product_id} [get] ListProducts liste les produits @Summary List products @Description List marketplace products with filters @Param status query string false "Product status" @Param seller_id query string false "Seller ID" @Success 200 {array} marketplace.Product @Router /api/v1/marketplace/products [get]/home/senke/git/talas/veza/veza-backend-api/internal/handlers/metrics.go"github.com/prometheus/client_golang/prometheus/promhttp" PrometheusMetrics expose les métriques Prometheus L'endpoint retourne les métriques au format Prometheus standard/home/senke/git/talas/veza/veza-backend-api/internal/handlers/metrics_aggregated.govalidWindowsallWindowsaggregatedMetricswindowTypeMetrics not available"Metrics not available"Aggregated metrics not available"Aggregated metrics not available""window"1m"1m"5m"5m"1h"1h"Invalid window type. Valid values: 1m, 5m, 1h"Invalid window type. Valid values: 1m, 5m, 1h""windows" AggregatedMetricsHandler gère l'exposition des métriques agrégées NewAggregatedMetricsHandler crée un nouveau handler pour les métriques agrégées GetAggregated expose les métriques agrégées Endpoint: GET /metrics/aggregated?window=1m|5m|1h Si window n'est pas spécifié, retourne toutes les fenêtres Retourner une seule fenêtre Retourner toutes les fenêtres AggregatedMetrics expose les métriques agrégées (fonction helper pour routes simples)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/notification_handlers.gounreadOnlynotificationID"read"Invalid notification ID"Invalid notification ID"Notification marked as read"Notification marked as read"All notifications marked as read"All notifications marked as read" GetNotifications retrieves all notifications for the authenticated user MarkAsRead marks a notification as read MarkAllAsRead marks all notifications as read for the user GetUnreadCount returns the count of unread notifications/home/senke/git/talas/veza/veza-backend-api/internal/handlers/oauth_handlers.goprovidersauthURLfrontendURLredirectURLGoogle"Google""google"authorizeUrl"authorizeUrl"/api/v1/auth/oauth/google"/api/v1/auth/oauth/google"icon"icon"GitHub"GitHub"github"github"/api/v1/auth/oauth/github"/api/v1/auth/oauth/github"Discord"Discord"discord"discord"/api/v1/auth/oauth/discord"/api/v1/auth/oauth/discord""providers""provider"StatusTemporaryRedirect307"state"missing code or state"missing code or state"%s/auth/callback?token=%s&user_id=%s"%s/auth/callback?token=%s&user_id=%s" OAuthHandlers handles OAuth authentication flows OAuthHandlersInstance is the global instance InitOAuthHandlers initializes the OAuth handlers GetOAuthProviders returns available OAuth providers InitiateOAuth initiates OAuth flow Get authorization URL Redirect to OAuth provider OAuthCallback handles OAuth callback Handle callback Redirect to frontend with token TODO: Get from config/home/senke/git/talas/veza/veza-backend-api/internal/handlers/password_reset_handler.goIf the email exists, a reset link has been sent"If the email exists, a reset link has been sent"failed to store token"failed to store token"`json:"token" binding:"required"`invalid or expired token"invalid or expired token"Password validation failed"Password validation failed"Failed to update password"Failed to update password"failed to update password"failed to update password"Failed to mark token as used"Failed to mark token as used"Failed to invalidate user sessions"Failed to invalidate user sessions"User sessions invalidated after password reset"User sessions invalidated after password reset"Password reset successfully"Password reset successfully" Added import for authcore RequestPasswordResetRequest represents a request to reset password T0193: Request structure for password reset endpoint RequestPasswordReset handles password reset request T0193: Creates endpoint POST /api/v1/auth/password/reset-request Find user by email Always return success for security (prevent email enumeration) Invalidate old tokens Generate token Store token Log but don't fail - user should still get success message Always return generic success message for security ResetPasswordRequest represents a request to complete password reset T0194: Request structure for password reset completion ResetPassword handles password reset completion T0194: Creates endpoint POST /api/v1/auth/password/reset T0200: Uses AuthService.InvalidateAllUserSessions to invalidate sessions and update token_version Changed to *auth.AuthService Verify token T0200: Invalidate all user sessions via AuthService This updates token_version and revokes all sessions/home/senke/git/talas/veza/veza-backend-api/internal/handlers/playback_analytics_handler.gorateLimitResultquotaInfodashboardtimeSeriestrendsfourteenDaysAgosevenDaysAgostats30Daysstats7DaysstatsPrev7DaysthirtyDaysAgoavgCompletionavgPausesavgPlayTimeavgSeekscompletedSessionscompletionRatetotalPausestotalSeekstotalSessionsdateKeydailyStatssegmentSizeStrheatmapsegmentSizeroundedRateendedAtmaxExpectedPlayTimesanitizedmath"math"`json:"play_time" binding:"required,min=0"``json:"pause_count" binding:"min=0"``json:"seek_count" binding:"min=0"``json:"completion_rate,omitempty"``json:"started_at" binding:"required"``json:"ended_at,omitempty"`failed to check rate limit"failed to check rate limit"X-RateLimit-Remaining"X-RateLimit-Remaining"X-RateLimit-Retry-After"X-RateLimit-Retry-After"X-RateLimit-Reason"X-RateLimit-Reason"Rate limit exceeded"Rate limit exceeded"retry_after"retry_after"quota_used"quota_used"quota_limit"quota_limit"invalid track ID: 0"invalid track ID: 0"invalid user ID: 0"invalid user ID: 0"invalid play time"invalid play time"invalid pause"invalid pause"invalid seek"invalid seek"invalid completion"invalid completion"started_at is required"started_at is required""recorded"rate limiting not enabled"rate limiting not enabled"failed to get quota info"failed to get quota info"`json:"stats"``json:"trends"``json:"time_series"``json:"play_time_trend"``json:"completion_trend"``json:"sessions_trend"``json:"average_play_time"``json:"average_completion"``json:"total_sessions_7days"``json:"total_sessions_30days"``json:"date"``json:"sessions"`failed to calculate trends: "failed to calculate trends: "failed to calculate time series: "failed to calculate time series: ""dashboard"-7-14`json:"total_plays"``json:"completion_rate"`"summary"heatmap service not available"heatmap service not available"segment_size"segment_size""heatmap"play_time"play_time"play_time must be greater than or equal to 0"play_time must be greater than or equal to 0"86400play_time cannot exceed 86400 seconds (24 hours)"play_time cannot exceed 86400 seconds (24 hours)"pause_count"pause_count"pause_count must be greater than or equal to 0"pause_count must be greater than or equal to 0"seek_count"seek_count"seek_count must be greater than or equal to 0"seek_count must be greater than or equal to 0"IsNaNcompletion_rate"completion_rate"completion_rate must be a valid number"completion_rate must be a valid number"%f"%f"completion_rate must be between 0 and 100"completion_rate must be between 0 and 100"started_at"started_at"started_at cannot be in the future"started_at cannot be in the future"started_at cannot be older than 30 days"started_at cannot be older than 30 days"ended_at"ended_at"ended_at cannot be in the future"ended_at cannot be in the future"ended_at must be after started_at"ended_at must be after started_at"1.11.10000000000000008882476979795053773/2251799813685248play_time (%.0f seconds) is inconsistent with session duration (%.0f seconds)"play_time (%.0f seconds) is inconsistent with session duration (%.0f seconds)"pause_count is too high for such a short play_time"pause_count is too high for such a short play_time"seek_count is too high for such a short play_time"seek_count is too high for such a short play_time" PlaybackAnalyticsHandler gère les requêtes pour les analytics de lecture T0358: Create Playback Analytics Endpoint T0389: Create Playback Analytics Rate Limiting NewPlaybackAnalyticsHandler crée un nouveau handler d'analytics de lecture Rate limiter optionnel NewPlaybackAnalyticsHandlerWithRateLimiter crée un nouveau handler avec rate limiter NewPlaybackAnalyticsHandlerWithHeatmap crée un nouveau handler avec service heatmap NewPlaybackAnalyticsHandlerFull crée un nouveau handler avec tous les services RecordAnalyticsRequest représente la requête pour enregistrer des analytics de lecture T0388: Create Playback Analytics Validation - Amélioré avec validation optional, default 0 optional, will be calculated if not provided ISO 8601 format optional ValidationResult représente le résultat d'une validation T0388: Create Playback Analytics Validation RecordAnalytics gère la requête POST /api/v1/tracks/:id/playback/analytics Enregistre les analytics de lecture pour un track Valider et sanitizer les données Utiliser les données sanitizées Vérifier le rate limiting si activé Ajouter les headers de rate limiting Créer le modèle PlaybackAnalytics Définir le completion_rate si fourni Enregistrer les analytics via le service Gérer les erreurs spécifiques Enregistrer la requête dans le rate limiter si activé Logger l'erreur mais ne pas échouer la requête Le rate limiting est une fonctionnalité de protection, pas critique Retourner le succès GetQuotaInfo gère la requête GET /api/v1/playback/analytics/quota Retourne les informations de quota pour l'utilisateur actuel Récupérer l'ID de l'utilisateur depuis le contexte MOD-P2-003: Utiliser AppError au lieu de gin.H (503 -> ErrCodeInternal avec message approprié) DashboardData représente les données du dashboard d'analytics T0363: Create Playback Analytics Dashboard Endpoint TrendsData représente les tendances d'analytics % de changement sur 7 jours Moyenne sur 7 jours Total sur 7 jours Total sur 30 jours TimeSeriesPoint représente un point dans une série temporelle Format: YYYY-MM-DD percentage GetDashboard gère la requête GET /api/v1/tracks/:id/playback/dashboard Retourne les statistiques agrégées, graphiques et tendances pour un track Récupérer les statistiques globales Calculer les tendances (comparaison 7 jours vs 14-7 jours) Calculer les séries temporelles (30 derniers jours) Construire la réponse calculateTrends calcule les tendances d'analytics Statistiques sur les 7 derniers jours Statistiques sur les 7 jours précédents (14-7 jours) Statistiques sur les 30 derniers jours Calculer les tendances en pourcentage Tendance des sessions Nouvelle donnée Tendance du temps de lecture Tendance du taux de complétion getStatsForDateRange récupère les statistiques pour une plage de dates Compter les sessions complétées (>90%) calculateTimeSeries calcule les séries temporelles pour les N derniers jours Récupérer toutes les sessions dans la plage Grouper par jour Créer les points de série temporelle pour tous les jours dailyStat représente les statistiques d'un jour SummaryData représente le résumé des analytics de lecture T0370: Create Playback Analytics Summary Endpoint Nombre total de lectures Taux de complétion moyen (%) Temps de lecture moyen (secondes) GetSummary gère la requête GET /api/v1/tracks/:id/playback/summary Retourne un résumé des analytics de lecture pour un track Récupérer les statistiques via le service Construire le résumé GetHeatmap gère la requête GET /api/v1/tracks/:id/playback/heatmap Retourne les données de heatmap pour un track T0376: Create Playback Analytics Heatmap Generation Récupérer la taille de segment depuis les query params (optionnel, défaut: 5) Générer la heatmap via le service validateAndSanitizeAnalyticsRequest valide et sanitize une requête d'analytics Copier les données pour la sanitization 1. Validation du schéma - PlayTime Limiter play_time à une valeur raisonnable (max 24 heures = 86400 secondes) 2. Validation du schéma - PauseCount Limiter pause_count à une valeur raisonnable (max 1000) 3. Validation du schéma - SeekCount Limiter seek_count à une valeur raisonnable (max 1000) 4. Validation du schéma - CompletionRate Arrondir à 2 décimales 5. Validation du schéma - StartedAt Vérifier que started_at n'est pas dans le futur (avec une marge de 1 minute pour les décalages d'horloge) Vérifier que started_at n'est pas trop ancien (max 30 jours) 6. Validation du schéma - EndedAt Si ended_at est fourni mais est zero, le traiter comme nil Vérifier que ended_at n'est pas dans le futur 7. Vérification de cohérence - EndedAt doit être après StartedAt 8. Vérification de cohérence - PlayTime doit être cohérent avec les dates Le play_time ne devrait pas être significativement supérieur à la durée entre started_at et ended_at (avec une marge de 10% pour les pauses) 9. Vérification de cohérence - CompletionRate doit être cohérent avec PlayTime si fourni Cette vérification nécessite la durée du track, donc elle sera faite après la récupération du track Pour l'instant, on valide juste que le completion_rate est dans une plage raisonnable 10. Vérification de cohérence - PauseCount et SeekCount doivent être raisonnables par rapport à PlayTime Si play_time est très court (< 10 secondes), pause_count et seek_count devraient être faibles/home/senke/git/talas/veza/veza-backend-api/internal/handlers/playback_websocket_handler.gowsMsg"github.com/gorilla/websocket"`json:"data"``json:"track_id,omitempty"`Failed to upgrade connection to WebSocket"Failed to upgrade connection to WebSocket"WebSocket client connected"WebSocket client connected"WebSocket read error"WebSocket read error"Failed to unmarshal WebSocket message"Failed to unmarshal WebSocket message""subscribe"unsubscribe"unsubscribe""ping"pong"pong"5454000000000
"\n"Failed to marshal message"Failed to marshal message"Client subscribed to track"Client subscribed to track"subscribed"subscribed"Client unsubscribed from track"Client unsubscribed from track"unsubscribed"unsubscribed"Client disconnected"Client disconnected"Failed to marshal broadcast message"Failed to marshal broadcast message"analytics_update"analytics_update"Broadcast channel full, dropping message"Broadcast channel full, dropping message"stats_update"stats_update" upgrader est utilisé pour mettre à niveau les connexions HTTP vers WebSocket En production, vérifier l'origine de la requête PlaybackWebSocketHandler gère les connexions WebSocket pour les analytics de lecture en temps réel T0368: Create Playback Analytics Real-time Updates trackID -> conn -> client Client représente un client WebSocket connecté Changed to UUID BroadcastMessage représente un message à diffuser WebSocketMessage représente un message reçu du client NewPlaybackWebSocketHandler crée un nouveau handler WebSocket pour les analytics Démarrer la goroutine de diffusion WebSocketHandler gère les connexions WebSocket pour les analytics de lecture Mettre à niveau la connexion HTTP vers WebSocket Créer un nouveau client Gérer la connexion dans une goroutine séparée readPump lit les messages du client Traiter le message Gérer différents types de messages S'abonner à un track Se désabonner d'un track Répondre au ping writePump envoie les messages au client Envoyer les messages en attente sendMessage envoie un message au client subscribeClient abonne un client à un track Envoyer un message de confirmation unsubscribeClient désabonne un client d'un track unregisterClient retire un client de tous les tracks broadcastMessages diffuse les messages à tous les clients abonnés Envoyer le message à tous les clients abonnés BroadcastAnalyticsUpdate diffuse une mise à jour d'analytics à tous les clients abonnés BroadcastStatsUpdate diffuse une mise à jour de statistiques à tous les clients abonnés GetConnectedClientsCount retourne le nombre de clients connectés pour un track GetTotalConnectedClientsCount retourne le nombre total de clients connectés/home/senke/git/talas/veza/veza-backend-api/internal/handlers/playlist_error_helper.goUne erreur inconnue s'est produite"Une erreur inconnue s'est produite"Le titre de la playlist est requis et doit contenir entre 1 et 200 caractères"Le titre de la playlist est requis et doit contenir entre 1 et 200 caractères"La description ne peut pas dépasser 1000 caractères"La description ne peut pas dépasser 1000 caractères"Les données fournies sont invalides. Veuillez vérifier vos informations"Les données fournies sont invalides. Veuillez vérifier vos informations"access denied"access denied"Vous n'avez pas la permission d'effectuer cette action sur cette playlist"Vous n'avez pas la permission d'effectuer cette action sur cette playlist"Vous devez être connecté pour effectuer cette action"Vous devez être connecté pour effectuer cette action"Cette playlist n'existe pas ou a été supprimée"Cette playlist n'existe pas ou a été supprimée"Ce morceau n'existe pas ou n'est pas accessible"Ce morceau n'existe pas ou n'est pas accessible"Cet utilisateur n'existe pas"Cet utilisateur n'existe pas"La ressource demandée est introuvable"La ressource demandée est introuvable"duplicate"duplicate"Cette ressource existe déjà"Cette ressource existe déjà""network"Une erreur réseau s'est produite. Veuillez réessayer dans quelques instants"Une erreur réseau s'est produite. Veuillez réessayer dans quelques instants"failed to"failed to"Une erreur de base de données s'est produite. Veuillez réessayer plus tard"Une erreur de base de données s'est produite. Veuillez réessayer plus tard"Vous avez atteint la limite autorisée. Veuillez supprimer certaines ressources pour continuer"Vous avez atteint la limite autorisée. Veuillez supprimer certaines ressources pour continuer"Une erreur s'est produite lors du traitement de votre demande. Veuillez réessayer"Une erreur s'est produite lors du traitement de votre demande. Veuillez réessayer""temporary" mapPlaylistError mappe les erreurs techniques vers des messages utilisateur clairs T0502: Create Playlist Error Handling Improvements Erreurs de permissions Erreurs de ressources non trouvées Erreurs de conflit Erreurs réseau/base de données Erreurs de quota/limite getPlaylistErrorStatusCode retourne le code de statut HTTP approprié pour une erreur de playlist getPlaylistErrorMessage retourne un message d'erreur utilisateur-friendly pour une erreur de playlist isRetryableError détermine si une erreur peut être retentée Erreurs non retryables Erreurs retryables (réseau, timeout, base de données temporaire) Par défaut, les erreurs 5xx sont retryables/home/senke/git/talas/veza/veza-backend-api/internal/handlers/playlist_export_handler.gouidInterfacehasAccesstrackDataplaylistTrackcurrentUserIDjsonDatacsvBuffercsvData"bytes""encoding/csv"invalid playlist id"invalid playlist id"PlaylistPermissionReadcover_url"cover_url"track_count"track_count"exported_at"exported_at""position"added_at"added_at"  "  "failed to generate JSON export"failed to generate JSON export"playlist_"playlist_""_"20060102"20060102".json".json"application/json"application/json"attachment; filename="attachment; filename=""Position"Track ID"Track ID""Title""Artist""Album"Duration (seconds)"Duration (seconds)""Genre""Year"Added At"Added At"failed to generate CSV export"failed to generate CSV export".csv".csv"text/csv"text/csv" PlaylistExportHandler gère les exports de playlists T0493: Create Playlist Export Feature NewPlaylistExportHandler crée un nouveau handler d'export de playlists ExportPlaylistJSON exporte une playlist au format JSON Vérifier que la playlist existe et que l'utilisateur a accès Vérifier que l'utilisateur a accès (propriétaire, collaborateur ou playlist publique) Vérifier si l'utilisateur est collaborateur Préparer les données d'export Ajouter les tracks avec leurs informations Track est un struct (non-pointer), toujours valide Convertir en JSON Définir les headers pour le téléchargement Changed to playlistID.String() ExportPlaylistCSV exporte une playlist au format CSV Créer le buffer CSV En-têtes Ajouter les tracks Changed to playlistTrack.Track.ID.String() Générer le CSV Écrire toutes les lignes/home/senke/git/talas/veza/veza-backend-api/internal/handlers/playlist_handler.gofollowServicefilterUserIDStrfilterUserIDcollaboratorcollaboratorUserIDcollaboratorsshareLinkduplicateServicenewPlaylistfilterIsPublicisPublicParamlimitParampageParamrecincludeOwnincludeOwnParamminScoreminScoreParamrecommendationServicerecommendations`json:"title" binding:"required,min=1,max=200" validate:"required,min=1,max=200"``json:"description,omitempty"``json:"title,omitempty" binding:"omitempty,min=1,max=200" validate:"omitempty,min=1,max=200"``json:"is_public,omitempty"``json:"track_ids" binding:"required,min=1" validate:"required,min=1"`Failed to create playlist"Failed to create playlist"Failed to get playlists"Failed to get playlists""playlists"ErrPlaylistNotFoundErrAccessDeniedFailed to get playlist"Failed to get playlist"Failed to update playlist"Failed to update playlist"Failed to delete playlist"Failed to delete playlist"playlist deleted"playlist deleted"trackId"trackId"ErrTrackAlreadyInPlaylisttrack already in playlist"track already in playlist"Failed to add track to playlist"Failed to add track to playlist"track added to playlist"track added to playlist"track not in playlist"track not in playlist"Failed to remove track from playlist"Failed to remove track from playlist"track removed from playlist"track removed from playlist"some tracks are not in the playlist"some tracks are not in the playlist"Failed to reorder tracks"Failed to reorder tracks"tracks reordered"tracks reordered"`json:"user_id" binding:"required" validate:"required"``json:"permission" binding:"required,oneof=read write admin" validate:"required,oneof=read write admin"`"write"PlaylistPermissionWritePlaylistPermissionAdmininvalid permission"invalid permission"user is already a collaborator"user is already a collaborator"cannot add playlist owner as collaborator"cannot add playlist owner as collaborator"forbidden: only playlist owner can add collaborators"forbidden: only playlist owner can add collaborators"Failed to add collaborator"Failed to add collaborator""collaborator"userId"userId"collaborator not found"collaborator not found"forbidden: only playlist owner can remove collaborators"forbidden: only playlist owner can remove collaborators"Failed to remove collaborator"Failed to remove collaborator"collaborator removed"collaborator removed"forbidden: only playlist owner can update collaborator permissions"forbidden: only playlist owner can update collaborator permissions"Failed to update collaborator permission"Failed to update collaborator permission"collaborator permission updated"collaborator permission updated"forbidden: access denied"forbidden: access denied"Failed to get collaborators"Failed to get collaborators""collaborators"forbidden: only owner or admin can create share links"forbidden: only owner or admin can create share links"Failed to create share link"Failed to create share link"share_link"share_link"cannot follow own playlist"cannot follow own playlist"Failed to follow playlist"Failed to follow playlist"playlist followed"playlist followed"Failed to unfollow playlist"Failed to unfollow playlist"playlist unfollowed"playlist unfollowed"analytics service not available"analytics service not available"Failed to get playlist stats"Failed to get playlist stats"`json:"new_title"``json:"new_description,omitempty"`PlaylistDuplicateServiceNewPlaylistDuplicateServiceforbidden: you don't have access to this playlist"forbidden: you don't have access to this playlist"Failed to duplicate playlist"Failed to duplicate playlist"playlist duplicated successfully"playlist duplicated successfully"Failed to search playlists"Failed to search playlists"min_score"min_score""0.1"include_own"include_own"PlaylistRecommendationServicePlaylistServiceForRecommendationPlaylistFollowServiceForRecommendationcalculateRecommendationScorecalculateSimilarityScorecalculatePopularityScorecalculateTrackCountScorecalculateRecencyScoreisPlaylistFollowedNewPlaylistRecommendationServiceRecommendationScoreGetRecommendationsParamsMinScoreIncludeOwnFailed to get recommendations"Failed to get recommendations""recommendations" PlaylistHandler gère les opérations sur les playlists NewPlaylistHandler crée un nouveau handler de playlists SetPlaylistAnalyticsService définit le service d'analytics de playlist T0491: Create Playlist Analytics Backend SetPlaylistFollowService définit le service de follow de playlist T0498: Create Playlist Recommendations CreatePlaylistRequest représente la requête pour créer une playlist UpdatePlaylistRequest représente la requête pour mettre à jour une playlist ReorderTracksRequest représente la requête pour réorganiser les tracks Changed to []uuid.UUID CreatePlaylist gère la création d'une playlist @Summary      Create Playlist @Description  Create a new playlist @Tags         Playlist @Param        request body CreatePlaylistRequest true "Playlist Metadata" @Success      201  {object}  APIResponse{data=object{playlist=models.Playlist}} @Failure      400  {object}  APIResponse "Validation Error" @Router       /playlists [post] MOD-P1-001: Utiliser GetUserIDUUID au lieu de c.Get manuel MOD-P1-004: Ajouter timeout context pour opération DB critique GetPlaylists gère la récupération des playlists avec pagination @Summary      Get Playlists @Description  Get a paginated list of playlists @Param        page     query     int     false  "Page number" default(1) @Param        limit    query     int     false  "Items per page" default(20) @Param        user_id  query     string  false  "Filter by User ID" @Success      200  {object}  APIResponse{data=object{playlists=[]models.Playlist,pagination=object}} @Router       /playlists [get] Filtres optionnels Get current user ID MOD-P1-004: Ajouter timeout context pour opération DB GetPlaylist gère la récupération d'une playlist @Summary      Get Playlist by ID @Description  Get detailed information about a playlist @Param        id   path      string  true  "Playlist ID" @Success      200  {object}  APIResponse{data=object{playlist=models.Playlist}} @Failure      400  {object}  APIResponse "Invalid ID" @Failure      404  {object}  APIResponse "Playlist not found" @Router       /playlists/{id} [get] Playlist IDs are uuid.UUID UpdatePlaylist gère la mise à jour d'une playlist @Summary      Update Playlist @Description  Update playlist metadata @Param        id        path      string                 true  "Playlist ID" @Param        playlist  body      UpdatePlaylistRequest  true  "Playlist Metadata" @Failure      403  {object}  APIResponse "Forbidden" @Router       /playlists/{id} [put] DeletePlaylist gère la suppression d'une playlist @Summary      Delete Playlist @Description  Permanently delete a playlist @Success      200  {object}  APIResponse{data=object{message=string}} @Router       /playlists/{id} [delete] AddTrack gère l'ajout d'un track à une playlist @Summary      Add Track to Playlist @Description  Add a track to the playlist @Param        id       path      string  true  "Playlist ID" @Param        trackId  body      object{track_id=string} true  "Track ID (in body)" @Failure      400  {object}  APIResponse "Track already present or invalid ID" @Failure      404  {object}  APIResponse "Playlist or Track not found" @Router       /playlists/{id}/tracks [post] Track IDs are uuid.UUID RemoveTrack gère la suppression d'un track d'une playlist @Summary      Remove Track from Playlist @Description  Remove a track from the playlist @Param        trackId  path      string  true  "Track ID" @Router       /playlists/{id}/tracks/{trackId} [delete] ReorderTracks gère la réorganisation des tracks d'une playlist @Summary      Reorder Tracks @Description  Reorder tracks in the playlist @Param        id       path      string                true  "Playlist ID" @Param        order    body      ReorderTracksRequest  true  "New Track Order" @Router       /playlists/{id}/tracks/reorder [put] AddCollaboratorRequest représente la requête pour ajouter un collaborateur UpdateCollaboratorPermissionRequest représente la requête pour mettre à jour la permission d'un collaborateur AddCollaborator gère l'ajout d'un collaborateur à une playlist T0479: POST /api/v1/playlists/:id/collaborators Convertir la permission string en PlaylistPermission RemoveCollaborator gère la suppression d'un collaborateur d'une playlist T0479: DELETE /api/v1/playlists/:id/collaborators/:userId User IDs are UUID UpdateCollaboratorPermission gère la mise à jour de la permission d'un collaborateur T0479: PUT /api/v1/playlists/:id/collaborators/:userId GetCollaborators gère la récupération des collaborateurs d'une playlist T0479: GET /api/v1/playlists/:id/collaborators CreateShareLink gère la création d'un lien de partage public pour une playlist T0488: Create Playlist Public Share Link Créer le lien de partage via le service La vérification des permissions (owner ou admin) est faite dans PlaylistService.CreateShareLink FollowPlaylist gère le follow d'une playlist T0489: Create Playlist Follow Feature UnfollowPlaylist gère l'unfollow d'une playlist GetPlaylistStats gère la récupération des statistiques d'une playlist Use uuid.Nil for comparison if userID is nil Récupérer les statistiques via le service d'analytics DuplicatePlaylistRequest représente la requête pour dupliquer une playlist DuplicatePlaylist gère la duplication d'une playlist T0495: Create Playlist Duplicate Feature Créer le service de duplication Dupliquer la playlist SearchPlaylists gère la recherche de playlists T0496: Create Playlist Search Backend Récupérer les paramètres de recherche Rechercher les playlists GetRecommendations gère la récupération des recommandations de playlists Parser les paramètres de requête Créer le service de recommandations Le service utilisera les services injectés via les interfaces logger Obtenir les recommandations Formater la réponse/home/senke/git/talas/veza/veza-backend-api/internal/handlers/profile_handler.goreqUUIDreqIDrequesterIDcompletioncanChangeagebirthdateminAgebirthdateStrserviceReqchar"profile"username required"username required"cannot access other user's profile completion"cannot access other user's profile completion"failed to calculate profile completion"failed to calculate profile completion"`json:"first_name" binding:"omitempty,max=100" validate:"omitempty,max=100"``json:"last_name" binding:"omitempty,max=100" validate:"omitempty,max=100"``json:"username" binding:"omitempty,min=3,max=30" validate:"omitempty,min=3,max=30,username"``json:"bio" binding:"omitempty,max=500" validate:"omitempty,max=500"``json:"location" binding:"omitempty,max=100" validate:"omitempty,max=100"``json:"birthdate" binding:"omitempty,datetime=2006-01-02" validate:"omitempty,datetime=2006-01-02"``json:"gender" binding:"omitempty,oneof=Male Female Other 'Prefer not to say'" validate:"omitempty,oneof=Male Female Other 'Prefer not to say'"`cannot update other user's profile"cannot update other user's profile"username must be 3-30 characters, alphanumeric and underscore only"username must be 3-30 characters, alphanumeric and underscore only"failed to check username change eligibility"failed to check username change eligibility"username can only be changed once per month"username can only be changed once per month"invalid birthdate format, expected YYYY-MM-DD"invalid birthdate format, expected YYYY-MM-DD"4745113880409968000000000000user must be at least 13 years old"user must be at least 13 years old"failed to update profile"failed to update profile"'a''z'122'A''Z''0''9''_'95 ProfileHandler handles profile-related operations NewProfileHandler creates a new ProfileHandler instance GetProfile retrieves a public user profile by ID @Summary      Get Profile by ID @Description  Get public profile information for a user @Tags         User @Param        id   path      string  true  "User ID" @Success      200  {object}  handlers.APIResponse{data=object{profile=object}} @Failure      400  {object}  handlers.APIResponse "Invalid ID" @Failure      404  {object}  handlers.APIResponse "User not found" @Router       /users/{id} [get] Get the requesting user ID if authenticated (optional) Get user profile with privacy check GetProfileByUsername retrieves a public profile by username @Summary      Get Profile by Username @Description  Get public profile information for a user by username @Param        username path string true "Username" @Failure      400  {object}  handlers.APIResponse "Missing username" @Router       /users/by-username/{username} [get] Get profile with privacy check GetProfileCompletion retrieves the profile completion status T0220: Returns percentage and missing fields @Summary      Get Profile Completion @Description  Get profile completion percentage and missing fields @Success      200  {object}  handlers.APIResponse{data=object} @Failure      403  {object}  handlers.APIResponse "Forbidden" @Router       /users/{id}/completion [get] Get authenticated user ID Verify that user_id corresponds to authenticated user Calculate profile completion UpdateProfileRequest represents the request body for updating a user profile UpdateProfile updates a user profile @Summary      Update Profile @Description  Update user profile details @Param        id      path      string                true  "User ID" @Param        profile body      UpdateProfileRequest  true  "Profile Data" @Success      200     {object}  handlers.APIResponse{data=object{profile=object}} @Failure      400     {object}  handlers.APIResponse "Validation Error" @Failure      401     {object}  handlers.APIResponse "Unauthorized" @Failure      403     {object}  handlers.APIResponse "Forbidden" @Router       /users/{id} [put] MOD-P1-003: Verify that user_id corresponds to authenticated user or user is admin Validate username if provided Validate username format (alphanumeric + underscore, 3-30 chars) Validate username uniqueness if modified Check if username can be modified (once per month) Validate birthdate if provided Check if user is at least 13 years old 13 years Convert UpdateProfileRequest to types.UpdateProfileRequest Update profile using the new UpdateProfile method isValidUsername validates username format (alphanumeric + underscore, 3-30 chars)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/response.go APIResponse is the unified response envelope for all API responses. RespondSuccess sends a success response with the standard envelope. If data is nil, the "data" field will be omitted (or null depending on helper, here omitempty)./home/senke/git/talas/veza/veza-backend-api/internal/handlers/role_handler.goroleIDStrassignedByassignedByInterfaceinvalid role id"invalid role id"role not found"role not found"role not found or is system role"role not found or is system role"role updated"role updated"cannot delete system role"cannot delete system role"role deleted"role deleted"invalid user id type"invalid user id type"role assigned"role assigned"roleId"roleId"role assignment not found"role assignment not found"role revoked"role revoked" RoleHandler gère les endpoints de gestion des rôles NewRoleHandler crée un nouveau RoleHandler GetRoles récupère tous les rôles GetRole récupère un rôle par ID CreateRole crée un nouveau rôle UpdateRole met à jour un rôle DeleteRole supprime un rôle AssignRole assigne un rôle à un utilisateur Récupérer l'ID de l'utilisateur qui assigne depuis le contexte RevokeRole révoque un rôle d'un utilisateur GetUserRoles récupère tous les rôles d'un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/handlers/room_handler.goroomIDStrconversationIDconversationIDStroffsetIntfailed to create room"failed to create room"room_name"room_name"Failed to create conversation"Failed to create conversation"room created successfully"room created successfully"room_id"room_id"failed to get user rooms"failed to get user rooms"Failed to fetch conversations"Failed to fetch conversations""conversations"Invalid room ID"Invalid room ID"ErrRoomNotFoundConversation not found"Conversation not found"failed to get room"failed to get room"Failed to get conversation"Failed to get conversation"`json:"user_id" binding:"required"`failed to add member to room"failed to add member to room"Failed to add member"Failed to add member"member added to room"member added to room"Member added successfully"Member added successfully"Invalid conversation ID"Invalid conversation ID""50"failed to get room history"failed to get room history"conversation_id"conversation_id"Failed to get conversation history"Failed to get conversation history" RoomServiceInterface defines the interface for room service operations RoomHandler gère les opérations sur les rooms (conversations) NewRoomHandler crée une nouvelle instance de RoomHandler CreateRoom gère la création d'une nouvelle room POST /api/v1/conversations Récupérer l'ID utilisateur du contexte Convertir userID en uuid.UUID Parser la requête Valider le type de room si non spécifié Créer la room GetUserRooms récupère toutes les rooms d'un utilisateur GET /api/v1/conversations Récupérer les rooms GetRoom récupère une room par son ID GET /api/v1/conversations/:id Récupérer l'ID de la room depuis l'URL Récupérer la room AddMemberRequest représente une requête pour ajouter un membre à une room AddMember ajoute un membre à une room POST /api/v1/conversations/:id/members Ajouter le membre GetRoomHistory récupère l'historique des messages d'une room GET /api/v1/conversations/:id/history/home/senke/git/talas/veza/veza-backend-api/internal/handlers/search_handlers.goSearch query is required"Search query is required" Search performs a full-text search across tracks, users, and playlists/home/senke/git/talas/veza/veza-backend-api/internal/handlers/session.gotokenPartsrevokedCountsessionDatasessionListsessionFoundsessionIDStrtargetSessionnewExpiresInInvalid user ID format"Invalid user ID format"Authorization header required"Authorization header required" " "Bearer"Bearer"Invalid Authorization header format"Invalid Authorization header format"Failed to revoke session"Failed to revoke session"Failed to logout"Failed to logout"User logged out"User logged out"Failed to revoke all user sessions"Failed to revoke all user sessions"Failed to logout all sessions"Failed to logout all sessions"All user sessions revoked"All user sessions revoked"sessions_revoked"sessions_revoked"All sessions logged out successfully"All sessions logged out successfully"Failed to get user sessions"Failed to get user sessions"Failed to get sessions"Failed to get sessions"expires_at"expires_at"is_current"is_current""sessions"session_id"session_id"Invalid session ID"Invalid session ID"Session not found"Session not found"Session revoked"Session revoked"Session revoked successfully"Session revoked successfully"Failed to get session stats"Failed to get session stats"86400000000000Failed to refresh session"Failed to refresh session"Session refreshed"Session refreshed"Session refreshed successfully"Session refreshed successfully"expires_in"expires_in" SessionHandler gère les opérations sur les sessions NewSessionHandler crée un nouveau handler de session Logout gère la déconnexion d'un utilisateur Récupérer le token depuis le header Authorization Extraire le token Révoquer la session LogoutAll gère la déconnexion de toutes les sessions d'un utilisateur Révoquer toutes les sessions GetSessions récupère toutes les sessions actives d'un utilisateur Récupérer les sessions Formater les sessions pour la réponse TODO: Déterminer si c'est la session actuelle RevokeSession révoque une session spécifique Récupérer l'ID de session depuis les paramètres (UUID) Récupérer les sessions de l'utilisateur pour vérifier la propriété Vérifier que la session appartient à l'utilisateur Revoke by Hash using DeleteSession GetSessionStats récupère les statistiques des sessions RefreshSession rafraîchit une session Rafraîchir la session 24 heures/home/senke/git/talas/veza/veza-backend-api/internal/handlers/settings_handler.gosettingsprefsvalidLanguages`json:"email_notifications"``json:"push_notifications"``json:"browser_notifications"``json:"email_on_follow"``json:"email_on_like"``json:"email_on_comment"``json:"email_on_message"``json:"email_on_mention"``json:"email_marketing"``json:"allow_search_indexing"``json:"explicit_content"``json:"autoplay"`failed to get settings"failed to get settings"failed to update settings"failed to update settings"settings updated"settings updated""fr""es""de""it"pt"pt""ru"ja"ja"zh"zh"ko"ko"invalid language code: %s"invalid language code: %s"LoadLocationinvalid timezone: %s"invalid timezone: %s" SettingsHandler handles settings-related operations NewSettingsHandler creates a new SettingsHandler instance UserSettingsResponse represents the response structure for user settings NotificationSettings represents notification preferences PrivacySettings represents privacy preferences ContentSettings represents content preferences PreferenceSettings represents user preferences ISO 639-1 light, dark, auto GetSettings retrieves user settings T0231: Utilise l'utilisateur authentifié depuis le contexte (route /users/settings sans :id) Récupérer l'ID utilisateur depuis le contexte d'authentification UpdateSettings updates user settings T0232: Utilise l'utilisateur authentifié depuis le contexte (route /users/settings sans :id) Valider preferences si fournies Mettre à jour settings validatePreferences validates preference settings Valider language (ISO 639-1) Valider timezone (IANA timezone)/home/senke/git/talas/veza/veza-backend-api/internal/handlers/social.goveza-backend-api/internal/core/social"veza-backend-api/internal/core/social"`json:"attachments"``json:"target_id" binding:"required,uuid"``json:"target_type" binding:"required,oneof=post track playlist"`Invalid target_id format"Invalid target_id format"Failed to toggle like"Failed to toggle like""liked"`json:"content" binding:"required,min=1,max=2000"`Failed to add comment"Failed to add comment"Failed to get feed"Failed to get feed" SocialHandler gère les opérations sociales NewSocialHandler crée une nouvelle instance de SocialHandler CreatePostRequest DTO pour la création de post track_id, playlist_id (UUID strings) CreatePost crée un post GO-013: Utilise validator centralisé pour validation améliorée P0: JSON Hardening - Utilise BindAndValidateJSON pour une gestion robuste des erreurs ToggleLikeRequest DTO pour liker ToggleLike like ou unlike un objet UUID validation déjà fait par binding tag, mais on garde le parse pour compatibilité AddCommentRequest DTO pour commenter GetFeed récupère le feed global/home/senke/git/talas/veza/veza-backend-api/internal/handlers/status_handler.gochatInfostreamInfodbInfoglobalStatusredisInfolatencyMsrespmonitoring"runtime"veza-backend-api/internal/monitoring"veza-backend-api/internal/monitoring"`json:"uptime_seconds"``json:"services"``json:"version"``json:"git_commit"``json:"build_time"``json:"environment,omitempty"``json:"latency_ms,omitempty"`chat_server"chat_server"stream_server"stream_server"RecordHealthCheck400000000'/'47health"health"NewRequestWithContext"GET"chat server returned non-200 status"chat server returned non-200 status"stream server returned non-200 status"stream server returned non-200 status"ReadMemStatsuptime_seconds"uptime_seconds"memory"memory"alloc_mb"alloc_mb"total_alloc_mb"total_alloc_mb"sys_mb"sys_mb"num_gc"num_gc""goroutines"NumGoroutine startTime tracks when the server started StatusResponse représente la réponse complète du status endpoint ServiceInfo représente l'état d'un service StatusHandler gère les endpoints de status NewStatusHandler crée un nouveau handler de status GetStatus retourne le status complet de l'application Check chat server (if configured) Check stream server (if configured) checkDatabase vérifie la connexion à la base de données checkChatServer vérifie la disponibilité du chat server checkStreamServer vérifie la disponibilité du stream server GetSystemInfo retourne des informations système (pour debug) Utiliser la fonction bToMb définie dans system_metrics.go/home/senke/git/talas/veza/veza-backend-api/internal/handlers/system_metrics.gocpu_count"cpu_count"NumCPU SystemMetrics retourne les métriques système (CPU, mémoire, goroutines) Endpoint: GET /system/metrics Retourne un JSON avec les métriques système pour le monitoring bToMb convertit des bytes en megabytes/home/senke/git/talas/veza/veza-backend-api/internal/handlers/upload.gouploadIDStrsupportedTypeisSupportedsupportedTypesmaxFiles`form:"track_id" binding:"required"``form:"file_type" binding:"required,oneof=audio image video"``form:"title" binding:"required,min=1,max=255"``form:"artist" binding:"required,min=1,max=255"``form:"duration" binding:"min=0"``form:"metadata"``json:"file_name"``json:"file_size"``json:"file_type"``json:"checksum"`No file provided"No file provided"Upload rejected: ClamAV unavailable"Upload rejected: ClamAV unavailable"file_name"file_name"File validation failed"File validation failed"Invalid file uploaded"Invalid file uploaded"Upload rejected: ClamAV scan error"Upload rejected: ClamAV scan error"Failed to log upload audit"Failed to log upload audit"File uploaded successfully"File uploaded successfully"file_type"file_type"uploaded"uploaded"Invalid upload ID"Invalid upload ID"upload"upload"Failed to log deletion audit"Failed to log deletion audit"Upload deleted"Upload deleted"Upload deleted successfully"Upload deleted successfully"total_uploads"total_uploads"audio_files"audio_files"image_files"image_files"video_files"video_files"File type parameter required"File type parameter required""image"video"video"Unsupported file type"Unsupported file type"supported_types"supported_types""supported"100MB"100MB"max_size_bytes"max_size_bytes"allowed_types"allowed_types"audio/mp3"audio/mp3"audio/m4a"audio/m4a"10MB"10MB"image/jpeg"image/jpeg"image/png"image/png"image/gif"image/gif"image/webp"image/webp"image/svg+xml"image/svg+xml"500MB"500MB"512000524288000video/mp4"video/mp4"video/webm"video/webm"video/ogg"video/ogg"video/avi"video/avi""limits"bytes_uploaded"bytes_uploaded"total_bytes"total_bytes"estimated_time_remaining"estimated_time_remaining"Invalid multipart form"Invalid multipart form"No files provided"No files provided"Too many files. Maximum %d files per batch"Too many files. Maximum %d files per batch"File %d (%s): Unknown file type"File %d (%s): Unknown file type"File %d (%s): Virus scanning service unavailable"File %d (%s): Virus scanning service unavailable"File %d (%s): Validation error"File %d (%s): Validation error"File %d (%s): %s"File %d (%s): %s""index""checksum"validated"validated"Batch upload processed"Batch upload processed"total_files"total_files"successful"successful""results" UploadRequest requête pour upload de fichier UploadResponse réponse pour upload UploadHandler gère les uploads de fichiers NewUploadHandler crée un nouveau handler d'upload UploadFile gère l'upload d'un fichier Parser la requête multipart Récupérer le fichier MOD-P1-001: Valider le fichier AVANT toute persistance (scan ClamAV inclus) MOD-P1-001-REFINEMENT: Détecter erreur ClamAV unavailable et retourner 503 Vérifier si le fichier est valide MOD-P1-001: Détecter virus détecté (code 422) vs autres erreurs MOD-P1-001: Détecter erreur de scan ClamAV (timeout, connexion, etc.) Créer l'enregistrement en base de données Note: Dans un vrai environnement, il faudrait sauvegarder le fichier et créer l'enregistrement dans la table tracks Log l'upload dans l'audit Ne pas faire échouer l'upload pour une erreur d'audit Retourner la réponse GetUploadStatus récupère le statut d'un upload Récupérer le statut depuis la base de données Note: Dans un vrai environnement, il faudrait interroger la DB DeleteUpload supprime un upload Log la suppression dans l'audit GetUploadStats récupère les statistiques d'upload Récupérer les statistiques depuis la base de données ValidateFileType valide le type de fichier Vérifier si le type est supporté GetUploadLimits récupère les limites d'upload UploadProgress gère le suivi de progression d'upload Récupérer la progression depuis la base de données BatchUpload gère les uploads multiples Parser le formulaire multipart Limiter le nombre de fichiers par batch Déterminer le type de fichier à partir de l'extension MOD-P1-001: Valider le fichier AVANT toute persistance MOD-P1-001-REFINEMENT: Détecter erreur ClamAV unavailable Créer le résultat/home/senke/git/talas/veza/veza-backend-api/internal/handlers/webhook_handlers.gowebhookwebhookIDwebhookIDStrjson:"url" binding:"required,url"json:"events" binding:"required,min=1"`json:"url" binding:"required,url"``json:"events" binding:"required,min=1"`Failed to register webhook"Failed to register webhook"Failed to list webhooks"Failed to list webhooks"Invalid webhook ID"Invalid webhook ID"Webhook not found"Webhook not found"Webhook deleted successfully"Webhook deleted successfully"This is a test webhook from Veza"This is a test webhook from Veza"test_id"test_id"Test webhook queued"Test webhook queued"webhook_id"webhook_id"Webhook test queued for %s"Webhook test queued for %s" WebhookHandler gère les handlers de webhooks NewWebhookHandler crée un nouveau handler de webhooks RegisterWebhook gère l'enregistrement d'un webhook Récupérer l'ID utilisateur ListWebhooks liste les webhooks d'un utilisateur DeleteWebhook supprime un webhook GetWebhookStats retourne les statistiques des webhooks TestWebhook teste un webhook/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/eventbus/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/eventbus/rabbitmq.goNewRabbitMQClientRabbitMQClientPublishEventEventTypejson:"event_type"AggregateIDjson:"aggregate_id"AggregateTypejson:"aggregate_type"`json:"event_id"``json:"event_type"``json:"aggregate_id"``json:"aggregate_type"``json:"metadata"`failed to connect to RabbitMQ: %w"failed to connect to RabbitMQ: %w"failed to open channel: %w"failed to open channel: %w"topic"topic"failed to declare exchange: %w"failed to declare exchange: %w"RabbitMQ client initialized"RabbitMQ client initialized"failed to marshal event: %w"failed to marshal event: %w"Failed to publish event"Failed to publish event"event_type"event_type"event_id"event_id"failed to publish event: %w"failed to publish event: %w"Event published"Event published"aggregate_id"aggregate_id"RabbitMQ client closed"RabbitMQ client closed"RabbitMQ connection is closed"RabbitMQ connection is closed" Event représente un événement métier dans le système Suit le pattern défini dans ORIGIN_MASTER_ARCHITECTURE.md format: {domain}.{entity}.{action}.{version} RabbitMQClient gère la connexion et publication d'événements vers RabbitMQ Implémentation minimale alignée avec ORIGIN pour Phase 1 NewRabbitMQClient crée un nouveau client RabbitMQ url format: amqp://user:pass@host:5672/ Déclarer l'exchange (topic type pour routing flexible) name type durable auto-deleted internal no-wait arguments PublishEvent publie un événement sur RabbitMQ routingKey format: {domain}.{entity}.{action} (ex: "auth.user.registered") exchange routing key mandatory immediate messages persistent Close ferme proprement la connexion RabbitMQ HealthCheck vérifie si la connexion RabbitMQ est active/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/events/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/events/eventbus.goEventBusNewRedisEventBusRedisEventBusfailed to marshal payload: %w"failed to marshal payload: %w"Subscribed to topic"Subscribed to topic"Error handling event"Error handling event" EventBus définit l'interface pour le système d'événements RedisEventBus implémente EventBus avec Redis Pub/Sub NewRedisEventBus crée une nouvelle instance de RedisEventBus Publish publie un événement sur un topic Subscribe souscrit à un topic et exécute le handler pour chaque message Note: Cette méthode est bloquante ou doit être lancée dans une goroutine/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/ssl/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/ssl/certificate_manager.goCertStatusErrorCertStatusExpiredCertStatusExpiringCertStatusRenewingCertStatusRevokedCertStatusRevokingCertStatusValidCertificateConfigCertificateManagerCertificateMonitorCertificateProviderCertificateStatusDomainConfigLetsEncryptConfigLetsEncryptProviderNewCertificateManagerNewLetsEncryptProviderNewSelfSignedProviderRenewalSchedulerSelfSignedConfigSelfSignedProvidercontactyaml:"domain"yaml:"aliases"CertificatePathyaml:"certificate_path"PrivateKeyPathyaml:"private_key_path"AutoRenewyaml:"auto_renew"yaml:"provider"yaml:"contact"yaml:"enabled"AutoRenewalyaml:"auto_renewal"RenewalThresholdyaml:"renewal_threshold"CheckIntervalyaml:"check_interval"yaml:"email_notifications"SlackNotificationsyaml:"slack_notifications"StoreTypeyaml:"store_type"StorePathyaml:"store_path"BackupEnabledyaml:"backup_enabled"BackupPathyaml:"backup_path"Domainsyaml:"domains"json:"domain"json:"aliases"json:"provider"PEMDataKeyDataLastCheckedjson:"last_checked"json:"auto_renew"json:"contact"GenerateCertificateGetCertificateInfoRenewCertificateRevokeCertificateValidateCertificatemonitormonitorCertificatescheckCertificateHealthvalidateCertificaterenewalQueueScheduleRenewalprocessRenewalsrenewCertificatecertStoreRequestCertificateListCertificatesGetCertificateStatusCheckCertificateExpiryinitializeProvidersloadExistingCertificatesloadCertificateFromFilesaveCertificategetProviderstartPeriodicChecksperformPeriodicChecktimeUntilExpiryexpiringCertsletsEncryptProviderselfSignedProviderdomainConfigproviderNamecerts"crypto/x509"`yaml:"enabled"``yaml:"auto_renewal"``yaml:"renewal_threshold"``yaml:"check_interval"``yaml:"provider"``yaml:"email_notifications"``yaml:"slack_notifications"``yaml:"store_type"``yaml:"store_path"``yaml:"backup_enabled"``yaml:"backup_path"``yaml:"domains"``yaml:"domain"``yaml:"aliases"``yaml:"certificate_path"``yaml:"private_key_path"``yaml:"auto_renew"``yaml:"contact"``json:"domain"``json:"aliases"``json:"provider"``json:"-"``json:"last_checked"``json:"auto_renew"``json:"contact"`"valid"expiring"expiring"revoking"revoking"revoked"revoked"renewing"renewing"Initializing Certificate Manager"Initializing Certificate Manager"failed to initialize providers: %w"failed to initialize providers: %w"failed to load existing certificates: %w"failed to load existing certificates: %w"Certificate Manager initialized successfully"Certificate Manager initialized successfully"Starting Certificate Manager"Starting Certificate Manager"Certificate Manager started successfully"Certificate Manager started successfully"Stopping Certificate Manager"Stopping Certificate Manager"Certificate Manager stopped"Certificate Manager stopped"certificate not found for domain: %s"certificate not found for domain: %s"Requesting certificate"Requesting certificate""domain"Certificate already exists and is valid"Certificate already exists and is valid"failed to get provider: %w"failed to get provider: %w"failed to generate certificate: %w"failed to generate certificate: %w"Failed to save certificate"Failed to save certificate"Certificate generated successfully"Certificate generated successfully"Renewing certificate"Renewing certificate"failed to renew certificate: %w"failed to renew certificate: %w"Failed to save renewed certificate"Failed to save renewed certificate"Certificate renewed successfully"Certificate renewed successfully"Revoking certificate"Revoking certificate"failed to revoke certificate: %w"failed to revoke certificate: %w"Certificate revoked successfully"Certificate revoked successfully"yaml:"endpoint"yaml:"email"yaml:"key_size"lepletsencrypt"letsencrypt"ValidDurationyaml:"valid_duration"yaml:"organization"yaml:"country"sspself-signed"self-signed"Failed to load certificate from file"Failed to load certificate from file"-1Certificate saved"Certificate saved"provider not found: %s"provider not found: %s"Performing periodic certificate check"Performing periodic certificate check"Failed to check certificate expiry"Failed to check certificate expiry"Starting Certificate Monitor"Starting Certificate Monitor"Certificate Monitor stopped"Certificate Monitor stopped"Checking certificate health"Checking certificate health"Certificate validation failed"Certificate validation failed"certificate is not valid for current time"certificate is not valid for current time"Starting Renewal Scheduler"Starting Renewal Scheduler"Renewal Scheduler stopped"Renewal Scheduler stopped"Certificate renewal scheduled"Certificate renewal scheduled"Renewal queue is full"Renewal queue is full"Processing certificate renewal"Processing certificate renewal"Failed to renew certificate"Failed to renew certificate" CertificateManager gère les certificats SSL automatiquement CertificateConfig configuration des certificats 6 heures par défaut "letsencrypt", "self-signed", "manual" "filesystem", "kubernetes", "vault" DomainConfig configuration par domaine Certificate représente un certificat SSL CertificateStatus statut du certificat CertificateProvider interface pour les fournisseurs de certificats CertificateMonitor surveille l'état des certificats RenewalScheduler planifie les renouvellements NewCertificateManager crée un nouveau gestionnaire de certificats Initialiser le monitor Initialiser le scheduler Initialize initialise le gestionnaire de certificats Initialiser les providers Charger les certificats existants Start démarre le gestionnaire de certificats Démarrer le monitor Démarrer le scheduler Démarrer le monitoring périodique Stop arrête le gestionnaire de certificats Arrêter les composants GetCertificate récupère un certificat par domaine RequestCertificate demande un nouveau certificat Vérifier si le certificat existe déjà Obtenir le provider Générer le certificat Stocker le certificat Sauvegarder sur disque RenewCertificate renouvelle un certificat Marquer comme en cours de renouvellement Renouveler le certificat Remplacer le certificat RevokeCertificate révoque un certificat Révoquer le certificat Marquer comme révoqué ListCertificates liste tous les certificats GetCertificateStatus retourne le statut d'un certificat CheckCertificateExpiry vérifie l'expiration des certificats Mettre à jour le statut Méthodes privées Initialiser le provider Let's Encrypt Initialiser le provider self-signed Charger les certificats depuis le store configuré Implémentation simplifiée Implémentation simplifiée - charger depuis fichier 1 mois avant 2 mois après Sauvegarder le certificat selon la configuration Vérifier l'expiration des certificats Planifier le renouvellement des certificats expirants CertificateMonitor methods Vérifier la validité du certificat Validation basique du certificat RenewalScheduler methods/home/senke/git/talas/veza/veza-backend-api/internal/infrastructure/ssl/providers.gocertDERx509Certbig"crypto/rand""crypto/rsa""crypto/x509/pkix"math/big"math/big"`yaml:"endpoint"``yaml:"email"``yaml:"key_size"``yaml:"valid_duration"``yaml:"organization"``yaml:"country"`https://acme-v02.api.letsencrypt.org/directory"https://acme-v02.api.letsencrypt.org/directory"876031536000000000000Veza Platform"Veza Platform"US"US"Generating Let's Encrypt certificate"Generating Let's Encrypt certificate"le_%s_%d"le_%s_%d""issuer"Let's Encrypt Authority X3"Let's Encrypt Authority X3"key_size"key_size"Let's Encrypt certificate generated"Let's Encrypt certificate generated"Renewing Let's Encrypt certificate"Renewing Let's Encrypt certificate"renewed_from"renewed_from"Let's Encrypt certificate renewed"Let's Encrypt certificate renewed"Revoking Let's Encrypt certificate"Revoking Let's Encrypt certificate"Let's Encrypt certificate revoked"Let's Encrypt certificate revoked"certificate is not from Let's Encrypt"certificate is not from Let's Encrypt"certificate has expired"certificate has expired"certificate info not available"certificate info not available"Generating self-signed certificate"Generating self-signed certificate"failed to generate private key: %w"failed to generate private key: %w"failed to create certificate: %w"failed to create certificate: %w"failed to parse certificate: %w"failed to parse certificate: %w"ss_%s_%d"ss_%s_%d"Self-Signed"Self-Signed"algorithm"algorithm""RSA"self_signed"self_signed"Self-signed certificate generated"Self-signed certificate generated"Renewing self-signed certificate"Renewing self-signed certificate"Revoking self-signed certificate"Revoking self-signed certificate"Self-signed certificate revoked"Self-signed certificate revoked"certificate is not self-signed"certificate is not self-signed"certificate info not available for self-signed"certificate info not available for self-signed" LetsEncryptProvider provider pour Let's Encrypt LetsEncryptConfig configuration Let's Encrypt SelfSignedProvider provider pour certificats auto-signés SelfSignedConfig configuration auto-signés NewLetsEncryptProvider crée un nouveau provider Let's Encrypt NewSelfSignedProvider crée un nouveau provider auto-signé 1 an LetsEncryptProvider implementation Simulation de génération avec Let's Encrypt En production, utiliser une librairie comme golang.org/x/crypto/acme Let's Encrypt: 90 jours Simulation de renouvellement 90 jours Simulation de révocation En production, utiliser l'API ACME pour révoquer Simulation de récupération d'info SelfSignedProvider implementation Générer une clé privée Créer le template de certificat Parser le certificat Auto-renew désactivé par défaut pour auto-signé Pour auto-signé, on génère un nouveau certificat Pour auto-signé, pas de révocation réelle nécessaire Juste marquer comme révoqué/home/senke/git/talas/veza/veza-backend-api/internal/interfaces/home/senke/git/talas/veza/veza-backend-api/internal/interfaces/interfaces.goAuditLogRepositoryAuthResultConfigurationServiceConversationConversationRepositoryConversationServiceCreateConversationRequestDatabaseServiceDownloadFileResponseFileMetadataFileServiceListConversationsRequestListConversationsResponseListMessagesRequestListMessagesResponseListTracksRequestListTracksResponseListUsersRequestListUsersResponseLoggerServiceMessageRepositoryMessageServiceMetricsServiceMigrationStatusRedisServiceRepositorySearchTracksRequestSearchTracksResponseSendMessageRequestSessionRepositoryTokenClaimsTrackRepositoryUpdateConversationRequestUpdateMessageRequestUploadFileRequestUploadFileResponseUploadTrackRequestconversationolderThanoldPasswordfileDatadestresetTokenverificationTokenfileIDexpirationmembersGetByConversationAddParticipantGetByUserRemoveParticipantGetByGenreGetPopularDeleteByUserDeleteExpiredGetByTokenDeleteOldGetByActionGetByDateRangejson:"password"ConfirmPasswordResetjson:"messages"Conversationsjson:"conversations"GetParticipantsGetStreamURLUploadClearByPrefixDecrementSendEmailVerificationSendNotificationEmailSendPasswordChangedEmailSendWelcomeEmailMimeTypejson:"mime_type"json:"file_id"GenerateThumbnailGetMetadataScanForVirusesSendInAppNotificationSendPushNotificationIncrementCounterIncrementCounterByObserveHistogramObserveSummarySetGaugeAppliedjson:"applied"AppliedAtjson:"applied_at"CommitTxGetConnectionGetMigrationStatusRollbackTxGetClient Repository définit l'interface commune pour tous les repositories Méthodes communes à tous les repositories UserRepository définit l'interface pour les opérations utilisateur MessageRepository définit l'interface pour les opérations de messages ConversationRepository définit l'interface pour les opérations de conversations TrackRepository définit l'interface pour les opérations de tracks SessionRepository définit l'interface pour les opérations de sessions AuditLogRepository définit l'interface pour les logs d'audit Service définit l'interface commune pour tous les services Méthodes communes à tous les services AuthService définit l'interface pour les services d'authentification UserService définit l'interface pour les services utilisateur MessageService définit l'interface pour les services de messages ConversationService définit l'interface pour les services de conversations TrackService définit l'interface pour les services de tracks CacheService définit l'interface pour les services de cache LoggerService définit l'interface pour les services de logging EmailService définit l'interface pour les services d'email FileService définit l'interface pour les services de fichiers NotificationService définit l'interface pour les services de notifications MetricsService définit l'interface pour les services de métriques ConfigurationService définit l'interface pour les services de configuration DatabaseService définit l'interface pour les services de base de données Retourne la connexion spécifique (GORM, SQLx, etc.) Méthodes pour les migrations RedisService définit l'interface pour les services Redis Méthodes de base Méthodes pour les listes Méthodes pour les sets Méthodes pour les hashs/home/senke/git/talas/veza/veza-backend-api/internal/interfaces/types.go`json:"conversation_id"``json:"action"``json:"resource"``json:"password"``json:"offset"``json:"users"``json:"bio"``json:"messages"``json:"conversations"``json:"file"``json:"tracks"``json:"query"``json:"filename"``json:"file_id"``json:"size"``json:"mime_type"``json:"read"``json:"applied"``json:"applied_at"` Types de base pour les interfaces User représente un utilisateur Message représente un message Conversation représente une conversation Track représente une track audio Session représente une session utilisateur AuditLog représente un log d'audit Types de requêtes AuthResult représente le résultat d'une authentification RegisterRequest représente une requête d'inscription TokenClaims représente les claims d'un token JWT CreateUserRequest représente une requête de création d'utilisateur UpdateUserRequest représente une requête de mise à jour d'utilisateur ListUsersRequest représente une requête de liste d'utilisateurs ListUsersResponse représente une réponse de liste d'utilisateurs UpdateProfileRequest représente une requête de mise à jour de profil SendMessageRequest représente une requête d'envoi de message ListMessagesRequest représente une requête de liste de messages ListMessagesResponse représente une réponse de liste de messages UpdateMessageRequest représente une requête de mise à jour de message CreateConversationRequest représente une requête de création de conversation ListConversationsRequest représente une requête de liste de conversations ListConversationsResponse représente une réponse de liste de conversations UpdateConversationRequest représente une requête de mise à jour de conversation UploadTrackRequest représente une requête d'upload de track ListTracksRequest représente une requête de liste de tracks ListTracksResponse représente une réponse de liste de tracks UpdateTrackRequest représente une requête de mise à jour de track SearchTracksRequest représente une requête de recherche de tracks SearchTracksResponse représente une réponse de recherche de tracks UploadFileRequest représente une requête d'upload de fichier UploadFileResponse représente une réponse d'upload de fichier DownloadFileResponse représente une réponse de téléchargement de fichier FileMetadata représente les métadonnées d'un fichier Notification représente une notification MigrationStatus représente le statut d'une migration/home/senke/git/talas/veza/veza-backend-api/internal/jobs/home/senke/git/talas/veza/veza-backend-api/internal/jobs/cleanup_hls_segments.goCleanupExpiredPasswordResetTokensCleanupExpiredVerificationTokensCleanupHLSSegmentsScheduleHLSCleanupJobSchedulePasswordResetCleanupJobScheduleSessionCleanupJobScheduleVerificationTokenCleanupJobcleanupServicehlsOutputDirHLS_OUTPUT_DIR"HLS_OUTPUT_DIR"hls_output"hls_output"HLSCleanupServiceCleanupDeletedTracksCleanupOrphanedSegmentscleanupStreamFilesCleanupAllNewHLSCleanupServiceFailed to cleanup HLS segments"Failed to cleanup HLS segments"HLS segments cleanup completed successfully"HLS segments cleanup completed successfully"Initial HLS cleanup job failed"Initial HLS cleanup job failed"Scheduled HLS cleanup job failed"Scheduled HLS cleanup job failed"HLS cleanup job scheduled to run daily"HLS cleanup job scheduled to run daily" CleanupHLSSegments nettoie les segments HLS obsolètes T0338: Nettoie les segments de tracks supprimés et les segments orphelins Récupérer le répertoire de sortie HLS depuis la config ou un défaut Créer le service de cleanup Exécuter le nettoyage ScheduleHLSCleanupJob programme le job de nettoyage HLS pour s'exécuter périodiquement T0338: Lance une goroutine qui exécute le nettoyage toutes les 24 heures Exécuter immédiatement au démarrage Puis exécuter toutes les 24 heures/home/senke/git/talas/veza/veza-backend-api/internal/jobs/cleanup_password_reset_tokens.go-168-604800000000000
		DELETE FROM password_reset_tokens
		WHERE expires_at < $1 OR (used = TRUE AND created_at < $2)
	`
		DELETE FROM password_reset_tokens
		WHERE expires_at < $1 OR (used = TRUE AND created_at < $2)
	`Failed to cleanup expired password reset tokens"Failed to cleanup expired password reset tokens"Failed to get rows affected count"Failed to get rows affected count"Cleaned up password reset tokens"Cleaned up password reset tokens"Initial password reset cleanup job failed"Initial password reset cleanup job failed"Scheduled password reset cleanup job failed"Scheduled password reset cleanup job failed"Password reset cleanup job scheduled to run daily"Password reset cleanup job scheduled to run daily" CleanupExpiredPasswordResetTokens supprime les tokens de réinitialisation de mot de passe expirés et utilisés T0199: Supprime les tokens expirés (expires_at < NOW()) et les tokens utilisés plus anciens que 7 jours Delete expired tokens (expires_at < NOW()) and used tokens older than 7 days Utilisation de paramètres pour compatibilité avec différentes bases de données SchedulePasswordResetCleanupJob programme le job de nettoyage pour s'exécuter quotidiennement T0199: Lance une goroutine qui exécute le nettoyage toutes les 24 heures/home/senke/git/talas/veza/veza-backend-api/internal/jobs/cleanup_sessions.goFailed to cleanup expired sessions"Failed to cleanup expired sessions"Initial sessions cleanup job failed"Initial sessions cleanup job failed"Scheduled sessions cleanup job failed"Scheduled sessions cleanup job failed"Sessions cleanup job scheduled to run daily"Sessions cleanup job scheduled to run daily" CleanupExpiredSessions supprime les sessions expirées T0208: Supprime les sessions avec expires_at < NOW() Créer SessionService pour utiliser la méthode existante Cleanup expired sessions Note: The service already logs the number of cleaned sessions ScheduleSessionCleanupJob programme le job de nettoyage des sessions pour s'exécuter quotidiennement T0208: Lance une goroutine qui exécute le nettoyage toutes les 24 heures/home/senke/git/talas/veza/veza-backend-api/internal/jobs/cleanup_verification_tokens.go
		DELETE FROM email_verification_tokens
		WHERE expires_at < $1 OR (used = TRUE AND created_at < $2)
	`
		DELETE FROM email_verification_tokens
		WHERE expires_at < $1 OR (used = TRUE AND created_at < $2)
	`Failed to cleanup expired verification tokens"Failed to cleanup expired verification tokens"Cleaned up verification tokens"Cleaned up verification tokens"Initial cleanup job failed"Initial cleanup job failed"Scheduled cleanup job failed"Scheduled cleanup job failed"Cleanup job scheduled to run daily"Cleanup job scheduled to run daily" CleanupExpiredVerificationTokens supprime les tokens de vérification expirés et utilisés T0189: Supprime les tokens expirés (expires_at < NOW()) et les tokens utilisés plus anciens que 7 jours ScheduleVerificationTokenCleanupJob programme le job de nettoyage des tokens de vérification pour s'exécuter quotidiennement T0189: Lance une goroutine qui exécute le nettoyage toutes les 24 heures/home/senke/git/talas/veza/veza-backend-api/internal/logging/home/senke/git/talas/veza/veza-backend-api/internal/logging/logger.goNewLoggerWithRotationNewOptimizedLoggerNewOptimizedLoggerWithRotationbufferedAsyncWritercreateBufferedAsyncWriterlogFilebawflushIntervallogChanflushRoutinesyncWriterbufferedFileWriter"gopkg.in/natefinch/lumberjack.v2""json"console"console"10000000010000000 Logger représente un logger structuré avec support pour champs contextuels NewLogger crée un nouveau logger selon l'environnement (production ou development) env: environnement ("production" ou autre) logLevel: niveau de log ("DEBUG", "INFO", "WARN", "ERROR"). Si vide ou invalide, utilise INFO par défaut En production, utiliser JSON structuré En développement, utiliser format console plus lisible Configurer le niveau de log (T0027) Si logLevel est vide, utiliser INFO par défaut En cas d'erreur de parsing, utiliser INFO par défaut NewLoggerWithRotation crée un nouveau logger avec rotation automatique des logs logFile: chemin vers le fichier de log (ex: "/var/log/app.log") Configuration:   - MaxSize: 100 MB par fichier   - MaxBackups: 10 fichiers de backup   - MaxAge: 30 jours de retention   - Compress: compression activée pour les vieux logs Configuration de la rotation des logs avec lumberjack Rotation par taille (100MB) et temps (daily) Retention: 30 jours, maximum 10 backups Compression: activée pour économiser l'espace disque MB - rotation quand le fichier atteint 100MB Garder maximum 10 fichiers de backup Jours - supprimer les logs de plus de 30 jours Compresser les fichiers de backup (gzip) Créer le core zap avec le writer de rotation et le niveau configuré Debug log un message au niveau DEBUG Info log un message au niveau INFO Warn log un message au niveau WARN Error log un message au niveau ERROR With crée un nouveau logger avec des champs contextuels préfixés Sync synchronise les buffers du logger (à appeler avant shutdown) GetZapLogger retourne le logger zap sous-jacent pour compatibilité SetLevel change le niveau de log dynamiquement (T0034) Fonctionne uniquement si le logger a été créé avec AtomicLevel Note: Cette implémentation est simplifiée car zap ne permet pas facilement de changer le niveau d'un logger déjà créé sans AtomicLevel Pour un changement dynamique complet, il faudrait recréer le logger TODO: Implémenter avec AtomicLevel lors de la création du logger Si le logger n'utilise pas AtomicLevel, on ne peut pas changer le niveau dynamiquement Dans ce cas, on retourne nil (pas d'erreur) car ce n'est pas critique GetLevel retourne le niveau de log actuel si accessible Essayer d'obtenir le niveau depuis le core Cette implémentation est simplifiée - zap ne permet pas facilement de récupérer le niveau d'un logger déjà créé NewOptimizedLogger crée un logger optimisé pour la haute performance avec: - Buffering pour réduire les appels système - Async writes pour ne pas bloquer les goroutines - Sampling pour éviter le spam de logs en cas de charge élevée Cette fonction est optimisée pour la production avec haute charge (T0030) Configurer le niveau de log Sampling pour éviter spam en cas de haute charge (T0030) Initial: log les 100 premiers messages par seconde Thereafter: log 1 message toutes les 100 messages suivants Créer un writer avec buffering et async writes Buffer de 256KB pour réduire les appels système Créer le core avec buffering Ajouter caller et stack trace pour les erreurs bufferedAsyncWriter implémente un writer avec buffering et writes asynchrones createBufferedAsyncWriter crée un writer avec buffering et async writes Buffer channel de 1000 messages Démarrer la goroutine pour les writes asynchrones Write implémente io.Writer - écrit de manière asynchrone Copier les données pour éviter les problèmes de race condition Si le channel est plein, flush immédiatement et réessayer Si toujours plein après flush, écrire directement (perte de performance mais pas de données) flushRoutine écrit les logs de manière asynchrone avec flushing périodique Ajouter au buffer Buffer plein, flush d'abord Flush périodique Flush final avant de terminer flush écrit le buffer vers le writer sous-jacent Reset buffer Sync synchronise les buffers (nécessaire pour zapcore.WriteSyncer) Flush toutes les données restantes dans le channel Close ferme le writer et flush les données restantes Attendre que flushRoutine se termine NewOptimizedLoggerWithRotation crée un logger optimisé avec rotation des logs Combine les optimisations de performance (buffering, async, sampling) avec la rotation Sampling pour éviter spam (T0030) MB jours Créer un writer avec buffering et async writes pour le fichier Créer le core avec le writer optimisé Ajouter caller et stack trace/home/senke/git/talas/veza/veza-backend-api/internal/metrics/home/senke/git/talas/veza/veza-backend-api/internal/metrics/aggregation.goNewAggregatedMetricsRecordCircuitBreakerRequestRecordErrorPrometheusUpdateCircuitBreakerMetricsUpdateDBPoolStatscircuitBreakerConsecutiveFailurescircuitBreakerFailuresTotalcircuitBreakerRequestsTotalcircuitBreakerStatedbConnectionsdbPoolIdledbPoolInUsedbPoolMaxIdleCloseddbPoolMaxIdleTimeCloseddbPoolMaxLifetimeCloseddbPoolOpenConnectionsdbPoolWaitCountdbPoolWaitDurationdbQueriesTotaldbQueryDurationerrorsTotalfoundwindowStartmaxAge`json:"start"``json:"end"``json:"requests"``json:"errors_by_code"``json:"errors_by_http_status"` TimeWindow représente une fenêtre de temps avec des métriques agrégées AggregatedMetrics gère l'agrégation des métriques sur des fenêtres de temps key: "1m", "5m", "1h" Configuration des fenêtres en secondes Nombre max de fenêtres à garder par type NewAggregatedMetrics crée une nouvelle instance de AggregatedMetrics Garder 60 fenêtres de 1 minute = 1 heure Garder 12 fenêtres de 5 minutes = 1 heure Garder 24 fenêtres de 1 heure = 24 heures Démarrer la routine de nettoyage AddError enregistre une erreur dans les fenêtres d'agrégation Initialiser la fenêtre si elle n'existe pas Fenêtre non supportée Trouver ou créer la fenêtre active Chercher la fenêtre active Fenêtre existante - mettre à jour Créer une nouvelle fenêtre Nettoyer les anciennes fenêtres (garder seulement les plus récentes) AddRequest enregistre une requête dans les fenêtres d'agrégation Nettoyer les anciennes fenêtres GetAggregated retourne les métriques agrégées pour un type de fenêtre Retourner une copie pour éviter les modifications concurrentes Copier les maps GetAllAggregated retourne toutes les métriques agrégées cleanupWindows nettoie les anciennes fenêtres pour un type donné Garder seulement les fenêtres les plus récentes Trier par date (les plus récentes en premier) Les fenêtres sont normalement déjà ordonnées, mais on s'assure On garde les max dernières cleanupRoutine nettoie périodiquement les anciennes fenêtres Nettoyer chaque minute Nettoyer les fenêtres expirées pour chaque type Garder les fenêtres qui ne sont pas trop anciennes/home/senke/git/talas/veza/veza-backend-api/internal/metrics/circuit_breaker.gostateValue"github.com/prometheus/client_golang/prometheus""github.com/prometheus/client_golang/prometheus/promauto""github.com/sony/gobreaker"veza_circuit_breaker_state"veza_circuit_breaker_state"Current state of the circuit breaker (0=closed, 1=half-open, 2=open)"Current state of the circuit breaker (0=closed, 1=half-open, 2=open)"circuit_breaker_name"circuit_breaker_name"veza_circuit_breaker_requests_total"veza_circuit_breaker_requests_total"Total number of requests through the circuit breaker"Total number of requests through the circuit breaker""result"veza_circuit_breaker_failures_total"veza_circuit_breaker_failures_total"Total number of failures through the circuit breaker"Total number of failures through the circuit breaker"veza_circuit_breaker_consecutive_failures"veza_circuit_breaker_consecutive_failures"Number of consecutive failures"Number of consecutive failures"2.0 circuitBreakerState indique l'état actuel du circuit breaker (0=closed, 1=half-open, 2=open) MOD-P2-007: Métrique pour suivre l'état du circuit breaker circuitBreakerRequestsTotal compte le nombre total de requêtes MOD-P2-007: Métrique pour compter les requêtes result: success, failure, rejected circuitBreakerFailuresTotal compte le nombre total d'échecs MOD-P2-007: Métrique pour compter les échecs circuitBreakerConsecutiveFailures indique le nombre d'échecs consécutifs MOD-P2-007: Métrique pour suivre les échecs consécutifs UpdateCircuitBreakerMetrics met à jour les métriques Prometheus pour un circuit breaker MOD-P2-007: Expose les métriques du circuit breaker via Prometheus État du circuit breaker (0=closed, 1=half-open, 2=open) Échecs consécutifs Total des échecs RecordCircuitBreakerRequest enregistre une requête dans les métriques MOD-P2-007: Enregistre le résultat d'une requête (success, failure, rejected)/home/senke/git/talas/veza/veza-backend-api/internal/metrics/db_pool.goveza_db_pool_open_connections"veza_db_pool_open_connections"Number of open database connections in the pool"Number of open database connections in the pool"veza_db_pool_in_use"veza_db_pool_in_use"Number of database connections currently in use"Number of database connections currently in use"veza_db_pool_idle"veza_db_pool_idle"Number of idle database connections in the pool"Number of idle database connections in the pool"veza_db_pool_wait_count_total"veza_db_pool_wait_count_total"Total number of times a connection had to wait (cumulative since startup)"Total number of times a connection had to wait (cumulative since startup)"veza_db_pool_wait_duration_seconds_total"veza_db_pool_wait_duration_seconds_total"Total time spent waiting for a database connection in seconds (cumulative since startup)"Total time spent waiting for a database connection in seconds (cumulative since startup)"veza_db_pool_max_idle_closed_total"veza_db_pool_max_idle_closed_total"Total number of connections closed due to MaxIdleConns limit (cumulative since startup)"Total number of connections closed due to MaxIdleConns limit (cumulative since startup)"veza_db_pool_max_idle_time_closed_total"veza_db_pool_max_idle_time_closed_total"Total number of connections closed due to MaxIdleTime limit (cumulative since startup)"Total number of connections closed due to MaxIdleTime limit (cumulative since startup)"veza_db_pool_max_lifetime_closed_total"veza_db_pool_max_lifetime_closed_total"Total number of connections closed due to MaxLifetime limit (cumulative since startup)"Total number of connections closed due to MaxLifetime limit (cumulative since startup)" dbPoolOpenConnections mesure le nombre de connexions ouvertes dans le pool dbPoolInUse mesure le nombre de connexions en cours d'utilisation dbPoolIdle mesure le nombre de connexions inactives dbPoolWaitCount mesure le nombre total de fois qu'une connexion a dû attendre Note: sql.DBStats.WaitCount est cumulatif depuis le démarrage, donc on utilise un Gauge et on le met à jour avec la valeur absolue dbPoolWaitDuration mesure la durée totale d'attente pour obtenir une connexion Note: sql.DBStats.WaitDuration est cumulatif depuis le démarrage, donc on utilise un Gauge dbPoolMaxIdleClosed mesure le nombre de connexions fermées à cause de MaxIdleConns Note: sql.DBStats.MaxIdleClosed est cumulatif depuis le démarrage, donc on utilise un Gauge dbPoolMaxIdleTimeClosed mesure le nombre de connexions fermées à cause de MaxIdleTime Note: sql.DBStats.MaxIdleTimeClosed est cumulatif depuis le démarrage, donc on utilise un Gauge dbPoolMaxLifetimeClosed mesure le nombre de connexions fermées à cause de MaxLifetime Note: sql.DBStats.MaxLifetimeClosed est cumulatif depuis le démarrage, donc on utilise un Gauge UpdateDBPoolStats met à jour les métriques du pool de connexions DB MOD-P2-004: Expose les métriques database/sql stats via Prometheus Métriques de connexions actuelles Métriques de wait (cumulatives depuis le démarrage) Note: sql.DBStats fournit des valeurs cumulatives, donc on utilise Set pour mettre à jour les gauges Métriques de connexions fermées (cumulatives depuis le démarrage) StartDBPoolStatsCollector démarre un collecteur périodique pour les métriques DB pool MOD-P2-004: Collecte les stats DB pool périodiquement et les expose via Prometheus Collecter immédiatement Collecter périodiquement/home/senke/git/talas/veza/veza-backend-api/internal/metrics/errors.gototal_errors"total_errors"errors_by_code"errors_by_code"errors_by_http_status"errors_by_http_status" ErrorMetrics collecte et stocke les métriques d'erreurs pour le monitoring Agrégation par fenêtres de temps (T0029) NewErrorMetrics crée une nouvelle instance de ErrorMetrics Initialiser l'agrégation (T0029) RecordError enregistre une erreur dans les métriques Enregistrer dans les fenêtres d'agrégation (T0029) GetStats retourne les statistiques actuelles des erreurs Reset réinitialise toutes les métriques (utile pour les tests) Note: on ne reset pas l'agrégation pour garder l'historique GetAggregatedMetrics retourne l'instance AggregatedMetrics/home/senke/git/talas/veza/veza-backend-api/internal/metrics/prometheus.gocodeStrstatusStrveza_errors_legacy_total"veza_errors_legacy_total"Total number of errors by code and HTTP status"Total number of errors by code and HTTP status"error_code"error_code"http_status"http_status"veza_errors_by_code_total"veza_errors_by_code_total"Total number of errors by error code"Total number of errors by error code"veza_errors_by_http_status_total"veza_errors_by_http_status_total"Total number of errors by HTTP status code"Total number of errors by HTTP status code"veza_db_queries_total"veza_db_queries_total"Total number of database queries"Total number of database queries"veza_db_query_duration_seconds"veza_db_query_duration_seconds"Database query duration in seconds"Database query duration in seconds".0010.00100000000000000002081152921504606847/1152921504606846976.0050.00500000000000000010415764607523034235/1152921504606846976.010.0100000000000000002085764607523034235/576460752303423488.0250.0250000000000000013883602879701896397/144115188075855872.050.0500000000000000027763602879701896397/72057594037927936.1.250.251/4.50.51/22.55/2veza_db_connections"veza_db_connections"Number of database connections"Number of database connections""open""idle"in_use"in_use" errorsTotal compte le total d'erreurs par code d'erreur et status HTTP errorsByCode compte les erreurs par code d'erreur errorsByHTTPStatus compte les erreurs par status HTTP dbQueriesTotal compte le total de requêtes DB par opération et table dbQueryDuration mesure la durée des requêtes DB dbConnections mesure le nombre de connexions DB par état open, idle, in_use RecordErrorPrometheus enregistre une erreur dans Prometheus RecordDBQuery enregistre une requête DB dans Prometheus duration: durée de la requête UpdateDBConnections met à jour les métriques de connexions DB idle: nombre de connexions inactives inUse: nombre de connexions en cours d'utilisation/home/senke/git/talas/veza/veza-backend-api/internal/middleware/home/senke/git/talas/veza/veza-backend-api/internal/middleware/auth.goCORSDefaultCheckPlaylistPermissionGetSpanIDNewVersioningPlaylistPermissionCheckerRequirePlaylistOwnerRequirePlaylistReadRequirePlaylistWriteRequireRoleRoleCheckerSpanIDHeaderSpanIDKeyTTL_LEGACY_ROUTESTraceIDHeaderTraceIDKeyTracingVersioningcapitalizeenrichErrorWithContexthttpRequestDurationhttpRequestsTotalisAllowedOriginroleNamepermissionNameallowedRoleshasAllowedRoleMissing Authorization header"Missing Authorization header""header"Invalid JWT token"Invalid JWT token"Invalid token"Invalid token"User not found during auth"User not found during auth"Token version mismatch (revoked)"Token version mismatch (revoked)"token_version"token_version"user_version"user_version"Token revoked"Token revoked"Invalid session"Invalid session"Session expired or invalid"Session expired or invalid"Session user mismatch"Session user mismatch"session_user_id"session_user_id"session_created_at"session_created_at"session_expires_at"session_expires_at"api_access"api_access"Failed to log API access"Failed to log API access"Failed to check admin role"Failed to check admin role"Internal server error"Internal server error"Admin access denied"Admin access denied"Insufficient permissions"Insufficient permissions"Admin access granted"Admin access granted"Permission denied"Permission denied"Permission check passed"Permission check passed""creator"producer"producer""label"Content creation denied - insufficient role"Content creation denied - insufficient role"Insufficient permissions. Content creation requires creator, premium, or admin role."Insufficient permissions. Content creation requires creator, premium, or admin role."Error checking roles (but user has allowed role)"Error checking roles (but user has allowed role)"Content creation access granted"Content creation access granted"Token refreshed"Token refreshed"Token refreshed successfully"Token refreshed successfully" ÉTAPE 3.4: Interfaces pour permettre l'injection de dépendances et les tests avec mocks SessionValidator définit l'interface pour valider les sessions AuditRecorder définit l'interface pour enregistrer les actions d'audit PermissionChecker définit l'interface pour vérifier les permissions AuthMiddleware middleware d'authentification avec validation de session ÉTAPE 3.4: Utilise des interfaces pour permettre l'injection de dépendances et les tests T0204: Use JWTService for validation T0204: Check TokenVersion NewAuthMiddleware crée un nouveau middleware d'authentification ÉTAPE 3.4: Accepte des interfaces au lieu de types concrets pour permettre les tests avec mocks authenticate performs the core authentication logic Returns userID and true if successful, otherwise handles error response and returns false T0204: Validate token using JWTService (checks sig, exp, iss, aud, alg) T0204: Check TokenVersion against DB to ensure immediate revocation Log audit access RequireAuth middleware qui exige une authentification OptionalAuth middleware d'authentification optionnelle MIGRATION UUID: Simplifié, utilise UUID directement T0204: Check TokenVersion (optional auth should also respect revocation) Ajouter UUID directement au contexte RequireAdmin middleware qui exige des droits administrateur GO-001, GO-005, GO-006: Implémentation RBAC réelle avec PermissionService MIGRATION UUID: userID est toujours uuid.UUID, plus de conversion Note: RequireAdmin() inclut la vérification d'authentification, pas besoin d'appeler RequireAuth() séparément Vérification RBAC réelle RequirePermission middleware qui exige une permission spécifique GO-001, GO-005: Implémentation RBAC réelle avec PermissionService MIGRATION UUID: userID est toujours uuid.UUID RequireContentCreatorRole middleware qui exige un rôle de créateur de contenu GO-012: Vérifie que l'utilisateur a un des rôles: creator, premium, admin Selon ORIGIN_SECURITY_FRAMEWORK, seuls ces rôles peuvent créer du contenu Vérifier si l'utilisateur a un des rôles autorisés: creator, premium, admin RefreshToken middleware pour rafraîchir les tokens MIGRATION UUID: Simplifié pour UUID Log le rafraîchissementdefaultVersionisVersionSupportedRequireVersion/home/senke/git/talas/veza/veza-backend-api/internal/middleware/cors.goallowedOrigins"Origin"Access-Control-Allow-Origin"Access-Control-Allow-Origin"Access-Control-Allow-Methods"Access-Control-Allow-Methods"GET, POST, PUT, DELETE, OPTIONS"GET, POST, PUT, DELETE, OPTIONS"Access-Control-Allow-Headers"Access-Control-Allow-Headers"Authorization, Content-Type"Authorization, Content-Type"Access-Control-Allow-Credentials"Access-Control-Allow-Credentials""OPTIONS"204 CORS middleware pour gérer les en-têtes CORS avec whitelist d'origins configurable allowedOrigins: liste des origines autorisées (ex: []string{"http://localhost:3000", "https://example.com"}) Si "*" est dans la liste, toutes les origines sont autorisées Vérifier si l'origine est autorisée isAllowedOrigin vérifie si une origine est dans la liste des origines autorisées Sécurité par défaut : si liste vide, on rejette tout Permettre toutes les origines si "*" est dans la liste ATTENTION: À utiliser seulement en dev CORSDefault crée un middleware CORS avec une whitelist par défaut Utile pour compatibilité avec le code existant/home/senke/git/talas/veza/veza-backend-api/internal/middleware/endpoint_limiter.goheaderPrefix900000000000Too many login attempts"Too many login attempts""register"Too many registration attempts"Too many registration attempts"Too many password reset attempts"Too many password reset attempts"Authentication required"Authentication required"%s:upload:user:%v"%s:upload:user:%v"X-UploadLimit-Limit"X-UploadLimit-Limit"X-UploadLimit-Remaining"X-UploadLimit-Remaining"X-UploadLimit-Reset"X-UploadLimit-Reset"Upload limit exceeded"Upload limit exceeded"%s:%s:ip:%s"%s:%s:ip:%s"X-%sLimit"X-%sLimit"-Limit"-Limit"-Remaining"-Remaining"-Reset"-Reset"
		local key = KEYS[1]
		local attempts = tonumber(ARGV[1])
		local window = tonumber(ARGV[2])
		
		local current = redis.call('GET', key)
		if current == false then
			redis.call('SET', key, 1, 'EX', window)
			return {1, attempts - 1}
		end
		
		local count = tonumber(current)
		if count < attempts then
			redis.call('INCR', key)
			return {1, attempts - count - 1}
		else
			return {0, 0}
		end
	`
		local key = KEYS[1]
		local attempts = tonumber(ARGV[1])
		local window = tonumber(ARGV[2])
		
		local current = redis.call('GET', key)
		if current == false then
			redis.call('SET', key, 1, 'EX', window)
			return {1, attempts - 1}
		end
		
		local count = tonumber(current)
		if count < attempts then
			redis.call('INCR', key)
			return {1, attempts - count - 1}
		else
			return {0, 0}
		end
	`%s:user:%v"%s:user:%v"X-UserLimit-Limit"X-UserLimit-Limit"X-UserLimit-Remaining"X-UserLimit-Remaining"X-UserLimit-Reset"X-UserLimit-Reset" EndpointLimiterConfig configuration pour les limites par endpoint EndpointLimits définit les limites pour chaque endpoint Login: 5 tentatives/15min par IP Register: 3 comptes/heure par IP Password reset: 3 tentatives/heure Upload: 10 fichiers/heure par user DefaultEndpointLimits retourne les limites par défaut EndpointLimiter gère les limites par endpoint NewEndpointLimiter crée un nouveau endpoint limiter LoginRateLimit middleware pour limiter les tentatives de login RegisterRateLimit middleware pour limiter les inscriptions PasswordResetRateLimit middleware pour limiter les reset de mot de passe UploadRateLimit middleware pour limiter les uploads par utilisateur En cas d'erreur Redis, autoriser la requête createEndpointLimit crée un middleware de limitation pour un endpoint checkLimit vérifie si une limite est respectée Script Lua pour l'atomicité capitalize met en majuscule la première lettre RateLimitByUser middleware pour limiter par utilisateur (pour endpoints génériques)/home/senke/git/talas/veza/veza-backend-api/internal/middleware/error_handler.gologFieldsrequestIDStrerrorMetricsPkgruntime/debug"runtime/debug"trace_id"trace_id"span_id"span_id"Application error"Application error"Resource not found"Resource not found"Record not found"Record not found"stack_trace"stack_trace" ErrorHandler middleware pour gérer toutes les erreurs de manière standardisée Traiter les erreurs stockées dans le contexte Vérifier si c'est une AppError personnalisée Enrichir l'erreur avec le contexte de la requête Enregistrer l'erreur dans les métriques (T0020) Enregistrer l'erreur dans Prometheus (T0021) Logger structuré avec contexte complet (T0028) Ajouter les champs de contexte au logger si disponibles Ajouter trace_id et span_id si disponibles (T0025) Ajouter l'erreur causale si présente Ajouter les détails de validation si présents Logger au niveau ERROR avec format JSON structuré Vérifier si c'est une erreur GORM Logger structuré avec contexte Ajouter request_id si disponible Erreur générique - logging structuré avec stack trace (T0028) Logger structuré avec contexte complet et stack trace Ajouter stack trace uniquement si configuré (MOD-P1-006) Ajouter user_id si disponible enrichErrorWithContext enrichit une AppError avec le contexte de la requête (request_id, user_id) Ajouter le request_id depuis le contexte Gin Ajouter le user_id depuis le contexte Gin si disponible mapErrorCodeToHTTPStatus convertit un code d'erreur en status HTTP/home/senke/git/talas/veza/veza-backend-api/internal/middleware/general.godeprecationDateRFC1123Mon, 02 Jan 2006 15:04:05 MSTAccess to deprecated route"Access to deprecated route"deprecation_date"deprecation_date"Please update your client to use the /api/v1/* equivalent."Please update your client to use the /api/v1/* equivalent.""Deprecated"true; sunset=%s; link=https://www.veza.app/api/v1/migration-guide"true; sunset=%s; link=https://www.veza.app/api/v1/migration-guide" TTL_LEGACY_ROUTES defines the time-to-live for legacy routes before they are removed. 30 days DeprecationWarning returns a Gin middleware that adds a "Deprecated" header and logs a warning for requests to legacy routes. Calculate the deprecation date once when the middleware is initialized Log a warning for each access to a deprecated route Add the Deprecated header/home/senke/git/talas/veza/veza-backend-api/internal/middleware/logger.go%s - [%s] "%s %s %s %d %s "%s" %s"
"%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n" Logger middleware pour logger les requêtes/home/senke/git/talas/veza/veza-backend-api/internal/middleware/metrics.goveza_gin_http_requests_total"veza_gin_http_requests_total"Total number of HTTP requests (Gin middleware)"Total number of HTTP requests (Gin middleware)"veza_gin_http_request_duration_seconds"veza_gin_http_request_duration_seconds"HTTP request duration in seconds (Gin middleware)"HTTP request duration in seconds (Gin middleware)" httpRequestsTotal compte le total de requêtes HTTP par méthode, path et status httpRequestDuration mesure la durée des requêtes HTTP Metrics middleware pour collecter métriques HTTP Mesure la durée et compte les requêtes HTTP avec labels (method, path, status)/home/senke/git/talas/veza/veza-backend-api/internal/middleware/playlist_permission.gorequiredPermissionplaylistIDStrplaylist id is required"playlist id is required"failed to check permission"failed to check permission" PlaylistPermissionChecker définit l'interface pour vérifier les permissions de playlist T0484: Interface pour permettre le mocking dans les tests CheckPlaylistPermission crée un middleware qui vérifie si un utilisateur a une permission spécifique sur une playlist T0484: Create Playlist Permission Middleware Le middleware vérifie: - Si l'utilisateur est le propriétaire (a toutes les permissions) - Si l'utilisateur est collaborateur avec la permission requise - Si la playlist est publique et la permission est "read" Récupérer user_id du contexte (doit être défini par AuthMiddleware) Convertir user_id en int64 Extraire playlistID depuis les paramètres de la route Vérifier la permission via le service Si la playlist n'existe pas, retourner 404 Permission accordée, continuer RequirePlaylistOwner crée un middleware qui exige que l'utilisateur soit le propriétaire de la playlist T0484: Helper pour vérifier l'ownership RequirePlaylistWrite crée un middleware qui exige que l'utilisateur ait la permission write ou admin T0484: Helper pour vérifier la permission d'écriture RequirePlaylistRead crée un middleware qui exige que l'utilisateur ait la permission read, write ou admin T0484: Helper pour vérifier la permission de lecture/home/senke/git/talas/veza/veza-backend-api/internal/middleware/rate_limiter.goisAuthenticatedlimiter"golang.org/x/time/rate"%s:ip:%s"%s:ip:%s"X-RateLimit-Limit"X-RateLimit-Limit"X-RateLimit-Reset"X-RateLimit-Reset"
		local key = KEYS[1]
		local limit = tonumber(ARGV[1])
		local window = tonumber(ARGV[2])
		
		local current = redis.call('GET', key)
		if current == false then
			redis.call('SET', key, 1, 'EX', window)
			return {1, limit - 1}
		end
		
		local count = tonumber(current)
		if count < limit then
			redis.call('INCR', key)
			return {1, limit - count - 1}
		else
			return {0, 0}
		end
	`
		local key = KEYS[1]
		local limit = tonumber(ARGV[1])
		local window = tonumber(ARGV[2])
		
		local current = redis.call('GET', key)
		if current == false then
			redis.call('SET', key, 1, 'EX', window)
			return {1, limit - 1}
		end
		
		local count = tonumber(current)
		if count < limit then
			redis.call('INCR', key)
			return {1, limit - count - 1}
		else
			return {0, 0}
		end
	`upload_rate_limit:%d"upload_rate_limit:%d"
			local key = KEYS[1]
			local limit = tonumber(ARGV[1])
			local window = tonumber(ARGV[2])
			
			local current = redis.call('GET', key)
			if current == false then
				redis.call('SET', key, 1, 'EX', window)
				return {1, limit - 1}
			end
			
			local count = tonumber(current)
			if count < limit then
				redis.call('INCR', key)
				return {1, limit - count - 1}
			else
				return {0, 0}
			end
		`
			local key = KEYS[1]
			local limit = tonumber(ARGV[1])
			local window = tonumber(ARGV[2])
			
			local current = redis.call('GET', key)
			if current == false then
				redis.call('SET', key, 1, 'EX', window)
				return {1, limit - 1}
			end
			
			local count = tonumber(current)
			if count < limit then
				redis.call('INCR', key)
				return {1, limit - count - 1}
			else
				return {0, 0}
			end
		`upload rate limit exceeded"upload rate limit exceeded" RateLimiterConfig configuration pour le rate limiter Limites par IP (non authentifié) Limites par utilisateur authentifié Configuration Redis RateLimiter middleware pour limiter le taux de requêtes NewRateLimiter crée un nouveau rate limiter RateLimitMiddleware middleware principal de rate limiting Déterminer si l'utilisateur est authentifié Utilisateur authentifié - limite plus élevée IP non authentifiée - limite plus stricte Vérifier la limite avec Redis pour persistance En cas d'erreur Redis, utiliser le limiter local checkRedisLimit vérifie la limite dans Redis Utiliser un script Lua pour l'atomicité 60 secondes RateLimitByIP middleware pour limiter par IP uniquement UploadRateLimit middleware pour limiter les uploads de tracks par utilisateur Limite: 10 uploads par heure par utilisateur Si pas d'utilisateur authentifié, passer au suivant Clé Redis pour cet utilisateur 10 uploads par heure En cas d'erreur Redis, autoriser la requête (fail-open)/home/senke/git/talas/veza/veza-backend-api/internal/middleware/ratelimit.go SimpleRateLimiter est un rate limiter simple basé sur une sliding window en mémoire Utilisé pour le rate limiting basique par IP sans dépendance Redis Channel to signal cleanup goroutine to stop NewSimpleRateLimiter crée un nouveau rate limiter simple limit: nombre maximum de requêtes window: fenêtre de temps (ex: 1 * time.Minute pour 100 req/min) Initialize the stop channel Démarrer la goroutine de nettoyage Middleware retourne le middleware Gin pour le rate limiting Nettoyer les anciennes requêtes Vérifier si la limite est atteinte Ajouter la nouvelle requête UpdateLimits met à jour les limites de rate limiting (T0034) Permet le rechargement à chaud des limites sans redémarrer l'application cleanup nettoie périodiquement les anciennes requêtes Ensure ticker is stopped Listen for stop signal Exit goroutine Stop signale au goroutine de nettoyage de s'arrêter/home/senke/git/talas/veza/veza-backend-api/internal/middleware/rbac_middleware.gofailed to check role"failed to check role"insufficient permissions"insufficient permissions" RoleChecker définit l'interface minimale pour vérifier les rôles et permissions Permet d'utiliser des mocks dans les tests sans modifier la signature publique RequireRole crée un middleware qui exige qu'un utilisateur ait un rôle spécifique Vérifier si l'utilisateur a le rôle requis RequirePermission crée un middleware qui exige qu'un utilisateur ait une permission spécifique Vérifier si l'utilisateur a la permission requise/home/senke/git/talas/veza/veza-backend-api/internal/middleware/recovery.go"stack"Panic recovered"Panic recovered" Recovery middleware personnalisé avec logging structuré Capture les panics et les log avec stack trace et contexte MOD-P1-005: Stack traces seulement si includeStackTrace=true (dev/DEBUG mode) MOD-P1-005: Stack traces seulement en development/debug, pas en prod Construire les champs de log Retourner une erreur 500 standardisée/home/senke/git/talas/veza/veza-backend-api/internal/middleware/request_id.go RequestID génère un ID unique pour chaque requête HTTP et l'ajoute au contexte pour traçabilité Si un header X-Request-ID est présent, il est utilisé, sinon un UUID v4 est généré Récupérer le request ID depuis le header si présent Si aucun request ID n'est fourni, en générer un nouveau Stocker le request ID dans le contexte Gin pour utilisation ultérieure Ajouter le header X-Request-ID à la réponse Continuer avec le traitement de la requête/home/senke/git/talas/veza/veza-backend-api/internal/middleware/request_logger.go"latency"body_size"body_size"Request completed"Request completed"Request completed with error"Request completed with error" RequestLogger middleware pour logger les requêtes HTTP avec contexte structuré Début de la requête Traiter la requête Calculer la durée Récupérer le request ID si présent Récupérer l'user ID si présent (après authentification) Préparer les champs structurés Ajouter request ID si présent Ajouter user ID si présent Ajouter le trace_id au logger si disponible (T0025) Ajouter le span_id au logger si disponible (T0025) Ajouter les erreurs s'il y en a Logger selon le status code Erreurs serveur Erreurs client Succès/home/senke/git/talas/veza/veza-backend-api/internal/middleware/security_headers.goStrict-Transport-Security"Strict-Transport-Security"max-age=31536000; includeSubDomains; preload"max-age=31536000; includeSubDomains; preload"X-Content-Type-Options"X-Content-Type-Options"nosniff"nosniff"X-Frame-Options"X-Frame-Options"DENY"DENY"X-XSS-Protection"X-XSS-Protection"1; mode=block"1; mode=block"Referrer-Policy"Referrer-Policy"strict-origin-when-cross-origin"strict-origin-when-cross-origin"Permissions-Policy"Permissions-Policy"geolocation=(), microphone=(), camera=()"geolocation=(), microphone=(), camera=()"Content-Security-Policy"Content-Security-Policy"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; connect-src 'self'"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; connect-src 'self'" SecurityHeaders ajoute des headers de sécurité HTTP recommandés MOD-P2-005: Headers sécurité manquants (HSTS, CSP, X-Frame-Options, etc.) Strict-Transport-Security (HSTS) - Force HTTPS Max-Age: 31536000 = 1 an IncludeSubDomains: inclut tous les sous-domaines Preload: permet d'être inclus dans les listes de préchargement HSTS des navigateurs X-Content-Type-Options - Empêche le MIME type sniffing Force le navigateur à respecter le Content-Type déclaré X-Frame-Options - Empêche le clickjacking DENY: empêche le site d'être affiché dans une frame (iframe, embed, object) X-XSS-Protection - Protection XSS (déprécié mais encore supporté par certains navigateurs) mode=block: bloque la page si une attaque XSS est détectée Referrer-Policy - Contrôle les informations de referrer envoyées strict-origin-when-cross-origin: envoie l'origine complète pour les requêtes same-origin, seulement l'origine pour les requêtes cross-origin HTTPS->HTTPS, rien pour HTTPS->HTTP Permissions-Policy - Contrôle les fonctionnalités du navigateur Désactive les fonctionnalités non nécessaires pour une API REST Content-Security-Policy (CSP) - Contrôle les ressources chargées Pour une API REST, on peut être strict car on ne sert pas de HTML default-src 'none': bloque tout par défaut script-src 'none': bloque les scripts style-src 'none': bloque les styles img-src 'none': bloque les images connect-src 'self': permet les requêtes vers la même origine (pour les appels API)/home/senke/git/talas/veza/veza-backend-api/internal/middleware/sentry_recover.goerrObjcomponent"component""gin""request"Panic: %v"Panic: %v"internal server error"internal server error"An unexpected error occurred"An unexpected error occurred"HTTP 5xx error without explicit error"HTTP 5xx error without explicit error" SentryRecover middleware pour capturer les panics et les erreurs avec Sentry Capturer le panic dans Sentry Récupérer l'user ID si présent Capturer l'erreur Logger l'erreur localement aussi Répondre avec une erreur générique Capturer les erreurs HTTP 5xx Récupérer les erreurs du contexte Gin Créer une erreur générique pour les 5xx sans erreur explicite toString convertit une valeur en string de manière sûre/home/senke/git/talas/veza/veza-backend-api/internal/middleware/timeout.goStatusGatewayTimeout504Request Timeout"Request Timeout"The request took too long to process."The request took too long to process." Timeout middleware wraps the context with a deadline MOD-P1-007: Fixed goroutine leak by ensuring cleanup on timeout Create a context with timeout Always cancel to free resources Replace the request context Create a channel to signal completion of the handler MOD-P1-007: Launch handler in goroutine with proper cleanup Ensure channel is closed even if handler panics Handler completed within timeout Timeout exceeded MOD-P1-007: Abort the request and ensure handler chain stops Note: We abort immediately without waiting for goroutine to avoid race conditions. The context cancellation (via defer cancel()) will signal the handler to stop. If handler tries to write after timeout, it's the handler's responsibility to check context. Return immediately - context cancellation will stop the handler goroutine The defer cancel() ensures resources are cleaned up/home/senke/git/talas/veza/veza-backend-api/internal/middleware/tracing.goX-Trace-ID"X-Trace-ID"X-Span-ID"X-Span-ID" TraceIDHeader est le nom du header HTTP pour propager le trace ID TraceIDKey est la clé utilisée pour stocker le trace ID dans le contexte Gin SpanIDHeader est le nom du header HTTP pour propager le span ID (optionnel) SpanIDKey est la clé utilisée pour stocker le span ID dans le contexte Gin Tracing middleware pour générer et propager trace ID (W3C Trace Context compatible) Le trace ID permet de tracer une requête à travers plusieurs services Si un trace ID est déjà présent dans le header, il est réutilisé (propagation) Sinon, un nouveau trace ID UUID v4 est généré Récupérer ou générer le trace ID Générer un nouveau trace ID UUID v4 (compatible W3C Trace Context) Récupérer ou générer le span ID (optionnel, pour corrélation fine) Générer un nouveau span ID UUID v4 Stocker dans le contexte Gin pour utilisation dans les handlers et logs Propager via les headers de réponse (pour que les clients puissent le réutiliser) GetTraceID retourne le trace ID du contexte, ou une chaîne vide si non défini GetSpanID retourne le span ID du contexte, ou une chaîne vide si non défini/home/senke/git/talas/veza/veza-backend-api/internal/middleware/versioning.gocurrentVersionrequiredVersion"v1""v2""api"api_version"api_version"X-API-Version"X-API-Version"X-API-Deprecated"X-API-Deprecated"X-API-Supported-Versions"X-API-Supported-Versions"API version mismatch"API version mismatch"required_version"required_version"provided_version"provided_version" Versioning middleware pour gérer le versioning de l'API NewVersioning crée un nouveau middleware de versioning Handle vérifie et extrait la version de l'API depuis l'URL Extraire la version depuis /api/v1/ ou /api/v2/ Valider que la version est supportée Utiliser la version par défaut Ajouter un header de dépréciation si nécessaire Pas de version dans l'URL, utiliser la valeur par défaut isVersionSupported vérifie si une version est supportée GetVersion récupère la version de l'API depuis le contexte RequireVersion vérifie que la version spécifiée est utilisée/home/senke/git/talas/veza/veza-backend-api/internal/models/home/senke/git/talas/veza/veza-backend-api/internal/models/admin.goAddTrackToPlaylistRequestAdminSettingsAuditLogWithUserBitrateAdaptationLogBitrateReasonBufferLowBitrateReasonNetworkFastBitrateReasonNetworkSlowBitrateReasonUserSelectedBulkUpdateRequestContestContestAnalyticsContestBadgeContestEntryContestJudgeContestPrizeContestSponsorContestStemsContestTimelineContestVoteCreatorRoyaltyRateEquipmentEquipmentTradeFederatedIdentityHLSStatusFailedHLSStatusPendingHLSStatusProcessingHLSStatusReadyHardwareOfferHardwareSaleJudgingCriterionJuryMemberMFAConfigPlaylistFollowPlaylistVersionActionCreatedPlaylistVersionActionRestoredPlaylistVersionActionUpdatedQueueStatusCompletedQueueStatusFailedQueueStatusPendingQueueStatusProcessingRecoveryCodeRolePermissionRoyaltyConfigRoyaltyPayoutRoyaltyRateRoyaltyRecordSellableContentShippingInfoStreamStatusErrorStreamStatusPendingStreamStatusProcessingStreamStatusReadySystemHealthTrackHistoryActionCreatedTrackHistoryActionDeletedTrackHistoryActionPublishedTrackHistoryActionRestoredTrackHistoryActionUnpublishedTrackHistoryActionUpdatedUpdateProductRequestUserProfileUserRoleUserSettingsWarrantyInfo`db:"total_users" json:"total_users"``db:"active_users" json:"active_users"``db:"total_tracks" json:"total_tracks"``db:"public_tracks" json:"public_tracks"``db:"total_shared_resources" json:"total_shared_resources"``db:"total_listings" json:"total_listings"``db:"active_listings" json:"active_listings"``db:"total_offers" json:"total_offers"``db:"pending_offers" json:"pending_offers"``db:"total_messages" json:"total_messages"``db:"total_rooms" json:"total_rooms"``db:"total_products" json:"total_products"``db:"total_categories" json:"total_categories"``json:"last_updated"``db:"user_id" json:"user_id"``db:"tracks_count" json:"tracks_count"``db:"resources_count" json:"resources_count"``db:"listings_count" json:"listings_count"``db:"messages_count" json:"messages_count"``db:"products_count" json:"products_count"``db:"registration_date" json:"registration_date"``db:"last_activity" json:"last_activity,omitempty"``db:"storage_used" json:"storage_used,omitempty"``json:"tracks_by_month"``json:"resources_by_month"``json:"users_by_month"``json:"popular_tags"``json:"top_uploaders"``json:"category_stats,omitempty"``db:"month" json:"month"``db:"count" json:"count"``db:"tag" json:"tag"``db:"total_uploads" json:"total_uploads"``db:"total_downloads" json:"total_downloads"``db:"category_id" json:"category_id"``db:"category_name" json:"category_name"``db:"product_count" json:"product_count"``db:"user_count" json:"user_count"`DatabaseStatusjson:"database_status"StorageAvailablejson:"storage_available"json:"memory_usage"ActiveConnectionsjson:"active_connections"json:"uptime"LastBackupjson:"last_backup,omitempty"json:"error_count"`json:"database_status"``json:"storage_available"``json:"memory_usage"``json:"cpu_usage"``json:"active_connections"``json:"uptime"``json:"last_backup,omitempty"``json:"error_count"`db:"action" json:"action"ResourceTypedb:"resource_type" json:"resource_type"db:"resource_id" json:"resource_id,omitempty"db:"details" json:"details,omitempty"db:"ip_address" json:"ip_address,omitempty"db:"user_agent" json:"user_agent,omitempty"`db:"action" json:"action"``db:"resource_type" json:"resource_type"``db:"resource_id" json:"resource_id,omitempty"``db:"details" json:"details,omitempty"``db:"ip_address" json:"ip_address,omitempty"``db:"user_agent" json:"user_agent,omitempty"`db:"username" json:"username,omitempty"db:"user_role" json:"user_role,omitempty"`db:"username" json:"username,omitempty"``db:"user_role" json:"user_role,omitempty"`db:"key" json:"key"db:"value" json:"value"db:"type" json:"type"db:"description" json:"description,omitempty"db:"category" json:"category"db:"is_public" json:"is_public"UpdatedBydb:"updated_by" json:"updated_by,omitempty"`db:"key" json:"key"``db:"value" json:"value"``db:"type" json:"type"``db:"description" json:"description,omitempty"``db:"category" json:"category"``db:"is_public" json:"is_public"``db:"updated_by" json:"updated_by,omitempty"`json:"name" validate:"required,min=2,max=100"json:"description" validate:"max=500"json:"price" validate:"min=0"json:"category_id" validate:"required,min=1"Brandjson:"brand" validate:"max=50"json:"status" validate:"required,oneof=active inactive"`json:"name" validate:"required,min=2,max=100"``json:"description" validate:"max=500"``json:"price" validate:"min=0"``json:"category_id" validate:"required,min=1"``json:"brand" validate:"max=50"``json:"status" validate:"required,oneof=active inactive"`json:"name,omitempty" validate:"omitempty,min=2,max=100"json:"description,omitempty" validate:"omitempty,max=500"json:"price,omitempty" validate:"omitempty,min=0"json:"category_id,omitempty" validate:"omitempty,min=1"json:"brand,omitempty" validate:"omitempty,max=50"json:"status,omitempty" validate:"omitempty,oneof=active inactive"`json:"name,omitempty" validate:"omitempty,min=2,max=100"``json:"description,omitempty" validate:"omitempty,max=500"``json:"price,omitempty" validate:"omitempty,min=0"``json:"category_id,omitempty" validate:"omitempty,min=1"``json:"brand,omitempty" validate:"omitempty,max=50"``json:"status,omitempty" validate:"omitempty,oneof=active inactive"`ProductIDsjson:"product_ids" validate:"required,min=1"json:"updates"`json:"product_ids" validate:"required,min=1"``json:"updates"` veza-backend-api/internal/models/admin.go DashboardStats represents admin dashboard statistics UserAnalytics represents detailed user analytics for admin AdminContentAnalytics represents content analytics for admin dashboard (anciennement ContentAnalytics) MonthlyCount represents count data by month TagCount represents tag usage statistics UploaderStats represents uploader statistics CategoryStats represents category statistics SystemHealth represents system health metrics AuditLog represents admin audit log entries AuditLogWithUser represents audit log with user information AdminSettings represents system settings manageable by admin string, int, bool, json system, features, limits, etc. ProductRequest types for admin operations Product est défini dans models/product.gogorm:"type:uuid;not null;index:idx_refresh_tokens_user_id" json:"user_id"gorm:"not null;size:255;index:idx_refresh_tokens_token_hash" json:"-"gorm:"not null" json:"expires_at"json:"track_id" binding:"required"json:"position"SubmissionDeadlinejson:"submission_deadline"VotingStartjson:"voting_start"VotingEndjson:"voting_end"ResultsAnnouncementjson:"results_announcement"Prizejson:"prize"CashAmountjson:"cash_amount,omitempty"json:"currency,omitempty"Badgejson:"badge,omitempty"Distributionjson:"distribution,omitempty"json:"weight"json:"id" gorm:"type:uuid;primaryKey"json:"description" db:"description"json:"price" db:"price"json:"is_active" db:"is_active"json:"updated_at" db:"updated_at"ContestIDjson:"contest_id" gorm:"type:uuid;not null;index"json:"user_id" gorm:"type:uuid;not null;index"json:"role" gorm:"not null"json:"weight" gorm:"not null;default:1.0"json:"credentials,omitempty"json:"is_active" gorm:"not null;default:true"json:"joined_at" gorm:"autoCreateTime"json:"created_at" gorm:"autoCreateTime"json:"updated_at" gorm:"autoUpdateTime"json:"contest,omitempty"json:"entry_id" gorm:"type:uuid;not null;index"JudgeIDjson:"judge_id,omitempty" gorm:"type:uuid"VoteTypejson:"vote_type" gorm:"not null"json:"score" gorm:"not null"Criteriajson:"criteria" gorm:"type:jsonb"json:"is_valid" gorm:"not null;default:true"json:"entry,omitempty"Judgejson:"judge,omitempty"json:"title" gorm:"not null"AudioFilejson:"audio_file" gorm:"not null"json:"metadata" gorm:"type:jsonb"json:"status" gorm:"not null;default:'submitted'"json:"position,omitempty"json:"score,omitempty"VoteCountjson:"vote_count" gorm:"not null;default:0"ViewCountjson:"view_count" gorm:"not null;default:0"Votesjson:"votes,omitempty"json:"description" gorm:"not null"json:"type" gorm:"not null;index"json:"status" gorm:"not null;default:'draft'"CreatorIDjson:"creator_id" gorm:"type:uuid;not null;index"OriginalTrackIDjson:"original_track_id,omitempty" gorm:"type:uuid"json:"genre,omitempty"BPMjson:"bpm,omitempty"json:"key,omitempty"Requirementsjson:"requirements" gorm:"type:jsonb"Rulesjson:"rules" gorm:"type:jsonb"Timelinejson:"timeline" gorm:"type:jsonb"Prizesjson:"prizes" gorm:"type:jsonb"JudgingCriteriajson:"judging_criteria" gorm:"type:jsonb"json:"settings" gorm:"type:jsonb"CoverImagejson:"cover_image,omitempty"json:"is_public" gorm:"not null;default:true"IsFeaturedjson:"is_featured" gorm:"not null;default:false"MaxParticipantsjson:"max_participants,omitempty"EntryCountjson:"entry_count" gorm:"not null;default:0"json:"creator,omitempty"OriginalTrackjson:"original_track,omitempty"json:"entries,omitempty"Judgesjson:"judges,omitempty"Sponsorsjson:"sponsors,omitempty"json:"name" gorm:"not null"Logojson:"logo,omitempty"Websitejson:"website,omitempty"Contributionjson:"contribution" gorm:"not null"json:"currency" gorm:"not null;default:'EUR'"Benefitsjson:"benefits" gorm:"type:jsonb"json:"contest_id" gorm:"type:uuid;not null;uniqueIndex"VocalsPathjson:"vocals_path" gorm:"not null"DrumsPathjson:"drums_path" gorm:"not null"BassPathjson:"bass_path" gorm:"not null"OtherPathjson:"other_path" gorm:"not null"DownloadURLjson:"download_url" gorm:"not null"gorm:"not null" json:"provider" validate:"required,oneof=google github facebook twitter"gorm:"not null" json:"provider_id"json:"display_name"gorm:"type:text" json:"-"gorm:"not null" json:"-"gorm:"default:false" json:"is_used"json:"used_at"gorm:"foreignKey:UserID" json:"-"json:"avatar_url,omitempty"FromUserurgorm:"type:uuid;not null;index;uniqueIndex:idx_user_roles_unique" json:"user_id" db:"user_id"gorm:"type:uuid;not null;index;uniqueIndex:idx_user_roles_unique" json:"role_id" db:"role_id"RoleNamegorm:"column:role;not null;size:50;uniqueIndex:uq_user_roles_user_role" json:"role_name" db:"role"AssignedAtgorm:"default:CURRENT_TIMESTAMP" json:"assigned_at" db:"assigned_at"AssignedBygorm:"type:uuid;index" json:"assigned_by" db:"assigned_by"gorm:"nullable" json:"expires_at" db:"expires_at"gorm:"foreignKey:RoleID;constraint:OnDelete:CASCADE" json:"-"Streetjson:"street"Cityjson:"city"json:"state"json:"postal_code"json:"country"EquipmentIDjson:"equipment_id" gorm:"type:uuid;not null;index"json:"seller_id" gorm:"type:uuid;not null;index"json:"buyer_id" gorm:"type:uuid;not null;index"json:"price" gorm:"not null"PaymentMethodjson:"payment_method" gorm:"not null"ShippingAddressjson:"shipping_address" gorm:"type:jsonb"json:"status" gorm:"not null;default:'active'"json:"notes,omitempty"TransactionIDjson:"transaction_id,omitempty"ProcessedAtjson:"processed_at,omitempty"gorm:"type:uuid;not null;uniqueIndex" json:"user_id"gorm:"default:false" json:"is_enabled"json:"last_used_at"gorm:"type:uuid;not null;index:idx_playlist_follows_playlist_id" json:"playlist_id" db:"playlist_id"gorm:"type:uuid;not null;index:idx_playlist_follows_user_id" json:"user_id" db:"user_id"PayoutIDjson:"payout_id" gorm:"uniqueIndex;not null"Amountjson:"amount" gorm:"not null"json:"period" gorm:"not null;index"json:"status" gorm:"not null;default:'pending'"json:"processed_at" gorm:"not null"EstimatedArrivaljson:"estimated_arrival" gorm:"not null"PlatformFeeRatejson:"platform_fee_rate" gorm:"not null;default:0.15"MinimumPayoutAmountjson:"minimum_payout_amount" gorm:"not null;default:50.0"PayoutSchedulejson:"payout_schedule" gorm:"not null;default:'monthly'"ProcessingDelayjson:"processing_delay" gorm:"not null;default:3"json:"cost"EstimatedDaysjson:"estimated_days"Trackingjson:"tracking"gorm:"type:uuid;not null;index:idx_bitrate_adaptation_track_id" json:"track_id"gorm:"type:uuid;not null;index:idx_bitrate_adaptation_user_id" json:"user_id"OldBitrategorm:"not null" json:"old_bitrate"NewBitrategorm:"not null" json:"new_bitrate"gorm:"type:varchar(50);not null" json:"reason"NetworkBandwidthgorm:"type:integer" json:"network_bandwidth,omitempty"gorm:"autoCreateTime;index:idx_bitrate_adaptation_created_at" json:"created_at"OfferAmountjson:"offer_amount" gorm:"not null"AcceptedAtjson:"accepted_at,omitempty"RejectedAtjson:"rejected_at,omitempty"json:"creator_id" gorm:"type:uuid;not null;uniqueIndex"json:"rate" gorm:"not null"json:"reason,omitempty"gorm:"type:uuid;not null" json:"contest_id" db:"contest_id"json:"role" db:"role"gorm:"not null;uniqueIndex;type:uuid"gorm:"default:'en'"gorm:"default:'UTC'"gorm:"default:'auto'"TotalEntriesjson:"total_entries" gorm:"not null;default:0"UniqueParticipantsjson:"unique_participants" gorm:"not null;default:0"TotalVotesjson:"total_votes" gorm:"not null;default:0"UniqueVotersjson:"unique_voters" gorm:"not null;default:0"AverageScorejson:"average_score" gorm:"not null;default:0"json:"completion_rate" gorm:"not null;default:0"EngagementRatejson:"engagement_rate" gorm:"not null;default:0"SocialSharesjson:"social_shares" gorm:"not null;default:0"json:"comments" gorm:"not null;default:0"Countriesjson:"countries" gorm:"not null;default:0"gorm:"not null;index" json:"user_id"gorm:"column:token_hash;uniqueIndex;not null" json:"-"json:"revoked_at"OfferedEquipmentIDjson:"offered_equipment_id" gorm:"type:uuid;not null;index"RequestedEquipmentIDjson:"requested_equipment_id" gorm:"type:uuid;not null;index"OfferedByUserIDjson:"offered_by_user_id" gorm:"type:uuid;not null;index"RequestedByUserIDjson:"requested_by_user_id" gorm:"type:uuid;not null;index"CashOfferjson:"cash_offer,omitempty"json:"content_type" gorm:"uniqueIndex;not null"BadgeTypejson:"badge_type" gorm:"not null"json:"icon" gorm:"not null"Rarityjson:"rarity" gorm:"not null;default:'common'"ContentIDjson:"content_id" gorm:"type:uuid;not null;index"json:"plays" gorm:"not null"Revenuejson:"revenue" gorm:"not null"RoyaltyAmountjson:"royalty_amount" gorm:"not null"json:"royalty_rate" gorm:"not null"json:"status" gorm:"not null;default:'calculated'"CalculatedAtjson:"calculated_at" gorm:"not null"PaidAtjson:"paid_at,omitempty"gorm:"default:true"gorm:"default:false"EquipmentTypejson:"equipment_type" gorm:"not null;index"json:"brand" gorm:"not null;index"json:"model" gorm:"not null"json:"year,omitempty"json:"condition" gorm:"not null"json:"location" gorm:"not null"json:"images" gorm:"type:jsonb"Specificationsjson:"specifications" gorm:"type:jsonb"IsForSalejson:"is_for_sale" gorm:"not null;default:false"IsForTradejson:"is_for_trade" gorm:"not null;default:false"json:"shipping_info" gorm:"type:jsonb"Warrantyjson:"warranty" gorm:"type:jsonb"json:"views" gorm:"not null;default:0"Favoritesjson:"favorites" gorm:"not null;default:0"gorm:"type:uuid;primaryKey;index;uniqueIndex:idx_role_permissions_unique" json:"role_id" db:"role_id"PermissionIDgorm:"type:uuid;primaryKey;index;uniqueIndex:idx_role_permissions_unique" json:"permission_id" db:"permission_id"gorm:"foreignKey:PermissionID;constraint:OnDelete:CASCADE" json:"-"/home/senke/git/talas/veza/veza-backend-api/internal/models/bitrate_adaptation.gonetwork_slow"network_slow"network_fast"network_fast"user_selected"user_selected"buffer_low"buffer_low"`gorm:"type:uuid;primaryKey" json:"id"``gorm:"type:uuid;not null;index:idx_bitrate_adaptation_track_id" json:"track_id"``gorm:"foreignKey:TrackID;constraint:OnDelete:CASCADE" json:"track,omitempty"``gorm:"type:uuid;not null;index:idx_bitrate_adaptation_user_id" json:"user_id"``gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"user,omitempty"``gorm:"not null" json:"old_bitrate"``gorm:"not null" json:"new_bitrate"``gorm:"type:varchar(50);not null" json:"reason"``gorm:"type:integer" json:"network_bandwidth,omitempty"``gorm:"autoCreateTime;index:idx_bitrate_adaptation_created_at" json:"created_at"`bitrate_adaptation_logs"bitrate_adaptation_logs" BitrateAdaptationReason représente la raison de l'adaptation de bitrate T0346: Create Bitrate Adaptation Database Model BitrateAdaptationLog représente un log d'adaptation de bitrate MIGRATION UUID: UserID et TrackID migrés vers uuid.UUID TableName définit le nom de la table pour GORM BeforeCreate hook GORM pour générer UUID si non défini/home/senke/git/talas/veza/veza-backend-api/internal/models/chat_message.go`gorm:"column:room_id;type:uuid;not null" json:"conversation_id"``gorm:"type:uuid;not null" json:"sender_id"``gorm:"type:varchar(50);not null" json:"message_type"``gorm:"type:uuid" json:"parent_message_id,omitempty"``gorm:"type:uuid" json:"reply_to_id,omitempty"``gorm:"default:false;not null" json:"is_pinned"``gorm:"default:false;not null" json:"is_edited"``gorm:"default:false;not null" json:"is_deleted"``json:"edited_at,omitempty"``gorm:"type:varchar(50);not null" json:"status"``gorm:"type:jsonb" json:"metadata,omitempty"` text, image, audio, etc. sent, delivered, read JSONB for additional data Rust uses 'messages' table/home/senke/git/talas/veza/veza-backend-api/internal/models/contest.go"github.com/lib/pq"`json:"id" gorm:"type:uuid;primaryKey"``json:"title" gorm:"not null"``json:"description" gorm:"not null"``json:"type" gorm:"not null;index"``json:"status" gorm:"not null;default:'draft'"``json:"creator_id" gorm:"type:uuid;not null;index"``json:"original_track_id,omitempty" gorm:"type:uuid"``json:"genre,omitempty"``json:"bpm,omitempty"``json:"key,omitempty"``json:"requirements" gorm:"type:jsonb"``json:"rules" gorm:"type:jsonb"``json:"timeline" gorm:"type:jsonb"``json:"prizes" gorm:"type:jsonb"``json:"judging_criteria" gorm:"type:jsonb"``json:"settings" gorm:"type:jsonb"``json:"cover_image,omitempty"``json:"is_public" gorm:"not null;default:true"``json:"is_featured" gorm:"not null;default:false"``json:"max_participants,omitempty"``json:"entry_count" gorm:"not null;default:0"``json:"view_count" gorm:"not null;default:0"``json:"vote_count" gorm:"not null;default:0"``json:"created_at" gorm:"autoCreateTime"``json:"updated_at" gorm:"autoUpdateTime"``json:"creator,omitempty"``json:"original_track,omitempty"``json:"entries,omitempty"``json:"judges,omitempty"``json:"sponsors,omitempty"``json:"start_date"``json:"submission_deadline"``json:"voting_start"``json:"voting_end"``json:"results_announcement"``json:"position"``json:"prize"``json:"cash_amount,omitempty"``json:"currency,omitempty"``json:"badge,omitempty"``json:"distribution,omitempty"``json:"weight"``json:"contest_id" gorm:"type:uuid;not null;index"``json:"user_id" gorm:"type:uuid;not null;index"``json:"audio_file" gorm:"not null"``json:"metadata" gorm:"type:jsonb"``json:"status" gorm:"not null;default:'submitted'"``json:"position,omitempty"``json:"score,omitempty"``json:"contest,omitempty"``json:"user,omitempty"``json:"votes,omitempty"``json:"role" gorm:"not null"``json:"weight" gorm:"not null;default:1.0"``json:"credentials,omitempty"``json:"is_active" gorm:"not null;default:true"``json:"joined_at" gorm:"autoCreateTime"``json:"entry_id" gorm:"type:uuid;not null;index"``json:"judge_id,omitempty" gorm:"type:uuid"``json:"vote_type" gorm:"not null"``json:"score" gorm:"not null"``json:"criteria" gorm:"type:jsonb"``json:"comment,omitempty"``json:"is_valid" gorm:"not null;default:true"``json:"entry,omitempty"``json:"judge,omitempty"``json:"name" gorm:"not null"``json:"logo,omitempty"``json:"website,omitempty"``json:"contribution" gorm:"not null"``json:"currency" gorm:"not null;default:'EUR'"``json:"benefits" gorm:"type:jsonb"``json:"contest_id" gorm:"type:uuid;not null;uniqueIndex"``json:"vocals_path" gorm:"not null"``json:"drums_path" gorm:"not null"``json:"bass_path" gorm:"not null"``json:"other_path" gorm:"not null"``json:"download_url" gorm:"not null"``json:"total_entries" gorm:"not null;default:0"``json:"unique_participants" gorm:"not null;default:0"``json:"total_votes" gorm:"not null;default:0"``json:"unique_voters" gorm:"not null;default:0"``json:"average_score" gorm:"not null;default:0"``json:"completion_rate" gorm:"not null;default:0"``json:"engagement_rate" gorm:"not null;default:0"``json:"social_shares" gorm:"not null;default:0"``json:"comments" gorm:"not null;default:0"``json:"countries" gorm:"not null;default:0"``json:"badge_type" gorm:"not null"``json:"icon" gorm:"not null"``json:"rarity" gorm:"not null;default:'common'"`contests"contests"contest_entries"contest_entries"contest_judges"contest_judges"contest_votes"contest_votes"contest_sponsors"contest_sponsors"contest_stems"contest_stems"contest_analytics"contest_analytics"contest_badges"contest_badges" Contest représente un concours musical remix, production, sound_design, collaboration draft, active, voting, completed, cancelled Relations ContestTimeline représente la timeline d'un concours ContestPrize représente un prix dans un concours JudgingCriterion représente un critère de jugement ContestEntry représente une participation à un concours submitted, approved, disqualified, winner ContestJudge représente un juge dans un concours head_judge, expert_judge, community_judge ContestVote représente un vote dans un concours expert, community ContestSponsor représente un sponsor d'un concours ContestStems représente les stems d'un concours (pour remix contests) ContestAnalytics représente les analytics d'un concours ContestBadge représente un badge de concours winner, participant, judge, sponsor common, rare, epic, legendary TableName spécifie le nom de la table pour Contest TableName spécifie le nom de la table pour ContestEntry TableName spécifie le nom de la table pour ContestJudge TableName spécifie le nom de la table pour ContestVote TableName spécifie le nom de la table pour ContestSponsor TableName spécifie le nom de la table pour ContestStems TableName spécifie le nom de la table pour ContestAnalytics TableName spécifie le nom de la table pour ContestBadge/home/senke/git/talas/veza/veza-backend-api/internal/models/custom_claims.go"github.com/golang-jwt/jwt/v5"`json:"sub"``json:"token_version"``json:"is_refresh,omitempty"``json:"token_type,omitempty"``json:"token_family,omitempty"` CustomClaims représente les claims JWT pour l'application MIGRATION UUID: UserID migré vers uuid.UUID pour cohérence avec User.ID Requis par Rust Chat Requis par Rust Chat ("access" ou "refresh") Requis par Rust Chat (Refresh rotation) TokenPair représente une paire de tokens JWTConfig contient la configuration JWT Ajouté/home/senke/git/talas/veza/veza-backend-api/internal/models/federated_identity.go`gorm:"not null" json:"provider" validate:"required,oneof=google github facebook twitter"``gorm:"not null" json:"provider_id"``json:"display_name"``json:"avatar_url"``gorm:"type:text" json:"-"``gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"-"`federated_identities"federated_identities" FederatedIdentity represents a federated identity (OAuth, etc.) BeforeCreate hook to generate UUID if not set TableName returns the table name for the FederatedIdentity model/home/senke/git/talas/veza/veza-backend-api/internal/models/hardware.go`json:"equipment_type" gorm:"not null;index"``json:"brand" gorm:"not null;index"``json:"model" gorm:"not null"``json:"year,omitempty"``json:"condition" gorm:"not null"``json:"price" gorm:"not null"``json:"location" gorm:"not null"``json:"images" gorm:"type:jsonb"``json:"specifications" gorm:"type:jsonb"``json:"is_for_sale" gorm:"not null;default:false"``json:"is_for_trade" gorm:"not null;default:false"``json:"status" gorm:"not null;default:'active'"``json:"shipping_info" gorm:"type:jsonb"``json:"warranty" gorm:"type:jsonb"``json:"views" gorm:"not null;default:0"``json:"favorites" gorm:"not null;default:0"``json:"equipment_id" gorm:"type:uuid;not null;index"``json:"seller_id" gorm:"type:uuid;not null;index"``json:"buyer_id" gorm:"type:uuid;not null;index"``json:"payment_method" gorm:"not null"``json:"shipping_address" gorm:"type:jsonb"``json:"notes,omitempty"``json:"transaction_id,omitempty"``json:"processed_at,omitempty"``json:"offered_equipment_id" gorm:"type:uuid;not null;index"``json:"requested_equipment_id" gorm:"type:uuid;not null;index"``json:"offered_by_user_id" gorm:"type:uuid;not null;index"``json:"requested_by_user_id" gorm:"type:uuid;not null;index"``json:"cash_offer,omitempty"``json:"status" gorm:"not null;default:'pending'"``json:"accepted_at,omitempty"``json:"rejected_at,omitempty"``json:"offer_amount" gorm:"not null"``json:"method"``json:"cost"``json:"estimated_days"``json:"tracking"``json:"street"``json:"city"``json:"state"``json:"postal_code"``json:"country"`equipment"equipment"hardware_sales"hardware_sales"equipment_trades"equipment_trades"hardware_offers"hardware_offers" Equipment équipement musical dans la base de données HardwareSale vente d'équipement EquipmentTrade échange d'équipement HardwareOffer offre pour un équipement Structures de données en mois TableName spécifie le nom de la table pour Equipment TableName spécifie le nom de la table pour HardwareSale TableName spécifie le nom de la table pour EquipmentTrade TableName spécifie le nom de la table pour HardwareOffer/home/senke/git/talas/veza/veza-backend-api/internal/models/hls_stream.go"database/sql/driver""processing"type assertion to []byte or string failed"type assertion to []byte or string failed"`gorm:"type:uuid;primaryKey" json:"id" db:"id"``gorm:"type:uuid;not null;index:idx_hls_streams_track_id" json:"track_id" db:"track_id"``gorm:"type:varchar(500);not null" json:"playlist_url" db:"playlist_url"``gorm:"not null;default:0" json:"segments_count" db:"segments_count"``gorm:"type:jsonb;default:'[]'" json:"bitrates" db:"bitrates"``gorm:"type:varchar(20);not null;default:'pending';index:idx_hls_streams_status" json:"status" db:"status"``gorm:"autoCreateTime" json:"created_at" db:"created_at"``gorm:"autoUpdateTime" json:"updated_at" db:"updated_at"`hls_streams"hls_streams" HLSStreamStatus représente le statut d'un stream HLS HLSStatusPending indique que le stream est en attente de traitement HLSStatusProcessing indique que le stream est en cours de traitement HLSStatusReady indique que le stream est prêt et disponible HLSStatusFailed indique que le traitement du stream a échoué BitrateList représente une liste de bitrates en kbps pour le JSONB Scan implémente l'interface sql.Scanner pour lire depuis la base de données Value implémente l'interface driver.Valuer pour écrire dans la base de données HLSStream représente un stream HLS pour un track MIGRATION UUID: Completée. ID et TrackID sont des UUIDs./home/senke/git/talas/veza/veza-backend-api/internal/models/hls_transcode_queue.go`gorm:"type:uuid;not null;index" json:"track_id"``gorm:"foreignKey:TrackID" json:"track,omitempty"``gorm:"not null;default:5" json:"priority"``gorm:"type:varchar(20);not null;default:'pending';index" json:"status"``gorm:"not null;default:0" json:"retry_count"``gorm:"not null;default:3" json:"max_retries"``gorm:"type:text" json:"error_message,omitempty"``json:"started_at,omitempty"``json:"completed_at,omitempty"`hls_transcode_queue"hls_transcode_queue" QueueStatus représente le statut d'un job dans la queue HLSTranscodeQueue représente un job de transcodage HLS dans la queue MIGRATION UUID: Completée. TrackID est un UUID./home/senke/git/talas/veza/veza-backend-api/internal/models/message.go`gorm:"type:uuid;not null" json:"room_id"``gorm:"column:sender_id;type:uuid;not null" json:"user_id"``gorm:"not null;type:text" json:"content"``gorm:"column:message_type;not null;default:'text'" json:"type"``gorm:"column:reply_to_id;type:uuid" json:"parent_id,omitempty"``gorm:"default:false" json:"is_edited"``gorm:"default:false" json:"is_deleted"``gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"-"``gorm:"foreignKey:ParentID;constraint:OnDelete:SET NULL" json:"-"` Message représente un message dans une room de chat/home/senke/git/talas/veza/veza-backend-api/internal/models/mfa_config.go`gorm:"type:uuid;not null;uniqueIndex" json:"user_id"``gorm:"not null" json:"-"``gorm:"default:false" json:"is_enabled"``json:"last_used_at"``gorm:"foreignKey:UserID" json:"-"`mfa_configs"mfa_configs" MFAConfig represents multi-factor authentication configuration JSON array of backup codes TableName returns the table name for the MFAConfig model/home/senke/git/talas/veza/veza-backend-api/internal/models/playback_analytics.go`gorm:"type:uuid;not null;index:idx_playback_analytics_track_id" json:"track_id"``gorm:"type:uuid;not null;index:idx_playback_analytics_user_id" json:"user_id"``gorm:"not null;default:0" json:"play_time"``gorm:"not null;default:0" json:"pause_count"``gorm:"not null;default:0" json:"seek_count"``gorm:"type:decimal(5,2);not null;default:0" json:"completion_rate"``gorm:"not null" json:"started_at"``gorm:"autoCreateTime;index:idx_playback_analytics_created_at" json:"created_at"`playback_analytics"playback_analytics" PlaybackAnalytics représente les analytics de lecture d'un track T0356: Create Playback Analytics Database Model MIGRATION UUID: UserID et TrackID migrés vers UUID pour cohérence percentage (0-100)/home/senke/git/talas/veza/veza-backend-api/internal/models/playlist.go`gorm:"type:uuid;not null" json:"user_id" db:"user_id"``gorm:"column:name;not null;size:200" json:"title" db:"title"``gorm:"type:text" json:"description,omitempty" db:"description"``gorm:"default:true" json:"is_public" db:"is_public"``gorm:"size:500" json:"cover_url,omitempty" db:"cover_url"``gorm:"default:0" json:"track_count" db:"track_count"``gorm:"default:0" json:"follower_count" db:"follower_count"``json:"-" db:"deleted_at"``gorm:"foreignKey:PlaylistID;constraint:OnDelete:CASCADE" json:"tracks,omitempty"``gorm:"foreignKey:PlaylistID;constraint:OnDelete:CASCADE" json:"collaborators,omitempty"``gorm:"type:uuid;not null" json:"playlist_id" db:"playlist_id"``gorm:"type:uuid;not null" json:"track_id" db:"track_id"``gorm:"not null" json:"position" db:"position"``gorm:"type:uuid;not null" json:"added_by" db:"added_by"``gorm:"autoCreateTime" json:"added_at" db:"added_at"``gorm:"foreignKey:PlaylistID;constraint:OnDelete:CASCADE" json:"-"`playlist_tracks"playlist_tracks" Playlist représente une playlist de tracks MIGRATION UUID: Completée. ID et UserID sont des UUIDs. PlaylistTrack représente l'association entre une playlist et un track avec position/home/senke/git/talas/veza/veza-backend-api/internal/models/playlist_collaborator.go`gorm:"type:uuid;not null;index:idx_playlist_collaborators_playlist_id" json:"playlist_id" db:"playlist_id"``gorm:"not null;type:uuid;index:idx_playlist_collaborators_user_id" json:"user_id" db:"user_id"``gorm:"not null;type:varchar(20);default:'read'" json:"permission" db:"permission"``gorm:"index" json:"-" db:"deleted_at"`playlist_collaborators"playlist_collaborators" Import uuid PlaylistPermission représente les permissions possibles pour un collaborateur PlaylistPermissionRead permet de lire la playlist PlaylistPermissionWrite permet de modifier la playlist (ajouter/retirer des tracks) PlaylistPermissionAdmin permet toutes les actions, y compris la gestion des collaborateurs IsValid vérifie si la permission est valide String retourne la représentation string de la permission PlaylistCollaborator représente un collaborateur d'une playlist avec ses permissions MIGRATION UUID: Completée. ID et PlaylistID sont des UUIDs. CanRead vérifie si le collaborateur peut lire la playlist CanWrite vérifie si le collaborateur peut modifier la playlist CanAdmin vérifie si le collaborateur peut administrer la playlist/home/senke/git/talas/veza/veza-backend-api/internal/models/playlist_follow.go`gorm:"type:uuid;not null;index:idx_playlist_follows_playlist_id" json:"playlist_id" db:"playlist_id"``gorm:"type:uuid;not null;index:idx_playlist_follows_user_id" json:"user_id" db:"user_id"`playlist_follows"playlist_follows" PlaylistFollow représente un follow d'un utilisateur sur une playlist/home/senke/git/talas/veza/veza-backend-api/internal/models/playlist_share_link.go`gorm:"type:uuid;not null;index:idx_playlist_share_links_playlist_id" json:"playlist_id" db:"playlist_id"``gorm:"type:uuid;not null;index:idx_playlist_share_links_user_id" json:"user_id" db:"user_id"``gorm:"uniqueIndex;not null;size:255" json:"share_token" db:"share_token"``json:"expires_at,omitempty" db:"expires_at"``gorm:"default:0" json:"access_count" db:"access_count"`playlist_share_links"playlist_share_links" PlaylistShareLink représente un lien de partage public pour une playlist/home/senke/git/talas/veza/veza-backend-api/internal/models/playlist_version.go"created"restored"restored"`gorm:"type:uuid;not null;index:idx_playlist_versions_playlist_id" json:"playlist_id" db:"playlist_id"``gorm:"type:uuid;not null;index:idx_playlist_versions_user_id" json:"user_id" db:"user_id"``gorm:"not null" json:"version" db:"version"``gorm:"not null;size:50;index:idx_playlist_versions_action" json:"action" db:"action"``gorm:"size:200" json:"title" db:"title"``gorm:"type:text" json:"tracks_snapshot,omitempty" db:"tracks_snapshot"``gorm:"autoCreateTime;index:idx_playlist_versions_created_at" json:"created_at" db:"created_at"``gorm:"foreignKey:PlaylistID;constraint:OnDelete:CASCADE" json:"playlist,omitempty"``gorm:"foreignKey:UserID;constraint:OnDelete:SET NULL" json:"user,omitempty"`playlist_versions"playlist_versions" PlaylistVersionAction représente le type d'action effectuée sur une playlist PlaylistVersion représente une version d'une playlist T0509: Create Playlist Version History Snapshot des tracks au moment de la version (JSON)/home/senke/git/talas/veza/veza-backend-api/internal/models/recovery_code.go`gorm:"default:false" json:"is_used"``json:"used_at"`recovery_codes"recovery_codes" RecoveryCode represents a recovery code for account recovery TableName returns the table name for the RecoveryCode model/home/senke/git/talas/veza/veza-backend-api/internal/models/refresh_token.go`gorm:"type:uuid;not null;index:idx_refresh_tokens_user_id" json:"user_id"``gorm:"not null;size:255;index:idx_refresh_tokens_token_hash" json:"-"``gorm:"not null" json:"expires_at"`refresh_tokens"refresh_tokens" RefreshToken représente un token de rafraîchissement JWT MIGRATION UUID: UserID migré vers UUID/home/senke/git/talas/veza/veza-backend-api/internal/models/requests.go`json:"name" binding:"required,min=1,max=255"``json:"track_id" binding:"required"` CreatePlaylistRequest represents a request to create a playlist AddTrackToPlaylistRequest represents a request to add a track to a playlist/home/senke/git/talas/veza/veza-backend-api/internal/models/responses.go`json:"avatar_url,omitempty"`2006-01-02T15:04:05Z"2006-01-02T15:04:05Z" UserResponse represents a user response (without sensitive data) MIGRATION UUID: ID est string (UUID serialisé) FromUser creates a UserResponse from a User model MIGRATION UUID: user.ID est uuid.UUID, serialisé en string/home/senke/git/talas/veza/veza-backend-api/internal/models/role.go`gorm:"uniqueIndex:uni_roles_name;not null;size:50" json:"name" db:"name"``gorm:"not null;size:100" json:"display_name" db:"display_name"``gorm:"type:text" json:"description" db:"description"``gorm:"default:false" json:"is_system" db:"is_system"``gorm:"default:true" json:"is_active" db:"is_active"``gorm:"many2many:user_roles;" json:"-"``gorm:"many2many:role_permissions;" json:"-"``gorm:"uniqueIndex:uni_permissions_name;not null;size:100" json:"name" db:"name"``gorm:"not null;size:50" json:"resource" db:"resource"``gorm:"not null;size:50" json:"action" db:"action"``gorm:"type:uuid;not null;index;uniqueIndex:idx_user_roles_unique" json:"user_id" db:"user_id"``gorm:"type:uuid;not null;index;uniqueIndex:idx_user_roles_unique" json:"role_id" db:"role_id"``gorm:"column:role;not null;size:50;uniqueIndex:uq_user_roles_user_role" json:"role_name" db:"role"``gorm:"default:CURRENT_TIMESTAMP" json:"assigned_at" db:"assigned_at"``gorm:"type:uuid;index" json:"assigned_by" db:"assigned_by"``gorm:"nullable" json:"expires_at" db:"expires_at"``gorm:"foreignKey:RoleID;constraint:OnDelete:CASCADE" json:"-"`user_roles"user_roles"`gorm:"type:uuid;primaryKey;index;uniqueIndex:idx_role_permissions_unique" json:"role_id" db:"role_id"``gorm:"type:uuid;primaryKey;index;uniqueIndex:idx_role_permissions_unique" json:"permission_id" db:"permission_id"``gorm:"foreignKey:PermissionID;constraint:OnDelete:CASCADE" json:"-"`role_permissions"role_permissions" Role représente un rôle dans le système Permission représente une permission dans le système UserRole représente l'association entre un utilisateur et un rôle MIGRATION UUID: UserID et AssignedBy migrés vers UUID RolePermission représente l'association entre un rôle et une permission/home/senke/git/talas/veza/veza-backend-api/internal/models/room.go`gorm:"size:255" json:"name"``gorm:"column:room_type;not null;default:'public'" json:"type"``gorm:"default:false" json:"is_private"``gorm:"column:creator_id;type:uuid;not null" json:"created_by"``gorm:"foreignKey:CreatedBy;constraint:OnDelete:CASCADE" json:"-"``gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"members,omitempty"``gorm:"foreignKey:RoomID;constraint:OnDelete:CASCADE" json:"messages,omitempty"``gorm:"type:uuid;not null" json:"user_id"``gorm:"not null;default:'member'" json:"role"``gorm:"autoCreateTime" json:"joined_at"`room_members"room_members" Room représente une room de chat RoomMember représente l'appartenance d'un utilisateur à une room/home/senke/git/talas/veza/veza-backend-api/internal/models/royalty.go`json:"content_id" gorm:"type:uuid;not null;index"``json:"period" gorm:"not null;index"``json:"plays" gorm:"not null"``json:"revenue" gorm:"not null"``json:"royalty_amount" gorm:"not null"``json:"royalty_rate" gorm:"not null"``json:"status" gorm:"not null;default:'calculated'"``json:"calculated_at" gorm:"not null"``json:"paid_at,omitempty"``json:"payout_id" gorm:"uniqueIndex;not null"``json:"amount" gorm:"not null"``json:"processed_at" gorm:"not null"``json:"estimated_arrival" gorm:"not null"``json:"content_type" gorm:"uniqueIndex;not null"``json:"rate" gorm:"not null"``json:"creator_id" gorm:"type:uuid;not null;uniqueIndex"``json:"reason,omitempty"``json:"platform_fee_rate" gorm:"not null;default:0.15"``json:"minimum_payout_amount" gorm:"not null;default:50.0"``json:"payout_schedule" gorm:"not null;default:'monthly'"``json:"processing_delay" gorm:"not null;default:3"`royalty_records"royalty_records"royalty_payouts"royalty_payouts"royalty_rates"royalty_rates"creator_royalty_rates"creator_royalty_rates"royalty_config"royalty_config" RoyaltyRecord enregistrement d'une royalty dans la base de données RoyaltyPayout paiement de royalties dans la base de données RoyaltyRate taux de royalty par type de contenu CreatorRoyaltyRate taux de royalty personnalisé par créateur RoyaltyConfig configuration des royalties TableName spécifie le nom de la table pour RoyaltyRecord TableName spécifie le nom de la table pour RoyaltyPayout TableName spécifie le nom de la table pour RoyaltyRate TableName spécifie le nom de la table pour CreatorRoyaltyRate TableName spécifie le nom de la table pour RoyaltyConfig/home/senke/git/talas/veza/veza-backend-api/internal/models/session.go`gorm:"not null;index" json:"user_id"``gorm:"column:token_hash;uniqueIndex;not null" json:"-"``json:"revoked_at"` Session represents a user session IsActive field removed - sessions table doesn't have this column UpdatedAt and DeletedAt removed - sessions table doesn't have these columns TableName returns the table name for the Session model/home/senke/git/talas/veza/veza-backend-api/internal/models/track.go`gorm:"type:uuid;not null;column:creator_id" json:"creator_id" db:"creator_id"``gorm:"type:uuid" json:"file_id,omitempty" db:"file_id"``gorm:"not null;size:255" json:"title" db:"title"``gorm:"size:255" json:"artist" db:"artist"``gorm:"size:255" json:"album" db:"album"``gorm:"not null" json:"duration" db:"duration"``gorm:"size:100" json:"genre" db:"genre"``gorm:"default:0" json:"year" db:"year"``gorm:"not null;size:500" json:"file_path" db:"file_path"``gorm:"not null" json:"file_size" db:"file_size"``gorm:"size:10" json:"format" db:"format"``gorm:"default:0" json:"bitrate" db:"bitrate"``gorm:"default:0" json:"sample_rate" db:"sample_rate"``gorm:"size:500" json:"waveform_path" db:"waveform_path"``gorm:"size:500" json:"cover_art_path" db:"cover_art_path"``gorm:"default:'uploading'" json:"status" db:"status"``gorm:"type:text" json:"status_message,omitempty" db:"status_message"``gorm:"default:'pending'" json:"stream_status" db:"stream_status"``gorm:"size:500" json:"stream_manifest_url" db:"stream_manifest_url"``gorm:"default:0" json:"play_count" db:"play_count"``gorm:"default:0" json:"like_count" db:"like_count"``gorm:"many2many:playlist_tracks;" json:"-"``gorm:"foreignKey:TrackID;constraint:OnDelete:CASCADE" json:"-"` Track représente une piste audio dans le système NULL temporairement avant création fichier mp3, flac, wav, etc. kbps Hz pending, processing, ready, error/home/senke/git/talas/veza/veza-backend-api/internal/models/track_comment.go`gorm:"type:uuid;not null;index:idx_track_comments_track_id" json:"track_id" db:"track_id"``gorm:"not null;type:uuid;index:idx_track_comments_user_id" json:"user_id" db:"user_id"``gorm:"type:uuid;index:idx_track_comments_parent_id" json:"parent_id,omitempty" db:"parent_id"``gorm:"type:text;not null" json:"content" db:"content"``gorm:"default:0" json:"timestamp,omitempty" db:"timestamp"``gorm:"default:false" json:"is_edited" db:"is_edited"``gorm:"autoCreateTime;index:idx_track_comments_created_at" json:"created_at" db:"created_at"``gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"user"``gorm:"foreignKey:ParentID;constraint:OnDelete:CASCADE" json:"-"``gorm:"foreignKey:ParentID;constraint:OnDelete:CASCADE" json:"replies,omitempty"`track_comments"track_comments" TrackComment représente un commentaire sur un track MIGRATION UUID: Completée. ID, TrackID, UserID et ParentID sont des UUIDs. Position in seconds/home/senke/git/talas/veza/veza-backend-api/internal/models/track_history.go"published"unpublished"unpublished"`gorm:"type:uuid;not null;index:idx_track_history_track_id" json:"track_id" db:"track_id"``gorm:"not null;type:uuid;index:idx_track_history_user_id" json:"user_id" db:"user_id"``gorm:"not null;size:50;index:idx_track_history_action" json:"action" db:"action"``gorm:"type:text" json:"old_value,omitempty" db:"old_value"``gorm:"type:text" json:"new_value,omitempty" db:"new_value"``gorm:"autoCreateTime;index:idx_track_history_created_at" json:"created_at" db:"created_at"`track_history"track_history" TrackHistoryAction représente le type d'action effectuée sur un track TrackHistory représente l'historique des modifications d'un track MIGRATION UUID: Completée. TrackID et UserID sont des UUIDs./home/senke/git/talas/veza/veza-backend-api/internal/models/track_like.go`gorm:"type:uuid;not null;index:idx_track_likes_user;uniqueIndex:idx_track_likes_unique" json:"user_id" db:"user_id"``gorm:"type:uuid;not null;index:idx_track_likes_track;uniqueIndex:idx_track_likes_unique" json:"track_id" db:"track_id"``gorm:"autoCreateTime;default:CURRENT_TIMESTAMP" json:"created_at" db:"created_at"`track_likes"track_likes" TrackLike représente un like d'un utilisateur sur un track MIGRATION UUID: Completée. ID, UserID et TrackID sont des UUIDs./home/senke/git/talas/veza/veza-backend-api/internal/models/track_play.go`gorm:"type:uuid;not null;index:idx_track_plays_track_id" json:"track_id" db:"track_id"``gorm:"type:uuid;index:idx_track_plays_user_id" json:"user_id,omitempty" db:"user_id"``gorm:"not null;index:idx_track_plays_played_at" json:"played_at" db:"played_at"``gorm:"size:100" json:"device,omitempty" db:"device"``gorm:"size:45" json:"ip_address,omitempty" db:"ip_address"``gorm:"foreignKey:UserID;constraint:OnDelete:SET NULL" json:"-"`track_plays"track_plays" TrackPlay représente une lecture de track pour analytics MIGRATION UUID: Completée. ID, TrackID et UserID sont des UUIDs. seconds played/home/senke/git/talas/veza/veza-backend-api/internal/models/track_share.go`gorm:"type:uuid;not null;index:idx_track_shares_track_id" json:"track_id" db:"track_id"``gorm:"not null;type:uuid;index:idx_track_shares_user_id" json:"user_id" db:"user_id"``gorm:"type:varchar(50);default:'read'" json:"permissions" db:"permissions"`track_shares"track_shares" TrackShare représente un lien de partage pour un track "read", "download", "read,download"/home/senke/git/talas/veza/veza-backend-api/internal/models/track_status.go"uploading"`json:"track_id" db:"track_id"``json:"status" db:"status"``json:"progress" db:"progress"``json:"message,omitempty" db:"message"``json:"stream_status,omitempty" db:"stream_status"``json:"stream_manifest_url,omitempty" db:"stream_manifest_url"` TrackStatus représente le statut d'un track lors de l'upload et du traitement TrackStatusUploading indique que le fichier est en cours d'upload TrackStatusProcessing indique que le fichier est en cours de traitement (extraction métadonnées, génération waveform, etc.) TrackStatusCompleted indique que le track est prêt et disponible TrackStatusFailed indique que l'upload ou le traitement a échoué StreamStatus constants UploadProgress représente la progression d'un upload de track 0-100/home/senke/git/talas/veza/veza-backend-api/internal/models/track_version.go`gorm:"type:uuid;not null;index:idx_track_versions_track_id;uniqueIndex:idx_track_versions_unique" json:"track_id" db:"track_id"``gorm:"not null;uniqueIndex:idx_track_versions_unique" json:"version_number" db:"version_number"``gorm:"type:text" json:"changelog,omitempty" db:"changelog"``gorm:"autoCreateTime;index:idx_track_versions_created_at" json:"created_at" db:"created_at"`track_versions"track_versions" TrackVersion représente une version d'un track/home/senke/git/talas/veza/veza-backend-api/internal/models/user.go`gorm:"type:uuid;primary_key" json:"id" db:"id"``gorm:"not null;size:30" json:"username" db:"username"``gorm:"size:255" json:"slug" db:"slug"``gorm:"not null;size:255" json:"email" db:"email"``gorm:"size:255" json:"-" db:"password_hash"``gorm:"-" json:"password,omitempty"``gorm:"default:0;not null" json:"token_version" db:"token_version"``gorm:"size:100" json:"first_name" db:"first_name"``gorm:"size:100" json:"last_name" db:"last_name"``gorm:"type:text" json:"avatar" db:"avatar"``gorm:"type:text" json:"bio" db:"bio"``gorm:"size:100" json:"location" db:"location"``json:"birthdate" db:"birthdate"``gorm:"size:20" json:"gender" db:"gender"``json:"username_changed_at" db:"username_changed_at"``gorm:"not null;default:'user'" json:"role" db:"role"``gorm:"default:false" json:"is_verified" db:"is_verified"``gorm:"default:false" json:"is_admin" db:"is_admin"``json:"last_login_at" db:"last_login_at"``json:"title" db:"title"``json:"description" db:"description"``json:"price" db:"price"``json:"is_active" db:"is_active"``json:"created_at" db:"created_at"``json:"updated_at" db:"updated_at"``gorm:"type:uuid;not null" json:"contest_id" db:"contest_id"``json:"role" db:"role"` User représente un utilisateur dans le système MIGRATION UUID: User.ID est maintenant un UUID pour cohérence Go↔Rust et alignment ORIGIN Virtual field for input SellableContent représente du contenu vendable JuryMember représente un membre du jury pour un contest/home/senke/git/talas/veza/veza-backend-api/internal/models/user_settings.go`gorm:"type:uuid;primaryKey"``gorm:"not null;uniqueIndex;type:uuid"``gorm:"default:true"``gorm:"default:false"`user_settings"user_settings"`gorm:"default:'en'"``gorm:"default:'UTC'"``gorm:"default:'auto'"`user_profiles"user_profiles" UserSettings représente les paramètres utilisateur Change to uuid.UUID Notifications Privacy Content UserProfile représente les préférences utilisateur (extended from User model) Note: Les champs language, timezone, theme sont dans la table users pour l'instant Cette structure est pour référence future si on veut une table séparée Preferences - stored in users table for now/home/senke/git/talas/veza/veza-backend-api/internal/models/webhook.go`gorm:"not null" json:"url"``gorm:"type:text[]" json:"events"``gorm:"default:true" json:"active"``gorm:"not null" json:"secret,omitempty"``gorm:"type:uuid;not null;index" json:"webhook_id"``gorm:"not null" json:"event"``gorm:"not null" json:"error"``gorm:"default:0" json:"retries"``gorm:"not null" json:"created_at"` Webhook représente une configuration de webhook Ne pas exposer dans l'API WebhookFailure représente un échec de livraison de webhook/home/senke/git/talas/veza/veza-backend-api/internal/monitoring/home/senke/git/talas/veza/veza-backend-api/internal/monitoring/metrics.goAuthLoginAttemptsAuthSessionActiveCacheHitsTotalCacheMissesTotalDashboardMetricsDatabaseConnectionsActiveDatabaseQueryDurationDatabaseQueryErrorsErrorsTotalFileUploadSizeFileUploadsTotalHTTPMetricsMiddlewareHTTPRequestDurationHTTPRequestsTotalHealthCheckDurationHealthCheckStatusNewPlaybackAnalyticsMonitorPerformanceMetricsPlaybackAnalyticsMonitorRateLimitHitsTotalRecordCacheHitRecordCacheMissRecordDatabaseErrorRecordDatabaseQueryRecordFileUploadRecordLoginAttemptRecordRateLimitHitRecordWebSocketMessageTrackMetricsUpdateActiveSessionsUpdateActiveUsersUpdateWebSocketConnectionsWebSocketConnectionsActiveWebSocketMessagesTotalactiveSessionsalertsActivealertsGeneratedaverageCompletionRateaveragePlayTimemetricsOncerecordedEventsDurationrecordedEventsErrorsrecordedEventsTotallimitTypecacheTypedurationMsstatusValueveza_http_requests_total"veza_http_requests_total"Total number of HTTP requests"Total number of HTTP requests"veza_http_request_duration_seconds"veza_http_request_duration_seconds"HTTP request duration in seconds"HTTP request duration in seconds"0.0010.0050.010.055.0veza_auth_login_attempts_total"veza_auth_login_attempts_total"Total number of login attempts"Total number of login attempts"veza_auth_sessions_active"veza_auth_sessions_active"Number of active sessions"Number of active sessions"veza_database_query_duration_seconds"veza_database_query_duration_seconds"veza_database_connections_active"veza_database_connections_active"Number of active database connections"Number of active database connections"veza_database_query_errors_total"veza_database_query_errors_total"Total number of database query errors"Total number of database query errors"error_type"error_type"veza_file_uploads_total"veza_file_uploads_total"Total number of file uploads"Total number of file uploads"veza_file_upload_size_bytes"veza_file_upload_size_bytes"File upload size in bytes"File upload size in bytes"veza_rate_limit_hits_total"veza_rate_limit_hits_total"Total number of rate limit hits"Total number of rate limit hits"limit_type"limit_type"veza_active_users"veza_active_users"Number of active users"Number of active users"veza_websocket_connections_active"veza_websocket_connections_active"Number of active WebSocket connections"Number of active WebSocket connections"veza_websocket_messages_total"veza_websocket_messages_total"Total number of WebSocket messages"Total number of WebSocket messages"veza_cache_hits_total"veza_cache_hits_total"Total number of cache hits"Total number of cache hits"cache_type"cache_type"veza_cache_misses_total"veza_cache_misses_total"Total number of cache misses"Total number of cache misses"veza_errors_total"veza_errors_total"Total number of errors"Total number of errors""severity"veza_health_check_duration_ms"veza_health_check_duration_ms"Health check duration in milliseconds"Health check duration in milliseconds"250veza_health_check_status"veza_health_check_status"Health check status (1=ok, 0.5=slow, 0=error)"Health check status (1=ok, 0.5=slow, 0=error)"failure"failure" Métriques Prometheus custom pour l'application Veza HTTP Requests Metrics Authentication Metrics Database Metrics File Upload Metrics 1KB to 32MB Rate Limiting Metrics Active Users Metrics WebSocket Metrics Cache Metrics Error Metrics Health Check Metrics database, redis, chat_server, stream_server Middleware pour enregistrer les métriques HTTP '2', '4', '5' Enregistrer une tentative de login Mettre à jour le nombre de sessions actives Enregistrer une requête database Enregistrer une erreur de database Enregistrer un upload de fichier Enregistrer un hit de rate limit Mettre à jour le nombre d'utilisateurs actifs Enregistrer une connexion WebSocket Enregistrer un message WebSocket Enregistrer un cache hit Enregistrer un cache miss Enregistrer une erreur Enregistrer un health check Convertir le status en valeur numérique pour la gaugeTotalEventsRecordedjson:"total_events_recorded"TotalEventsFailedjson:"total_events_failed"AverageRecordLatencyjson:"average_record_latency"P95RecordLatencyjson:"p95_record_latency"P99RecordLatencyjson:"p99_record_latency"ActiveSessionsjson:"active_sessions"AverageCompletionRatejson:"average_completion_rate"TotalAlertsGeneratedjson:"total_alerts_generated"ActiveAlertsjson:"active_alerts"json:"severity"json:"threshold"DetectedAtjson:"detected_at"json:"metadata,omitempty"TrackTitlejson:"track_title"ErrorRatejson:"error_rate"Performancejson:"performance"RecentAlertsjson:"recent_alerts"TopTracksjson:"top_tracks"SuccessRatejson:"success_rate"Throughputjson:"throughput"PlaybackAlertsServiceCheckAlertsdetectAnomaliesdetectLowCompletionRatedetectDropOffPointscalculateMeanAndStdDevalertsServicelastAlertCheckalertCheckIntervalRecordEventRecordBatchEventUpdateMetricsGetPerformanceMetricsGetDashboardMetricsgetTopTracksStartBackgroundMonitoringAlertConfigLowCompletionRateThresholdAnomalyDeviationThresholdDropOffPointThreshold/home/senke/git/talas/veza/veza-backend-api/internal/monitoring/playback_analytics_monitor.gototalLatencyactiveSessionsCountactiveSessionsThresholdalertsallAlertsrecentThresholderrorRateeventsLastHouroneHourAgoperfMetricsrecentAlertssuccessRatethroughputtotalEventsoneDayAgotrackMetricsupdateInterval`json:"total_events_recorded"``json:"total_events_failed"``json:"average_record_latency"``json:"p95_record_latency"``json:"p99_record_latency"``json:"active_sessions"``json:"average_completion_rate"``json:"total_alerts_generated"``json:"active_alerts"``json:"performance"``json:"recent_alerts"``json:"top_tracks"``json:"error_rate"``json:"success_rate"``json:"throughput"``json:"track_title"``json:"total_sessions"`veza_playback_analytics_events_total"veza_playback_analytics_events_total"Total number of playback analytics events recorded"Total number of playback analytics events recorded"veza_playback_analytics_record_duration_seconds"veza_playback_analytics_record_duration_seconds"Duration of playback analytics recording in seconds"Duration of playback analytics recording in seconds"veza_playback_analytics_errors_total"veza_playback_analytics_errors_total"Total number of playback analytics recording errors"Total number of playback analytics recording errors"veza_playback_analytics_active_sessions"veza_playback_analytics_active_sessions"Number of active playback sessions"Number of active playback sessions"veza_playback_analytics_average_completion_rate"veza_playback_analytics_average_completion_rate"Average completion rate across all playback sessions"Average completion rate across all playback sessions"veza_playback_analytics_average_play_time_seconds"veza_playback_analytics_average_play_time_seconds"Average play time in seconds across all playback sessions"Average play time in seconds across all playback sessions"veza_playback_analytics_alerts_generated_total"veza_playback_analytics_alerts_generated_total"Total number of playback analytics alerts generated"Total number of playback analytics alerts generated"alert_type"alert_type"veza_playback_analytics_alerts_active"veza_playback_analytics_alerts_active"Number of active playback analytics alerts"Number of active playback analytics alerts""record""batch"-1800000000000started_at > ? AND (ended_at IS NULL OR ended_at > ?)"started_at > ? AND (ended_at IS NULL OR ended_at > ?)"Failed to count active sessions"Failed to count active sessions"COALESCE(AVG(completion_rate), 0)"COALESCE(AVG(completion_rate), 0)"completion_rate > 0"completion_rate > 0"Failed to calculate average completion rate"Failed to calculate average completion rate"COALESCE(AVG(play_time), 0)"COALESCE(AVG(play_time), 0)"play_time > 0"play_time > 0"Failed to calculate average play time"Failed to calculate average play time"alerts service not available"alerts service not available"-24-86400000000000started_at > ?"started_at > ?"failed to get recent track IDs: %w"failed to get recent track IDs: %w"Failed to check alerts for track"Failed to check alerts for track"Checked playback analytics alerts"Checked playback analytics alerts"tracks_checked"tracks_checked"alerts_found"alerts_found"Failed to update metrics"Failed to update metrics"Failed to check alerts"Failed to check alerts"Failed to get top tracks"Failed to get top tracks"-3600000000000created_at > ?"created_at > ?"3600.03600gorm:"column:track_id"gorm:"column:track_title"gorm:"column:total_sessions"gorm:"column:average_completion"gorm:"column:average_play_time"gorm:"column:error_count"`gorm:"column:track_id"``gorm:"column:track_title"``gorm:"column:total_sessions"``gorm:"column:average_completion"``gorm:"column:average_play_time"``gorm:"column:error_count"`playback_analytics pa"playback_analytics pa"
			pa.track_id,
			COALESCE(t.title, 'Unknown') as track_title,
			COUNT(*) as total_sessions,
			COALESCE(AVG(pa.completion_rate), 0) as average_completion,
			COALESCE(AVG(pa.play_time), 0) as average_play_time,
			0 as error_count
		`
			pa.track_id,
			COALESCE(t.title, 'Unknown') as track_title,
			COUNT(*) as total_sessions,
			COALESCE(AVG(pa.completion_rate), 0) as average_completion,
			COALESCE(AVG(pa.play_time), 0) as average_play_time,
			0 as error_count
		`LEFT JOIN tracks t ON pa.track_id = t.id"LEFT JOIN tracks t ON pa.track_id = t.id"pa.created_at > ?"pa.created_at > ?"pa.track_id, t.title"pa.track_id, t.title"total_sessions DESC"total_sessions DESC"failed to get top tracks: %w"failed to get top tracks: %w"Failed to update metrics on startup"Failed to update metrics on startup"Stopping playback analytics monitoring"Stopping playback analytics monitoring" PlaybackAnalyticsMonitor gère le monitoring des analytics de playback T0386: Create Playback Analytics Monitoring Métriques Prometheus Métriques internes PerformanceMetrics représente les métriques de performance collectées DashboardMetrics représente les métriques pour le dashboard de monitoring Events per second TrackMetrics représente les métriques pour un track spécifique Metrics variables (package-level to ensure single registration) NewPlaybackAnalyticsMonitor crée un nouveau monitor pour les analytics de playback Assign shared metrics RecordEvent enregistre un événement d'analytics et met à jour les métriques Mettre à jour les métriques Prometheus Mettre à jour les métriques internes Mettre à jour la latence moyenne (calcul simplifié) RecordBatchEvent enregistre un événement batch et met à jour les métriques UpdateMetrics met à jour les métriques depuis la base de données Compter les sessions actives (sessions commencées dans les dernières 30 minutes) Calculer le taux de complétion moyen Calculer le temps de lecture moyen CheckAlerts vérifie les alertes pour tous les tracks actifs Récupérer les tracks avec des sessions récentes (dernières 24 heures) Mettre à jour le nombre d'alertes actives GetPerformanceMetrics retourne les métriques de performance actuelles GetDashboardMetrics retourne les métriques complètes pour le dashboard Mettre à jour les métriques depuis la base de données Vérifier les alertes si nécessaire Récupérer les top tracks Calculer les taux d'erreur et de succès Calculer le throughput (événements par seconde sur la dernière heure) getTopTracks récupère les métriques pour les tracks les plus actifs Utiliser GORM builder pour compatibilité SQLite/Postgres (évite NOW() - INTERVAL) StartBackgroundMonitoring démarre le monitoring en arrière-plan Mettre à jour immédiatement au démarrage Vérifier les alertes périodiquement/home/senke/git/talas/veza/veza-backend-api/internal/repositories/home/senke/git/talas/veza/veza-backend-api/internal/repositories/chat_message_repository.goNewPlaylistVersionRepositoryplaylistCollaboratorRepositoryplaylistRepositoryplaylistTrackRepositoryplaylistVersionRepositoryroom_id = ? AND is_deleted = ?"room_id = ? AND is_deleted = ?"created_at DESC"created_at DESC"failed to get conversation messages: %w"failed to get conversation messages: %w" Note: ChatMessage.ConversationID is mapped to column "room_id" in DB/home/senke/git/talas/veza/veza-backend-api/internal/repositories/playlist_collaborator_repository.gocollaborator already exists"collaborator already exists"playlist_id = ? AND user_id = ?"playlist_id = ? AND user_id = ?"playlist_id = ?"playlist_id = ?""Playlist" PlaylistCollaboratorRepository définit l'interface pour les opérations sur les collaborateurs de playlists AddCollaborator ajoute un collaborateur à une playlist RemoveCollaborator retire un collaborateur d'une playlist GetCollaborators récupère tous les collaborateurs d'une playlist GetCollaborator récupère un collaborateur spécifique UpdatePermission met à jour la permission d'un collaborateur GetByUserID récupère toutes les playlists où un utilisateur est collaborateur Exists vérifie si un collaborateur existe pour une playlist et un utilisateur playlistCollaboratorRepository implémente PlaylistCollaboratorRepository avec GORM NewPlaylistCollaboratorRepository crée une nouvelle instance de PlaylistCollaboratorRepository MIGRATION UUID: Completée. playlistID et userID sont des UUIDs. Valider la permission Vérifier si le collaborateur existe déjà Créer le collaborateur FIXME: Assurer que le modèle PlaylistCollaborator utilise UUID/home/senke/git/talas/veza/veza-backend-api/internal/repositories/playlist_repository.goisPublicdbQuery"Tracks"Tracks.Track"Tracks.Track"is_public = ?"is_public = ?"(name LIKE ? OR description LIKE ?)"(name LIKE ? OR description LIKE ?)" PlaylistRepository définit l'interface pour les opérations sur les playlists Create crée une nouvelle playlist GetByID récupère une playlist par son ID GetByUserID récupère les playlists d'un utilisateur Update met à jour une playlist Delete supprime une playlist List récupère une liste de playlists avec pagination Exists vérifie si une playlist existe GetByIDWithTracks récupère une playlist avec ses tracks T0501: Create Playlist Performance Optimization Search recherche des playlists selon des critères playlistRepository implémente PlaylistRepository avec GORM NewPlaylistRepository crée une nouvelle instance de PlaylistRepository T0501: Optimisé avec lazy loading des tracks T0501: Ne pas charger les tracks par défaut (lazy loading) Les tracks seront chargés à la demande via GetTracks si nécessaire GetByIDWithTracks récupère une playlist avec ses tracks (pour les cas où on en a besoin) T0501: Méthode séparée pour charger les tracks à la demande MIGRATION UUID: filterUserID migré vers *uuid.UUID Recherche par titre ou description Title field is mapped to 'name' column in database Filtrer par utilisateur Filtrer par statut public/privé Compter le total Récupérer les playlists avec pagination/home/senke/git/talas/veza/veza-backend-api/internal/repositories/playlist_track_repository.gotrackPositionsmaxPositionplaylistTracksplaylist_id = ? AND track_id = ?"playlist_id = ? AND track_id = ?"COALESCE(MAX(position), 0)"COALESCE(MAX(position), 0)"UPDATE playlist_tracks SET position = position + 1 WHERE playlist_id = ? AND position >= ?"UPDATE playlist_tracks SET position = position + 1 WHERE playlist_id = ? AND position >= ?"track_count + 1"track_count + 1"track not found in playlist"track not found in playlist"UPDATE playlist_tracks SET position = position - 1 WHERE playlist_id = ? AND position > ?"UPDATE playlist_tracks SET position = position - 1 WHERE playlist_id = ? AND position > ?"UPDATE playlists SET track_count = CASE WHEN track_count > 0 THEN track_count - 1 ELSE 0 END WHERE id = ?"UPDATE playlists SET track_count = CASE WHEN track_count > 0 THEN track_count - 1 ELSE 0 END WHERE id = ?""Track"position ASC"position ASC" PlaylistTrackRepository définit l'interface pour les opérations sur les playlist_tracks AddTrack ajoute un track à une playlist à une position donnée RemoveTrack retire un track d'une playlist ReorderTracks réorganise les positions des tracks dans une playlist GetTracks récupère tous les tracks d'une playlist avec leurs informations playlistTrackRepository implémente PlaylistTrackRepository avec GORM NewPlaylistTrackRepository crée une nouvelle instance de PlaylistTrackRepository Vérifier que la playlist existe Vérifier que le track n'est pas déjà dans la playlist Si erreur due à la structure de la table, on continue Si position <= 0, ajouter à la fin Décaler les positions existantes >= position Créer le PlaylistTrack Utiliser une transaction pour garantir la cohérence Mettre à jour le TrackCount de la playlist Vérifier que le PlaylistTrack existe Supprimer le PlaylistTrack Décaler les positions des tracks suivants Mettre à jour chaque position Ignorer les positions invalides Vérifier si la colonne position existe avant de l'utiliser dans ORDER BY/home/senke/git/talas/veza/veza-backend-api/internal/repositories/playlist_version_repository.goversion DESC"version DESC"playlist_id = ? AND version = ?"playlist_id = ? AND version = ?"COALESCE(MAX(version), 0)"COALESCE(MAX(version), 0)" PlaylistVersionRepository définit l'interface pour les opérations sur les versions de playlists Create crée une nouvelle version GetByID récupère une version par son ID GetByPlaylistID récupère toutes les versions d'une playlist GetLatestVersion récupère la dernière version d'une playlist GetByVersion récupère une version spécifique d'une playlist GetNextVersionNumber retourne le prochain numéro de version pour une playlist playlistVersionRepository implémente PlaylistVersionRepository avec GORM NewPlaylistVersionRepository crée une nouvelle instance de PlaylistVersionRepository/home/senke/git/talas/veza/veza-backend-api/internal/repositories/room_repository.go"Members""Messages"JOIN room_members ON rooms.id = room_members.room_id"JOIN room_members ON rooms.id = room_members.room_id"room_members.user_id = ?"room_members.user_id = ?"room_id = ? AND user_id = ?"room_id = ? AND user_id = ?"room_id = ? AND deleted_at IS NULL"room_id = ? AND deleted_at IS NULL" RoomRepository gère les opérations de base de données pour les rooms NewRoomRepository crée une nouvelle instance de RoomRepository Create crée une nouvelle room GetByID récupère une room par son ID Use explicit WHERE clause for UUID GetByUserID récupère toutes les rooms d'un utilisateur Note: RoomMember model doesn't have DeletedAt field, so we don't check for deleted_at Also, Preload("Members") would try to add deleted_at IS NULL which doesn't exist for RoomMember So we load members separately or use Unscoped() to avoid the deleted_at check Don't add deleted_at condition since RoomMember doesn't have DeletedAt Update met à jour une room Delete supprime une room (soft delete) RemoveMember retire un membre d'une room GetMembersByRoomID récupère tous les membres d'une room/home/senke/git/talas/veza/veza-backend-api/internal/repositories/user_repository.goidIntfailed to get user by ID: %w"failed to get user by ID: %w"failed to get user by email: %w"failed to get user by email: %w"failed to get user by username: %w"failed to get user by username: %w"token_version + ?"token_version + ?" UserRepository définit les méthodes pour interagir avec le modèle User (Cette interface est celle utilisée par les autres packages qui dépendent de ce repository) GormUserRepository est une implémentation de UserRepository utilisant GORM NewGormUserRepository crée une nouvelle instance de GormUserRepository CreateUser crée un nouvel utilisateur dans la base de données Utilisateur non trouvé GetUserByEmail récupère un utilisateur par son email DeleteUser supprime un utilisateur (soft delete si GORM est configuré pour ça) UpdateLastLoginAt met à jour le champ last_login_at pour un utilisateur IncrementTokenVersion incrémente la version du token d'un utilisateur --- Compatibility methods for services.UserRepository interface ---/home/senke/git/talas/veza/veza-backend-api/internal/repository/home/senke/git/talas/veza/veza-backend-api/internal/repository/user_repository.goNewUserRepositoryUserRepositoryImplemailsusernamesuserCopyemailExistsexistingUserIDusernameExistsexistingUser UserRepositoryImpl implémentation en mémoire du repository des utilisateurs username -> userID mapping NewUserRepository crée une nouvelle instance du repository GetByID récupère un utilisateur par son ID Retourner une copie pour éviter les modifications accidentelles GetByEmail récupère un utilisateur par son email GetByUsername récupère un utilisateur par son username Create crée un nouvel utilisateur Vérifier si l'email existe déjà Assigner un ID si vide Créer une copie pour éviter les modifications accidentelles Forcer les valeurs par défaut Update met à jour un utilisateur existant Vérifier si l'utilisateur existe Si l'email a changé, vérifier qu'il n'existe pas déjà Mettre à jour les mappings Si le username a changé, mettre à jour le mapping Vérifier que le nouveau username n'est pas déjà pris (par un autre utilisateur) Delete supprime un utilisateur Supprimer les mappings/home/senke/git/talas/veza/veza-backend-api/internal/response/home/senke/git/talas/veza/veza-backend-api/internal/response/response.goerrorCodeerrorDetails APIResponse is the unified response envelope Success sends a successful JSON response Created sends a 201 Created response BadRequest sends a 400 Bad Request response P0: Migré vers format AppError standardisé Unauthorized sends a 401 Unauthorized response Forbidden sends a 403 Forbidden response NotFound sends a 404 Not Found response InternalServerError sends a 500 Internal Server Error response Error sends a custom error response with specified status code Convertir status HTTP vers ErrorCode RespondWithAppError répond avec une AppError au format standardisé P0: Helper pour utiliser AppError depuis le package response Utiliser la structure APIResponse standardisée ValidationError sends a 400 Bad Request response with detailed validation errors/home/senke/git/talas/veza/veza-backend-api/internal/security/home/senke/git/talas/veza/veza-backend-api/internal/security/mfa.goMFAManagerMFAMethodMFASessionNewMFAManagerjson:"secret,omitempty"Phonejson:"phone,omitempty"VerifiedAtjson:"verified_at,omitempty"json:"last_used_at,omitempty"MethodIDjson:"method_id"GenerateTOTPSecretmfaGenerateTOTPQRCodeGenerateBackupCodesVerifyBackupCodeGenerateSMSMFASendSMSCodeVerifySMSCodeGenerateEmailMFASendEmailCodeVerifyEmailCodeGetUserMFAMethodsActivateMFAMethodDeactivateMFAMethodDeleteMFAMethodRequireMFAValidateMFALoginsecretBase32accountNamemethodIDcodeBytesphonesecurity"encoding/base32""github.com/pquerna/otp/totp"`json:"secret,omitempty"``json:"phone,omitempty"``json:"verified_at,omitempty"``json:"last_used_at,omitempty"``json:"method_id"``json:"used"`failed to generate secret: %w"failed to generate secret: %w"totp_%s"totp_%s""totp"otpauth://totp/%s:%s?secret=%s&issuer=%s"otpauth://totp/%s:%s?secret=%s&issuer=%s"method not found"method not found"method is not TOTP"method is not TOTP"failed to generate backup code: %w"failed to generate backup code: %w"backup_%s"backup_%s""backup"backup method not found"backup method not found"sms_%s"sms_%s"sms"sms"method is not SMS"method is not SMS"%06d"%06d"SMS code sent to %s: %s
"SMS code sent to %s: %s\n"email_%s"email_%s"method is not email"method is not email"Email code sent to %s: %s
"Email code sent to %s: %s\n"method must be verified before activation"method must be verified before activation"method does not belong to user"method does not belong to user"method is not active or verified"method is not active or verified"unsupported method type"unsupported method type" MFAMethod représente une méthode MFA totp, sms, email, backup MFASession représente une session MFA MFAManager gère l'authentification multi-facteurs NewMFAManager crée un nouveau gestionnaire MFA GenerateTOTPSecret génère un secret TOTP Générer un secret aléatoire Encoder en base32 Créer la méthode TOTP GenerateTOTPQRCode génère le QR code pour TOTP Format: otpauth://totp/issuer:account?secret=secret&issuer=issuer VerifyTOTP vérifie un code TOTP Vérifier le code TOTP GenerateBackupCodes génère des codes de sauvegarde Générer un code de 8 caractères Encoder en base32 et prendre les 8 premiers caractères Créer la méthode de sauvegarde Les codes sont stockés séparément VerifyBackupCode vérifie un code de sauvegarde Dans un vrai système, les codes seraient stockés de manière sécurisée Ici on simule la vérification GenerateSMSMFA génère une méthode MFA par SMS SendSMSCode envoie un code SMS Générer un code à 6 chiffres Dans un vrai système, on enverrait le SMS via un service Ici on simule l'envoi VerifySMSCode vérifie un code SMS Dans un vrai système, on vérifierait le code stocké GenerateEmailMFA génère une méthode MFA par email SendEmailCode envoie un code par email Dans un vrai système, on enverrait l'email via un service VerifyEmailCode vérifie un code email GetUserMFAMethods récupère toutes les méthodes MFA d'un utilisateur ActivateMFAMethod active une méthode MFA DeactivateMFAMethod désactive une méthode MFA DeleteMFAMethod supprime une méthode MFA RequireMFA vérifie si un utilisateur doit utiliser MFA ValidateMFALogin valide une connexion MFA/home/senke/git/talas/veza/veza-backend-api/internal/services/home/senke/git/talas/veza/veza-backend-api/internal/services/analytics_service.goABTestPercentageChangeABTestResultABTestStatsDifferenceAggregationResultAllowedCodecsAllowedFormatsArchiveResultAudioMetadataAvatarHeightAvatarWidthBitrateStrategyBitrateStrategyServiceBufferMonitorServiceComparisonResultDefaultCacheConfigDefaultRateLimitConfigDefaultRetentionPolicyEmailVerificationTokenEngagementMetricsErrCacheMissErrExportFailedErrExportFormatNotSupportedErrFFmpegNotAvailableErrInvalidCredentialsErrInvalidEmailErrInvalidTokenErrPlaylistShareExpiredErrPlaylistShareNotFoundErrSharePermissionDeniedErrSourceFileNotFoundErrTitleEmptyErrTitleTooLongErrUserNotFoundErrVersionNotFoundErrWeakPasswordExitPointExportFormatFormatCSVHLSPlaylistGeneratorIsInvalidCredentialsErrorIsInvalidTokenErrorIsUserNotFoundErrorMaxAvatarSizeMaxTrackDurationMaxTrackSizeMetadataServiceMinTrackDurationNewAnalyticsServiceNewBandwidthDetectionServiceNewBitrateAdaptationServiceNewBitrateStrategyServiceNewBufferMonitorServiceNewCircuitBreakerHTTPClientNewCommentServiceNewHLSPlaylistGeneratorNewHLSQueueServiceNewHLSServiceNewHLSServiceWithTranscodeNewHLSTranscodeServiceNewImageServiceNewMetadataServiceNewNotificationServiceNewOAuthServiceNewPlaybackABTestServiceNewPlaybackAggregationServiceNewPlaybackAlertsServiceNewPlaybackAnalyticsRateLimiterNewPlaybackAnalyticsServiceNewPlaybackAnalyticsServiceWithCacheNewPlaybackComparisonServiceNewPlaybackExportServiceNewPlaybackFilterServiceNewPlaybackHeatmapServiceNewPlaybackRetentionPolicyServiceNewPlaybackRetentionServiceNewPlaybackSegmentationServiceNewPlaylistAnalyticsServiceNewPlaylistFollowServiceNewPlaylistNotificationServiceNewPlaylistShareServiceNewPlaylistVersionServiceNewRBACServiceNewRedisUploadStoreNewRoleServiceNewRoyaltyServiceNewSearchServiceNewSocialServiceNewTokenBlacklistNewTrackExportServiceNewTrackHistoryServiceNewTrackSearchServiceNewTrackShareServiceNewTrackValidationServiceNewTrackVersionServiceNewTwoFactorServiceNewUserServiceOAuthAccountPaginationParamsPasswordResetTokenPercentageChangePeriodAggregationPeriodDayPeriodMonthPeriodTypePeriodWeekPlaybackABTestServicePlaybackAggregationServicePlaybackComparisonServicePlaybackExportServicePlaybackFilterPlaybackFilterServicePlaybackRetentionPolicyServicePlaybackRetentionServicePlaybackSegmentationServiceRateLimitConfigRedisUploadStoreReportStatsRetentionAnalysisResultRetentionPolicyRoyaltyServiceSegmentActiveListenerSegmentCasualListenerSegmentFocusedListenerSegmentFrequentSkipperSegmentHighCompletionSegmentHighEngagementSegmentInfoSegmentLowCompletionSegmentLowEngagementSegmentMediumCompletionSegmentMediumEngagementSegmentRetentionSegmentationResultStatisticalSignificanceStatsDifferenceStrategyAggressiveStrategyBalancedStrategyConservativeStrategyThresholdsTOTPSecretTokenBlacklistTrackExportServiceTrackValidationResultTrackValidationServiceTranscodeRequestTwoFactorServiceTwoFactorSetupTwoFactorVerificationTypeAnalyticsProcessTypeEmailSendTypeThumbnailGenerateTypeWebhookDeliveryUserMetricsUserSegmentVariantFilterVariantStatsWebhookPayloadbcryptCostcopyFilegeneratePlaylistShareTokengenerateShareTokengormUserRepositoryintPtrtimeUntilMidnighttimeUntilNextWeekplaycompletedPlayscompletionThresholdavgDurationparsedDatedateFormatSQLitesqliteResultstotalDuration`json:"count"``json:"unique_listeners"``json:"average_duration"`failed to check track: %w"failed to check track: %w"failed to record play: %w"failed to record play: %w"Track play recorded"Track play recorded"failed to count total plays: %w"failed to count total plays: %w"track_id = ? AND user_id IS NOT NULL"track_id = ? AND user_id IS NOT NULL"failed to count unique listeners: %w"failed to count unique listeners: %w"COALESCE(AVG(duration), 0)"COALESCE(AVG(duration), 0)"failed to calculate average duration: %w"failed to calculate average duration: %w"0.90.90000000000000002228106479329266893/9007199254740992track_id = ? AND duration >= ?"track_id = ? AND duration >= ?"failed to count completed plays: %w"failed to count completed plays: %w"%Y-%m-%d %H:00:00"%Y-%m-%d %H:00:00"%Y-%m-%d"%Y-%m-%d"%Y-W%W"%Y-W%W"%Y-%m"%Y-%m"gorm:"column:date"gorm:"column:count"`gorm:"column:date"``gorm:"column:count"`strftime('%s', played_at) as date, COUNT(*) as count"strftime('%s', played_at) as date, COUNT(*) as count"track_id = ? AND played_at >= ? AND played_at <= ?"track_id = ? AND played_at >= ? AND played_at <= ?""date"date ASC"date ASC"failed to get plays over time: %w"failed to get plays over time: %w"2006-01-02 15:04:05"2006-01-02 15:04:05"2006-01"2006-01"2006-W01"2006-W01"
			track_plays.track_id,
			tracks.title,
			tracks.artist,
			COUNT(*) as total_plays,
			COUNT(DISTINCT track_plays.user_id) as unique_listeners,
			COALESCE(AVG(track_plays.duration), 0) as average_duration
		`
			track_plays.track_id,
			tracks.title,
			tracks.artist,
			COUNT(*) as total_plays,
			COUNT(DISTINCT track_plays.user_id) as unique_listeners,
			COALESCE(AVG(track_plays.duration), 0) as average_duration
		`JOIN tracks ON tracks.id = track_plays.track_id"JOIN tracks ON tracks.id = track_plays.track_id"track_plays.track_id, tracks.title, tracks.artist"track_plays.track_id, tracks.title, tracks.artist"track_plays.played_at >= ?"track_plays.played_at >= ?"track_plays.played_at <= ?"track_plays.played_at <= ?"total_plays DESC"total_plays DESC"failed to count unique tracks: %w"failed to count unique tracks: %w"COALESCE(SUM(duration), 0)"COALESCE(SUM(duration), 0)"failed to calculate total duration: %w"failed to calculate total duration: %w" AnalyticsService gère les analytics de lecture de tracks NewAnalyticsService crée un nouveau service d'analytics TrackStats est maintenant défini dans internal/types/stats.go Import: veza-backend-api/internal/types PlayTimePoint représente un point de données temporel pour les graphiques TopTrack représente un track dans le classement UserStats est maintenant défini dans internal/types/stats.go RecordPlay enregistre une lecture de track MIGRATION UUID: userID migré vers *uuid.UUID (nullable) Updated query to use "id = ?" for UUID Total plays Unique listeners (distinct user_id, en excluant NULL) Average duration Completion rate (90% de la durée du track) GetPlaysOverTime récupère les lectures sur une période pour un graphique temporel Requête SQL pour grouper par intervalle Utiliser strftime pour SQLite (compatible avec la plupart des bases de données) Convertir les résultats Essayer de parser avec différents formats GetTopTracks récupère les tracks les plus écoutés Filtrer par date si fourni GetUserStats récupère les statistiques d'un utilisateur Vérifier que l'utilisateur existe Unique tracks Total durationjson:"session_count"EngagementScorejson:"engagement_score"SkipRatejson:"skip_rate"CompareVariantsgetAnalyticsForVariantcalculateVariantStatscalculateDifferencecalculatePercentageChangesafePercentageChangecalculateStatisticalSignificancecalculateTTestcalculateWelchDFnormalCDFerfdetermineWinnergenerateRecommendationPValuejson:"p_value"IsSignificantjson:"is_significant"ConfidenceLeveljson:"confidence_level"ConfidenceIntervalLowerjson:"confidence_interval_lower"ConfidenceIntervalUpperjson:"confidence_interval_upper"EffectSizejson:"effect_size"applyFiltersapplySortingapplyPaginationGetFilteredStatsGenerateMasterPlaylistGenerateMasterPlaylistWithCodecsGenerateQualityPlaylistGenerateQualityPlaylistWithVariableDurationsGetThresholdsShouldAdaptSelectStrategyIsValidStrategyOverallRetentionRatejson:"overall_retention_rate"HighEngagementRatejson:"high_engagement_rate"LowEngagementRatejson:"low_engagement_rate"exportDirExportTrackcopyTrackFileconvertTrackgetExportPathisFormatSupportedisFFmpegAvailablegetCodecgetBitrategetQualityDeleteExportDeleteAllExportsGenerateSecretEnableTwoFactorDisableTwoFactorVerifyTwoFactorGetTwoFactorStatusgenerateRecoveryCodeshashRecoveryCodeisRecoveryCoderemoveRecoveryCodejson:"event"AggregateByPeriodgetPeriodKeysortPeriodsAggregateByDateRangeGetTopTracksByPlaybackjson:"start_date,omitempty"json:"end_date,omitempty"UserIDsjson:"user_ids,omitempty"MinPlayTimejson:"min_play_time,omitempty"ArchiveAfterDeleteAfterlowThresholdhighThresholdSetThresholdsCalculateBufferLevelIsBufferLowIsBufferHighShouldAdaptBufferGetBufferStatusMonitorBufferExtractMetadatagetDefaultMetadataValidateMetadataIsBlacklistedAddTokenHashdb:"user_id"db:"token"db:"used"json:"parent_id" db:"parent_id"RequestsPerMinuteRequestsWindowMinRequestIntervalDailyQuotaWeeklyQuotaFollowUserUnfollowUserGetFollowersCountGetFollowingCountGetLikesCountIsTrackLikedjson:"role_id"json:"period"PausesTrendjson:"pauses_trend"SeeksTrendjson:"seeks_trend"json:"trends,omitempty"CompletedSessionsjson:"completed_sessions"ExportCSVExportJSONExportReportcalculateReportStatsexportReportCSVexportReportJSONExportToWriterexportCSVToWriterexportJSONToWriterarchiveDirexportServiceArchiveOldDataDeleteOldDataApplyRetentionPolicyshouldCompresscompressFileGetArchiveStatsRestoreFromArchivevalidateMagicBytesValidateFileSizeValidateDurationValidateCodecdetectFormatgetPeriodDatesgetStatsForPeriodComparePeriodsCompareTracksCompareUsersgetStatsForUserjson:"code" db:"code"json:"used" db:"used"json:"used_at" db:"used_at"CalculateRoyaltiesGetUserRoyaltiesVariantNamejson:"variant_name"SegmentStartjson:"segment_start"SegmentEndjson:"segment_end"RetentionRatejson:"retention_rate"ExitCountjson:"exit_count"ExitRatejson:"exit_rate"SegmentRetentionsjson:"segment_retentions"ExitPointsjson:"exit_points"json:"engagement_metrics"AnalyzedAtjson:"analyzed_at"SegmentUserscalculateUserMetricssegmentByEngagementsegmentByCompletionRatesegmentByBehaviorGetUserSegmentjson:"total_users"json:"user_metrics,omitempty"SegmentCountsjson:"segment_counts"ArchivedCountjson:"archived_count"ArchiveFilejson:"archive_file"json:"track_ids"ArchivedAtjson:"archived_at"AnalyzeRetentioncalculateSegmentRetentionidentifyExitPointsanalyzeEngagementPeriod1json:"period1"Period2json:"period2"Differencejson:"difference"json:"percentage_change"json:"code" binding:"required"json:"recovery_code,omitempty"json:"provider" db:"provider"json:"provider_id" db:"provider_id"json:"display_name" db:"display_name"json:"avatar_url" db:"avatar_url"json:"-" db:"access_token"json:"-" db:"refresh_token"RecoveryCodesjson:"recovery_codes"BufferLevelThresholdBandwidthRatioThresholdUseOrConditionMinCompletionRatejson:"min_completion_rate,omitempty"MaxCompletionRatejson:"max_completion_rate,omitempty"MaxPlayTimejson:"max_play_time,omitempty"json:"period,omitempty"json:"page,omitempty"json:"sort_by,omitempty"json:"sort_order,omitempty"VariantAjson:"variant_a"VariantBjson:"variant_b"Significancejson:"significance"Winnerjson:"winner,omitempty"Recommendationjson:"recommendation,omitempty"json:"-" db:"secret"json:"enabled" db:"enabled"/home/senke/git/talas/veza/veza-backend-api/internal/services/audit_service.gometadataJSONresourceIDnewPermissionsoldPermissionstargetUserID`json:"id" db:"id"``json:"user_id" db:"user_id"``json:"action" db:"action"``json:"resource" db:"resource"``json:"resource_id" db:"resource_id"``json:"ip_address" db:"ip_address"``json:"user_agent" db:"user_agent"``json:"metadata" db:"metadata"``json:"timestamp" db:"timestamp"``json:"resource_id"``json:"end_date"``json:"action_count" db:"action_count"``json:"unique_users" db:"unique_users"``json:"unique_ips" db:"unique_ips"``json:"unique_actions" db:"unique_actions"``json:"risk_score" db:"risk_score"`Failed to marshal audit metadata"Failed to marshal audit metadata"failed to marshal audit metadata: %w"failed to marshal audit metadata: %w"
		INSERT INTO audit_logs (id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
	`
		INSERT INTO audit_logs (id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
	`Failed to log audit action"Failed to log audit action"failed to log audit action: %w"failed to log audit action: %w"Audit action logged"Audit action logged"login_failed"login_failed"login_success"login_success"logout"logout"permission_change"permission_change"old_permissions"old_permissions"new_permissions"new_permissions""delete"
		SELECT id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp
		FROM audit_logs
		WHERE 1=1
	`
		SELECT id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp
		FROM audit_logs
		WHERE 1=1
	` AND user_id = $%d" AND user_id = $%d" AND action = $%d" AND action = $%d" AND resource = $%d" AND resource = $%d" AND timestamp >= $%d" AND timestamp >= $%d" AND timestamp <= $%d" AND timestamp <= $%d" ORDER BY timestamp DESC" ORDER BY timestamp DESC" LIMIT $%d" LIMIT $%d" OFFSET $%d" OFFSET $%d"failed to search audit logs: %w"failed to search audit logs: %w"Failed to scan audit log"Failed to scan audit log"
		SELECT action, resource, COUNT(*) as action_count, 
		       COUNT(DISTINCT user_id) as unique_users,
		       COUNT(DISTINCT ip_address) as unique_ips
		FROM audit_logs
		WHERE timestamp BETWEEN $1 AND $2
		GROUP BY action, resource
		ORDER BY action_count DESC
	`
		SELECT action, resource, COUNT(*) as action_count, 
		       COUNT(DISTINCT user_id) as unique_users,
		       COUNT(DISTINCT ip_address) as unique_ips
		FROM audit_logs
		WHERE timestamp BETWEEN $1 AND $2
		GROUP BY action, resource
		ORDER BY action_count DESC
	`failed to get audit stats: %w"failed to get audit stats: %w"Failed to scan audit stat"Failed to scan audit stat"
		WITH user_activity AS (
			SELECT 
				user_id,
				ip_address,
				COUNT(*) as action_count,
				COUNT(DISTINCT action) as unique_actions
			FROM audit_logs
			WHERE timestamp >= NOW() - INTERVAL '%d hours'
			GROUP BY user_id, ip_address
		)
		SELECT 
			user_id,
			ip_address,
			action_count,
			unique_actions,
			CASE 
				WHEN action_count > 1000 THEN 100
				WHEN action_count > 500 THEN 80
				WHEN action_count > 100 THEN 60
				WHEN action_count > 50 THEN 40
				WHEN action_count > 20 THEN 20
				ELSE 0
			END as risk_score
		FROM user_activity
		WHERE action_count > 20
		ORDER BY risk_score DESC, action_count DESC
	`
		WITH user_activity AS (
			SELECT 
				user_id,
				ip_address,
				COUNT(*) as action_count,
				COUNT(DISTINCT action) as unique_actions
			FROM audit_logs
			WHERE timestamp >= NOW() - INTERVAL '%d hours'
			GROUP BY user_id, ip_address
		)
		SELECT 
			user_id,
			ip_address,
			action_count,
			unique_actions,
			CASE 
				WHEN action_count > 1000 THEN 100
				WHEN action_count > 500 THEN 80
				WHEN action_count > 100 THEN 60
				WHEN action_count > 50 THEN 40
				WHEN action_count > 20 THEN 20
				ELSE 0
			END as risk_score
		FROM user_activity
		WHERE action_count > 20
		ORDER BY risk_score DESC, action_count DESC
	`failed to detect suspicious activity: %w"failed to detect suspicious activity: %w"Failed to scan suspicious activity"Failed to scan suspicious activity"
		DELETE FROM audit_logs 
		WHERE timestamp < NOW() - INTERVAL '%d days'
	`
		DELETE FROM audit_logs 
		WHERE timestamp < NOW() - INTERVAL '%d days'
	`failed to cleanup old audit logs: %w"failed to cleanup old audit logs: %w"
		SELECT id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp
		FROM audit_logs
		WHERE ip_address = $1
		ORDER BY timestamp DESC
		LIMIT $2
	`
		SELECT id, user_id, action, resource, resource_id, ip_address, user_agent, metadata, timestamp
		FROM audit_logs
		WHERE ip_address = $1
		ORDER BY timestamp DESC
		LIMIT $2
	`failed to get IP activity: %w"failed to get IP activity: %w" AuditService gère les logs d'audit AuditLogCreateRequest données pour créer un log d'audit AuditLogSearchRequest paramètres de recherche AuditStats statistiques d'audit SuspiciousActivity activité suspecte détectée NewAuditService crée un nouveau service d'audit LogAction enregistre une action d'audit Convertir les métadonnées en JSON Insérer le log d'audit LogLogin enregistre une tentative de connexion LogLogout enregistre une déconnexion LogUpload enregistre un upload de fichier LogPermissionChange enregistre un changement de permission LogDeletion enregistre une suppression Construire la requête dynamiquement/home/senke/git/talas/veza/veza-backend-api/internal/services/bandwidth_detection_service.gobandwidthbytesTransferredsecondsavailableKbpsInvalid duration for bandwidth measurement"Invalid duration for bandwidth measurement"Invalid bytes transferred for bandwidth measurement"Invalid bytes transferred for bandwidth measurement"8.01000.0 BandwidthDetectionService gère la détection de bande passante réseau T0347: Create Network Bandwidth Detection Service NewBandwidthDetectionService crée un nouveau service de détection de bande passante MeasureBandwidth mesure la bande passante en bps (bits per second) bytesTransferred: nombre d'octets transférés duration: durée du transfert Retourne la moyenne de bande passante en bps Calculer la bande passante en bps (bits per second) bytesTransferred * 8 pour convertir en bits duration.Seconds() pour obtenir la durée en secondes Utiliser float64 pour éviter les problèmes de précision avec les durées très courtes Ajouter l'échantillon Limiter le nombre d'échantillons Calculer et retourner la moyenne calculateAverage calcule la moyenne des échantillons de bande passante GetAverageBandwidth retourne la moyenne actuelle de bande passante sans ajouter de nouvel échantillon RecommendBitrate recommande un bitrate optimal en kbps basé sur la bande passante disponible bandwidth: bande passante en bps (bits per second) Retourne le bitrate recommandé en kbps Par défaut, retourner le bitrate le plus bas Réserver 20% de buffer pour éviter les problèmes de réseau Convertir en kbps pour la comparaison Recommander le bitrate le plus élevé possible selon la bande passante disponible Les bitrates standards sont: 128, 192, 320 kbps Si la bande passante est très faible, retourner quand même 128 kbps (le client devra gérer la mise en buffer) ClearSamples efface tous les échantillons de bande passante GetSampleCount retourne le nombre d'échantillons actuels/home/senke/git/talas/veza/veza-backend-api/internal/services/bitrate_adaptation_service.gobufferLevelcurrentBitraterecommendedBitratedateStrDayCountdayCountssortedDaysReasonCountavgBandwidthavgResultreasonCountstotalCount0: %w"0: %w"nil UUID: %w"nil UUID: %w"invalid current bitrate: %d"invalid current bitrate: %d"%f (must be between 0.0 and 1.0): %w"%f (must be between 0.0 and 1.0): %w"0.20.20000000000000001113602879701896397/18014398509481984Bitrate increase prevented due to low buffer"Bitrate increase prevented due to low buffer"current_bitrate"current_bitrate"buffer_level"buffer_level"Bitrate reduced due to very low buffer"Bitrate reduced due to very low buffer"new_bitrate"new_bitrate"Failed to create bitrate adaptation log"Failed to create bitrate adaptation log"Bitrate adaptation logged"Bitrate adaptation logged"old_bitrate"old_bitrate"`json:"total_adaptations"``json:"reasons"``json:"adaptations_over_time"``json:"average_bandwidth,omitempty"`Failed to count adaptations"Failed to count adaptations"failed to get analytics: %w"failed to get analytics: %w"reason, COUNT(*) as count"reason, COUNT(*) as count"Failed to get reason counts"Failed to get reason counts"AVG(network_bandwidth) as avg"AVG(network_bandwidth) as avg"track_id = ? AND network_bandwidth IS NOT NULL"track_id = ? AND network_bandwidth IS NOT NULL"created_at ASC"created_at ASC"Failed to get adaptations over time"Failed to get adaptations over time" BitrateAdaptationService gère l'adaptation de bitrate pour le streaming T0348: Create Bitrate Adaptation Service NewBitrateAdaptationService crée un nouveau service d'adaptation de bitrate AdaptBitrate adapte le bitrate en fonction de la bande passante et du niveau de buffer trackID: ID de la piste audio userID: ID de l'utilisateur currentBitrate: bitrate actuel en kbps bandwidth: bande passante disponible en bps bufferLevel: niveau de buffer (0.0 à 1.0) Retourne le nouveau bitrate recommandé en kbps MIGRATION UUID: userID est maintenant int64 Valider les paramètres Obtenir la recommandation de bitrate basée sur la bande passante Ajuster en fonction du niveau de buffer Si le buffer est faible (< 20%), ne pas augmenter le bitrate Si le buffer est très faible (<= 10%), réduire le bitrate Réduire d'un niveau Si le bitrate a changé, logger l'adaptation Ne pas retourner l'erreur, l'adaptation peut continuer même si le log échoue determineReason détermine la raison de l'adaptation de bitrate Si le buffer est faible, c'est la raison principale Sinon, déterminer selon si on augmente ou diminue Par défaut (ne devrait pas arriver) BitrateAnalytics représente les statistiques d'adaptation de bitrate AdaptationTimePoint représente un point dans le temps pour l'évolution des adaptations GetAnalytics récupère les statistiques d'adaptation de bitrate pour un track Compter le nombre total d'adaptations uuid.UUID Compter par raison Calculer la moyenne de bande passante (si disponible) Évolution dans le temps (groupé par jour) Récupérer tous les logs et grouper par jour en Go pour compatibilité SQLite/PostgreSQL Extraire la date (YYYY-MM-DD) Convertir en slice triée Trier par date (tri simple) Ajouter aux analytics Continuer sans les données temporelles intPtr retourne un pointeur vers un int/home/senke/git/talas/veza/veza-backend-api/internal/services/bitrate_strategy_service.gostrategybandwidthLowbandwidthRatiobufferLowthresholdsnetworkStabilityuserPreferenceconservative"conservative"aggressive"aggressive"balanced"balanced"0.30.29999999999999998895404319552844595/180143985094819840.150.149999999999999994455404319552844595/360287970189639680.60.59999999999999997785404319552844595/9007199254740992Invalid buffer level"Invalid buffer level""strategy"Invalid bandwidth ratio"Invalid bandwidth ratio"bandwidth_ratio"bandwidth_ratio" BitrateStrategy représente une stratégie d'adaptation de bitrate T0361: Create Bitrate Adaptation Strategy Service StrategyConservative est une stratégie conservatrice qui adapte le bitrate seulement quand les conditions sont vraiment défavorables StrategyAggressive est une stratégie agressive qui adapte le bitrate rapidement pour éviter les problèmes de streaming StrategyBalanced est une stratégie équilibrée entre conservative et aggressive StrategyThresholds représente les seuils pour une stratégie Seuil de niveau de buffer (0.0 à 1.0) Seuil de ratio de bande passante (0.0 à 1.0) Si true, utilise OR au lieu de AND BitrateStrategyService gère les stratégies d'adaptation de bitrate NewBitrateStrategyService crée un nouveau service de stratégies d'adaptation GetThresholds retourne les seuils pour une stratégie donnée Conservative: adapte seulement si buffer ET bande passante sont faibles 30% de buffer 70% de la bande passante nécessaire Utilise AND Aggressive: adapte si buffer OU bande passante est faible 15% de buffer 50% de la bande passante nécessaire Utilise OR Balanced: adapte si buffer ET bande passante sont modérément faibles 20% de buffer 60% de la bande passante nécessaire ShouldAdapt détermine si une adaptation de bitrate est nécessaire selon la stratégie, le niveau de buffer et le ratio de bande passante bufferLevel: niveau de buffer (0.0 = vide, 1.0 = plein) bandwidthRatio: ratio de bande passante disponible / nécessaire (0.0 à 1.0+) Retourne true si une adaptation est nécessaire Vérifier si le buffer est faible Vérifier si la bande passante est faible bandwidthRatio < threshold signifie que la bande passante disponible est inférieure au seuil requis Appliquer la logique selon la stratégie OR: adapter si buffer OU bande passante est faible AND: adapter seulement si buffer ET bande passante sont faibles SelectStrategy sélectionne une stratégie selon le contexte networkStability: stabilité du réseau (0.0 = instable, 1.0 = stable) userPreference: préférence de l'utilisateur (peut être nil pour auto) Retourne la stratégie recommandée Si l'utilisateur a une préférence, l'utiliser Sélectionner automatiquement selon la stabilité du réseau Réseau instable: utiliser une stratégie conservative Réseau stable: utiliser une stratégie aggressive pour meilleure qualité Réseau modéré: utiliser une stratégie balanced IsValidStrategy vérifie si une stratégie est valide/home/senke/git/talas/veza/veza-backend-api/internal/services/buffer_monitor_service.gobufferedshouldAdaptInvalid duration for buffer calculation"Invalid duration for buffer calculation"Invalid buffered time for buffer calculation"Invalid buffered time for buffer calculation""buffered""low"normal"normal"Buffer adaptation needed"Buffer adaptation needed" BufferMonitorService gère le monitoring du niveau de buffer T0353: Create Buffer Level Monitor Service Seuils de buffer (configurables) Seuil bas (défaut: 0.2) Seuil haut (défaut: 0.8) NewBufferMonitorService crée un nouveau service de monitoring de buffer 20% - buffer faible 80% - buffer élevé SetThresholds configure les seuils de buffer GetThresholds retourne les seuils actuels CalculateBufferLevel calcule le niveau de buffer (0.0 à 1.0) buffered: temps de contenu buffered en secondes duration: durée totale du contenu en secondes Retourne le niveau de buffer (0.0 = vide, 1.0 = plein) Calculer le niveau de buffer (ratio) S'assurer que le niveau est entre 0.0 et 1.0 IsBufferLow vérifie si le buffer est faible IsBufferHigh vérifie si le buffer est élevé ShouldAdaptBuffer détermine si une adaptation est nécessaire Retourne true si le buffer est trop faible ou trop élevé GetBufferStatus retourne le statut du buffer MonitorBuffer surveille le niveau de buffer et détermine si une adaptation est nécessaire Retourne le niveau de buffer calculé et si une adaptation est nécessaire/home/senke/git/talas/veza/veza-backend-api/internal/services/cache_service.go1800000000000failed to marshal value: %w"failed to marshal value: %w"Failed to set cache value"Failed to set cache value""key"Cache value set"Cache value set""ttl"redis: nilFailed to get cache value"Failed to get cache value"Failed to unmarshal cache value"Failed to unmarshal cache value"Cache value retrieved"Cache value retrieved"Failed to delete cache value"Failed to delete cache value"Cache value deleted"Cache value deleted"Failed to get keys by pattern"Failed to get keys by pattern""pattern"Failed to delete keys by pattern"Failed to delete keys by pattern"Cache keys deleted by pattern"Cache keys deleted by pattern"Failed to check cache key existence"Failed to check cache key existence"user:%d"user:%d"track:%d"track:%d"room:%d"room:%d"messages:%d:page:%d"messages:%d:page:%d"messages:%d:*"messages:%d:*"user_tracks:%d:page:%d"user_tracks:%d:page:%d"user_tracks:%d:*"user_tracks:%d:*"search:%s"search:%s"user_sessions:%d:*"user_sessions:%d:*"Failed to invalidate user cache pattern"Failed to invalidate user cache pattern"User cache invalidated"User cache invalidated"search:*"search:*"Failed to invalidate track cache pattern"Failed to invalidate track cache pattern"Track cache invalidated"Track cache invalidated"Failed to invalidate room cache pattern"Failed to invalidate room cache pattern"Room cache invalidated"Room cache invalidated"`json:"info"`cache miss"cache miss"! Service de cache Redis pour optimiser les performances! Ce service implémente une stratégie cache-aside avec invalidation automatique! pour améliorer les performances des requêtes fréquentes. CacheService gère le cache Redis avec différentes stratégies CacheConfig contient la configuration du cache DefaultCacheConfig retourne la configuration par défaut du cache NewCacheService crée un nouveau service de cache Set stocke une valeur dans le cache avec TTL Get récupère une valeur du cache Delete supprime une valeur du cache DeletePattern supprime toutes les clés correspondant à un pattern Exists vérifie si une clé existe dans le cache SetUser met en cache les données d'un utilisateur GetUser récupère les données d'un utilisateur depuis le cache DeleteUser supprime les données d'un utilisateur du cache SetTrack met en cache les métadonnées d'un track GetTrack récupère les métadonnées d'un track depuis le cache DeleteTrack supprime les métadonnées d'un track du cache SetRoom met en cache les données d'une room/conversation GetRoom récupère les données d'une room depuis le cache DeleteRoom supprime les données d'une room du cache SetMessages met en cache une liste de messages GetMessages récupère une liste de messages depuis le cache DeleteRoomMessages supprime tous les messages d'une room du cache SetUserTracks met en cache la liste des tracks d'un utilisateur GetUserTracks récupère la liste des tracks d'un utilisateur depuis le cache DeleteUserTracks supprime tous les tracks d'un utilisateur du cache SetSearchResults met en cache les résultats de recherche GetSearchResults récupère les résultats de recherche depuis le cache InvalidateUserCache invalide tout le cache lié à un utilisateur InvalidateTrackCache invalide tout le cache lié à un track Invalider les recherches car le track peut apparaître dans les résultats InvalidateRoomCache invalide tout le cache lié à une room GetStats retourne les statistiques du cache Parser les informations Redis pour extraire les métriques CacheStats contient les statistiques du cache ErrCacheMiss est retourné quand une clé n'existe pas dans le cache Close ferme la connexion Redis/home/senke/git/talas/veza/veza-backend-api/internal/services/chat_service.go`json:"ws_url"`JWT secret is not configured"JWT secret is not configured""sub"aud"aud"veza-chat"veza-chat"iss"iss"veza-backend"veza-backend"iat"iat""exp"failed to sign token: %w"failed to sign token: %w"/ws"/ws" Relative path, frontend appends base URL/home/senke/git/talas/veza/veza-backend-api/internal/services/circuit_breaker.gocbNamehttpRespCircuit breaker state changed"Circuit breaker state changed""from"server error: %d"server error: %d"rejected"rejected"Circuit breaker is open, request rejected"Circuit breaker is open, request rejected"circuit_breaker"circuit_breaker"circuit breaker is open: service unavailable"circuit breaker is open: service unavailable"unexpected response type from circuit breaker"unexpected response type from circuit breaker" CircuitBreakerHTTPClient wraps an HTTP client with circuit breaker protection MOD-P2-007: Circuit breaker pour protéger contre dépendances lentes/indisponibles NewCircuitBreakerHTTPClient creates a new HTTP client with circuit breaker MOD-P2-007: Circuit breaker avec seuils configurables Configuration circuit breaker: - MaxRequests: 3 requêtes simultanées max - Interval: 60s pour réinitialiser les compteurs - Timeout: 30s avant de passer en half-open - ReadyToTrip: s'ouvre après 5 échecs consécutifs MOD-P2-007: Mettre à jour les métriques lors du changement d'état Note: On ne peut pas accéder à cb ici car il n'est pas encore créé Les métriques seront mises à jour dans Do() après chaque requête Do executes an HTTP request with circuit breaker protection MOD-P2-007: Wrapper pour http.Client.Do avec circuit breaker MOD-P2-007: Mettre à jour les métriques avant l'exécution Exécuter la requête via circuit breaker MOD-P2-007: Enregistrer l'échec dans les métriques Considérer les codes 5xx comme des erreurs pour le circuit breaker MOD-P2-007: Enregistrer le succès dans les métriques Circuit breaker ouvert ou erreur HTTP MOD-P2-007: Enregistrer le rejet dans les métriques Type assertion pour récupérer la réponse MOD-P2-007: Mettre à jour les métriques après succès DoWithContext executes an HTTP request with context and circuit breaker protection MOD-P2-007: Version avec contexte pour timeout/cancellation Créer une nouvelle requête avec le contexte/home/senke/git/talas/veza/veza-backend-api/internal/services/comment_service.goFailed to create comment"Failed to create comment"Comment created"Comment created"track_id = ? AND parent_id IS NULL"track_id = ? AND parent_id IS NULL""Replies"Replies.User"Replies.User"Failed to get comments"Failed to get comments"Failed to update comment"Failed to update comment"Comment updated"Comment updated"parent_id = ?"parent_id = ?"Failed to get replies"Failed to get replies"Failed to delete comment"Failed to delete comment" CreateComment creates a new comment on a track Updated trackID and parentID to uuid.UUID Verify if track exists Verify if parent comment exists (if reply) Ensure parent belongs to the same track Preload user info for response Return comment without user info if preload fails GetComments retrieves comments for a track Updated trackID to uuid.UUID Count total top-level comments (or all comments? usually top-level for pagination, replies fetched separately or nested) Here we fetch all top-level comments Fetch comments with user info and replies Note: Deep nesting of replies might require recursive query or multiple queries. For simplicity, we just preload direct replies or let frontend handle threading if flat list. Assuming flat list of top level + preloaded replies? Let's just fetch top level and preload their replies one level deep for now UpdateComment updates a comment Updated commentID to uuid.UUID Check permission GetReplies retrieves replies for a given parent comment ID Updated parentID to uuid.UUID Verify if parent comment exists Count total replies Fetch replies with user info Order by oldest first DeleteComment deletes a comment MIGRATION UUID: userID migré vers uuid.UUID, commentID reste int64 Soft delete or hard delete? Model has DeletedAt so soft delete/home/senke/git/talas/veza/veza-backend-api/internal/services/email_service.goverifyURLvtverified"encoding/base64"html/template"html/template"SMTP_USER"SMTP_USER"FROM_EMAIL"FROM_EMAIL"FROM_NAME"FROM_NAME"`db:"id"``db:"user_id"``db:"token"``db:"expires_at"``db:"used"``db:"created_at"`%s/verify-email?token=%s"%s/verify-email?token=%s"Verify your Veza account"Verify your Veza account"failed to send verification email: %w"failed to send verification email: %w"Verification email sent"Verification email sent"
		SELECT id, user_id, token, expires_at, used, created_at
		FROM email_verification_tokens
		WHERE token = $1 AND used = FALSE
	`
		SELECT id, user_id, token, expires_at, used, created_at
		FROM email_verification_tokens
		WHERE token = $1 AND used = FALSE
	`invalid or expired verification token"invalid or expired verification token"failed to verify token: %w"failed to verify token: %w"failed to update user email verification: %w"failed to update user email verification: %w"
		UPDATE email_verification_tokens
		SET used = TRUE
		WHERE id = $1
	`
		UPDATE email_verification_tokens
		SET used = TRUE
		WHERE id = $1
	`failed to mark token as used: %w"failed to mark token as used: %w"
		UPDATE users
		SET email_verified = TRUE, email_verified_at = NOW()
		WHERE id = $1
	`
		UPDATE users
		SET email_verified = TRUE, email_verified_at = NOW()
		WHERE id = $1
	`Email verified"Email verified"
		SELECT email_verified
		FROM users
		WHERE id = $1
	`
		SELECT email_verified
		FROM users
		WHERE id = $1
	`failed to check verification status: %w"failed to check verification status: %w"
		UPDATE email_verification_tokens
		SET used = TRUE
		WHERE user_id = $1 AND used = FALSE
	`
		UPDATE email_verification_tokens
		SET used = TRUE
		WHERE user_id = $1 AND used = FALSE
	`
		INSERT INTO email_verification_tokens (user_id, token, expires_at, used)
		VALUES ($1, $2, $3, FALSE)
	`
		INSERT INTO email_verification_tokens (user_id, token, expires_at, used)
		VALUES ($1, $2, $3, FALSE)
	`Email not configured, logging instead"Email not configured, logging instead"From: %s <%s>
"From: %s <%s>\r\n"From: %s <%s>
To: %s
Subject: %s
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

%sfailed to send email: %w"failed to send email: %w"
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Verify your Veza account</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h1 style="color: #4CAF50;">Welcome to Veza!</h1>
        <p>Thank you for signing up. Please verify your email address to complete your registration.</p>
        <div style="text-align: center; margin: 30px 0;">
            <a href="{{.VerifyURL}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
                Verify Email Address
            </a>
        </div>
        <p>Or copy and paste this link into your browser:</p>
        <p style="word-break: break-all; color: #666;">{{.VerifyURL}}</p>
        <p style="margin-top: 30px; color: #666; font-size: 12px;">
            This link will expire in 24 hours.
        </p>
    </div>
</body>
</html>
`
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Verify your Veza account</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h1 style="color: #4CAF50;">Welcome to Veza!</h1>
        <p>Thank you for signing up. Please verify your email address to complete your registration.</p>
        <div style="text-align: center; margin: 30px 0;">
            <a href="{{.VerifyURL}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
                Verify Email Address
            </a>
        </div>
        <p>Or copy and paste this link into your browser:</p>
        <p style="word-break: break-all; color: #666;">{{.VerifyURL}}</p>
        <p style="margin-top: 30px; color: #666; font-size: 12px;">
            This link will expire in 24 hours.
        </p>
    </div>
</body>
</html>
`verification"verification"Click here to verify your email: %s"Click here to verify your email: %s"VerifyURL"VerifyURL"failed to send password reset email: %w"failed to send password reset email: %w"Password reset email sent"Password reset email sent"
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Reset your Veza password</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h1 style="color: #4CAF50;">Reset your password</h1>
        <p>You requested to reset your Veza account password. Click the button below to continue.</p>
        <div style="text-align: center; margin: 30px 0;">
            <a href="{{.ResetURL}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
                Reset Password
            </a>
        </div>
        <p>Or copy and paste this link into your browser:</p>
        <p style="word-break: break-all; color: #666;">{{.ResetURL}}</p>
        <p style="margin-top: 30px; color: #666; font-size: 12px;">
            This link will expire in 1 hour. If you didn't request this, please ignore this email.
        </p>
    </div>
</body>
</html>
`
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Reset your Veza password</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
    <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
        <h1 style="color: #4CAF50;">Reset your password</h1>
        <p>You requested to reset your Veza account password. Click the button below to continue.</p>
        <div style="text-align: center; margin: 30px 0;">
            <a href="{{.ResetURL}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
                Reset Password
            </a>
        </div>
        <p>Or copy and paste this link into your browser:</p>
        <p style="word-break: break-all; color: #666;">{{.ResetURL}}</p>
        <p style="margin-top: 30px; color: #666; font-size: 12px;">
            This link will expire in 1 hour. If you didn't request this, please ignore this email.
        </p>
    </div>
</body>
</html>
`Click here to reset your password: %s"Click here to reset your password: %s" EmailService handles email operations NewEmailService creates a new email service EmailVerificationToken represents an email verification token SendVerificationEmail sends a verification email to the user T0184: Accepte email et token (le token est généré et stocké par EmailVerificationService) T0184: Étape 3 - Générer URL de vérification avec token T0184: Étape 4 - Construire email HTML avec lien T0184: Étape 5 - Envoyer email via SMTP (gestion erreurs sans faire échouer registration) SendVerificationEmailWithUserID sends a verification email to the user (legacy method for backward compatibility) This method generates and stores the token itself Generate verification token Use the new method to send the email VerifyEmailToken verifies an email verification token Check if token has expired Update user's email verification status ResendVerificationEmail resends a verification email Check if already verified Send new verification email (use legacy method that generates token) generateVerificationToken generates a secure random token storeVerificationToken stores a verification token in the database Token expires in 24 hours sendEmail sends an email using SMTP If no SMTP configured, just log (for development) Email headers buildVerificationEmailHTML builds the HTML email template T0184: Construit l'email HTML avec lien de vérification SendPasswordResetEmail sends a password reset email Build reset URL Prepare email content buildPasswordResetEmail builds the HTML password reset email template/home/senke/git/talas/veza/veza-backend-api/internal/services/email_verification_service.gotokenHashtokenPreview"crypto/sha256""encoding/hex"Failed to generate random token"Failed to generate random token"failed to generate token: %w"failed to generate token: %w"INSERT INTO email_verification_tokens (user_id, email, token, token_hash, expires_at, used) VALUES ($1, $2, $3, $4, $5, FALSE)"INSERT INTO email_verification_tokens (user_id, email, token, token_hash, expires_at, used) VALUES ($1, $2, $3, $4, $5, FALSE)"Failed to store verification token"Failed to store verification token"failed to store token: %w"failed to store token: %w"Verification token stored"Verification token stored"SELECT user_id, expires_at, used FROM email_verification_tokens WHERE token_hash = $1"SELECT user_id, expires_at, used FROM email_verification_tokens WHERE token_hash = $1"Verification token not found"Verification token not found"invalid token"invalid token"Failed to verify token"Failed to verify token"Verification token already used"Verification token already used"token already used"token already used"Verification token expired"Verification token expired"token expired"token expired"UPDATE email_verification_tokens SET used = TRUE WHERE token_hash = $1"UPDATE email_verification_tokens SET used = TRUE WHERE token_hash = $1"Verification token verified successfully"Verification token verified successfully"UPDATE email_verification_tokens SET used = TRUE WHERE user_id = $1 AND used = FALSE"UPDATE email_verification_tokens SET used = TRUE WHERE user_id = $1 AND used = FALSE"failed to invalidate old tokens: %w"failed to invalidate old tokens: %w"Failed to get rows affected"Failed to get rows affected"Old verification tokens invalidated"Old verification tokens invalidated"tokens_invalidated"tokens_invalidated" EmailVerificationService gère la génération, le stockage et la validation des tokens de vérification email T0182: Service pour gérer les tokens de vérification email avec expiration et invalidation NewEmailVerificationService crée une nouvelle instance d'EmailVerificationService GenerateToken génère un token aléatoire sécurisé de 32 bytes encodé en base64 URL-safe T0182: Génère un token aléatoire pour la vérification d'email hashToken helper pour hasher le token StoreToken stocke un token de vérification en base de données avec une expiration de 24h T0182: Sauvegarde le token avec expiration 24h Note: On insère le token hash dans token_hash et NULL dans token (si la colonne existe et est nullable) ou on garde token plain text si schema legacy l'exige, mais l'erreur dit token_hash NOT NULL. On ne connait pas la contrainte sur 'token'. On va supposer qu'on peut migrer vers le hash. Si 'token' est aussi NOT NULL, il faudra le remplir. Mais pour la sécurité, on ne devrait pas. Essayons de remplir les deux pour compatibilité si besoin, ou juste le hash si 'token' est nullable. D'apres le code existant qui insérait 'token', la colonne 'token' existe. On va insérer le hash dans 'token_hash' ET le token dans 'token' (pour l'instant, pour éviter une erreur not-null sur 'token' si elle existe). EDIT: Secure practice -> token should be hashed. Plain token column should be removed or nullable. L'erreur précédente était "null value in column token_hash". Supposons que 'token' column est NULLABLE ou supprimé? Tente d'écrire dans 'token_hash' et 'token'. VerifyToken valide un token de vérification, vérifie son expiration et le marque comme utilisé T0182: Valide le token, vérifie l'expiration et marque comme utilisé MIGRATION UUID: retourne uuid.UUID au lieu de int64 Mark as used InvalidateOldTokens invalide tous les tokens de vérification précédents pour un utilisateur T0182: Invalide les tokens précédents pour un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/errors.gouser already exists"user already exists"password does not meet security requirements"password does not meet security requirements"invalid email format"invalid email format"title must be less than 200 characters"title must be less than 200 characters"invalid track ID"invalid track ID"invalid user ID"invalid user ID"invalid bitrate"invalid bitrate"invalid buffer level"invalid buffer level"parent comment belongs to a different track"parent comment belongs to a different track"conversation not found"conversation not found" Common service errors ErrUserAlreadyExists is returned when trying to create a user that already exists ErrInvalidCredentials is returned when login credentials are invalid ErrUserNotFound is returned when a user is not found ErrInvalidToken is returned when a token is invalid or expired ErrWeakPassword is returned when password doesn't meet requirements ErrInvalidEmail is returned when email format is invalid ErrPlaylistNotFound is returned when a playlist is not found ErrTrackNotFound is returned when a track is not found ErrForbidden is returned when access is denied ErrAccessDenied is alias for ErrForbidden ErrTrackAlreadyInPlaylist is returned when adding a duplicate track ErrTitleEmpty is returned when title is empty ErrTitleTooLong is returned when title exceeds limit ErrInvalidTrackID is returned when track ID is invalid/nil ErrInvalidUserID is returned when user ID is invalid/nil ErrInvalidBitrate is returned when bitrate is invalid ErrInvalidBufferLevel is returned when buffer level is invalid ErrCommentNotFound is returned when a comment is not found ErrParentCommentNotFound is returned when a parent comment is not found ErrParentTrackMismatch is returned when parent comment is on different track ErrRoomNotFound is returned when a room/conversation is not found IsUserAlreadyExistsError checks if the error is a user already exists error IsInvalidCredentialsError checks if the error is an invalid credentials error IsUserNotFoundError checks if the error is a user not found error IsInvalidTokenError checks if the error is an invalid token error IsWeakPassword checks if the error is a weak password error IsInvalidEmail checks if the error is an invalid email error/home/senke/git/talas/veza/veza-backend-api/internal/services/hls_cleanup_service.gocleanedCounttrackDirvalidDirsabsOutputDirabsTrackDirorphanedCountfailed to fetch streams: %w"failed to fetch streams: %w"Cleaning up segments for deleted track"Cleaning up segments for deleted track"stream_id"stream_id"Failed to cleanup stream files"Failed to cleanup stream files"Failed to delete stream record"Failed to delete stream record"Failed to check track existence"Failed to check track existence"Cleanup deleted tracks completed"Cleanup deleted tracks completed"cleaned_count"cleaned_count"track_%s"track_%s"track_"track_"Found orphaned segment directory"Found orphaned segment directory"Failed to remove orphaned directory"Failed to remove orphaned directory"failed to walk output directory: %w"failed to walk output directory: %w"Cleanup orphaned segments completed"Cleanup orphaned segments completed"failed to get absolute path: %w"failed to get absolute path: %w"failed to get absolute output dir: %w"failed to get absolute output dir: %w"invalid track directory path: %s"invalid track directory path: %s"failed to remove track directory: %w"failed to remove track directory: %w"Cleaned up stream files"Cleaned up stream files"track_dir"track_dir"Starting HLS cleanup"Starting HLS cleanup"Failed to cleanup deleted tracks"Failed to cleanup deleted tracks"failed to cleanup deleted tracks: %w"failed to cleanup deleted tracks: %w"Failed to cleanup orphaned segments"Failed to cleanup orphaned segments"failed to cleanup orphaned segments: %w"failed to cleanup orphaned segments: %w"HLS cleanup completed"HLS cleanup completed"deleted_tracks_cleaned"deleted_tracks_cleaned"orphaned_segments_cleaned"orphaned_segments_cleaned" HLSCleanupService gère le nettoyage des segments HLS obsolètes NewHLSCleanupService crée un nouveau service de cleanup HLS CleanupDeletedTracks nettoie les segments HLS des tracks supprimés MIGRATION UUID: Completée. TrackID et StreamID en UUID. Track deleted, cleanup segments Continue avec les autres streams même en cas d'erreur Continue avec les autres streams CleanupOrphanedSegments nettoie les segments HLS qui n'ont pas de stream associé dans la base de données Récupérer tous les streams valides Créer un map des répertoires de streams valides Construire le chemin du répertoire du stream Parcourir le répertoire de sortie HLS Ignorer les erreurs de lecture de répertoire Vérifier si c'est un répertoire de track (format: track_XXX) Obtenir le répertoire parent pour vérifier si c'est un track_XXX Vérifier si ce répertoire est dans la liste des répertoires valides Supprimer le répertoire orphelin Continue avec les autres répertoires cleanupStreamFiles supprime les fichiers d'un stream Construire le chemin du répertoire du track Vérifier que le chemin est sécurisé (pas de directory traversal) Vérifier que le répertoire est bien dans outputDir Supprimer le répertoire et tous ses contenus CleanupAll exécute tous les nettoyages Nettoyer les tracks supprimés Nettoyer les segments orphelins/home/senke/git/talas/veza/veza-backend-api/internal/services/hls_playlist_generator.gosortedBitratessegmentDurationtargetDurationseg#EXTM3U
"#EXTM3U\n"#EXT-X-VERSION:3
"#EXT-X-VERSION:3\n"#EXT-X-STREAM-INF:BANDWIDTH=%d
"#EXT-X-STREAM-INF:BANDWIDTH=%d\n"%s/%dk/playlist.m3u8
"%s/%dk/playlist.m3u8\n"#EXT-X-STREAM-INF:BANDWIDTH=%d,CODECS="%s"
"#EXT-X-STREAM-INF:BANDWIDTH=%d,CODECS=\"%s\"\n"#EXT-X-TARGETDURATION:%d
"#EXT-X-TARGETDURATION:%d\n"#EXT-X-MEDIA-SEQUENCE:0
"#EXT-X-MEDIA-SEQUENCE:0\n"#EXT-X-PLAYLIST-TYPE:VOD
"#EXT-X-PLAYLIST-TYPE:VOD\n"#EXTINF:%.2f,
"#EXTINF:%.2f,\n"#EXT-X-ENDLIST
"#EXT-X-ENDLIST\n"#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ENDLIST
"#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ENDLIST\n" HLSPlaylistGenerator génère des playlists HLS au format standard T0341: Create HLS Master Playlist Generator NewHLSPlaylistGenerator crée un nouveau générateur de playlist HLS GenerateMasterPlaylist génère un master playlist HLS avec les variantes de qualité bitrates: liste des bitrates en kbps (ex: [128, 192, 320]) baseURL: URL de base pour les playlists de qualité (ex: "track_123" ou "http://example.com/track_123") Retourne le contenu du master playlist au format HLS standard En-tête HLS standard Trier les bitrates par ordre croissant pour un meilleur streaming adaptatif Générer une entrée pour chaque qualité Calculer la bandwidth en bits par seconde (bitrate est en kbps) Format HLS standard: #EXT-X-STREAM-INF:BANDWIDTH={bandwidth} Pour l'audio, on peut aussi ajouter CODECS si nécessaire URL relative vers le playlist de qualité Format: {baseURL}/{bitrate}k/playlist.m3u8 GenerateMasterPlaylistWithCodecs génère un master playlist HLS avec codecs spécifiés bitrates: liste des bitrates en kbps baseURL: URL de base pour les playlists de qualité codec: codec audio (ex: "mp4a.40.2" pour AAC-LC) Retourne le contenu du master playlist avec codecs Trier les bitrates par ordre croissant Générer une entrée pour chaque qualité avec codec Format HLS avec codec: #EXT-X-STREAM-INF:BANDWIDTH={bandwidth},CODECS="{codec}" GenerateQualityPlaylist génère une quality playlist HLS pour une qualité spécifique T0342: Create HLS Quality Playlist Generator segments: liste des noms de fichiers de segments (ex: ["segment_000.ts", "segment_001.ts"]) segmentDuration: durée de chaque segment en secondes (ex: 10.0) Retourne le contenu de la quality playlist au format HLS standard TARGETDURATION: durée maximale d'un segment (arrondie à l'entier supérieur) Format: #EXT-X-TARGETDURATION:{duration} MEDIA-SEQUENCE: numéro de séquence du premier segment (0 pour VOD) PLAYLIST-TYPE: VOD (Video On Demand) pour les playlists complètes Ajouter chaque segment avec sa durée Format: #EXTINF:{duration}, La durée est en secondes avec 2 décimales Nom du fichier segment Marqueur de fin pour les playlists VOD GenerateQualityPlaylistWithVariableDurations génère une quality playlist avec durées variables par segment segments: liste des segments avec leurs durées respectives Calculer la durée maximale pour TARGETDURATION MEDIA-SEQUENCE: numéro de séquence du premier segment PLAYLIST-TYPE: VOD Ajouter chaque segment avec sa durée spécifique Marqueur de fin SegmentInfo représente un segment avec sa durée/home/senke/git/talas/veza/veza-backend-api/internal/services/hls_queue_service.goexistingJobtrack_id = ? AND status IN ?"track_id = ? AND status IN ?"Job already exists for track"Job already exists for track"Job enqueued"Job enqueued""priority"priority DESC, created_at ASC"priority DESC, created_at ASC"completed_at"completed_at"Max retries exceeded"Max retries exceeded"retry_count"retry_count" HLSQueueService gère la queue de transcodage HLS NewHLSQueueService crée un nouveau service de queue HLS Enqueue ajoute un job de transcodage à la queue EnqueueWithID ajoute un job de transcodage à la queue et retourne le job ID T0343: Retourne le job ID pour l'endpoint de déclenchement Vérifier si un job existe déjà pour ce track avec statut pending ou processing Un job existe déjà, retourner son ID Dequeue récupère le prochain job à traiter (par priorité puis date de création) Utiliser une transaction pour éviter les race conditions Récupérer le job avec la plus haute priorité et la plus ancienne date de création Mettre à jour le statut et la date de début Pas de job disponible MarkCompleted marque un job comme terminé MarkFailed marque un job comme échoué RetryJob réessaie un job qui a échoué Vérifier si on peut encore réessayer Réinitialiser le job pour un nouvel essai GetJob récupère un job par son ID GetPendingJobsCount retourne le nombre de jobs en attente/home/senke/git/talas/veza/veza-backend-api/internal/services/hls_service.gohlsStreammasterPlaylistPathqualityPlaylistPathabsSegmentPathexistingStreamtranscodedStreamqueueJobtrack_id = ? AND status = ?"track_id = ? AND status = ?"HLS stream not found for track %s"HLS stream not found for track %s"failed to query HLS stream: %w"failed to query HLS stream: %w"master playlist file not found: %s"master playlist file not found: %s"failed to read master playlist: %w"failed to read master playlist: %w"playlist.m3u8"playlist.m3u8"quality playlist file not found: %s"quality playlist file not found: %s"failed to read quality playlist: %w"failed to read quality playlist: %w"segment file not found: %s"segment file not found: %s"failed to get absolute track dir: %w"failed to get absolute track dir: %w"invalid segment path: %s"invalid segment path: %s"transcode service not configured"transcode service not configured"track cannot be nil"track cannot be nil"HLS stream already exists and is ready for track %s"HLS stream already exists and is ready for track %s"HLS stream is already being processed for track %s"HLS stream is already being processed for track %s"Failed to delete existing stream"Failed to delete existing stream"failed to create HLS stream record: %w"failed to create HLS stream record: %w"failed to transcode track: %w"failed to transcode track: %w"failed to update HLS stream: %w"failed to update HLS stream: %w"Failed to update track status to completed"Failed to update track status to completed"HLS transcoding completed"HLS transcoding completed"queue service not configured"queue service not configured"failed to query track: %w"failed to query track: %w"failed to enqueue transcode job: %w"failed to enqueue transcode job: %w"HLS transcode job enqueued"HLS transcode job enqueued""bitrates"segments_count"segments_count"playlist_url"playlist_url"queue_job_id"queue_job_id" HLSService gère la récupération et le service des fichiers HLS NewHLSService crée un nouveau service HLS NewHLSServiceWithTranscode crée un nouveau service HLS avec service de transcodage SetTranscodeService définit le service de transcodage SetQueueService définit le service de queue HLS GetMasterPlaylist récupère le contenu du master playlist pour un track Lire le fichier master.m3u8 Le PlaylistURL est relatif au outputDir (ex: track_123/master.m3u8) Si c'est un chemin relatif, il devrait déjà être relatif à outputDir Vérifier si c'est déjà un chemin complet ou relatif GetQualityPlaylist récupère le contenu d'une quality playlist pour un track et bitrate Construire le chemin vers la quality playlist GetSegmentPath récupère le chemin complet d'un segment pour un track, bitrate et nom de segment Construire le chemin vers le segment Vérifier que le segment est bien dans le répertoire du track TriggerTranscode déclenche le transcodage d'un track en HLS Vérifier si un stream existe déjà pour ce track Un stream existe déjà, vérifier son statut Si le stream est en cours de traitement ou a échoué, on peut le retranscoder Supprimer l'ancien stream si nécessaire Mettre à jour le statut du track si nécessaire Créer un stream en statut "processing" Transcoder le track Mettre à jour le statut en "failed" Mettre à jour le stream avec les données du transcodage Mettre à jour le statut du track TriggerTranscodeQueue déclenche le transcodage HLS via la queue (T0343) Vérifie les permissions et ajoute un job dans la queue Vérifier que le track existe et que l'utilisateur est propriétaire Vérifier les permissions (UUID comparison) Ajouter le job dans la queue avec priorité par défaut (5) GetStreamStatus récupère le statut d'un stream HLS pour un track Ajouter des informations supplémentaires si le stream est en cours de traitement Vérifier s'il y a un job de transcodage en cours/home/senke/git/talas/veza/veza-backend-api/internal/services/hls_transcode_service.gocleanupErrplaylistURLsegmentsCountoutputPatternplaylistPathqualityDirdurationStros/exec"os/exec"track file path is empty"track file path is empty"track file does not exist: %s"track file does not exist: %s"failed to create track directory: %w"failed to create track directory: %w"Failed to cleanup track directory"Failed to cleanup track directory"failed to transcode bitrate %dk: %w"failed to transcode bitrate %dk: %w"Transcoded bitrate"Transcoded bitrate"master.m3u8"master.m3u8"failed to generate master playlist: %w"failed to generate master playlist: %w"failed to count segments: %w"failed to count segments: %w"%dk"%dk"failed to create quality directory: %w"failed to create quality directory: %w"segment_%03d.ts"segment_%03d.ts"ffmpeg"ffmpeg"-i"-i"-codec:a"-codec:a""aac"-b:a"-b:a"-hls_time"-hls_time""10"-hls_playlist_type"-hls_playlist_type"vod"vod"-hls_segment_filename"-hls_segment_filename"-hls_list_size"-hls_list_size"-y"-y"FFmpeg transcoding failed"FFmpeg transcoding failed""output"ffmpeg failed: %w"ffmpeg failed: %w"playlist file was not created: %s"playlist file was not created: %s"#EXTM3U"#EXTM3U"#EXT-X-VERSION:3"#EXT-X-VERSION:3"#EXT-X-STREAM-INF:BANDWIDTH=%d000"#EXT-X-STREAM-INF:BANDWIDTH=%d000"failed to write master playlist: %w"failed to write master playlist: %w"#EXTINF:"#EXTINF:":":"track directory does not exist: %s"track directory does not exist: %s"segment_*.ts"segment_*.ts"failed to glob segments in %s: %w"failed to glob segments in %s: %w" HLSTranscodeService gère le transcodage HLS des tracks audio NewHLSTranscodeService crée un nouveau service de transcodage HLS SetBitrates configure les bitrates à utiliser pour le transcodage TranscodeTrack transcodage un track en format HLS avec plusieurs qualités Vérifier que le fichier source existe Cleanup en cas d'erreur Nettoyer en cas d'erreur transcodeBitrate transcodage un track pour un bitrate spécifique Commande ffmpeg pour transcoder en HLS Inclure tous les segments Overwrite output files Capturer la sortie pour le logging Vérifier que le fichier playlist a été créé generateMasterPlaylist génère le fichier master.m3u8 avec toutes les qualités Ajouter l'entrée pour cette qualité getPlaylistDuration lit la durée totale d'une playlist .m3u8 Format: #EXTINF:10.0, countSegments compte le nombre de segments .ts dans le répertoire du track T0344: Compte les segments dans chaque répertoire de qualité et retourne le maximum Check if track directory exists cleanupTrackDir supprime le répertoire d'un track en cas d'erreur CleanupTrackDir supprime le répertoire d'un track (méthode publique)/home/senke/git/talas/veza/veza-backend-api/internal/services/image_service.goallowedTypeallowedTypesboundscropHeightcropWidthcropXcropYcroppedimgimgHeightimgWidthratiotargetRatioresizedjpeg"github.com/disintegration/imaging"51205242880uploads/avatars"uploads/avatars"file size exceeds 5MB limit"file size exceeds 5MB limit"unsupported image format. Allowed: JPEG, PNG, WebP"unsupported image format. Allowed: JPEG, PNG, WebP"failed to encode image: %w"failed to encode image: %w"invalid image format: %w"invalid image format: %w""jpeg""png""webp"unsupported image format: %s"unsupported image format: %s"failed to create upload directory: %w"failed to create upload directory: %w"failed to save file: %w"failed to save file: %w"/uploads/avatars/%s"/uploads/avatars/%s"failed to delete file: %w"failed to delete file: %w"avatars/%d/%d.jpg"avatars/%d/%d.jpg" 5MB ImageService handles image processing operations NewImageService creates a new ImageService instance ValidateImage validates the image file format and size T0223: Validates format (JPEG, PNG, WebP) and size (max 5MB) Validate file size Validate MIME type ResizeImage resizes an image to the specified dimensions with crop center T0223: Maintains aspect ratio and crops center to fit target dimensions Calculate dimensions for crop center Calculate ratio to maintain aspect ratio Image is wider, crop width Image is taller, crop height Crop center Final resize EncodeJPEG encodes an image as JPEG with the specified quality T0223: Encodes image as JPEG with quality 90 ProcessAvatar validates and processes an avatar image T0221: Validates format (JPEG, PNG, WebP), size (max 5MB), and resizes to 200x200px T0223: Refactored to use ValidateImage, ResizeImage, and EncodeJPEG methods Validate file Open file Decode image Validate decoded format Resize with crop center Encode as JPEG UploadToS3 uploads image data to S3 (or local storage for now) T0221: For now, stores locally. S3 implementation will be added in T0224 Create upload directory if it doesn't exist Save file locally (S3 will be implemented in T0224) Return local URL (will be S3 URL in T0224) DeleteFromS3 deletes an image from S3 (or local storage for now) Extract filename from URL Delete file (S3 implementation will be added in T0224) GenerateS3Key generates an S3 key for avatar storage/home/senke/git/talas/veza/veza-backend-api/internal/services/job_service.goemail:send"email:send"thumbnail:generate"thumbnail:generate"analytics:process"analytics:process"webhook:delivery"webhook:delivery"Email job enqueued"Email job enqueued"Thumbnail job enqueued"Thumbnail job enqueued" JobService gère les jobs en arrière-plan TODO: Intégrer asynq ou autre système de queue Job types EmailPayload représente les données pour l'envoi d'email ThumbnailPayload représente les données pour la génération de miniatures NewJobService crée un nouveau service de jobs EnqueueEmail enfile un job d'envoi d'email TODO: Intégrer queue système (asynq, RabbitMQ, etc.) EnqueueThumbnail enfile un job de génération de miniature TODO: Intégrer queue système/home/senke/git/talas/veza/veza-backend-api/internal/services/jwt_service.gouserTokenVersionJWT secret is required"JWT secret is required""access"refresh"refresh"unexpected signing method: %v"unexpected signing method: %v""alg"HS256"HS256"invalid signing algorithm: %v, expected HS256"invalid signing algorithm: %v, expected HS256"failed to parse token: %w"failed to parse token: %w"failed to extract user ID: %w"failed to extract user ID: %w"token version mismatch: token version %d does not match user version %d"token version mismatch: token version %d does not match user version %d" Fallback to env for safety during transition Default config Mark as refresh token Nouvelle famille de token GenerateTokenPair génère une paire de tokens (access + refresh) en une seule opération Generate access token Generate refresh token VerifyToken valide et parse un token JWT ValidateToken valide un token JWT et retourne les claims Parse avec validation des claims standards (exp, iat, nbf) ET custom (iss, aud) Validation stricte de l'algorithme (MOD-P2-002) Options de validation stricte ParseToken parse un token JWT sans validation complète (utilise ValidateToken) ExtractClaims extrait les claims d'un token JWT ExtractUserID extrait l'ID utilisateur depuis un token JWT VerifyTokenVersion vérifie si la version du token correspond à celle de l'utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/metadata_service.gotrackNum"github.com/dhowden/tag"failed to open file for metadata extraction: %w"failed to open file for metadata extraction: %w"Failed to extract metadata, using defaults"Failed to extract metadata, using defaults" - " - "title is required"title is required"artist is required"artist is required" AudioMetadata represents extracted audio metadata in seconds MetadataService extracts metadata from audio files NewMetadataService creates a new metadata service ExtractMetadata extracts metadata from an audio file Read metadata from file If metadata can't be read, return default metadata Extract metadata Duration and bitrate would typically be extracted using ffprobe or similar For now, we'll leave these as 0 getDefaultMetadata returns default metadata based on filename Try to parse "Artist - Title" pattern This won't work, need proper parsing ValidateMetadata validates extracted metadata/home/senke/git/talas/veza/veza-backend-api/internal/services/notification_service.gonotificationTypenotification`json:"type" db:"type"``json:"content" db:"content"``json:"link" db:"link"``json:"read" db:"read"`
		INSERT INTO notifications (user_id, type, title, content, link)
		VALUES ($1, $2, $3, $4, $5)
	`
		INSERT INTO notifications (user_id, type, title, content, link)
		VALUES ($1, $2, $3, $4, $5)
	`failed to create notification: %w"failed to create notification: %w"
		SELECT id, user_id, type, title, content, link, read, created_at
		FROM notifications
		WHERE user_id = $1
	`
		SELECT id, user_id, type, title, content, link, read, created_at
		FROM notifications
		WHERE user_id = $1
	` AND read = FALSE" AND read = FALSE" ORDER BY created_at DESC LIMIT 50" ORDER BY created_at DESC LIMIT 50"failed to get notifications: %w"failed to get notifications: %w"
		UPDATE notifications
		SET read = TRUE
		WHERE id = $1 AND user_id = $2
	`
		UPDATE notifications
		SET read = TRUE
		WHERE id = $1 AND user_id = $2
	`failed to mark notification as read: %w"failed to mark notification as read: %w"
		UPDATE notifications
		SET read = TRUE
		WHERE user_id = $1 AND read = FALSE
	`
		UPDATE notifications
		SET read = TRUE
		WHERE user_id = $1 AND read = FALSE
	`failed to mark all notifications as read: %w"failed to mark all notifications as read: %w"
		SELECT COUNT(*)
		FROM notifications
		WHERE user_id = $1 AND read = FALSE
	`
		SELECT COUNT(*)
		FROM notifications
		WHERE user_id = $1 AND read = FALSE
	`failed to get unread count: %w"failed to get unread count: %w" NotificationService handles notification operations Notification represents a notification NewNotificationService creates a new notification service CreateNotification creates a new notification GetNotifications retrieves notifications for a user MarkAllAsRead marks all notifications as read for a user/home/senke/git/talas/veza/veza-backend-api/internal/services/oauth_service.gohttpClientdiscordClientIDdiscordClientSecretgithubClientIDgithubClientSecretgoogleClientIDgoogleClientSecretstateTokentokenBytesjwtTokenoauthUseruserInfoapiURLbaseSluginsertQueryexistingID"golang.org/x/oauth2""golang.org/x/oauth2/google"`json:"provider" db:"provider"``json:"provider_id" db:"provider_id"``json:"email" db:"email"``json:"display_name" db:"display_name"``json:"avatar_url" db:"avatar_url"``json:"-" db:"access_token"``json:"-" db:"refresh_token"``json:"expires_at" db:"expires_at"``db:"state_token"``db:"provider"``db:"redirect_url"`oauth-service"oauth-service"%s/api/v1/auth/oauth/google/callback"%s/api/v1/auth/oauth/google/callback"https://www.googleapis.com/auth/userinfo.email"https://www.googleapis.com/auth/userinfo.email"https://www.googleapis.com/auth/userinfo.profile"https://www.googleapis.com/auth/userinfo.profile"%s/api/v1/auth/oauth/github/callback"%s/api/v1/auth/oauth/github/callback"user:email"user:email"read:user"read:user"https://github.com/login/oauth/authorize"https://github.com/login/oauth/authorize"https://github.com/login/oauth/access_token"https://github.com/login/oauth/access_token"%s/api/v1/auth/oauth/discord/callback"%s/api/v1/auth/oauth/discord/callback"identify"identify"https://discord.com/api/oauth2/authorize"https://discord.com/api/oauth2/authorize"https://discord.com/api/oauth2/token"https://discord.com/api/oauth2/token"OAuth configs initialized"OAuth configs initialized"600000000000
		INSERT INTO oauth_states (state_token, provider, redirect_url, expires_at)
		VALUES ($1, $2, $3, $4)
	`
		INSERT INTO oauth_states (state_token, provider, redirect_url, expires_at)
		VALUES ($1, $2, $3, $4)
	`State token generated"State token generated"
		SELECT id, state_token, provider, redirect_url, expires_at, created_at
		FROM oauth_states
		WHERE state_token = $1
	`
		SELECT id, state_token, provider, redirect_url, expires_at, created_at
		FROM oauth_states
		WHERE state_token = $1
	`invalid state token"invalid state token"state token expired"state token expired"DELETE FROM oauth_states WHERE id = $1`DELETE FROM oauth_states WHERE id = $1`google OAuth not configured"google OAuth not configured"GitHub OAuth not configured"GitHub OAuth not configured"discord OAuth not configured"discord OAuth not configured"unknown provider: %s"unknown provider: %s"`json:"avatar"``json:"username" db:"username"`https://www.googleapis.com/oauth2/v2/userinfo"https://www.googleapis.com/oauth2/v2/userinfo"https://api.github.com/user"https://api.github.com/user"https://discord.com/api/users/@me"https://discord.com/api/users/@me"token %s"token %s"Bearer %s"Bearer %s"OAuth API request failed after %d attempts: %w"OAuth API request failed after %d attempts: %w"OAuth API request failed: no response after %d attempts"OAuth API request failed: no response after %d attempts"json:"login"`json:"login"`
		SELECT id, email, username
		FROM users
		WHERE email = $1
	`
		SELECT id, email, username
		FROM users
		WHERE email = $1
	`SlugifySELECT COUNT(*) FROM users WHERE slug = $1"SELECT COUNT(*) FROM users WHERE slug = $1"%s%d"%s%d"user_%d"user_%d"
		INSERT INTO users (email, username, slug, is_verified, is_active, created_at, updated_at)
		VALUES ($1, $2, $3, TRUE, TRUE, NOW(), NOW())
		RETURNING id, email, username
	`
		INSERT INTO users (email, username, slug, is_verified, is_active, created_at, updated_at)
		VALUES ($1, $2, $3, TRUE, TRUE, NOW(), NOW())
		RETURNING id, email, username
	`New user created via OAuth"New user created via OAuth"oauth"oauth"
		SELECT id FROM federated_identities
		WHERE user_id = $1 AND provider_id = $2
	`
		SELECT id FROM federated_identities
		WHERE user_id = $1 AND provider_id = $2
	`
			UPDATE federated_identities
			SET email = $1, display_name = $2, access_token = $3, refresh_token = $4, expires_at = $5, updated_at = NOW()
			WHERE id = $6
		`
			UPDATE federated_identities
			SET email = $1, display_name = $2, access_token = $3, refresh_token = $4, expires_at = $5, updated_at = NOW()
			WHERE id = $6
		`
		INSERT INTO federated_identities (id, user_id, provider, provider_id, email, display_name, avatar_url, access_token, refresh_token, expires_at, created_at, updated_at)
		VALUES (gen_random_uuid(), $1, $2, $3, $4, $5, $6, $7, $8, $9, NOW(), NOW())
	`
		INSERT INTO federated_identities (id, user_id, provider, provider_id, email, display_name, avatar_url, access_token, refresh_token, expires_at, created_at, updated_at)
		VALUES (gen_random_uuid(), $1, $2, $3, $4, $5, $6, $7, $8, $9, NOW(), NOW())
	` OAuthService handles OAuth authentication OAuthAccount represents an OAuth account linking Mapped to federated_identities table OAuthState represents an OAuth state for CSRF protection NewOAuthService creates a new OAuth service InitializeConfigs initializes OAuth configurations Google OAuth GitHub OAuth Discord OAuth GenerateStateToken generates a secure state token for CSRF protection Generate random token Store in database ValidateStateToken validates and consumes a state token Check if expired Delete used token GetAuthURL returns the OAuth provider authorization URL Generate state token Return authorization URL HandleCallback processes the OAuth callback Validate state Exchange code for token Get user info from provider Check if user already exists (by provider account or email) Save/update OAuth account Generate JWT for the user OAuthUser represents an OAuth authenticated user Added to store provider ID OAuthUserInfo represents a user from the database getUserInfo fetches user information from the OAuth provider Add auth header MOD-P2-006: Retry avec backoff exponentiel pour requêtes HTTP externes MOD-P2-007: Circuit breaker pour protéger contre dépendances lentes MOD-P2-007: Utiliser circuit breaker pour protéger contre dépendances lentes Log retry Exponential backoff: 1s, 2s, 4s Parse response based on provider getOrCreateUser gets an existing user or creates a new one Try to find existing user by email T0219: Generate slug from username Ensure slug is unique by appending a number if needed Create new user ID est généré automatiquement par gen_random_uuid() saveOAuthAccount saves or updates OAuth account information Uses federated_identities table Check if OAuth account already exists Update existing Insert new generateJWT generates a JWT token for the user/home/senke/git/talas/veza/veza-backend-api/internal/services/password_reset_service.goINSERT INTO password_reset_tokens (user_id, token, expires_at, used) VALUES ($1, $2, $3, FALSE)"INSERT INTO password_reset_tokens (user_id, token, expires_at, used) VALUES ($1, $2, $3, FALSE)"Password reset token stored"Password reset token stored"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = $1"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = $1"Password reset token not found"Password reset token not found"Password reset token already used"Password reset token already used"Password reset token expired"Password reset token expired"Password reset token verified successfully"Password reset token verified successfully"UPDATE password_reset_tokens SET used = TRUE WHERE token = $1"UPDATE password_reset_tokens SET used = TRUE WHERE token = $1"No token found to mark as used"No token found to mark as used"token not found"token not found"Password reset token marked as used"Password reset token marked as used"UPDATE password_reset_tokens SET used = TRUE WHERE user_id = $1 AND used = FALSE"UPDATE password_reset_tokens SET used = TRUE WHERE user_id = $1 AND used = FALSE"Old password reset tokens invalidated"Old password reset tokens invalidated" PasswordResetService gère la génération, le stockage et la validation des tokens de réinitialisation de mot de passe T0192: Service pour gérer les tokens de réinitialisation de mot de passe avec expiration et invalidation NewPasswordResetService crée une nouvelle instance de PasswordResetService T0192: Génère un token aléatoire pour la réinitialisation de mot de passe StoreToken stocke un token de réinitialisation en base de données avec une expiration de 1h T0192: Sauvegarde le token avec expiration 1h VerifyToken valide un token de réinitialisation, vérifie son expiration et s'il n'a pas déjà été utilisé T0192: Valide le token, vérifie l'expiration et s'il n'est pas déjà utilisé MarkTokenAsUsed marque un token comme utilisé T0192: Marque le token comme utilisé après utilisation InvalidateOldTokens invalide tous les tokens de réinitialisation précédents pour un utilisateur T0192: Invalide les tokens précédents pour un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/password_service.go`db:"email"``db:"username"`
		INSERT INTO password_reset_tokens (user_id, token, expires_at, used)
		VALUES ($1, $2, $3, FALSE)
	`
		INSERT INTO password_reset_tokens (user_id, token, expires_at, used)
		VALUES ($1, $2, $3, FALSE)
	`Password reset token generated"Password reset token generated"
		SELECT id, user_id, token, expires_at, used, created_at
		FROM password_reset_tokens
		WHERE token = $1 AND used = FALSE
	`
		SELECT id, user_id, token, expires_at, used, created_at
		FROM password_reset_tokens
		WHERE token = $1 AND used = FALSE
	`invalid or expired reset token"invalid or expired reset token"reset token has expired"reset token has expired"ValidatePasswordStrength
		UPDATE users
		SET password_hash = $1, updated_at = NOW()
		WHERE id = $2
	`
		UPDATE users
		SET password_hash = $1, updated_at = NOW()
		WHERE id = $2
	`
		UPDATE password_reset_tokens
		SET used = TRUE
		WHERE id = $1
	`
		UPDATE password_reset_tokens
		SET used = TRUE
		WHERE id = $1
	`Failed to mark reset token as used"Failed to mark reset token as used"token_id"token_id"Password reset successful"Password reset successful"
		SELECT password_hash
		FROM users
		WHERE id = $1
	`
		SELECT password_hash
		FROM users
		WHERE id = $1
	`incorrect old password"incorrect old password"Password updated successfully"Password updated successfully"72 PasswordService handles password operations PasswordResetToken represents a password reset token UserInfo represents a user from the database NewPasswordService creates a new password service GetUserByEmail retrieves a user by email GeneratePasswordResetToken generates a secure password reset token Set expiration (1 hour) ResetPassword validates and processes password reset Get token info T0197: Use ValidatePasswordStrength from utils package Update user password ValidatePassword validates password strength T0197: Uses ValidatePasswordStrength from utils package ChangePassword changes user's password (for authenticated users) Get current password hash Verify old password Validate new password GenerateJWT generates a JWT token for the user (used internally) Convert UUID to string for JWT claims UpdatePassword updates a user's password by user ID T0194: Updates password with bcrypt hash Hash hashes a password using bcrypt with cost 12 This is a standalone method for T0154 that can be used independently Bcrypt has a limit of 72 bytes. Truncate longer passwords to avoid errors. This matches the behavior expected by tests and is a reasonable security practice. Compare compares a password with a hashed password Returns true if the password matches the hash/home/senke/git/talas/veza/veza-backend-api/internal/services/permission_service.gopermissionIDrolePermissionfailed to get permissions: %w"failed to get permissions: %w"permission not found"permission not found"failed to get permission: %w"failed to get permission: %w"failed to create permission: %w"failed to create permission: %w"failed to assign permission: %w"failed to assign permission: %w"role_id = ? AND permission_id = ?"role_id = ? AND permission_id = ?"failed to revoke permission: %w"failed to revoke permission: %w"permission assignment not found"permission assignment not found"JOIN role_permissions ON permissions.id = role_permissions.permission_id"JOIN role_permissions ON permissions.id = role_permissions.permission_id"role_permissions.role_id = ?"role_permissions.role_id = ?"failed to get role permissions: %w"failed to get role permissions: %w"JOIN roles ON user_roles.role_id = roles.id"JOIN roles ON user_roles.role_id = roles.id"user_roles.user_id = ? AND roles.name = ?"user_roles.user_id = ? AND roles.name = ?"user_roles.is_active = ?"user_roles.is_active = ?"user_roles.expires_at IS NULL OR user_roles.expires_at > ?"user_roles.expires_at IS NULL OR user_roles.expires_at > ?"failed to check role: %w"failed to check role: %w"JOIN role_permissions ON user_roles.role_id = role_permissions.role_id"JOIN role_permissions ON user_roles.role_id = role_permissions.role_id"JOIN permissions ON role_permissions.permission_id = permissions.id"JOIN permissions ON role_permissions.permission_id = permissions.id"user_roles.user_id = ? AND permissions.name = ?"user_roles.user_id = ? AND permissions.name = ?"failed to check permission: %w"failed to check permission: %w" PermissionService gère les permissions NewPermissionService crée un nouveau service de permissions GetPermissions récupère toutes les permissions GetPermission récupère une permission par son ID CreatePermission crée une nouvelle permission AssignPermissionToRole assigne une permission à un rôle RevokePermissionFromRole révoque une permission d'un rôle GetRolePermissions récupère toutes les permissions d'un rôle HasRole vérifie si un utilisateur a un rôle spécifique HasPermission vérifie si un utilisateur a une permission spécifique/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_abtest_service.goanalyticsAanalyticsBdifferencefilterAfilterBpercentageChangerecommendationsignificancestatsAstatsBvariantAvariantBwinnersessionCountvariantNamecompletionRatesAcompletionRatesBconfidenceIntervalLowerconfidenceIntervalUpperconfidenceLeveleffectSizemeanAmeanBpValuepooledStdDevseAseBseDiffstdDevAstdDevBtValuemeanstdDevsumSqDiffdataAdataBnAnBtStatdenominatornumeratora1a2a3a4a5improvement`json:"start_date,omitempty"``json:"end_date,omitempty"``json:"user_ids,omitempty"``json:"min_play_time,omitempty"``json:"variant_name"``json:"average_pauses"``json:"average_seeks"``json:"p_value"``json:"is_significant"``json:"confidence_level"``json:"confidence_interval_lower"``json:"confidence_interval_upper"``json:"effect_size"``json:"total_pauses"``json:"total_seeks"``json:"variant_a"``json:"variant_b"``json:"difference"``json:"percentage_change"``json:"significance"``json:"winner,omitempty"``json:"recommendation,omitempty"``json:"analyzed_at"`variant names cannot be empty"variant names cannot be empty"failed to get analytics for variant A: %w"failed to get analytics for variant A: %w"failed to get analytics for variant B: %w"failed to get analytics for variant B: %w"Compared A/B test variants"Compared A/B test variants"variant_a"variant_a"variant_b"variant_b"sessions_a"sessions_a"sessions_b"sessions_b"significant"significant""winner"created_at >= ?"created_at >= ?"created_at <= ?"created_at <= ?"user_id IN ?"user_id IN ?"play_time >= ?"play_time >= ?"failed to query analytics: %w"failed to query analytics: %w"90.095.01.961.95999999999999996452206763817411543/1125899906842624PowSqrt21.41421356237309514556369051672525773/45035996273704960.2548295920.254829591999999993672295300911148351/90071992547409920.2844967360.284496735999999972318890523/31250000-0.28449673599999997231-5125037576950889/180143985094819841.4214137411.42141374100000006396401478394306903/45035996273704961.4531520271.45315202700000001281453152027/1000000000-1.4531520270000000128-6544414927309881/45035996273704961.0614054291.06140542899999990034780145094533421/45035996273704960.32759110.327591100000000023941475339155889891/4503599627370496inconclusive"inconclusive""B""A"Les résultats ne sont pas statistiquement significatifs. Continuer le test ou augmenter la taille de l'échantillon."Les résultats ne sont pas statistiquement significatifs. Continuer le test ou augmenter la taille de l'échantillon."Le variant B est significativement meilleur avec une amélioration de %.2f%% du taux de complétion."Le variant B est significativement meilleur avec une amélioration de %.2f%% du taux de complétion."Le variant A est significativement meilleur avec une amélioration de %.2f%% du taux de complétion."Le variant A est significativement meilleur avec une amélioration de %.2f%% du taux de complétion."Aucune différence significative entre les variants."Aucune différence significative entre les variants." PlaybackABTestService gère le support A/B testing pour les analytics de lecture T0379: Create Playback Analytics A/B Testing Support NewPlaybackABTestService crée un nouveau service A/B testing VariantFilter représente les critères de filtrage pour un variant GO-004: Migré vers UUID pour TrackID et UserIDs Liste d'IDs utilisateurs spécifiques Filtre optionnel par temps de lecture minimum VariantStats représente les statistiques d'un variant percentage of sessions with >90% completion StatisticalSignificance représente la significativité statistique P-value (0-1) True si p-value < 0.05 Niveau de confiance (95%, 99%, etc.) Borne inférieure de l'intervalle de confiance Borne supérieure de l'intervalle de confiance Taille de l'effet (Cohen's d) ABTestStatsDifference représente la différence absolue entre deux variants ABTestPercentageChange représente le changement en pourcentage entre deux variants ABTestResult représente le résultat d'un test A/B "A", "B", ou "inconclusive" Recommandation basée sur les résultats CompareVariants compare deux variants et calcule la significativité statistique Récupérer les analytics pour le variant A Récupérer les analytics pour le variant B Calculer les statistiques pour chaque variant Calculer les différences Calculer la significativité statistique Déterminer le gagnant getAnalyticsForVariant récupère les analytics pour un variant selon les filtres calculateVariantStats calcule les statistiques pour un variant calculateDifference calcule la différence absolue entre deux variants calculatePercentageChange calcule le changement en pourcentage entre deux variants safePercentageChange calcule le changement en pourcentage en gérant la division par zéro Infini si la base est zéro et le courant est non-zéro calculateStatisticalSignificance calcule la significativité statistique entre deux variants Utilise un test t de Student pour comparer les moyennes de completion rate Extraire les completion rates Calculer les moyennes et écarts-types Calculer le test t de Student Calculer l'intervalle de confiance à 95% Pour un intervalle de confiance à 95% Calculer la taille de l'effet (Cohen's d) calculateMeanAndStdDev calcule la moyenne et l'écart-type Calcul de la moyenne Calcul de l'écart-type Échantillon calculateTTest calcule la p-value d'un test t de Student Approximation simplifiée pour deux échantillons indépendants Pas assez de données pour un test significatif Calcul de l'erreur standard de la différence Calcul de la statistique t Calcul des degrés de liberté (approximation de Welch) Calculé mais non utilisé dans l'approximation normale Approximation de la p-value (test bilatéral) Utilisation d'une approximation normale pour simplifier En production, on utiliserait une table t ou une fonction de distribution calculateWelchDF calcule les degrés de liberté pour le test t de Welch normalCDF calcule la fonction de répartition cumulative de la distribution normale standard Approximation utilisant la fonction d'erreur erf calcule la fonction d'erreur (approximation) Approximation de la fonction d'erreur Formule d'Abramowitz et Stegun determineWinner détermine le gagnant du test A/B Le gagnant est déterminé par le completion rate le plus élevé generateRecommendation génère une recommandation basée sur les résultats/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_aggregation_service.goperiodKeyperiodMapperiods`json:"period"``json:"periods"``json:"trends,omitempty"``json:"pauses_trend"``json:"seeks_trend"`invalid track ID: %s"invalid track ID: %s"invalid period type: %s (must be day, week, or month)"invalid period type: %s (must be day, week, or month)"track not found: %d"track not found: %d"track_id = ? AND created_at >= ? AND created_at <= ?"track_id = ? AND created_at >= ? AND created_at <= ?"failed to get sessions: %w"failed to get sessions: %w"%d-W%02d"%d-W%02d"%s to %s"%s to %s"track_id, COUNT(*) as sessions, SUM(play_time) as total_play_time, AVG(completion_rate) as avg_completion"track_id, COUNT(*) as sessions, SUM(play_time) as total_play_time, AVG(completion_rate) as avg_completion"sessions DESC"sessions DESC"created_at >= ? AND created_at <= ?"created_at >= ? AND created_at <= ?"gorm:"column:sessions"gorm:"column:total_play_time"AvgCompletiongorm:"column:avg_completion"`gorm:"column:sessions"``gorm:"column:total_play_time"``gorm:"column:avg_completion"`avg_completion"avg_completion" PlaybackAggregationService gère l'agrégation des analytics de lecture T0365: Create Playback Analytics Aggregation Service NewPlaybackAggregationService crée un nouveau service d'agrégation d'analytics PeriodType représente le type de période d'agrégation PeriodAggregation représente les données agrégées pour une période Format: YYYY-MM-DD, YYYY-WW, YYYY-MM AggregationResult représente le résultat d'une agrégation TrendsData représente les tendances calculées % de changement AggregateByPeriod agrège les analytics par période (day, week, month) Valider le type de période Récupérer toutes les sessions dans la plage de dates Grouper par période Compter les sessions complétées Calculer les moyennes pour chaque période Trier les périodes par ordre chronologique Calculer les moyennes globales Calculer les tendances (comparaison entre la première et la dernière période) getPeriodKey génère une clé de période basée sur la date et le type de période sortPeriods trie les périodes par ordre chronologique Utiliser un tri simple basé sur la clé de période (qui est déjà formatée) calculateTrends calcule les tendances entre la première et la dernière période Tendance des pauses Tendance des seeks AggregateByDateRange agrège les analytics dans une plage de dates sans groupement par période GetTopTracksByPlayback récupère les tracks les plus écoutés/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_alerts_service.goanomalyAlertscompletionAlertsdropOffAlertsplayTimecompletionMeancompletionRatescompletionStdDevplayTimeMeanplayTimeStdDevplayTimesaverageCompletionlowCompletionCountlowCompletionPercentageavgDropOffTimedropOffPointPercentagedropOffCountdropOffPercentagedropOffThresholdSecondsdropOffTimesvariance`json:"severity"``json:"value"``json:"threshold"``json:"detected_at"``json:"metadata,omitempty"`30.025.0Failed to detect anomalies"Failed to detect anomalies"Failed to detect low completion rates"Failed to detect low completion rates"Failed to detect drop-off points"Failed to detect drop-off points"Checked playback alerts"Checked playback alerts"alerts_count"alerts_count"track_id = ? AND created_at >= ?"track_id = ? AND created_at >= ?"medium"medium"anomaly"anomaly"Anomalous play time detected: %.0f seconds (mean: %.0f, std dev: %.0f)"Anomalous play time detected: %.0f seconds (mean: %.0f, std dev: %.0f)"analytics_id"analytics_id""mean"std_dev"std_dev""deviation"Anomalous completion rate detected: %.2f%% (mean: %.2f%%, std dev: %.2f%%)"Anomalous completion rate detected: %.2f%% (mean: %.2f%%, std dev: %.2f%%)"low_completion_rate"low_completion_rate"Low average completion rate: %.2f%% (threshold: %.2f%%)"Low average completion rate: %.2f%% (threshold: %.2f%%)"total_sessions"total_sessions"low_completion_count"low_completion_count"percentage_low"percentage_low"75.075High percentage of sessions with low completion rate: %.2f%%"High percentage of sessions with low completion rate: %.2f%%"average_completion"average_completion"drop_off_point"drop_off_point"Drop-off detected: %.2f%% of sessions stop before %.2f%% of track duration (avg drop-off at %.2f%%)"Drop-off detected: %.2f%% of sessions stop before %.2f%% of track duration (avg drop-off at %.2f%%)"drop_off_count"drop_off_count"drop_off_threshold"drop_off_threshold"average_drop_off_time"average_drop_off_time"drop_off_point_percentage"drop_off_point_percentage"track_duration"track_duration" PlaybackAlertsService gère la détection d'alertes pour les analytics de lecture T0374: Create Playback Analytics Alerts Service Alert représente une alerte détectée "anomaly", "low_completion_rate", "drop_off_point" "low", "medium", "high" Message descriptif Valeur qui a déclenché l'alerte Seuil utilisé Date de détection Métadonnées supplémentaires AlertConfig représente la configuration des seuils d'alerte Seuil pour completion rate bas (défaut: 30%) Nombre d'écarts-types pour détecter une anomalie (défaut: 2.0) Seuil de drop-off en pourcentage de la durée (défaut: 25%) NewPlaybackAlertsService crée un nouveau service d'alertes d'analytics CheckAlerts vérifie les alertes pour un track donné Utiliser la configuration par défaut si non fournie Détecter les anomalies Détecter les completion rates bas Détecter les drop-off points detectAnomalies détecte les anomalies dans les statistiques de lecture Récupérer toutes les analytics récentes (30 derniers jours) Pas assez de données pour détecter des anomalies Calculer la moyenne et l'écart-type pour le play_time Détecter les anomalies dans le play_time Détecter les anomalies dans le completion rate detectLowCompletionRate détecte les completion rates bas Récupérer les statistiques récentes (7 derniers jours) Calculer le taux de completion moyen Si le taux moyen est bas, créer une alerte Si un pourcentage élevé de sessions a un completion rate bas, créer une alerte detectDropOffPoints détecte les points de drop-off (moments où les utilisateurs arrêtent de regarder) Récupérer le track pour connaître sa durée Récupérer les analytics récentes (7 derniers jours) Calculer le pourcentage de la durée où les utilisateurs arrêtent Si le play_time est inférieur au seuil de drop-off, c'est un drop-off Si un pourcentage significatif de sessions s'arrête tôt, créer une alerte Calculer le temps moyen de drop-off calculateMeanAndStdDev calcule la moyenne et l'écart-type d'une série de valeurs Calculer la moyenne Calculer l'écart-type/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_analytics_rate_limiter.goretryAftertimeSinceLastRequestlastRequestreqTimeoldestRequestdailyCountvalidRequestsweeklyCountremainingRequestsstartOfDaystartOfWeekcutoffLastRequestmidnightdaysUntilMondaynextMonday50000throttling: request too soon"throttling: request too soon"rate limit exceeded: %d requests per %v"rate limit exceeded: %d requests per %v"Failed to get quota counts, using cache"Failed to get quota counts, using cache"daily quota exceeded: %d/%d"daily quota exceeded: %d/%d"weekly quota exceeded: %d/%d"weekly quota exceeded: %d/%d"rate_limit"rate_limit"requests_per_minute"requests_per_minute""remaining"throttling"throttling"min_interval"min_interval"quotas"quotas"daily"daily""used"weekly"weekly"COUNT(*)"COUNT(*)"user_id = ? AND created_at >= ?"user_id = ? AND created_at >= ?" PlaybackAnalyticsRateLimiter gère le rate limiting pour les analytics de playback Rate limiting par utilisateur (requêtes par minute) Throttling (délai minimum entre requêtes) Quotas (limites quotidiennes et hebdomadaires) Cache en mémoire pour le rate limiting userID -> []time.Time userID -> last request time userID -> daily count userID -> weekly count RateLimitConfig configuration pour le rate limiter Nombre de requêtes par minute Fenêtre de temps pour les requêtes Délai minimum entre requêtes (throttling) Quota quotidien Quota hebdomadaire DefaultRateLimitConfig retourne une configuration par défaut 60 requêtes par minute Fenêtre de 1 minute Minimum 1 seconde entre requêtes 10000 analytics par jour 50000 analytics par semaine NewPlaybackAnalyticsRateLimiter crée un nouveau rate limiter pour les analytics Démarrer le nettoyage périodique RateLimitResult représente le résultat d'une vérification de rate limit CheckRateLimit vérifie si une requête est autorisée selon les limites Nettoyer périodiquement le cache 1. Vérifier le throttling (délai minimum entre requêtes) 2. Vérifier le rate limiting (requêtes par minute) Calculer le temps d'attente jusqu'à ce que la plus ancienne requête expire 3. Vérifier les quotas (quotas quotidiens et hebdomadaires) Utiliser les valeurs en cache en cas d'erreur Toutes les vérifications passées, autoriser la requête RecordRequest enregistre une requête (appelé après qu'une requête a été traitée avec succès) Mettre à jour les compteurs de quota Enregistrer dans la base de données pour persistance Note: On pourrait créer une table de quotas si nécessaire Pour l'instant, on utilise uniquement le cache en mémoire GetQuotaInfo retourne les informations de quota pour un utilisateur Utiliser les valeurs en cache Calculer les requêtes restantes dans la fenêtre actuelle getQuotaCounts récupère les compteurs de quota depuis la base de données Calculer les dates de début Dimanche = 7 Lundi Compter les analytics enregistrées aujourd'hui Compter les analytics enregistrées cette semaine cleanup nettoie périodiquement le cache cleanupLocked nettoie le cache (doit être appelé avec le mutex verrouillé) Nettoyer les requêtes expirées Nettoyer les dernières requêtes si trop anciennes timeUntilMidnight calcule le temps jusqu'à minuit timeUntilNextWeek calcule le temps jusqu'au prochain lundi Jours jusqu'au prochain lundi/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_analytics_service.gobackoffDurationanalyticsListtrackDurationcachedStatsanalyticsIDinvalid user ID: nil UUID"invalid user ID: nil UUID"invalid play time: %d"invalid play time: %d"invalid pause count: %d"invalid pause count: %d"invalid seek count: %d"invalid seek count: %d"invalid completion rate: %f (must be between 0 and 100)"invalid completion rate: %f (must be between 0 and 100)"track not found: %s"track not found: %s"Playback analytics recorded after retry"Playback analytics recorded after retry"Failed to record playback analytics, retrying"Failed to record playback analytics, retrying"max_retries"max_retries"Failed to record playback analytics after all retries"Failed to record playback analytics after all retries"failed to record playback analytics after %d retries: %w"failed to record playback analytics after %d retries: %w"playback_stats:track:%s"playback_stats:track:%s"Failed to invalidate cache"Failed to invalidate cache"Playback analytics recorded"Playback analytics recorded"analytics list cannot be empty"analytics list cannot be empty"invalid track ID at index %d: 0"invalid track ID at index %d: 0"invalid user ID at index %d: nil UUID"invalid user ID at index %d: nil UUID"invalid play time at index %d: %d"invalid play time at index %d: %d"started_at is required at index %d"started_at is required at index %d"Failed to record playback analytics batch"Failed to record playback analytics batch"batch_start"batch_start"batch_end"batch_end"failed to record playback analytics batch: %w"failed to record playback analytics batch: %w"Playback analytics batch recorded"Playback analytics batch recorded"batches"batches"Cache hit for track stats"Cache hit for track stats"failed to count sessions: %w"failed to count sessions: %w"COALESCE(SUM(play_time), 0)"COALESCE(SUM(play_time), 0)"failed to calculate total play time: %w"failed to calculate total play time: %w"COALESCE(SUM(pause_count), 0)"COALESCE(SUM(pause_count), 0)"failed to calculate total pauses: %w"failed to calculate total pauses: %w"COALESCE(SUM(seek_count), 0)"COALESCE(SUM(seek_count), 0)"failed to calculate total seeks: %w"failed to calculate total seeks: %w"failed to calculate average completion: %w"failed to calculate average completion: %w"track_id = ? AND completion_rate >= 90"track_id = ? AND completion_rate >= 90"failed to count completed sessions: %w"failed to count completed sessions: %w"Failed to cache track stats"Failed to cache track stats"user not found: %s"user not found: %s"user_id = ? AND completion_rate >= 90"user_id = ? AND completion_rate >= 90"`json:"page_size"`analytics cannot be nil"analytics cannot be nil"analytics must be saved before tracking completion"analytics must be saved before tracking completion"invalid track duration: %d"invalid track duration: %d"Track completion detected"Track completion detected"Failed to update analytics completion"Failed to update analytics completion"failed to update analytics completion: %w"failed to update analytics completion: %w"invalid analytics ID: 0"invalid analytics ID: 0"analytics not found: %s"analytics not found: %s" PlaybackAnalyticsService gère les analytics de lecture de tracks T0357: Create Playback Analytics Service T0381: Create Playback Analytics Performance Optimization Optionnel, pour le cache des agrégations TTL pour le cache des statistiques Taille du batch pour l'enregistrement en lot NewPlaybackAnalyticsService crée un nouveau service d'analytics de lecture Cache optionnel TTL par défaut de 5 minutes Taille de batch par défaut NewPlaybackAnalyticsServiceWithCache crée un nouveau service avec cache SetBatchSize définit la taille du batch pour l'enregistrement en lot RecordPlayback enregistre un événement d'analytics de lecture Calculer le taux de complétion si non fourni Enregistrer l'analytics avec retry logic T0385: Create Playback Analytics Error Handling Logger l'erreur Ne pas retry pour certaines erreurs (contraintes, etc.) Attendre avant de retry (exponential backoff) Invalider le cache si disponible RecordPlaybackBatch enregistre plusieurs analytics en lot pour optimiser les performances Valider tous les analytics avant l'insertion Enregistrer par batch pour optimiser les performances Collecter les track IDs pour invalider le cache Invalider le cache pour tous les tracks affectés CalculateCompletionRate calcule le taux de complétion en pourcentage playTime: temps de lecture en secondes trackDuration: durée totale du track en secondes Retourne le taux de complétion (0-100) Limiter à 100% PlaybackStats représente les statistiques agrégées de lecture GetTrackStats récupère les statistiques agrégées pour un track T0381: Optimisé avec cache Vérifier le cache si disponible Total sessions Total play time Average play time Total pauses Total seeks Average completion rate Completion rate (sessions with >90% completion) Mettre en cache si disponible GetUserStats récupère les statistiques agrégées pour un utilisateur GetSessionsByDateRange récupère les sessions dans une plage de dates PaginationParams représente les paramètres de pagination Numéro de page (commence à 1) Taille de la page PaginatedResult représente un résultat paginé GetSessionsByDateRangePaginated récupère les sessions dans une plage de dates avec pagination Appliquer la pagination si spécifiée GetSessionsByDateRangePaginatedResult récupère les sessions avec pagination complète Taille par défaut Limite maximale Récupérer les données paginées TrackCompletion détecte et enregistre la completion d'un track (≥95%) T0366: Create Playback Completion Tracking Calculer le taux de complétion Détecter si le track est complété (≥95%) Marquer comme complété en définissant EndedAt Mettre à jour les analytics dans la base de données UpdatePlaybackProgress met à jour le progrès de lecture et détecte la completion Récupérer l'analytics existant Mettre à jour le temps de lecture Utiliser TrackCompletion pour calculer et détecter la completion/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_comparison_service.gostats1stats2endDate1endDate2period1period2startDate1startDate2track1track2trackID1trackID2user1user2`json:"period1"``json:"period2"`today"today"invalid period: %s (must be today, week, month, or year)"invalid period: %s (must be today, week, month, or year)"track_id = ? AND created_at >= ? AND created_at <= ? AND completion_rate >= ?"track_id = ? AND created_at >= ? AND created_at <= ? AND completion_rate >= ?"invalid period1: %w"invalid period1: %w"invalid period2: %w"invalid period2: %w"failed to get stats for period1: %w"failed to get stats for period1: %w"failed to get stats for period2: %w"failed to get stats for period2: %w"Compared playback analytics periods"Compared playback analytics periods""period1""period2"invalid track ID 1: %s"invalid track ID 1: %s"invalid track ID 2: %s"invalid track ID 2: %s"failed to get track 1: %w"failed to get track 1: %w"failed to get track 2: %w"failed to get track 2: %w"failed to get stats for track 1: %w"failed to get stats for track 1: %w"failed to get stats for track 2: %w"failed to get stats for track 2: %w"Compared playback analytics tracks"Compared playback analytics tracks"track_id1"track_id1"track_id2"track_id2"invalid user ID 1: nil UUID"invalid user ID 1: nil UUID"invalid user ID 2: nil UUID"invalid user ID 2: nil UUID"failed to get user 1: %w"failed to get user 1: %w"failed to get user 2: %w"failed to get user 2: %w"failed to get stats for user 1: %w"failed to get stats for user 1: %w"failed to get stats for user 2: %w"failed to get stats for user 2: %w"Compared playback analytics users"Compared playback analytics users"user_id1"user_id1"user_id2"user_id2"track_id = ? AND user_id = ? AND created_at >= ? AND created_at <= ?"track_id = ? AND user_id = ? AND created_at >= ? AND created_at <= ?"track_id = ? AND user_id = ? AND created_at >= ? AND created_at <= ? AND completion_rate >= ?"track_id = ? AND user_id = ? AND created_at >= ? AND created_at <= ? AND completion_rate >= ?" PlaybackComparisonService gère la comparaison des analytics de lecture T0373: Create Playback Analytics Comparison Service NewPlaybackComparisonService crée un nouveau service de comparaison d'analytics ComparisonResult représente le résultat d'une comparaison StatsDifference représente la différence absolue entre deux statistiques PercentageChange représente le changement en pourcentage entre deux statistiques % getPeriodDates retourne les dates de début et de fin pour une période donnée getStatsForPeriod récupère les statistiques pour une période donnée calculateDifference calcule la différence absolue entre deux statistiques calculatePercentageChange calcule le changement en pourcentage entre deux statistiques 100% increase from 0 Average pauses Average seeks Average completion Completion rate ComparePeriods compare les analytics entre deux périodes pour un track Obtenir les dates pour chaque période Récupérer les statistiques pour chaque période CompareTracks compare les analytics entre deux tracks Vérifier que les tracks existent Récupérer les statistiques pour chaque track CompareUsers compare les analytics entre deux users pour un track Vérifier que les users existent Récupérer les statistiques pour chaque user getStatsForUser récupère les statistiques pour un utilisateur spécifique MIGRATION UUID: userID en uuid.UUID, trackID reste int64/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_export_service.gosessionsOver90statsHeaderstatsRowscsvWriter"csv"no analytics data to export"no analytics data to export"failed to create directory: %w"failed to create directory: %w"failed to create file: %w"failed to create file: %w""ID"User ID"User ID"Play Time (seconds)"Play Time (seconds)"Pause Count"Pause Count"Seek Count"Seek Count"Completion Rate (%)"Completion Rate (%)"Started At"Started At"Ended At"Ended At"Created At"Created At"failed to write CSV header: %w"failed to write CSV header: %w"%.2f"%.2f"failed to write CSV row: %w"failed to write CSV row: %w"Analytics exported to CSV"Analytics exported to CSV"failed to marshal JSON: %w"failed to marshal JSON: %w"failed to write JSON file: %w"failed to write JSON file: %w"Analytics exported to JSON"Analytics exported to JSON"unsupported export format: %s"unsupported export format: %s"`json:"completed_sessions"`Statistic"Statistic""Value"failed to write stats header: %w"failed to write stats header: %w"Total Sessions"Total Sessions"Total Play Time (seconds)"Total Play Time (seconds)"Average Play Time (seconds)"Average Play Time (seconds)"Total Pauses"Total Pauses"Average Pauses"Average Pauses"Total Seeks"Total Seeks"Average Seeks"Average Seeks"Average Completion (%)"Average Completion (%)"Completed Sessions (≥95%)"Completed Sessions (≥95%)"failed to write stats row: %w"failed to write stats row: %w"failed to write empty row: %w"failed to write empty row: %w"Analytics report exported to CSV"Analytics report exported to CSV"generated_at"generated_at"statistics"statistics"Analytics report exported to JSON"Analytics report exported to JSON"writer must be *os.File for CSV export"writer must be *os.File for CSV export"writer must be *os.File for JSON export"writer must be *os.File for JSON export" PlaybackExportService gère l'export des analytics de lecture T0367: Create Playback Analytics Export Service NewPlaybackExportService crée un nouveau service d'export d'analytics ExportFormat représente le format d'export ExportCSV exporte les analytics en format CSV Créer le répertoire parent si nécessaire Écrire l'en-tête CSV Écrire les données UUID as string ExportJSON exporte les analytics en format JSON ExportReport génère un rapport d'analytics avec statistiques agrégées Calculer les statistiques Générer le rapport selon le format ReportStats représente les statistiques d'un rapport sessions with ≥95% completion calculateReportStats calcule les statistiques agrégées exportReportCSV exporte un rapport en CSV avec statistiques Écrire les statistiques Ligne vide Écrire l'en-tête des données exportReportJSON exporte un rapport en JSON avec statistiques Structure du rapport ExportToWriter exporte les analytics vers un writer (pour streaming HTTP) exportCSVToWriter exporte en CSV vers un writer Cette méthode peut être étendue pour supporter différents types de writers Pour l'instant, on retourne une erreur si le writer n'est pas un *os.File Écrire l'en-tête exportJSONToWriter exporte en JSON vers un writer/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_filter_service.go`json:"user_id,omitempty"``json:"min_completion_rate,omitempty"``json:"max_completion_rate,omitempty"``json:"max_play_time,omitempty"``json:"period,omitempty"``json:"page,omitempty"``json:"limit,omitempty"``json:"sort_by,omitempty"``json:"sort_order,omitempty"`failed to count filtered analytics: %w"failed to count filtered analytics: %w"failed to filter analytics: %w"failed to filter analytics: %w"Filtered playback analytics"Filtered playback analytics"results_count"results_count"Invalid period filter"Invalid period filter""period"completion_rate >= ?"completion_rate >= ?"completion_rate <= ?"completion_rate <= ?"play_time <= ?"play_time <= ?" PlaybackFilter représente les critères de filtrage pour les analytics de lecture T0372: Create Playback Analytics Filtering Service Filtres par date Date de début (inclusive) Date de fin (inclusive) Filtre par utilisateur ID de l'utilisateur Filtres par completion rate Taux de complétion minimum (0-100) Taux de complétion maximum (0-100) Filtres par temps de lecture Temps de lecture minimum (secondes) Temps de lecture maximum (secondes) Filtres par période (prédéfinies) "today", "week", "month", "year" Pagination Nombre d'éléments par page Tri Champ de tri: "created_at", "play_time", "completion_rate" Ordre: "asc" ou "desc" PlaybackFilterService gère le filtrage des analytics de lecture NewPlaybackFilterService crée un nouveau service de filtrage d'analytics Filter applique les filtres et retourne les analytics correspondantes Construire la requête de base applyFilters applique tous les filtres à la requête Filtre par période prédéfinie (prioritaire sur StartDate/EndDate) Période invalide, ignorer Filtres par date personnalisés applySorting applique le tri à la requête Valider le champ de tri Fallback si invalide Valider l'ordre de tri applyPagination applique la pagination à la requête Valeurs par défaut GetFilteredStats retourne les statistiques agrégées pour les analytics filtrées Construire la requête avec les filtres/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_heatmap_service.goheatmapSegmentsmaxIntensityskipZonesendTimesegmentPlayTimesegmentEndsegmentStartplayTimeSecondstotalSegmentszonesskipRatioseekCountskipPenaltycompletionRatiointensitylistenedZoneskipCountskipZonelistenedZonesintensities`json:"start_time"``json:"end_time"``json:"listen_count"``json:"skip_count"``json:"intensity"``json:"track_duration"``json:"segment_size"``json:"segments"``json:"max_intensity"``json:"generated_at"`track has invalid duration: %d"track has invalid duration: %d"Generated playback heatmap"Generated playback heatmap" PlaybackHeatmapService gère la génération de heatmap pour les analytics de lecture NewPlaybackHeatmapService crée un nouveau service de génération de heatmap HeatmapSegment représente un segment de la heatmap Temps de début du segment (secondes) Temps de fin du segment (secondes) Nombre de fois que ce segment a été écouté Nombre de fois que ce segment a été sauté Intensité d'écoute (0-1, normalisée) Temps de lecture moyen dans ce segment (secondes) HeatmapData représente les données complètes de la heatmap Taille des segments (secondes) Intensité maximale (pour normalisation) GenerateHeatmap génère les données de heatmap pour un track Par défaut, segments de 5 secondes Maximum 60 secondes par segment Récupérer toutes les analytics pour ce track Calculer les zones écoutées et skip Combiner les données et calculer l'intensité Trouver l'intensité maximale pour normalisation Normaliser les intensités (0-1) ListenedZone représente une zone écoutée calculateListenedZones calcule les zones écoutées Arrondi supérieur Initialiser tous les segments Pour chaque session, calculer les segments écoutés Pour chaque segment, vérifier s'il a été écouté Si la session a atteint ce segment Calculer le temps passé dans ce segment SkipZone représente une zone skip calculateSkipZones calcule les zones skip (basées sur les seeks) Pour chaque session avec des seeks, considérer que les segments non écoutés sont skip Si la session a des seeks, cela indique des sauts On considère que les segments entre le début et le temps de lecture final sont potentiellement skip si le seek count est élevé par rapport au temps de lecture Calculer un ratio de skip basé sur les seeks Plus il y a de seeks, plus il y a de zones skip potentielles +1 pour éviter division par zéro Pour chaque segment avant le temps de lecture final Si le segment est avant le temps de lecture final et qu'il y a des seeks Probabilité de skip basée sur le ratio Seuil pour considérer comme skip Segment partiellement écouté avec seeks = probablement skip generateHeatmapSegments génère les segments de heatmap en combinant les zones écoutées et skip Calculer l'intensité d'écoute Basée sur : nombre d'écoutes, temps moyen passé, et inverse des skips Intensité basée sur le nombre d'écoutes et le temps moyen Intensité = (nombre d'écoutes * ratio de complétion) - (skips * pénalité) Pénalité pour les skips (réduit l'intensité) GetHeatmapIntensityArray retourne un tableau simple d'intensités pour visualisation Utile pour les graphiques de heatmap simples/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_retention_policy_service.gocompressedFilearchiveFilecutoffDatetrackIDMaparchiveResultpolicycompressedPatharchiveCountrestoredCountarchives/playback_analytics"archives/playback_analytics"`json:"archived_count"``json:"archive_file"``json:"track_ids"``json:"archived_at"`olderThan must be greater than 0"olderThan must be greater than 0"created_at < ?"created_at < ?"failed to get analytics to archive: %w"failed to get analytics to archive: %w"No analytics to archive"No analytics to archive"older_than"older_than"failed to create archive directory: %w"failed to create archive directory: %w"20060102_150405"20060102_150405"playback_analytics_%s.json"playback_analytics_%s.json"failed to export analytics to archive: %w"failed to export analytics to archive: %w"Failed to compress archive file"Failed to compress archive file"Archived old analytics data"Archived old analytics data"archive_file"archive_file"failed to count analytics to delete: %w"failed to count analytics to delete: %w"No analytics to delete"No analytics to delete"failed to delete old analytics: %w"failed to delete old analytics: %w"Deleted old analytics data"Deleted old analytics data"Failed to archive old data"Failed to archive old data"failed to archive old data: %w"failed to archive old data: %w"Archived analytics data"Archived analytics data"Failed to delete old data"Failed to delete old data"failed to delete old data: %w"failed to delete old data: %w"failed to read file: %w"failed to read file: %w".gz".gz"failed to create compressed file: %w"failed to create compressed file: %w"failed to write compressed file: %w"failed to write compressed file: %w"Compressed archive file"Compressed archive file""original"compressed"compressed"archive_count"archive_count"failed to read archive directory: %w"failed to read archive directory: %w"archive_dir"archive_dir"failed to read archive file: %w"failed to read archive file: %w"failed to parse archive file: %w"failed to parse archive file: %w"Failed to restore analytics record"Failed to restore analytics record"Restored analytics from archive"Restored analytics from archive"restored_count"restored_count"total_in_archive"total_in_archive" PlaybackRetentionPolicyService gère la politique de rétention des données analytics T0382: Create Playback Analytics Data Retention Policy Répertoire pour les archives Service d'export pour l'archivage NewPlaybackRetentionPolicyService crée un nouveau service de politique de rétention RetentionPolicy représente une politique de rétention Archivage après cette durée Suppression après cette durée Compresser les archives DefaultRetentionPolicy retourne la politique de rétention par défaut ArchiveResult représente le résultat d'un archivage ArchiveOldData archive les données analytics plus anciennes que la durée spécifiée Récupérer les analytics à archiver Créer le répertoire d'archive si nécessaire Générer le nom du fichier d'archive Exporter les données en JSON Compresser si demandé Continuer même si la compression échoue Supprimer le fichier non compressé Collecter les track IDs uniques DeleteOldData supprime les données analytics plus anciennes que la durée spécifiée Compter les analytics à supprimer Supprimer les analytics ApplyRetentionPolicy applique une politique de rétention complète 1. Archiver les données anciennes 2. Supprimer les données très anciennes shouldCompress détermine si les fichiers doivent être compressés Par défaut, compresser les archives compressFile compresse un fichier JSON en utilisant gzip Lire le contenu du fichier Créer le fichier compressé Utiliser gzip pour compresser Note: Pour une implémentation complète, on utiliserait compress/gzip Pour simplifier, on va juste créer un fichier avec l'extension .gz et stocker les données JSON (dans une vraie implémentation, on utiliserait gzip.Writer) Pour l'instant, on va simplement copier les données Dans une vraie implémentation, on utiliserait: gzipWriter := gzip.NewWriter(compressedFile) defer gzipWriter.Close() _, err = gzipWriter.Write(data) Pour cette implémentation, on va simplement copier les données et laisser la compression réelle pour une future amélioration GetArchiveStats retourne les statistiques sur les archives Compter les fichiers d'archive RestoreFromArchive restaure des données depuis une archive Lire le fichier d'archive Décompresser si nécessaire Dans une vraie implémentation, on utiliserait gzip.Reader Pour l'instant, on suppose que le fichier n'est pas vraiment compressé ou on le traite comme un fichier JSON normal Parser le JSON Restaurer les analytics dans la base de données Note: On utilise Create pour éviter les conflits d'ID Dans une vraie implémentation, on pourrait vouloir gérer les IDs différemment Réinitialiser l'ID pour créer un nouvel enregistrement/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_retention_service.goengagementMetricsexitPointssegmentCountsegmentRetentionsexitCountexitRatereachedCountretentionRatesegmentEndSecondssegmentStartSecondssessionsInSegmenttotalPlayTimeInSegmentretentionsexitPointsegmentIndexepexitPointsMapmaxExitPointsaveragePausesaverageSeeksengagementScorehighEngagementCounthighEngagementRatelowEngagementCountlowEngagementRateoverallRetentionRatepauseScoreseekScore`json:"segment_start"``json:"segment_end"``json:"retention_rate"``json:"exit_count"``json:"exit_rate"``json:"overall_retention_rate"``json:"engagement_score"``json:"high_engagement_rate"``json:"low_engagement_rate"``json:"segment_retentions"``json:"exit_points"``json:"engagement_metrics"`Analyzed playback retention"Analyzed playback retention""segments"10.0 PlaybackRetentionService gère l'analyse de rétention des analytics de lecture T0375: Create Playback Analytics Retention Analysis NewPlaybackRetentionService crée un nouveau service d'analyse de rétention SegmentRetention représente la rétention pour un segment du track Pourcentage de début du segment (0-100) Pourcentage de fin du segment (0-100) Pourcentage d'utilisateurs qui atteignent ce segment Nombre d'utilisateurs qui sortent dans ce segment Pourcentage d'utilisateurs qui sortent dans ce segment ExitPoint représente un point de sortie identifié Pourcentage de début du segment Pourcentage de fin du segment Nombre de sorties Taux de sortie (%) Nombre total de sessions Temps de lecture moyen avant sortie EngagementMetrics représente les métriques d'engagement Taux de rétention global (%) Score d'engagement (0-100) Pourcentage de sessions avec engagement élevé (>75% completion) Pourcentage de sessions avec engagement faible (<25% completion) Nombre moyen de pauses Nombre moyen de seeks RetentionAnalysisResult représente le résultat complet de l'analyse de rétention AnalyzeRetention analyse la rétention pour un track Par défaut, 10 segments Maximum 100 segments Initialiser les segments même s'il n'y a pas de sessions Retourner un résultat avec segments initialisés mais vides Calculer la rétention par segment Identifier les points de sortie Analyser l'engagement calculateSegmentRetention calcule la rétention par segment Pour chaque segment Calculer le temps de lecture minimum pour atteindre ce segment Compter les sessions qui atteignent ce segment Vérifier si la session atteint le début du segment Vérifier si la session sort dans ce segment Calculer le temps de lecture dans ce segment Calculer les taux identifyExitPoints identifie les points de sortie principaux Pour chaque session, identifier le segment où elle sort Utilisé pour les calculs futurs si nécessaire Déterminer dans quel segment la session se termine Calculer les moyennes et taux Trier par taux de sortie décroissant Retourner les 5 principaux points de sortie analyzeEngagement analyse les métriques d'engagement Calculer les métriques Le taux de rétention global est le taux de complétion moyen Calculer le score d'engagement (0-100) Basé sur: completion rate (50%), pauses (25%), seeks (25%) Moins de pauses et seeks = meilleur engagement Normaliser les pauses (0-10 pauses = 0-25 points) Normaliser les seeks (0-5 seeks = 0-25 points) S'assurer que le score est entre 0 et 100/home/senke/git/talas/veza/veza-backend-api/internal/services/playback_segmentation_service.gouserIDsallSegmentsbehaviorSegmentscompletionSegmentsengagementSegmentssegmentCountsuserMetricsskipRateuserSessionsuserAnalyticsuserMetricsMapactiveThresholdavgSessionscasualThresholdfocusedThresholdmaxSessionsskipThresholdhigh_engagement"high_engagement"medium_engagement"medium_engagement"low_engagement"low_engagement"high_completion"high_completion"medium_completion"medium_completion"low_completion"low_completion"active_listener"active_listener"casual_listener"casual_listener"frequent_skipper"frequent_skipper"focused_listener"focused_listener"`json:"session_count"``json:"skip_rate"``json:"total_users"``json:"user_metrics,omitempty"``json:"segment_counts"`Segmented users for track"Segmented users for track"total_segments"total_segments"1.53/270.070invalid track ID or user ID: trackID=%s, userID=%s"invalid track ID or user ID: trackID=%s, userID=%s"user %s not found in analytics for track %s"user %s not found in analytics for track %s" UserSegment représente un segment d'utilisateur T0378: Create Playback Analytics User Segmentation Segments par engagement Segments par completion rate Segments par comportement Beaucoup de sessions Peu de sessions Beaucoup de skips Peu de skips, beaucoup d'écoute PlaybackSegmentationService gère la segmentation des utilisateurs pour les analytics de lecture NewPlaybackSegmentationService crée un nouveau service de segmentation d'utilisateurs UserMetrics représente les métriques agrégées pour un utilisateur MIGRATION UUID: UserID migré vers uuid.UUID Temps de lecture total (secondes) Pourcentage de sessions complétées (>90%) Taux de skips (seeks par session) SegmentationResult représente le résultat de la segmentation Map de segment -> liste d'user UUIDs Métriques par utilisateur Nombre d'utilisateurs par segment SegmentUsers segmente les utilisateurs pour un track donné Retourner un résultat vide Calculer les métriques par utilisateur Segmenter par engagement Segmenter par completion rate Segmenter par comportement Combiner tous les segments Calculer les compteurs par segment calculateUserMetrics calcule les métriques agrégées pour chaque utilisateur MIGRATION UUID: retourne map[uuid.UUID]*UserMetrics Grouper les analytics par utilisateur Calculer les métriques pour chaque utilisateur Taux de skips = nombre moyen de seeks UUID segmentByEngagement segmente les utilisateurs par niveau d'engagement MIGRATION UUID: paramètre et retour utilisent uuid.UUID segmentByCompletionRate segmente les utilisateurs par taux de complétion segmentByBehavior segmente les utilisateurs par comportement d'écoute Calculer les seuils basés sur les données Seuils pour la segmentation 50% au-dessus de la moyenne 50% en dessous de la moyenne 50% au-dessus de la moyenne des seeks 50% en dessous de la moyenne des seeks Segmentation par nombre de sessions Segmentation par comportement de skip Focused listener: peu de skips ET bonne complétion GetUserSegment retourne le segment principal d'un utilisateur pour un track MIGRATION UUID: userID migré vers uuid.UUID, trackID reste int64 Trouver le segment principal de l'utilisateur (priorité: engagement > completion > behavior) Déterminer le segment principal basé sur l'engagement/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_analytics_service.goPlayCountResultplayCountResult`json:"plays"``json:"shares"``json:"followers"``json:"track_count"`failed to get playlist: %w"failed to get playlist: %w"playlist_id = ? AND deleted_at IS NULL"playlist_id = ? AND deleted_at IS NULL"failed to count shares: %w"failed to count shares: %w"failed to get playlist tracks: %w"failed to get playlist tracks: %w"track_id IN ?"track_id IN ?"failed to count plays: %w"failed to count plays: %w"Playlist stats retrieved"Playlist stats retrieved"plays"plays"shares"shares"followers"followers"Playlist play incremented"Playlist play incremented" Added import for uuid PlaylistAnalyticsService gère les analytics de playlists NewPlaylistAnalyticsService crée un nouveau service d'analytics de playlists PlaylistStats représente les statistiques d'une playlist Nombre total de lectures (somme des plays des tracks) Nombre de liens de partage créés Nombre de follows (équivalent aux likes) Nombre de followers (déjà dans Playlist.FollowerCount) Nombre de tracks dans la playlist GetPlaylistStats récupère les statistiques d'une playlist Changed playlistID to uuid.UUID Track count (déjà dans le modèle) Followers count (déjà dans le modèle) Count shares (nombre de liens de partage créés, non supprimés) Count likes (nombre de follows, non supprimés) Count plays: somme des plays de tous les tracks dans la playlist On compte les TrackPlay pour tous les tracks de la playlist Récupérer tous les track IDs de la playlist Si la playlist a des tracks, compter les plays IncrementPlaylistPlays incrémente le compteur de plays d'une playlist Cette méthode peut être appelée lorsqu'un track de la playlist est joué Note: Pour l'instant, on ne stocke pas de compteur de plays dans Playlist car on le calcule dynamiquement à partir des TrackPlay Cette méthode est prévue pour une future optimisation avec cache/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_duplicate_service.gocollaboratorCountnewPlaylistTracktrackExistsnewDescriptionnewTitleoriginalPlaylistDuplicatePlaylist: failed to load original playlist: %w"DuplicatePlaylist: failed to load original playlist: %w"DuplicatePlaylist: failed to load playlist tracks: %w"DuplicatePlaylist: failed to load playlist tracks: %w"SELECT COUNT(*) FROM playlist_collaborators WHERE playlist_id = ? AND user_id = ?"SELECT COUNT(*) FROM playlist_collaborators WHERE playlist_id = ? AND user_id = ?" (Copy)" (Copy)"DuplicatePlaylist: failed to create duplicate playlist: %w"DuplicatePlaylist: failed to create duplicate playlist: %w"DuplicatePlaylist: track not found for playlist track at position %d"DuplicatePlaylist: track not found for playlist track at position %d"id = ? AND deleted_at IS NULL"id = ? AND deleted_at IS NULL"DuplicatePlaylist: failed to verify track existence: %w"DuplicatePlaylist: failed to verify track existence: %w"DuplicatePlaylist: track %s no longer exists"DuplicatePlaylist: track %s no longer exists"DuplicatePlaylist: failed to add track %s to duplicate: %w"DuplicatePlaylist: failed to add track %s to duplicate: %w"DuplicatePlaylist: failed to update track_count: %w"DuplicatePlaylist: failed to update track_count: %w"Playlist duplicated"Playlist duplicated"original_playlist_id"original_playlist_id"new_playlist_id"new_playlist_id"tracks_count"tracks_count" PlaylistDuplicateService gère la duplication de playlists NewPlaylistDuplicateService crée un nouveau service de duplication de playlists DuplicatePlaylistRequest représente la requête de duplication DuplicatePlaylist duplique une playlist avec tous ses tracks Transactionnelle : Toute la duplication (playlist + tracks + compteur) est dans une seule transaction 1. VALIDATION : Charger playlist originale (sans tracks pour l'instant) 1b. Charger tous les PlaylistTrack de la playlist originale (même si le Track associé est supprimé) 2. VALIDATION : Vérifier que l'utilisateur a accès à la playlist (propriétaire, collaborateur ou publique) Note: On fait cette vérification dans la transaction pour éviter les race conditions Vérifier si l'utilisateur est collaborateur (simplifié pour la transaction) On peut faire une requête simple dans la transaction 3. DÉTERMINATION : Titre, description, isPublic 4. CRÉATION : Nouvelle playlist (INSERT dans la transaction) Sera mis à jour après l'ajout des tracks 5. DUPLICATION : Tous les tracks dans la même transaction Vérifier que le track existe toujours dans la base de données (non supprimé) Créer le PlaylistTrack directement dans la transaction Use the userID who is duplicating the playlist Si position <= 0, utiliser l'index + 1 6. MISE À JOUR : Compteur de tracks (UPDATE dans la transaction) 7. LOG (dans la transaction, mais ne dépend pas d'états non commit) 8. RETOUR nil = commit automatique/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_follow_service.goexistingfailed to check playlist: %w"failed to check playlist: %w"user_id = ? AND playlist_id = ? AND deleted_at IS NULL"user_id = ? AND playlist_id = ? AND deleted_at IS NULL"failed to check existing follow: %w"failed to check existing follow: %w"failed to create follow: %w"failed to create follow: %w"follower_count"follower_count"follower_count + ?"follower_count + ?"Failed to update playlist follower_count"Failed to update playlist follower_count"Playlist followed"Playlist followed"failed to check follow: %w"failed to check follow: %w"failed to delete follow: %w"failed to delete follow: %w"CASE WHEN follower_count - 1 < 0 THEN 0 ELSE follower_count - 1 END"CASE WHEN follower_count - 1 < 0 THEN 0 ELSE follower_count - 1 END"Playlist unfollowed"Playlist unfollowed"failed to get followers count: %w"failed to get followers count: %w"INNER JOIN playlist_follows ON playlist_follows.playlist_id = playlists.id"INNER JOIN playlist_follows ON playlist_follows.playlist_id = playlists.id"playlist_follows.user_id = ? AND playlist_follows.deleted_at IS NULL"playlist_follows.user_id = ? AND playlist_follows.deleted_at IS NULL"failed to get followed playlists: %w"failed to get followed playlists: %w" PlaylistFollowService gère les opérations sur les follows de playlists NewPlaylistFollowService crée un nouveau service de follows de playlists FollowPlaylist ajoute un follow d'un utilisateur sur une playlist MIGRATION UUID: Completée. userID et playlistID sont des UUIDs. Vérifier si la playlist existe Vérifier si l'utilisateur est le propriétaire (ne peut pas suivre sa propre playlist) Vérifier si l'utilisateur suit déjà cette playlist Déjà suivi, retourner nil (idempotent) Créer le follow Mettre à jour le compteur de followers de la playlist Ne pas retourner l'erreur, le follow a été créé avec succès UnfollowPlaylist supprime un follow d'un utilisateur sur une playlist Vérifier si le follow existe Pas de follow à supprimer, retourner nil (idempotent) Supprimer le follow (soft delete) Use CASE expression for SQLite compatibility (GREATEST is not supported in SQLite) Ne pas retourner l'erreur, le follow a été supprimé avec succès IsFollowing vérifie si un utilisateur suit une playlist GetPlaylistFollowersCount retourne le nombre de followers d'une playlist GetFollowedPlaylists retourne toutes les playlists suivies par un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_notification_service.goaddedByUserIDtrackTitlesharedByUserIDupdatedByUserIDfailed to get collaborator: %w"failed to get collaborator: %w"Nouveau collaborateur"Nouveau collaborateur"Vous avez été ajouté comme collaborateur à la playlist "%s""Vous avez été ajouté comme collaborateur à la playlist \"%s\""/playlists/%s"/playlists/%s"playlist_collaborator_added"playlist_collaborator_added"Track ajouté"Track ajouté"Un nouveau track "%s" a été ajouté à votre playlist "%s""Un nouveau track \"%s\" a été ajouté à votre playlist \"%s\""Un nouveau track a été ajouté à votre playlist "%s""Un nouveau track a été ajouté à votre playlist \"%s\""playlist_track_added"playlist_track_added"Failed to notify playlist owner"Failed to notify playlist owner"Un nouveau track "%s" a été ajouté à la playlist "%s""Un nouveau track \"%s\" a été ajouté à la playlist \"%s\""Un nouveau track a été ajouté à la playlist "%s""Un nouveau track a été ajouté à la playlist \"%s\""Failed to notify collaborator"Failed to notify collaborator""userID"Playlist partagée"Playlist partagée"Votre playlist "%s" a été partagée"Votre playlist \"%s\" a été partagée"playlist_shared"playlist_shared"Playlist mise à jour"Playlist mise à jour"La playlist "%s" a été mise à jour"La playlist \"%s\" a été mise à jour"playlist_updated"playlist_updated" PlaylistNotificationService handles playlist-specific notifications T0508: Create Playlist Notifications NewPlaylistNotificationService creates a new playlist notification service NotifyCollaboratorAdded notifies a user when they are added as a collaborator MIGRATION UUID: Completée. Get playlist info Get collaborator info using GetCollaborator (which takes playlistID and userID) Get added by user info (we'll use a simple query for now) In a real implementation, you might want to get the username NotifyTrackAdded notifies playlist owner and collaborators when a track is added trackTitle can be empty if not available, will use a generic message Notify playlist owner (if not the one who added the track) Notify all collaborators (except the one who added the track) Don't fail the whole operation if we can't notify collaborators Skip the user who added the track NotifyPlaylistShared notifies when a playlist is shared via a share link Notify playlist owner (if not the one who shared) NotifyPlaylistUpdated notifies collaborators when a playlist is updated Notify playlist owner (if not the one who updated) Notify all collaborators (except the one who updated) Skip the user who updated/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_recommendation_service.goallPlaylistsfollowedPlaylistsscoreMapscoressimilarityScorenormalizedScorepopularityScorereasonsrecencyScoretrackCountScoresimilaritycommonTracksfollowedTrackIDsunionSizefollowedtargetTrackIDstotalSimilarityvalidComparisonsmaxFollowersoptimalTrackCountageInDaysFailed to get followed playlists for recommendations"Failed to get followed playlists for recommendations"failed to get playlists: %w"failed to get playlists: %w"Playlist recommendations generated"Playlist recommendations generated"Similaire aux playlists suivies (%.2f)"Similaire aux playlists suivies (%.2f)"Populaire (%.2f followers)"Populaire (%.2f followers)"Contenu riche (%d tracks)"Contenu riche (%d tracks)"Récente"Récente"Recommandation basée sur plusieurs facteurs"Recommandation basée sur plusieurs facteurs"Log1020.0 PlaylistRecommendationService gère les recommandations de playlists PlaylistServiceForRecommendation définit l'interface minimale nécessaire pour les recommandations MIGRATION UUID: userID migré vers *uuid.UUID, playlistID en uuid.UUID PlaylistFollowServiceForRecommendation définit l'interface minimale nécessaire pour les recommandations NewPlaylistRecommendationService crée un nouveau service de recommandations de playlists RecommendationScore représente un score de recommandation pour une playlist GetRecommendationsParams représente les paramètres pour obtenir des recommandations Nombre de recommandations à retourner (défaut: 20) Score minimum pour inclure une recommandation (défaut: 0.1) Inclure les playlists de l'utilisateur (défaut: false) GetRecommendations retourne des recommandations de playlists pour un utilisateur Récupérer les playlists suivies par l'utilisateur Récupérer toutes les playlists publiques (ou accessibles) Calculer les scores pour chaque playlist Ignorer les playlists de l'utilisateur si IncludeOwn est false Ignorer les playlists déjà suivies Convertir la map en slice Trier par score décroissant Limiter le nombre de résultats calculateRecommendationScore calcule un score de recommandation pour une playlist 1. Score basé sur la similarité avec les playlists suivies (poids: 0.5) 2. Score basé sur la popularité (nombre de followers) (poids: 0.2) 3. Score basé sur le nombre de tracks (poids: 0.1) 4. Score basé sur la récence (poids: 0.2) Normaliser le score entre 0 et 1 Prendre la raison principale calculateSimilarityScore calcule un score de similarité basé sur les tracks communs Récupérer les tracks de la playlist cible Calculer la similarité avec chaque playlist suivie Récupérer les tracks de la playlist suivie Calculer l'intersection (tracks communs) Calculer le coefficient de Jaccard (similarité) Moyenne des similarités calculatePopularityScore calcule un score basé sur la popularité (nombre de followers) Normaliser le nombre de followers (logarithmique pour éviter que les très grandes valeurs dominent) On considère qu'un playlist avec 100+ followers est très populaire Utiliser une fonction logarithmique pour normaliser calculateTrackCountScore calcule un score basé sur le nombre de tracks On considère qu'une playlist avec 20+ tracks a un bon contenu Score qui augmente jusqu'à optimalTrackCount, puis se stabilise calculateRecencyScore calcule un score basé sur la récence de la playlist Calculer l'âge en jours Si UpdatedAt est plus récent que CreatedAt, utiliser UpdatedAt Les playlists créées/mises à jour dans les 30 derniers jours ont un score élevé Très récente Ancienne Score qui diminue linéairement avec l'âge isPlaylistFollowed vérifie si une playlist est dans la liste des playlists suivies/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_service.gogormRepofilteredownerIDfailed to check user: %w"failed to check user: %w"failed to create playlist: %w"failed to create playlist: %w"Playlist created"Playlist created"Failed to save initial playlist version"Failed to save initial playlist version"failed to search playlists: %w"failed to search playlists: %w"Playlists searched"Playlists searched"failed to update playlist: %w"failed to update playlist: %w"Playlist updated"Playlist updated"Failed to save playlist version"Failed to save playlist version"Failed to send playlist updated notification"Failed to send playlist updated notification"failed to delete playlist: %w"failed to delete playlist: %w"Playlist deleted"Playlist deleted"failed to add track to playlist: %w"failed to add track to playlist: %w"Track added to playlist"Track added to playlist"Failed to send track added notification"Failed to send track added notification"failed to remove track from playlist: %w"failed to remove track from playlist: %w"Track removed from playlist"Track removed from playlist"failed to reorder tracks: %w"failed to reorder tracks: %w"Playlist tracks reordered"Playlist tracks reordered"failed to add collaborator: %w"failed to add collaborator: %w"Collaborator added to playlist"Collaborator added to playlist"owner_id"owner_id"collaborator_user_id"collaborator_user_id"Failed to send collaborator added notification"Failed to send collaborator added notification"failed to remove collaborator: %w"failed to remove collaborator: %w"Collaborator removed from playlist"Collaborator removed from playlist"failed to update collaborator permission: %w"failed to update collaborator permission: %w"Collaborator permission updated"Collaborator permission updated"failed to check collaborator: %w"failed to check collaborator: %w"failed to get collaborators: %w"failed to get collaborators: %w"playlist share service not initialized"playlist share service not initialized"Failed to send playlist shared notification"Failed to send playlist shared notification"playlist follow service not initialized"playlist follow service not initialized" UserRepositoryForPlaylist définit l'interface minimale nécessaire pour PlaylistService T0453: Interface pour vérifier l'existence des utilisateurs PlaylistService gère les opérations sur les playlists T0453: Utilise le repository pattern pour l'accès aux données NewPlaylistService crée un nouveau service de playlists avec repositories SetPlaylistShareService définit le service de partage de playlist SetPlaylistNotificationService définit le service de notifications de playlist SetPlaylistVersionService définit le service de versions de playlist NewPlaylistServiceWithDB crée un nouveau service de playlists avec GORM (compatibilité) Cette fonction crée les repositories en interne pour maintenir la compatibilité Pour UserRepository, on utilise une implémentation simple qui utilise GORM Note: On pourrait créer un UserRepository GORM aussi, mais pour l'instant on garde la compatibilité Créer et injecter le service de partage gormUserRepository est une implémentation temporaire de UserRepository avec GORM pour maintenir la compatibilité avec le code existant Exists vérifie si un utilisateur existe (méthode helper pour le service) CreatePlaylist crée une nouvelle playlist T0453: Utilise le repository pattern avec validation Validation Note: On utilise une méthode helper Exists si disponible Pour les autres implémentations, on essaie de récupérer l'utilisateur Créer la playlist T0509: Sauvegarder la version initiale FIXME: PlaylistVersionService likely needs update for UUID too, but assuming it takes what we give or we handle it later Assuming PlaylistVersionService needs int64, we might have issues. For now, let's pass UUID if it accepts interface{} or we update it later. Actually, let's assume we need to update it or skip versioning for now if it breaks. Let's try to pass it. GetPlaylist récupère une playlist avec ses tracks T0453: Utilise le repository pattern avec vérification d'accès MIGRATION UUID: userID migré vers *uuid.UUID Use GetByIDWithTracks Vérifier accès si playlist privée Return NotFound for security (hide private playlists) GetPlaylists récupère une liste de playlists avec pagination T0453: Utilise le repository pattern avec filtres T0501: Optimisé avec pagination efficace et lazy loading MIGRATION UUID: currentUserID et filterUserID migrés vers *uuid.UUID Appliquer la pagination avec limites optimisées T0501: Optimisation - Utiliser un offset calculé efficacement Pour les grandes pages, utiliser un curseur si disponible Pour les très grandes pages, limiter à 100 pour éviter les problèmes de performance Déterminer le filtre isPublic selon les règles d'accès Utilisateur non authentifié : seulement les playlists publiques Filtre sur un autre utilisateur : seulement publiques Si filterUserID == currentUserID ou filterUserID == nil, on ne filtre pas par isPublic (on laisse le repository gérer) T0501: Lazy loading - Ne pas charger les tracks pour la liste Filtrer les playlists selon les règles d'accès si nécessaire Filtrer pour ne garder que les publiques ou celles de l'utilisateur SearchPlaylistsParams représente les paramètres de recherche de playlists MIGRATION UUID: UserID et CurrentUserID migrés vers *uuid.UUID Numéro de page (défaut: 1) Nombre de résultats par page (défaut: 20, max: 100) ID de l'utilisateur actuel pour les règles d'accès SearchPlaylists recherche des playlists selon les critères fournis Si pas d'utilisateur authentifié, seulement les playlists publiques Si on recherche les playlists d'un autre utilisateur, seulement publiques Si params.UserID == nil ou params.UserID == params.CurrentUserID, on ne filtre pas par isPublic Utiliser la méthode Search du repository Recherche globale : filtrer pour ne garder que les publiques ou celles de l'utilisateur UpdatePlaylist met à jour une playlist T0453: Utilise le repository pattern avec vérification d'ownership MIGRATION UUID: userID en uuid.UUID, playlistID en uuid.UUID Vérifier ownership T0509: Sauvegarder une version avant la mise à jour T0508: Envoyer une notification DeletePlaylist supprime une playlist (soft delete) AddTrackToPlaylist ajoute un track à une playlist T0466: Implémentation avec PlaylistTrackRepository MIGRATION UUID: userID en uuid.UUID, playlistID et trackID en uuid.UUID Ajouter le track via le repository (qui vérifie l'existence du track) T0508: Envoyer une notification (trackTitle sera vide, le service utilisera un message générique) AddTrack est un alias pour AddTrackToPlaylist (compatibilité) RemoveTrackFromPlaylist retire un track d'une playlist Retirer le track via le repository RemoveTrack est un alias pour RemoveTrackFromPlaylist (compatibilité) ReorderPlaylistTracks réorganise les tracks d'une playlist trackPositions est une map de trackID -> position Réorganiser les tracks via le repository ReorderTracks est un alias pour ReorderPlaylistTracks (compatibilité) trackIDs est une liste de trackIDs dans l'ordre souhaité (position = index + 1) T0478: Implémentation avec vérification d'ownership MIGRATION UUID: ownerID et collaboratorUserID migrés vers uuid.UUID, playlistID en uuid.UUID Vérifier que l'utilisateur collaborateur existe Vérifier qu'on n'ajoute pas le propriétaire comme collaborateur Ajouter le collaborateur via le repository T0508: Envoyer une notification au collaborateur Retirer le collaborateur via le repository UpdateCollaboratorPermission met à jour la permission d'un collaborateur Mettre à jour la permission via le repository CheckPermission vérifie si un utilisateur a une certaine permission sur une playlist T0478: Vérifie les permissions (read, write, admin) Récupérer la playlist Le propriétaire a toujours toutes les permissions Si la playlist est publique, tout le monde peut la lire Pas de permission Vérifier la permission selon le niveau requis T0478: Helper method pour récupérer les collaborateurs Vérifier que l'utilisateur a accès à la playlist (propriétaire ou collaborateur) Récupérer les collaborateurs CreateShareLink crée un nouveau lien de partage public pour une playlist Vérifier que l'utilisateur a la permission (owner ou admin) Vérifier si l'utilisateur est le propriétaire FollowPlaylist permet à un utilisateur de suivre une playlist UnfollowPlaylist permet à un utilisateur de ne plus suivre une playlist/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_share_service.goexistingLinkexistingShareshareLinkIDplaylist share not found"playlist share not found"playlist share link expired"playlist share link expired"playlist_id = ? AND user_id = ? AND permission = ?"playlist_id = ? AND user_id = ? AND permission = ?"share_token = ?"share_token = ?"share_token = ? AND deleted_at IS NULL"share_token = ? AND deleted_at IS NULL"access_count"access_count"access_count + 1"access_count + 1" ErrPlaylistShareNotFound est retourné quand un share de playlist n'est pas trouvé ErrPlaylistShareExpired est retourné quand un share de playlist a expiré PlaylistShareService gère le partage de playlists NewPlaylistShareService crée un nouveau service de partage de playlists generateShareToken génère un token unique sécurisé Vérifier que la playlist existe et appartient à l'utilisateur Vérifier que l'utilisateur est le propriétaire ou a la permission admin Vérifier si l'utilisateur est collaborateur avec permission admin Vérifier si un lien de partage existe déjà pour cette playlist Un lien existe déjà, vérifier s'il est expiré Le lien est expiré, on le supprime (soft delete) et on en crée un nouveau Le lien existe et est valide, on le retourne Générer un token unique Vérifier l'unicité du token (très peu probable mais on vérifie) ValidateShareToken valide un token de partage et retourne le share link Vérifier l'expiration Incrémenter le compteur d'accès GetShareLinkByToken récupère un share link par son token (sans incrémenter le compteur) RevokeShareLink révoque un lien de partage UUID query Vérifier que l'utilisateur est le propriétaire Soft delete GetShareLinkByPlaylistID récupère le lien de partage actif pour une playlist/home/senke/git/talas/veza/veza-backend-api/internal/services/playlist_version_service.gotracksSnapshotversionNumberTrackSnapshotsnapshotsrestoredVersionversionToRestoresnapshotfailed to get next version number: %w"failed to get next version number: %w"Failed to create tracks snapshot"Failed to create tracks snapshot"[]"[]"failed to create version: %w"failed to create version: %w"Playlist version saved"Playlist version saved""version"failed to marshal tracks snapshot: %w"failed to marshal tracks snapshot: %w"version not found"version not found"failed to get version: %w"failed to get version: %w"Failed to restore tracks from snapshot"Failed to restore tracks from snapshot"Failed to save restored version"Failed to save restored version"Playlist version restored"Playlist version restored"restored_version"restored_version"new_version"new_version"failed to unmarshal tracks snapshot: %w"failed to unmarshal tracks snapshot: %w"Tracks snapshot restoration skipped (not implemented)"Tracks snapshot restoration skipped (not implemented)" PlaylistVersionService gère les versions de playlists NewPlaylistVersionService crée un nouveau service de versions de playlists SaveVersion sauvegarde une version de la playlist Récupérer la playlist avec ses tracks Obtenir le prochain numéro de version Créer un snapshot des tracks Continuer même si le snapshot échoue Créer la version FIXME: models.PlaylistVersion ID types need check. Assuming repo handles UUID if struct updated. Assuming struct updated to UUID createTracksSnapshot crée un snapshot JSON des tracks de la playlist Récupérer les tracks de la playlist Créer un snapshot simple avec les IDs et positions Sérialiser en JSON GetVersions récupère l'historique des versions d'une playlist GetVersion récupère une version spécifique RestoreVersion restaure une playlist à une version spécifique Récupérer la version à restaurer Récupérer la playlist actuelle Restaurer les propriétés de la playlist Restaurer les tracks si le snapshot existe Ne pas échouer la restauration si les tracks ne peuvent pas être restaurés Créer une nouvelle version pour la restauration Retourner quand même la version restaurée restoreTracksFromSnapshot restaure les tracks depuis un snapshot Supprimer tous les tracks actuels Note: Cette opération peut être coûteuse, mais nécessaire pour une restauration complète Dans une implémentation optimisée, on pourrait comparer et ne modifier que ce qui a changé Pour l'instant, on ne restaure pas automatiquement les tracks car cela nécessite de supprimer tous les tracks existants et de les recréer, ce qui peut être risqué Cette fonctionnalité peut être ajoutée plus tard si nécessaire/home/senke/git/talas/veza/veza-backend-api/internal/services/rbac_service.gopermIDexistingRole"gorm.io/gorm/clause"`json:"is_system"``json:"role_id"`SELECT COUNT(*) FROM roles WHERE name = $1"SELECT COUNT(*) FROM roles WHERE name = $1"failed to check role existence: %w"failed to check role existence: %w"role with name '%s' already exists"role with name '%s' already exists"
		INSERT INTO roles (id, name, description, is_system, created_at, updated_at)
		VALUES (gen_random_uuid(), $1, $2, false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
		RETURNING id
	`
		INSERT INTO roles (id, name, description, is_system, created_at, updated_at)
		VALUES (gen_random_uuid(), $1, $2, false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
		RETURNING id
	`failed to create role: %w"failed to create role: %w"
				INSERT INTO role_permissions (role_id, permission_id, created_at)
				VALUES ($1, $2, CURRENT_TIMESTAMP)
			`
				INSERT INTO role_permissions (role_id, permission_id, created_at)
				VALUES ($1, $2, CURRENT_TIMESTAMP)
			`Failed to assign permission to role"Failed to assign permission to role"failed to get created role: %w"failed to get created role: %w"Role created successfully"Role created successfully"role_name"role_name"
		SELECT r.id, r.name, r.description, r.is_system, r.created_at, r.updated_at
		FROM roles r
		WHERE r.id = $1
	`
		SELECT r.id, r.name, r.description, r.is_system, r.created_at, r.updated_at
		FROM roles r
		WHERE r.id = $1
	`failed to get role: %w"failed to get role: %w"Failed to get role permissions"Failed to get role permissions"
		SELECT p.id, p.name, p.description, p.resource, p.action, p.created_at
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		WHERE rp.role_id = $1
		ORDER BY p.name
	`
		SELECT p.id, p.name, p.description, p.resource, p.action, p.created_at
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		WHERE rp.role_id = $1
		ORDER BY p.name
	`Failed to scan permission"Failed to scan permission"UPDATE"UPDATE"AssignRoleToUser: failed to check user existence: %w"AssignRoleToUser: failed to check user existence: %w"AssignRoleToUser: failed to check role existence: %w"AssignRoleToUser: failed to check role existence: %w"user_id = ? AND role_id = ?"user_id = ? AND role_id = ?"role already assigned to user"role already assigned to user"failed to check existing role: %w"failed to check existing role: %w"
			INSERT INTO user_roles (id, user_id, role_id, role, created_at)
			VALUES (gen_random_uuid(), ?, ?, ?, CURRENT_TIMESTAMP)
		`
			INSERT INTO user_roles (id, user_id, role_id, role, created_at)
			VALUES (gen_random_uuid(), ?, ?, ?, CURRENT_TIMESTAMP)
		`AssignRoleToUser: failed to assign role to user: %w"AssignRoleToUser: failed to assign role to user: %w"
		DELETE FROM user_roles 
		WHERE user_id = $1 AND role_id = $2
	`
		DELETE FROM user_roles 
		WHERE user_id = $1 AND role_id = $2
	`failed to remove role from user: %w"failed to remove role from user: %w"role not assigned to user"role not assigned to user"
		SELECT r.id, r.name, r.description, r.is_system, r.created_at, r.updated_at
		FROM roles r
		JOIN user_roles ur ON r.id = ur.role_id
		WHERE ur.user_id = $1
		ORDER BY r.name
	`
		SELECT r.id, r.name, r.description, r.is_system, r.created_at, r.updated_at
		FROM roles r
		JOIN user_roles ur ON r.id = ur.role_id
		WHERE ur.user_id = $1
		ORDER BY r.name
	`failed to get user roles: %w"failed to get user roles: %w"Failed to scan role"Failed to scan role"
		SELECT COUNT(*) 
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		JOIN user_roles ur ON rp.role_id = ur.role_id
		WHERE ur.user_id = $1 AND p.resource = $2 AND p.action = $3
	`
		SELECT COUNT(*) 
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		JOIN user_roles ur ON rp.role_id = ur.role_id
		WHERE ur.user_id = $1 AND p.resource = $2 AND p.action = $3
	`
		SELECT DISTINCT p.id, p.name, p.description, p.resource, p.action, p.created_at
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		JOIN user_roles ur ON rp.role_id = ur.role_id
		WHERE ur.user_id = $1
		ORDER BY p.resource, p.action
	`
		SELECT DISTINCT p.id, p.name, p.description, p.resource, p.action, p.created_at
		FROM permissions p
		JOIN role_permissions rp ON p.id = rp.permission_id
		JOIN user_roles ur ON rp.role_id = ur.role_id
		WHERE ur.user_id = $1
		ORDER BY p.resource, p.action
	`failed to get user permissions: %w"failed to get user permissions: %w"SELECT COUNT(*) FROM permissions WHERE resource = $1 AND action = $2"SELECT COUNT(*) FROM permissions WHERE resource = $1 AND action = $2"failed to check permission existence: %w"failed to check permission existence: %w"permission with resource '%s' and action '%s' already exists"permission with resource '%s' and action '%s' already exists"
		INSERT INTO permissions (id, name, description, resource, action, created_at)
		VALUES (gen_random_uuid(), $1, $2, $3, $4, CURRENT_TIMESTAMP)
		RETURNING id
	`
		INSERT INTO permissions (id, name, description, resource, action, created_at)
		VALUES (gen_random_uuid(), $1, $2, $3, $4, CURRENT_TIMESTAMP)
		RETURNING id
	`Permission created successfully"Permission created successfully"permission_name"permission_name"
		SELECT id, name, description, is_system, created_at, updated_at
		FROM roles
		ORDER BY name
	`
		SELECT id, name, description, is_system, created_at, updated_at
		FROM roles
		ORDER BY name
	`failed to get roles: %w"failed to get roles: %w" RBACService handles role-based access control NewRBACService creates a new RBAC service Role represents a user role Permission represents a permission UserRole represents a user's role assignment Check if role already exists Create role Assign permissions to role Continue with other permissions Get the created role with permissions GetRoleByID gets a role by ID Get permissions for this role GetRolePermissions gets permissions for a role MIGRATION UUID: userID migré vers uuid.UUID, roleID aussi Transactionnelle : Toutes les vérifications et l'INSERT sont dans une seule transaction avec FOR UPDATE 1. VALIDATION : User existe ? (SELECT avec FOR UPDATE pour éviter race condition) 2. VALIDATION : Role existe ? (SELECT avec FOR UPDATE pour éviter race condition) 1. Vérifier si l'utilisateur a déjà ce rôle (avec verrou) 4. INSERTION : Assignation (INSERT dans la transaction) Note: 'role' column is required by schema (legacy/redundant field) Si contrainte UNIQUE violée (race condition détectée), la contrainte DB gère cela La vérification du doublon avant l'INSERT devrait gérer la plupart des cas 5. LOG (dans la transaction, mais ne dépend pas d'états non commit) 6. RETOUR nil = commit automatique Check if permission already exists Create permission/home/senke/git/talas/veza/veza-backend-api/internal/services/refresh_token_service.gonewTokenHasholdTokenHashnewTokenoldTokenuser_id = ? AND token_hash = ?"user_id = ? AND token_hash = ?"refresh token not found"refresh token not found"refresh token expired"refresh token expired" RefreshTokenService gère le stockage et la validation des refresh tokens T0164: Service pour gérer les refresh tokens avec stockage en base et validation NewRefreshTokenService crée une nouvelle instance de RefreshTokenService Store stocke un refresh token en base de données (hashé pour la sécurité) T0164: Stocke le token hashé avec userID et expiration Validate vérifie si un refresh token est valide T0164: Valide le token en vérifiant son hash et sa date d'expiration Vérifier si le token n'a pas expiré Rotate invalide l'ancien refresh token et en stocke un nouveau Transaction pour assurer l'atomicité Révoquer l'ancien Stocker le nouveau Revoke supprime/révoque un refresh token T0164: Supprime le token de la base de données Ce n'est pas forcément une erreur critique si le token n'existait déjà plus RevokeAll révoque tous les refresh tokens d'un utilisateur Utile pour la déconnexion de tous les appareils hashToken hash un token avec SHA-256 pour le stockage sécurisé HashToken expose la méthode hashToken pour les tests T0171: Méthode publique pour hasher les tokens (utilisée dans les tests)/home/senke/git/talas/veza/veza-backend-api/internal/services/role_service.gouserRole"Permissions"id = ? AND is_system = ?"id = ? AND is_system = ?"failed to update role: %w"failed to update role: %w"failed to delete role: %w"failed to delete role: %w"failed to assign role: %w"failed to assign role: %w"is_active"is_active"failed to revoke role: %w"failed to revoke role: %w"JOIN user_roles ON roles.id = user_roles.role_id"JOIN user_roles ON roles.id = user_roles.role_id"user_roles.user_id = ? AND user_roles.is_active = ?"user_roles.user_id = ? AND user_roles.is_active = ?"user_roles.user_id = ? AND user_roles.is_active = ? AND roles.name = ?"user_roles.user_id = ? AND user_roles.is_active = ? AND roles.name = ?"JOIN user_roles ON role_permissions.role_id = user_roles.role_id"JOIN user_roles ON role_permissions.role_id = user_roles.role_id"user_roles.user_id = ? AND user_roles.is_active = ? AND permissions.resource = ? AND permissions.action = ?"user_roles.user_id = ? AND user_roles.is_active = ? AND permissions.resource = ? AND permissions.action = ?" RoleService gère les rôles et permissions NewRoleService crée un nouveau service de rôles GetRoles récupère tous les rôles avec leurs permissions GetRole récupère un rôle par son ID avec ses permissions UpdateRole met à jour un rôle (seulement les rôles non-système) DeleteRole supprime un rôle (seulement les rôles non-système) AssignRoleToUser assigne un rôle à un utilisateur MIGRATION UUID: userID, roleID et assignedBy migrés vers uuid.UUID RevokeRoleFromUser révoque un rôle d'un utilisateur GetUserRoles récupère tous les rôles actifs d'un utilisateur HasPermission vérifie si un utilisateur a une permission spécifique via ses rôles/home/senke/git/talas/veza/veza-backend-api/internal/services/room_service.goparticipantsresponses`json:"type" binding:"required,oneof=public private direct"``json:"participants"`room name is required"room name is required"failed to create room: %w"failed to create room: %w"failed to add creator as room member"failed to add creator as room member""2006-01-02T15:04:05Z07:00"failed to get user rooms: %w"failed to get user rooms: %w"failed to get room members"failed to get room members"failed to get room: %w"failed to get room: %w""member"failed to add member: %w"failed to add member: %w"`json:"sender_id"``json:"message_type"`failed to get room history: %w"failed to get room history: %w" Add time import Add uuid import RoomService gère la logique métier pour les rooms NewRoomService crée une nouvelle instance de RoomService CreateRoomRequest représente une requête de création de room RoomResponse représente une réponse de room pour l'API MIGRATION UUID: CreatedBy et Participants migrés vers UUID CreateRoom crée une nouvelle room Corrected: userID is uuid.UUID, models.Room.CreatedBy is uuid.UUID Ajouter le créateur comme membre admin use uuid Ne pas retourner d'erreur, la room est créée Corrected: & to get pointer to uuid.UUID Récupérer les membres pour avoir la liste des participants Récupérer les membres ChatMessageResponse pour la réponse d'historique Check if room exists first? Assuming Repo handles it or we could use GetRoom logic If messageRepo returns error on room not found/home/senke/git/talas/veza/veza-backend-api/internal/services/royalty_service.go RoyaltyService is a stub for the missing royalty service/home/senke/git/talas/veza/veza-backend-api/internal/services/search_service.gosearchAllsearchPlaylistssearchTrackssearchUsers`json:"playlists"``json:"cover"`
			SELECT id, title, artist, url
			FROM tracks
			WHERE title ILIKE $1 OR artist ILIKE $1
			LIMIT 10
		`
			SELECT id, title, artist, url
			FROM tracks
			WHERE title ILIKE $1 OR artist ILIKE $1
			LIMIT 10
		`failed to search tracks: %w"failed to search tracks: %w"
			SELECT id, username, avatar
			FROM users
			WHERE username ILIKE $1
			LIMIT 10
		`
			SELECT id, username, avatar
			FROM users
			WHERE username ILIKE $1
			LIMIT 10
		`failed to search users: %w"failed to search users: %w"
			SELECT id, name, cover_image_url
			FROM playlists
			WHERE name ILIKE $1 AND is_public = TRUE
			LIMIT 10
		`
			SELECT id, name, cover_image_url
			FROM playlists
			WHERE name ILIKE $1 AND is_public = TRUE
			LIMIT 10
		` SearchService handles search operations SearchResult represents search results NewSearchService creates a new search service Search performs a full-text search Build search types - if empty, search all Search tracks Search users Search playlists/home/senke/git/talas/veza/veza-backend-api/internal/services/session_service.gonewExpiresAttotalActiveuniqueUsers`json:"-" db:"token_hash"``json:"revoked_at" db:"revoked_at"`
		INSERT INTO sessions (id, user_id, token_hash, created_at, expires_at, ip_address, user_agent)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
	`
		INSERT INTO sessions (id, user_id, token_hash, created_at, expires_at, ip_address, user_agent)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
	`Failed to create session"Failed to create session"failed to create session: %w"failed to create session: %w"Session created"Session created"
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE token_hash = $1 AND expires_at > $2 AND revoked_at IS NULL
	`
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE token_hash = $1 AND expires_at > $2 AND revoked_at IS NULL
	`session not found or expired"session not found or expired"Failed to validate session"Failed to validate session"token_hash"token_hash"failed to validate session: %w"failed to validate session: %w"
		UPDATE sessions 
		SET revoked_at = $1
		WHERE token_hash = $2 AND revoked_at IS NULL
	`
		UPDATE sessions 
		SET revoked_at = $1
		WHERE token_hash = $2 AND revoked_at IS NULL
	`failed to revoke session: %w"failed to revoke session: %w"session not found or already revoked"session not found or already revoked"
		UPDATE sessions 
		SET revoked_at = $2
		WHERE user_id = $1 AND revoked_at IS NULL
	`
		UPDATE sessions 
		SET revoked_at = $2
		WHERE user_id = $1 AND revoked_at IS NULL
	`failed to revoke user sessions: %w"failed to revoke user sessions: %w"
		UPDATE sessions 
		SET expires_at = $1
		WHERE token_hash = $2 AND revoked_at IS NULL AND expires_at > $3
	`
		UPDATE sessions 
		SET expires_at = $1
		WHERE token_hash = $2 AND revoked_at IS NULL AND expires_at > $3
	`failed to refresh session: %w"failed to refresh session: %w"new_expires_at"new_expires_at"
		DELETE FROM sessions 
		WHERE expires_at < $1 OR revoked_at IS NOT NULL
	`
		DELETE FROM sessions 
		WHERE expires_at < $1 OR revoked_at IS NOT NULL
	`failed to cleanup expired sessions: %w"failed to cleanup expired sessions: %w"Expired sessions cleaned up"Expired sessions cleaned up"
		SELECT 
			COUNT(*) as total_active,
			COUNT(DISTINCT user_id) as unique_users
		FROM sessions
		WHERE expires_at > $1 AND revoked_at IS NULL
	`
		SELECT 
			COUNT(*) as total_active,
			COUNT(DISTINCT user_id) as unique_users
		FROM sessions
		WHERE expires_at > $1 AND revoked_at IS NULL
	`failed to get session stats: %w"failed to get session stats: %w"total_active"total_active"unique_users"unique_users"
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE id = $1
	`
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE id = $1
	`session not found"session not found"Failed to get session by ID"Failed to get session by ID"failed to get session by ID: %w"failed to get session by ID: %w"
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE user_id = $1 AND expires_at > $2 AND revoked_at IS NULL
		ORDER BY created_at DESC
	`
		SELECT id, user_id, token_hash, created_at, expires_at, revoked_at, ip_address, user_agent
		FROM sessions
		WHERE user_id = $1 AND expires_at > $2 AND revoked_at IS NULL
		ORDER BY created_at DESC
	`failed to get user sessions: %w"failed to get user sessions: %w"failed to scan session: %w"failed to scan session: %w"
		UPDATE sessions 
		SET revoked_at = $2
		WHERE token_hash = $1 AND revoked_at IS NULL
	`
		UPDATE sessions 
		SET revoked_at = $2
		WHERE token_hash = $1 AND revoked_at IS NULL
	`Failed to revoke session by hash"Failed to revoke session by hash"Session revoked by hash"Session revoked by hash" SessionService gère les sessions utilisateur MIGRATION UUID: ID migré vers uuid.UUID SessionCreateRequest données pour créer une session Ignored by DB, kept for compatibility if needed NewSessionService crée un nouveau service de session CreateSession crée une nouvelle session Hasher le token pour le stockage Calculer la date d'expiration If ExpiresIn is 0, default to 24 hours Créer la session struct Insérer en base ValidateSession valide une session par token hash RevokeSession révoque une session par token RevokeAllUserSessions révoque toutes les sessions d'un utilisateur RevokeAllUserSessionsByUserID est un alias pour satisfaire l'interface attendue par AuthService RefreshSession étend la durée d'une session hashToken hashe un token pour le stockage GetSessionStats retourne les statistiques des sessions GetSessionByID récupère une session par ID GetUserSessions récupère toutes les sessions d'un utilisateur HashTokenForMiddleware hashe un token (pour usage middleware/handler) DeleteSession révoque une session (alias pour RevokeSession, utilisé par les handlers) Note: tokenHash is already hashed. RevokeSession expects raw token. But DeleteSession takes tokenHash. We need a method to revoke by hash./home/senke/git/talas/veza/veza-backend-api/internal/services/social_service.gofollowedIDfollowerID`json:"parent_id" db:"parent_id"`
		INSERT INTO follows (follower_id, followed_id)
		VALUES ($1, $2)
		ON CONFLICT (follower_id, followed_id) DO NOTHING
	`
		INSERT INTO follows (follower_id, followed_id)
		VALUES ($1, $2)
		ON CONFLICT (follower_id, followed_id) DO NOTHING
	`failed to follow user: %w"failed to follow user: %w"User followed"User followed"follower_id"follower_id"followed_id"followed_id"
		DELETE FROM follows
		WHERE follower_id = $1 AND followed_id = $2
	`
		DELETE FROM follows
		WHERE follower_id = $1 AND followed_id = $2
	`failed to unfollow user: %w"failed to unfollow user: %w"
		INSERT INTO likes (user_id, track_id)
		VALUES ($1, $2)
		ON CONFLICT (user_id, track_id) DO NOTHING
	`
		INSERT INTO likes (user_id, track_id)
		VALUES ($1, $2)
		ON CONFLICT (user_id, track_id) DO NOTHING
	`failed to like track: %w"failed to like track: %w"
		DELETE FROM likes
		WHERE user_id = $1 AND track_id = $2
	`
		DELETE FROM likes
		WHERE user_id = $1 AND track_id = $2
	`failed to unlike track: %w"failed to unlike track: %w"
		INSERT INTO comments (id, user_id, track_id, parent_id, content)
		VALUES (gen_random_uuid(), $1, $2, $3, $4)
		RETURNING id
	`
		INSERT INTO comments (id, user_id, track_id, parent_id, content)
		VALUES (gen_random_uuid(), $1, $2, $3, $4)
		RETURNING id
	`failed to create comment: %w"failed to create comment: %w"
		SELECT id, user_id, track_id, parent_id, content, created_at, updated_at
		FROM comments
		WHERE id = $1
	`
		SELECT id, user_id, track_id, parent_id, content, created_at, updated_at
		FROM comments
		WHERE id = $1
	`failed to fetch comment: %w"failed to fetch comment: %w"
		SELECT COUNT(*)
		FROM follows
		WHERE followed_id = $1
	`
		SELECT COUNT(*)
		FROM follows
		WHERE followed_id = $1
	`
		SELECT COUNT(*)
		FROM follows
		WHERE follower_id = $1
	`
		SELECT COUNT(*)
		FROM follows
		WHERE follower_id = $1
	`failed to get following count: %w"failed to get following count: %w"
		SELECT COUNT(*)
		FROM likes
		WHERE track_id = $1
	`
		SELECT COUNT(*)
		FROM likes
		WHERE track_id = $1
	`failed to get likes count: %w"failed to get likes count: %w"
		SELECT EXISTS(
			SELECT 1 FROM follows
			WHERE follower_id = $1 AND followed_id = $2
		)
	`
		SELECT EXISTS(
			SELECT 1 FROM follows
			WHERE follower_id = $1 AND followed_id = $2
		)
	`failed to check follow status: %w"failed to check follow status: %w"
		SELECT EXISTS(
			SELECT 1 FROM likes
			WHERE user_id = $1 AND track_id = $2
		)
	`
		SELECT EXISTS(
			SELECT 1 FROM likes
			WHERE user_id = $1 AND track_id = $2
		)
	`failed to check like status: %w"failed to check like status: %w" SocialService handles social features (follows, likes, comments) Comment represents a comment on a track NewSocialService creates a new social service FollowUser creates a follow relationship UnfollowUser removes a follow relationship LikeTrack creates a like on a track UnlikeTrack removes a like from a track CreateComment creates a comment on a track Fetch and return the created comment GetFollowersCount returns the number of followers for a user GetFollowingCount returns the number of users being followed GetLikesCount returns the number of likes for a track IsFollowing checks if a user is following another user IsTrackLiked checks if a user has liked a track/home/senke/git/talas/veza/veza-backend-api/internal/services/stream_service.gojsonBodystream-service"stream-service"`json:"file_path"`%s/internal/jobs/transcode"%s/internal/jobs/transcode"failed to marshal request: %w"failed to marshal request: %w"context cancelled before attempt %d: %w"context cancelled before attempt %d: %w""POST"failed to create request: %w"failed to create request: %w"Stream server request failed, retrying"Stream server request failed, retrying"context cancelled during backoff: %w"context cancelled during backoff: %w"stream server request failed after %d attempts: %w"stream server request failed after %d attempts: %w"Started processing for track"Started processing for track"Stream server returned non-200 status"Stream server returned non-200 status"stream server returned non-200 status after %d attempts"stream server returned non-200 status after %d attempts" Converted uuid.UUID to string MOD-P1-RES-002: Ajouter retry avec backoff exponentiel (pattern similaire à WebhookService) Vérifier si le contexte est annulé avant chaque tentative Créer une nouvelle requête pour chaque tentative (le body peut être consommé) Attendre avec backoff exponentiel avant de réessayer Status code non-OK : retry si possible/home/senke/git/talas/veza/veza-backend-api/internal/services/token_blacklist.gotoken_blacklist:"token_blacklist:"failed to add token to blacklist: %w"failed to add token to blacklist: %w"failed to check token blacklist: %w"failed to check token blacklist: %w"failed to remove token from blacklist: %w"failed to remove token from blacklist: %w"failed to add token hash to blacklist: %w"failed to add token hash to blacklist: %w" TokenBlacklist gère la blacklist de tokens JWT pour invalider les tokens après logout ou révocation T0174: Service pour gérer la blacklist de tokens avec Redis Préfixe pour les clés Redis (ex: "token_blacklist:") NewTokenBlacklist crée une nouvelle instance de TokenBlacklist T0174: Crée un service TokenBlacklist avec Redis Add ajoute un token à la blacklist avec un TTL T0174: Ajoute un token à la blacklist avec expiration automatique T0174: Ajouter le token à Redis avec TTL pour expiration automatique IsBlacklisted vérifie si un token est dans la blacklist T0174: Vérifie si un token est blacklisté T0174: Vérifier si la clé existe dans Redis Remove supprime un token de la blacklist (optionnel, utile pour tests) AddTokenHash ajoute un token hash directement à la blacklist (T0206) Cette méthode permet d'ajouter un tokenHash sans le re-hasher Ajouter le tokenHash à Redis avec TTL pour expiration automatique hashToken hash un token avec SHA-256 pour la sécurité/home/senke/git/talas/veza/veza-backend-api/internal/services/totp_service.gobackupCodesexistingSecretqrCodeURLsecretIDencodedbackupCode`json:"-" db:"secret"``json:"enabled" db:"enabled"``json:"secret"``json:"qr_code_url"``json:"backup_codes"``json:"backup_code,omitempty"``json:"code" db:"code"``json:"used" db:"used"``json:"used_at" db:"used_at"`
		SELECT id, user_id, secret, created_at, enabled
		FROM totp_secrets
		WHERE user_id = $1
	`
		SELECT id, user_id, secret, created_at, enabled
		FROM totp_secrets
		WHERE user_id = $1
	`Failed to check existing TOTP secret"Failed to check existing TOTP secret"failed to check existing TOTP secret: %w"failed to check existing TOTP secret: %w"
			INSERT INTO totp_secrets (id, user_id, secret, created_at, enabled)
			VALUES ($1, $2, $3, $4, $5)
		`
			INSERT INTO totp_secrets (id, user_id, secret, created_at, enabled)
			VALUES ($1, $2, $3, $4, $5)
		`Failed to create TOTP secret"Failed to create TOTP secret"failed to create TOTP secret: %w"failed to create TOTP secret: %w"failed to generate backup codes: %w"failed to generate backup codes: %w"TOTP setup initiated"TOTP setup initiated"secret_id"secret_id"
		SELECT secret, enabled
		FROM totp_secrets
		WHERE user_id = $1
	`
		SELECT secret, enabled
		FROM totp_secrets
		WHERE user_id = $1
	`TOTP not configured for user"TOTP not configured for user"Failed to get TOTP secret"Failed to get TOTP secret"failed to get TOTP secret: %w"failed to get TOTP secret: %w"TOTP verification successful"TOTP verification successful"failed to verify backup code: %w"failed to verify backup code: %w"Backup code verification successful"Backup code verification successful"TOTP verification failed"TOTP verification failed"failed to verify TOTP code: %w"failed to verify TOTP code: %w"invalid TOTP code"invalid TOTP code"
		UPDATE totp_secrets
		SET enabled = true
		WHERE user_id = $1
	`
		UPDATE totp_secrets
		SET enabled = true
		WHERE user_id = $1
	`Failed to enable TOTP"Failed to enable TOTP"failed to enable TOTP: %w"failed to enable TOTP: %w"TOTP enabled"TOTP enabled"
		UPDATE totp_secrets
		SET enabled = false
		WHERE user_id = $1
	`
		UPDATE totp_secrets
		SET enabled = false
		WHERE user_id = $1
	`Failed to disable TOTP"Failed to disable TOTP"failed to disable TOTP: %w"failed to disable TOTP: %w"
		DELETE FROM backup_codes
		WHERE user_id = $1
	`
		DELETE FROM backup_codes
		WHERE user_id = $1
	`Failed to delete backup codes"Failed to delete backup codes"TOTP disabled"TOTP disabled"
		SELECT enabled
		FROM totp_secrets
		WHERE user_id = $1
	`
		SELECT enabled
		FROM totp_secrets
		WHERE user_id = $1
	`Failed to check TOTP status"Failed to check TOTP status"failed to check TOTP status: %w"failed to check TOTP status: %w"Failed to generate TOTP key"Failed to generate TOTP key"failed to delete old backup codes: %w"failed to delete old backup codes: %w"
			INSERT INTO backup_codes (id, user_id, code, created_at, used)
			VALUES ($1, $2, $3, $4, $5)
		`
			INSERT INTO backup_codes (id, user_id, code, created_at, used)
			VALUES ($1, $2, $3, $4, $5)
		`Failed to insert backup code"Failed to insert backup code"code_index"code_index"failed to insert backup code: %w"failed to insert backup code: %w"
		SELECT id, user_id, code, used, created_at, used_at
		FROM backup_codes
		WHERE user_id = $1 AND code = $2 AND used = false
	`
		SELECT id, user_id, code, used, created_at, used_at
		FROM backup_codes
		WHERE user_id = $1 AND code = $2 AND used = false
	`Failed to verify backup code"Failed to verify backup code"
		UPDATE backup_codes
		SET used = true, used_at = NOW()
		WHERE id = $1
	`
		UPDATE backup_codes
		SET used = true, used_at = NOW()
		WHERE id = $1
	`Failed to mark backup code as used"Failed to mark backup code as used"backup_code_id"backup_code_id"failed to mark backup code as used: %w"failed to mark backup code as used: %w"Backup code used"Backup code used"
		SELECT code
		FROM backup_codes
		WHERE user_id = $1 AND used = false
		ORDER BY created_at ASC
	`
		SELECT code
		FROM backup_codes
		WHERE user_id = $1 AND used = false
		ORDER BY created_at ASC
	`Failed to get backup codes"Failed to get backup codes"failed to get backup codes: %w"failed to get backup codes: %w"Failed to scan backup code"Failed to scan backup code" TOTPService gère l'authentification à deux facteurs TOTPSecret représente un secret TOTP pour un utilisateur TOTPSetupResponse réponse pour la configuration 2FA TOTPVerificationRequest requête de vérification 2FA BackupCode représente un code de sauvegarde NewTOTPService crée un nouveau service TOTP SetupTOTP configure le 2FA pour un utilisateur Vérifier si l'utilisateur a déjà un secret TOTP Créer un nouveau secret Utiliser le secret existant Générer les codes de sauvegarde Générer l'URL QR Code Récupérer le secret TOTP de l'utilisateur Si le code TOTP n'est pas valide, vérifier les codes de sauvegarde EnableTOTP active le 2FA pour un utilisateur Vérifier le code avant d'activer Activer le 2FA DisableTOTP désactive le 2FA pour un utilisateur Vérifier le code avant de désactiver Désactiver le 2FA Supprimer les codes de sauvegarde IsTOTPEnabled vérifie si le 2FA est activé pour un utilisateur generateSecret génère un secret TOTP Générer 20 bytes aléatoires generateQRCodeURL génère l'URL du QR Code generateBackupCodes génère des codes de sauvegarde Supprimer les anciens codes Générer 10 nouveaux codes generateBackupCode génère un code de sauvegarde Générer 8 bytes aléatoires verifyBackupCode vérifie un code de sauvegarde Marquer le code comme utilisé GetBackupCodes récupère les codes de sauvegarde d'un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/track_chunk_service.gototalChunkschunkMD5chunkNumberchunkPathdestFilemultiWriterchunkFilefinalFilefinalMD5chunkNumchunksReceivedlastChunkreceivedCount"crypto/md5"`json:"upload_id"``json:"total_chunks"``json:"total_size"``json:"chunks"``json:"received_md5,omitempty"``json:"chunk_number"``json:"md5"``json:"received"``json:"chunks_received"``json:"last_chunk"``json:"received_count"`uploads/tracks/chunks"uploads/tracks/chunks"Failed to create chunks directory"Failed to create chunks directory"failed to initiate upload: %w"failed to initiate upload: %w"Chunked upload initiated"Chunked upload initiated"chunk %d already received"chunk %d already received"total chunks mismatch: expected %d, got %d"total chunks mismatch: expected %d, got %d"chunk_%d"chunk_%d"failed to open chunk file: %w"failed to open chunk file: %w"failed to create chunk file: %w"failed to create chunk file: %w"MultiWriterfailed to save chunk: %w"failed to save chunk: %w"failed to update upload state: %w"failed to update upload state: %w"Chunk saved"Chunk saved"chunk_number"chunk_number""size"missing chunks: received %d/%d"missing chunks: received %d/%d"chunk %d is missing"chunk %d is missing"failed to create destination directory: %w"failed to create destination directory: %w"failed to create final file: %w"failed to create final file: %w"failed to open chunk %d: %w"failed to open chunk %d: %w"failed to write chunk %d: %w"failed to write chunk %d: %w"size mismatch: expected %d, got %d"size mismatch: expected %d, got %d"Failed to cleanup chunks"Failed to cleanup chunks"Failed to delete state from Redis"Failed to delete state from Redis"Chunked upload completed"Chunked upload completed"final_path"final_path"failed to cleanup chunks: %w"failed to cleanup chunks: %w"Upload cleaned up"Upload cleaned up"Starting orphaned chunks cleanup"Starting orphaned chunks cleanup"Failed to read chunks directory"Failed to read chunks directory"Failed to delete orphaned chunk folder"Failed to delete orphaned chunk folder"Deleted orphaned upload folder"Deleted orphaned upload folder"Cleanup completed"Cleanup completed" ChunkUploadInfo représente les informations sur un upload par chunks chunk_number -> ChunkInfo MD5 du fichier final ChunkInfo représente les informations sur un chunk UploadState représente l'état d'un upload pour la reprise Liste des numéros de chunks reçus Dernier chunk reçu (0 si aucun) Nombre de chunks reçus Pourcentage de progression (0-100) TrackChunkService gère l'upload par chunks de fichiers audio NewTrackChunkService crée un nouveau service de gestion d'upload par chunks MIGRATION: Ajout de Redis Client pour le store 24h retention for uploads Créer le répertoire de chunks Démarrer le nettoyages des FICHIERS orphelins (Garbage Collector) Save to Redis SaveChunk sauvegarde un chunk reçu 1. Get State from Redis Use mutex within memory object is Useless in distributed system, BUT since we just fetched it and will write it back, we rely on Redis being fast. Optimistic locking (WATCH) would be better but simple GET/SET is acceptable for P0 fix assuming low contention per user/upload. Vérifier que le chunk n'a pas déjà été reçu Vérifier les paramètres Créer le répertoire pour cet upload Calculer le MD5 pendant la copie Enregistrer les informations du chunk Update State in Redis GetUploadInfo récupère les informations d'un upload CompleteChunkedUpload assemble tous les chunks et crée le fichier final Get State Vérifier que tous les chunks ont été reçus Vérifier l'ordre des chunks (1 à totalChunks) Créer le répertoire de destination Assembler les chunks dans l'ordre Vérifier la taille totale Nettoyer les chunks temporaires Supprimer l'upload de Redis GetUploadState récupère l'état d'un upload pour permettre la reprise Compter les chunks reçus et déterminer le dernier GetUploadProgress retourne la progression d'un upload par chunks CleanupUpload supprime un upload et ses chunks Clean from Redis Ignore error if already deleted Clean from Disk startDiskCleanup démarre le nettoyage périodique des FICHIERS orphelins (Garbage Collector) CleanupOrphanedChunks scan le disque et supprime les dossiers qui n'ont pas bougé depuis maxUploadAge Ceci agit comme un Garbage Collector pour les fichiers orphelins Si le dossier est plus vieux que maxUploadAge On vérifie s'il existe dans Redis (au cas où Redis a été flushé mais pas les fichiers, ou TTL mismatch) Si Redis n'a plus l'info, on considère que c'est orphelin Upload not in Redis (or error), assume safe to delete if older than 24h/home/senke/git/talas/veza/veza-backend-api/internal/services/track_export_service.goexportPathsourceDatasupportedFormatsexport format not supported"export format not supported"source file not found"source file not found"ffmpeg not available"ffmpeg not available"export failed"export failed"Failed to create export directory"Failed to create export directory"Source file not found"Source file not found"Using cached export"Using cached export"export_path"export_path"failed to create export directory: %w"failed to create export directory: %w"failed to read source file: %w"failed to read source file: %w"failed to write export file: %w"failed to write export file: %w"Track file copied"Track file copied"FFmpeg not available"FFmpeg not available"-compression_level"-compression_level"FFmpeg conversion failed"FFmpeg conversion failed""stderr"%w: %v"%w: %v"%w: output file was not created"%w: output file was not created"Track exported successfully"Track exported successfully"%s.%s"%s.%s""mp3""flac""wav""ogg""m4a"-version"-version"libmp3lame"libmp3lame"pcm_s16le"pcm_s16le"libvorbis"libvorbis""copy"192k"192k"128k"128k""5"failed to delete export file: %w"failed to delete export file: %w"Failed to delete export"Failed to delete export" ErrExportFormatNotSupported est retourné quand le format d'export n'est pas supporté ErrSourceFileNotFound est retourné quand le fichier source n'existe pas ErrFFmpegNotAvailable est retourné quand ffmpeg n'est pas disponible ErrExportFailed est retourné quand l'export échoue TrackExportService gère l'export de tracks en différents formats NewTrackExportService crée un nouveau service d'export de tracks Créer le répertoire d'export s'il n'existe pas ExportTrack exporte un track vers le format spécifié Si le fichier exporté existe déjà, il est retourné directement (cache) MIGRATION UUID: Completée. TrackID en UUID. Normaliser le format (minuscules) Vérifier que le format est supporté Vérifier si le fichier exporté existe déjà (cache) Si le format source est le même que le format cible, copier le fichier Convertir avec ffmpeg copyTrackFile copie le fichier source vers le répertoire d'export Lire le fichier source Écrire le fichier exporté convertTrack convertit un track vers un format différent en utilisant ffmpeg Vérifier que ffmpeg est disponible Construire la commande ffmpeg Overwrite output file Ajouter les options de codec Ajouter le bitrate pour MP3 Ajouter la qualité pour FLAC Ajouter le fichier de sortie Créer la commande avec timeout Capturer stderr pour les logs Exécuter la conversion Vérifier que le fichier exporté existe getExportPath retourne le chemin du fichier exporté isFormatSupported vérifie si le format est supporté isFFmpegAvailable vérifie si ffmpeg est disponible getCodec retourne le codec audio approprié pour le format getBitrate retourne le bitrate approprié pour le format Bitrate par défaut pour MP3 Bitrate par défaut pour AAC Pas de bitrate pour les formats lossless getQuality retourne le niveau de qualité/compression pour le format Niveau de compression FLAC (0-8, 5 est un bon compromis) Pas de paramètre de qualité pour les autres formats DeleteExport supprime un fichier exporté du cache DeleteAllExports supprime tous les exports d'un track Log l'erreur mais continue avec les autres formats/home/senke/git/talas/veza/veza-backend-api/internal/services/track_history_service.gooldValueBytesnewValueBytesnewValueStroldValueStrhistoriesfailed to marshal old_value: %w"failed to marshal old_value: %w"failed to marshal new_value: %w"failed to marshal new_value: %w"failed to create track history: %w"failed to create track history: %w"Track history recorded"Track history recorded"history_id"history_id"failed to count track history: %w"failed to count track history: %w"failed to get track history: %w"failed to get track history: %w"failed to count user track history: %w"failed to count user track history: %w"failed to get user track history: %w"failed to get user track history: %w"track_id = ? AND action = ?"track_id = ? AND action = ?"failed to count track history by action: %w"failed to count track history by action: %w"failed to get track history by action: %w"failed to get track history by action: %w" TrackHistoryService gère l'historique des modifications de tracks NewTrackHistoryService crée un nouveau service d'historique de tracks RecordHistoryParams représente les paramètres pour enregistrer un historique MIGRATION UUID: UserID et TrackID en UUID Peut être n'importe quel type, sera sérialisé en JSON RecordHistory enregistre une entrée dans l'historique d'un track Sérialiser old_value et new_value en JSON si nécessaire Créer l'entrée d'historique FIXME: models.TrackHistory needs UUID too if not updated Assuming UUID GetHistory récupère l'historique d'un track Compter le total d'entrées Récupérer les entrées avec pagination GetHistoryByUser récupère l'historique des tracks modifiés par un utilisateur GetHistoryByAction récupère l'historique filtré par action/home/senke/git/talas/veza/veza-backend-api/internal/services/track_like_service.gouser_id = ? AND track_id = ?"user_id = ? AND track_id = ?"failed to check existing like: %w"failed to check existing like: %w"failed to create like: %w"failed to create like: %w"like_count + ?"like_count + ?"Failed to update track like_count"Failed to update track like_count"Track liked"Track liked"failed to check like: %w"failed to check like: %w"failed to delete like: %w"failed to delete like: %w"CASE WHEN like_count - 1 < 0 THEN 0 ELSE like_count - 1 END"CASE WHEN like_count - 1 < 0 THEN 0 ELSE like_count - 1 END"Track unliked"Track unliked"INNER JOIN track_likes ON tracks.id = track_likes.track_id"INNER JOIN track_likes ON tracks.id = track_likes.track_id"track_likes.user_id = ?"track_likes.user_id = ?"track_likes.created_at DESC"track_likes.created_at DESC"failed to get user liked tracks: %w"failed to get user liked tracks: %w"failed to get user liked tracks count: %w"failed to get user liked tracks count: %w" TrackLikeService gère les opérations sur les likes de tracks NewTrackLikeService crée un nouveau service de likes de tracks LikeTrack ajoute un like d'un utilisateur sur un track MIGRATION UUID: userID migré vers uuid.UUID, trackID reste int64 - Corrected: trackID est maintenant uuid.UUID Vérifier si le track existe Vérifier si l'utilisateur a déjà liké ce track Déjà liké, retourner nil (idempotent) Créer le like Mettre à jour le compteur de likes du track Ne pas retourner l'erreur, le like a été créé avec succès UnlikeTrack supprime un like d'un utilisateur sur un track Vérifier si le like existe Pas de like à supprimer, retourner nil (idempotent) Supprimer le like Ne pas retourner l'erreur, le like a été supprimé avec succès IsLiked vérifie si un utilisateur a liké un track GetTrackLikesCount retourne le nombre de likes d'un track GetUserLikedTracks retourne la liste des tracks likés par un utilisateur GetUserLikedTracksCount retourne le nombre total de tracks likés par un utilisateur/home/senke/git/talas/veza/veza-backend-api/internal/services/track_search_service.gosearchTermis_public = ? AND deleted_at IS NULL"is_public = ? AND deleted_at IS NULL"LOWER(title) LIKE ? OR LOWER(artist) LIKE ? OR LOWER(album) LIKE ?"LOWER(title) LIKE ? OR LOWER(artist) LIKE ? OR LOWER(album) LIKE ?"duration >= ? AND duration <= ?"duration >= ? AND duration <= ?"duration >= ?"duration >= ?"duration <= ?"duration <= ?"LOWER(genre) = ?"LOWER(genre) = ?"LOWER(format) = ?"LOWER(format) = ?"like_count %s"like_count %s"play_count"play_count"play_count %s"play_count %s"tracks.*, COALESCE(comment_counts.count, 0) as comment_count"tracks.*, COALESCE(comment_counts.count, 0) as comment_count"LEFT JOIN (SELECT track_id, COUNT(*) as count FROM track_comments WHERE deleted_at IS NULL GROUP BY track_id) as comment_counts ON comment_counts.track_id = tracks.id"LEFT JOIN (SELECT track_id, COUNT(*) as count FROM track_comments WHERE deleted_at IS NULL GROUP BY track_id) as comment_counts ON comment_counts.track_id = tracks.id"comment_count %s"comment_count %s"LOWER(title) %s"LOWER(title) %s"LOWER(artist) %s"LOWER(artist) %s"created_at %s"created_at %s" TrackSearchParams représente les paramètres de recherche de tracks "AND" or "OR" ISO date TrackSearchService gère la recherche avancée de tracks NewTrackSearchService crée un nouveau service de recherche de tracks SearchTracks effectue une recherche avancée de tracks avec support de filtres combinés Full-text search on title, artist, album Tag search - Note: Tags field not in current model, skipping for now This can be implemented when tags are added to the Track model Tags functionality would go here when Tags field is added For now, we'll skip tag filtering Duration filter (supports combined min/max) Validate that min <= max BPM filter - Note: BPM field not in current model, skipping for now This can be implemented when BPM field is added to the Track model BPM functionality would go here when BPM field is added When implemented, should support combined min/max like duration Genre filter (case-insensitive) Format filter (case-insensitive) Date range filter (supports combined min/max) Count total before pagination Apply sorting with computed fields Handle different sorting options Sort by like_count (popularity) Sort by play_count (total plays) Sort by number of comments (requires join and count) Sort by title alphabetically (case-insensitive) Sort by artist alphabetically (case-insensitive) Direct field sorting Sort by like_count (same as popularity) Default to created_at Apply pagination Max limit/home/senke/git/talas/veza/veza-backend-api/internal/services/track_share_service.gopermission denied"permission denied"failed to reload share: %w"failed to reload share: %w" ErrShareNotFound est retourné quand un share n'est pas trouvé ErrShareExpired est retourné quand un share a expiré ErrSharePermissionDenied est retourné quand la permission demandée n'est pas accordée TrackShareService gère le partage de tracks NewTrackShareService crée un nouveau service de partage de tracks MIGRATION UUID: Completée. UserID et TrackID en UUID. Vérifier que le track existe et appartient à l'utilisateur ValidateShareToken valide un token de partage et retourne le share Recharger l'objet pour obtenir la valeur mise à jour CheckPermission vérifie si un share a une permission spécifique Vérifier les permissions GetShareByToken récupère un share par son token (sans incrémenter le compteur) MIGRATION UUID: Completée. UserID et ShareID en UUID./home/senke/git/talas/veza/veza-backend-api/internal/services/track_storage_service.gofileBytesdestPathrelativePathuniqueFilenameinvalid S3 service type"invalid S3 service type"%s%s"%s%s"tracks/%s/%d/%s"tracks/%s/%d/%s"Retrying file upload"Retrying file upload"Track file saved successfully"Track file saved successfully"Failed to save track file"Failed to save track file"failed to save track file after %d attempts: %w"failed to save track file after %d attempts: %w"S3 service not configured"S3 service not configured"ReadFullfailed to upload to S3: %w"failed to upload to S3: %w"/uploads/%s"/uploads/%s"tracks/%d/%d/%s"tracks/%d/%d/%s"failed to delete from S3: %w"failed to delete from S3: %w" TrackStorageService gère le stockage des fichiers audio S3Service sera implémenté plus tard (T0224) S3Service interface pour le service S3 (à implémenter plus tard) NewTrackStorageService crée un nouveau service de stockage de tracks SetS3Service définit le service S3 (quand il sera disponible) GetDownloadURL retourne une URL de téléchargement (signée pour S3, relative pour local) On suppose que filePath contient la clé ou l'URL complète. Pour simplifier, on considère que filePath est la clé si on utilise S3. En réalité, il faudrait extraire la clé de l'URL stockée si nécessaire. Local storage: retourner le chemin tel quel (relatif) SaveTrack sauvegarde un fichier audio avec structure tracks/{user_id}/{track_id}/{filename} Générer nom fichier unique Chemin: tracks/{user_id}/{trackID}/{filename} Retry logic saveToS3 sauvegarde le fichier vers S3 Ouvrir le fichier Lire le fichier en bytes Déterminer le Content-Type Upload vers S3 saveLocally sauvegarde le fichier localement Chemin complet local Créer les répertoires nécessaires Copier le contenu Retourner le chemin relatif pour l'URL DeleteTrack supprime un fichier audio deleteFromS3 supprime le fichier de S3 deleteLocally supprime le fichier localement Le fichier n'existe pas, considérer comme succès getContentTypeFromExtension retourne le Content-Type basé sur l'extension GenerateTrackKey génère une clé S3 pour un track/home/senke/git/talas/veza/veza-backend-api/internal/services/track_upload_service.gofailed to update status: %w"failed to update status: %w"Track upload status updated"Track upload status updated" TrackUploadService gère le suivi de progression des uploads de tracks NewTrackUploadService crée un nouveau service de suivi d'upload GetUploadProgress récupère la progression d'un upload de track Calculer le pourcentage de progression basé sur le statut UpdateUploadStatus met à jour le statut d'un track calculateProgress calcule le pourcentage de progression basé sur le statut 25% pendant l'upload 50% pendant le traitement 100% une fois terminé 0% en cas d'échec/home/senke/git/talas/veza/veza-backend-api/internal/services/track_validation_service.gomagicBytesadditionalBytesmagicStrallowedCodeccodecLower18010800audio/vorbis"audio/vorbis"pcm"pcm"vorbis"vorbis"file too small to validate format"file too small to validate format"insufficient data for magic byte validation"insufficient data for magic byte validation"2510xFB2430xF32420xF2invalid audio file format: unsupported format or corrupted file"invalid audio file format: unsupported format or corrupted file"file size exceeds maximum allowed size of 100MB"file size exceeds maximum allowed size of 100MB"track duration is too short: minimum %d seconds required"track duration is too short: minimum %d seconds required"track duration is too long: maximum %d seconds (3 hours) allowed"track duration is too long: maximum %d seconds (3 hours) allowed"codec is required"codec is required"unsupported codec: %s. Allowed codecs: %s"unsupported codec: %s. Allowed codecs: %s"validation failed: %s"validation failed: %s"; "; " MaxTrackSize limite maximale de taille pour un fichier audio (100MB) MinTrackDuration durée minimale d'un track en secondes (1 seconde) MaxTrackDuration durée maximale d'un track en secondes (3 heures) Formats audio supportés Codecs audio supportés TrackValidationService gère la validation des fichiers audio NewTrackValidationService crée un nouveau service de validation ValidateFormat valide le format du fichier en utilisant les magic bytes Lire les premiers bytes pour vérifier les magic bytes Valider les magic bytes validateMagicBytes valide les magic bytes pour les formats audio supportés FLAC: "fLaC" (starts at offset 4 after "fLaC" stream marker) Check for WAVE in the next 4 bytes if available If we have RIFF, check further for WAVE ValidateFileSize valide la taille du fichier ValidateDuration valide la durée d'un track ValidateCodec valide le codec audio TrackValidationResult représente le résultat d'une validation complète ValidateTrackFile combine toutes les validations pour un fichier audio Valider le format (magic bytes) Déterminer le format détecté Valider la durée si fournie Valider le codec si fourni detectFormat détecte le format du fichier à partir des magic bytes MP3 FLAC WAV OGG M4A/AAC min est maintenant défini dans internal/utils/math.go Import: veza-backend-api/internal/utils/home/senke/git/talas/veza/veza-backend-api/internal/services/track_version_service.gonextVersionversionIDdestinationFiledstDirsourceFileCOALESCE(MAX(version_number), 0)"COALESCE(MAX(version_number), 0)"failed to get max version number: %w"failed to get max version number: %w"Track version created"Track version created"version_id"version_id"version_number"version_number"id = ? AND track_id = ?"id = ? AND track_id = ?"track_id = ? AND version_number = ?"track_id = ? AND version_number = ?"version_number DESC"version_number DESC"failed to list versions: %w"failed to list versions: %w"version file not found: %s"version file not found: %s"failed to restore version file: %w"failed to restore version file: %w"Track version restored"Track version restored"Failed to delete version file"Failed to delete version file"failed to delete version: %w"failed to delete version: %w"Track version deleted"Track version deleted"failed to open source file: %w"failed to open source file: %w"failed to create destination file: %w"failed to create destination file: %w"failed to copy file: %w"failed to copy file: %w" ErrVersionNotFound est retourné quand une version n'est pas trouvée TrackVersionService gère le versioning de tracks NewTrackVersionService crée un nouveau service de versioning de tracks CreateVersionParams représente les paramètres pour créer une nouvelle version CreateVersion crée une nouvelle version d'un track Trouver le prochain numéro de version Créer la nouvelle version GetVersion récupère une version spécifique d'un track GetVersionByNumber récupère une version par son numéro ListVersions récupère toutes les versions d'un track RestoreVersion restaure une version spécifique (copie le fichier de la version vers le track actuel) Récupérer la version Vérifier que le fichier de la version existe Sauvegarder l'ancien fichier du track comme backup (optionnel, on pourrait créer une version automatique) Pour l'instant, on remplace directement Copier le fichier de la version vers le track Mettre à jour les métadonnées du track avec les informations de la version DeleteVersion supprime une version spécifique Supprimer le fichier de la version si il existe Supprimer la version de la base de données (soft delete) copyFile est une fonction utilitaire pour copier un fichier Créer le répertoire de destination si nécessaire/home/senke/git/talas/veza/veza-backend-api/internal/services/two_factor_service.gorecoveryCodeshashedCodesstoredCodestoredCodeshashedUsedCodenewCodesusedCodemathrandmath/rand"math/rand"`json:"recovery_codes"``json:"code" binding:"required"``json:"recovery_code,omitempty"`otpauth://totp/Veza:%s?secret=%s&issuer=Veza&algorithm=SHA1&digits=6&period=30"otpauth://totp/Veza:%s?secret=%s&issuer=Veza&algorithm=SHA1&digits=6&period=30"
		UPDATE users 
		SET two_factor_enabled = true, 
			two_factor_secret = $1, 
			backup_codes = $2,
			updated_at = CURRENT_TIMESTAMP
		WHERE id = $3
	`
		UPDATE users 
		SET two_factor_enabled = true, 
			two_factor_secret = $1, 
			backup_codes = $2,
			updated_at = CURRENT_TIMESTAMP
		WHERE id = $3
	`Failed to enable 2FA"Failed to enable 2FA"failed to enable 2FA: %w"failed to enable 2FA: %w"2FA enabled successfully"2FA enabled successfully"
		UPDATE users 
		SET two_factor_enabled = false, 
			two_factor_secret = '', 
			backup_codes = '{}',
			updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`
		UPDATE users 
		SET two_factor_enabled = false, 
			two_factor_secret = '', 
			backup_codes = '{}',
			updated_at = CURRENT_TIMESTAMP
		WHERE id = $1
	`Failed to disable 2FA"Failed to disable 2FA"failed to disable 2FA: %w"failed to disable 2FA: %w"2FA disabled successfully"2FA disabled successfully"SELECT two_factor_secret, backup_codes FROM users WHERE id = $1 AND two_factor_enabled = true`SELECT two_factor_secret, backup_codes FROM users WHERE id = $1 AND two_factor_enabled = true`2FA not enabled for user"2FA not enabled for user"failed to get 2FA secret: %w"failed to get 2FA secret: %w"Invalid 2FA code"Invalid 2FA code"SELECT two_factor_enabled FROM users WHERE id = $1`SELECT two_factor_enabled FROM users WHERE id = $1`failed to get 2FA status: %w"failed to get 2FA status: %w"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"hashed_%s"hashed_%s"SELECT backup_codes FROM users WHERE id = $1`SELECT backup_codes FROM users WHERE id = $1`Failed to get recovery codes"Failed to get recovery codes"UPDATE users SET backup_codes = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2`UPDATE users SET backup_codes = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2`Failed to remove recovery code"Failed to remove recovery code" TwoFactorService handles 2FA operations NewTwoFactorService creates a new 2FA service TwoFactorSetup represents 2FA setup information TwoFactorVerification represents 2FA verification GenerateSecret generates a new TOTP secret Generate a random secret Encode as base32 Generate QR code URL Generate recovery codes EnableTwoFactor enables 2FA for a user Hash the recovery codes before storing Update user with 2FA settings DisableTwoFactor disables 2FA for a user VerifyTwoFactor verifies a 2FA code Get user's 2FA secret Check if it's a recovery code Remove the used recovery code Verify TOTP code GetTwoFactorStatus gets the 2FA status for a user generateRecoveryCodes generates 8 recovery codes Generate 8-character alphanumeric code hashRecoveryCode hashes a recovery code for storage In production, use proper hashing (bcrypt, argon2, etc.) For now, using a simple hash for demonstration isRecoveryCode checks if a code is a valid recovery code removeRecoveryCode removes a used recovery code Get current recovery codes Remove the used code Update the user/home/senke/git/talas/veza/veza-backend-api/internal/services/upload_store.goveza:upload:%s"veza:upload:%s"failed to marshal upload info: %w"failed to marshal upload info: %w"failed to save upload state to redis: %w"failed to save upload state to redis: %w"failed to get upload state from redis: %w"failed to get upload state from redis: %w"failed to unmarshal upload info: %w"failed to unmarshal upload info: %w"failed to delete upload state from redis: %w"failed to delete upload state from redis: %w" UploadStateStore defines the interface for storing upload state RedisUploadStore implements UploadStateStore using Redis NewRedisUploadStore create a new RedisUploadStore Use the configured TTL (e.g. 24h) to automatically clean up state Re-initialize map if nil (can happen with JSON)/home/senke/git/talas/veza/veza-backend-api/internal/services/upload_validator.goscanResultdetectedMIMEmimeTypeallowedExtscontrolChanresponseChanscanCtxquarantinePathsrcFileaudioExtimageExtvideoExtaudioExtsimageExtsvideoExts"github.com/dutchcoders/go-clamd"audio/wave"audio/wave"localhost:3310"localhost:3310"/quarantine"/quarantine"ClamAV is enabled but unavailable - uploads will be rejected until ClamAV is available"ClamAV is enabled but unavailable - uploads will be rejected until ClamAV is available""address"ClamAV connection successful"ClamAV connection successful"Failed to open file"Failed to open file"Failed to read file header"Failed to read file header"DetectContentTypeInvalid file type: %s"Invalid file type: %s"File too large for type %s"File too large for type %s"Failed to calculate checksum"Failed to calculate checksum"%x"%x"Virus scanning service is temporarily unavailable. Uploads are disabled for security reasons."Virus scanning service is temporarily unavailable. Uploads are disabled for security reasons."clamav_unavailable: %s"clamav_unavailable: %s"ClamAV scan failed"ClamAV scan failed"Virus scan failed: %v"Virus scan failed: %v"clamav_scan_error: %w"clamav_scan_error: %w""OK"Virus detected: %s"Virus detected: %s"Virus detected in uploaded file"Virus detected in uploaded file"virus"virus"clamav_infected: %s"clamav_infected: %s"File scanned successfully with ClamAV"File scanned successfully with ClamAV""clean"Invalid file extension: %s"Invalid file extension: %s".jpg".jpg".jpeg".jpeg".png".png".gif".gif".webp".webp".svg".svg".mp4".mp4".webm".webm".avi".avi"failed to read file for scan: %w"failed to read file for scan: %w"clamav scan initialization failed: %w"clamav scan initialization failed: %w"clamav scan timeout: %w"clamav scan timeout: %w"%s_%s_%s"%s_%s_%s"File quarantined"File quarantined"original_name"original_name"quarantine_path"quarantine_path" UploadValidator service pour valider les uploads de fichiers MOD-P1-001-REFINEMENT: Flag pour fail-secure localisé UploadConfig configuration pour les uploads Limites de taille 500MB Types MIME autorisés Configuration ClamAV Dossier de quarantaine DefaultUploadConfig retourne la configuration par défaut Alias valide pour WAV (http.DetectContentType retourne audio/wave) NewUploadValidator crée un nouveau validateur d'upload MOD-P1-001-REFINEMENT: Fail-secure localisé - serveur démarre même si ClamAV down, mais uploads seront rejetés lors de la validation Test connection - MOD-P1-001-REFINEMENT: Ne pas bloquer le démarrage, mais flag pour fail-secure Ne pas retourner d'erreur - le serveur peut démarrer mais les uploads seront rejetés dans ValidateFile ValidationResult résultat de la validation ValidateFile valide un fichier uploadé MOD-P1-001: Le scan ClamAV se fait AVANT toute persistance Reset la position du fichier Détecter le type MIME réel Valider le type de fichier Calculer le checksum MD5 MOD-P1-001: Fail-secure - rejeter upload si ClamAV requis mais indisponible Cette vérification se fait AVANT le scan pour éviter toute persistance Retourner une erreur spéciale pour que le handler puisse retourner 503 Scanner avec ClamAV si disponible MOD-P1-001: En cas d'erreur de scan (timeout, connexion, etc.), rejeter (fail-secure) MOD-P1-001: Si virus détecté, rejeter immédiatement (code 422) Valider l'extension du fichier isValidFileType vérifie si le type MIME est autorisé isValidFileSize vérifie si la taille du fichier est autorisée isValidExtension vérifie si l'extension est valide pour le type scanWithClamAV scanne le fichier avec ClamAV avec timeout strict MOD-P1-001: Timeout strict via context pour éviter les blocages Timeout strict: 30 secondes max pour le scan Lire tout le fichier en mémoire pour le scan Scanner avec ClamAV - ScanStream retourne (chan *ScanResult, error) Lire le premier résultat avec timeout Pas de résultat = OK (pas de virus détecté) Timeout: annuler le scan QuarantineFile met un fichier en quarantaine Créer le nom de fichier avec timestamp Créer le fichier de quarantaine Note: Dans un vrai environnement, il faudrait créer le dossier s'il n'existe pas et gérer les permissions appropriées GetFileTypeFromPath détermine le type de fichier à partir du chemin/home/senke/git/talas/veza/veza-backend-api/internal/services/user_service.gofirstnamelastnameusernameChangedAtbiogendertimeSinceChangeoneMonthAgocompletedFieldspercentagetotalFieldstimezonetzthprofileUpdates`json:"first_name"``json:"last_name"``json:"location"``json:"birth_date"``json:"gender"``json:"social_links"``json:"website_url"``json:"profile_privacy"``json:"birthdate"``json:"percentage"``json:"missing"`first_name"first_name"last_name"last_name"username_changed_at"username_changed_at""bio""location""birthdate""gender"failed to update profile: %w"failed to update profile: %w"failed to update avatar URL: %w"failed to update avatar URL: %w"username already taken"username already taken"failed to check username change date: %w"failed to check username change date: %w"database access not available"database access not available"failed to create default settings: %w"failed to create default settings: %w"failed to get settings: %w"failed to get settings: %w"auto"auto"failed to create default profile: %w"failed to create default profile: %w"failed to get profile: %w"failed to get profile: %w"YYYY-MM-DD"YYYY-MM-DD"email_notifications"email_notifications"push_notifications"push_notifications"browser_notifications"browser_notifications"email_on_follow"email_on_follow"email_on_like"email_on_like"email_on_comment"email_on_comment"email_on_mention"email_on_mention"explicit_content"explicit_content"failed to update settings: %w"failed to update settings: %w""timezone"theme"theme" UserRepository defines the interface for user repository operations UserService gère les opérations sur les utilisateurs Optional DB access for settings UpdateProfileRequest represents profile update data Profile represents a user profile with necessary fields MIGRATION UUID: ID et UserID migrés vers uuid.UUID ProfileCompletion represents profile completion status NewUserService crée une nouvelle instance d'UserService NewUserServiceWithDB crée une nouvelle instance d'UserService avec accès DB GetProfileByString récupère le profil d'un utilisateur par ID string (legacy method) PasswordHash est déjà exclu avec json:"-" UpdateProfile met à jour le profil d'un utilisateur UpdateProfileLegacy updates user profile using a map (legacy method, kept for backward compatibility) DEPRECATED: Use UpdateProfile(userID uuid.UUID, req types.UpdateProfileRequest) instead Sauvegarder les modifications GetByID retrieves a user by ID GetProfileByID retrieves a user profile by ID (alias for GetByID for clarity) GetByUsername retrieves a user by username UpdateProfileWithRequest updates user profile with new request structure Apply updates Add more field updates as needed Save changes GetProfile retrieves a user profile by ID requesterID can be nil for unauthenticated requests If profile is private and requesterID is different from userID, returns limited fields MIGRATION UUID: requesterID migré vers *uuid.UUID If profile is private and requester is different from owner, limit fields GetProfileByUsername retrieves a user profile by username UpdateProfile updates a user profile and returns the updated profile Build updates map dynamically based on provided fields Set username_changed_at when username changes T0219: Generate and update slug when username changes Simplified: let the database handle uniqueness via unique constraint Apply updates to user object Return updated profile userToProfile converts a models.User to a Profile struct UploadAvatar handles avatar file upload Create uploads directory if it doesn't exist Generate unique filename Save file Return URL UpdateAvatarURL updates the avatar URL for a user T0221: Updates the avatar field in the users table T0222: Can accept empty string to set avatar to NULL If avatarURL is empty string, set to empty (will be NULL in DB) GetUserStats retrieves user statistics This would typically query the database for stats For now, return empty stats ValidateUsername checks if a username is unique and if it can be changed (once per month) Vérifier si username existe pour autre user Vérifier si username modifiable (1 fois par mois) Si le username actuel est le même, pas besoin de vérifier la date de changement Vérifier si username_changed_at existe et si moins de 30 jours CanChangeUsername checks if a user can change their username (once per month) If UsernameChangedAt is nil, user can change username Check if it's been at least 1 month since last change CalculateProfileCompletion calculates the profile completion percentage T0220: Returns percentage (0-100) and list of missing required fields Get profile as owner (to see all fields) Check username Check first_name Check last_name Check bio Check avatar Calculate percentage UpdateProfileByID updates a user profile by ID with the new request structure GetUserSettings récupère les paramètres utilisateur T0231: Récupère user_settings depuis DB et user_profiles pour language, timezone, theme Récupérer ou créer user_settings Créer settings par défaut Récupérer user_profiles pour preferences (language, timezone, theme) T0233: Récupérer depuis user_profiles avec création auto si n'existe pas Créer profile par défaut theme := profile.Theme // Not used in PreferenceSettings (no Theme field) Not mapped from settings Default, should be read from settings if available UpdateUserSettings met à jour les paramètres utilisateur T0232: Mettre à jour user_settings et user_profiles en DB Mettre à jour user_settings EmailOnMessage and EmailMarketing not mapped (no corresponding fields in NotificationSettings) AllowSearchIndexing and ShowActivity not mapped (no corresponding fields in PrivacySettings) PrivacySettings only has ProfileVisibility and PlaylistsPublic Autoplay not available in ContentSettings type S'assurer que user_settings existe d'abord Créer settings par défaut si n'existe pas Mettre à jour Mettre à jour user_profiles (preferences) T0233: Mettre à jour user_profiles avec création auto si n'existe pas Theme not available in PreferenceSettings type (only Language, Timezone, DateFormat) S'assurer que user_profiles existe d'abord Créer profile par défaut si n'existe pas Appliquer les updates avant création/home/senke/git/talas/veza/veza-backend-api/internal/services/webhook_service.go"crypto/hmac"`json:"event"`failed to register webhook: %w"failed to register webhook: %w"Webhook registered"Webhook registered""events"X-Veza-Signature"X-Veza-Signature"X-Veza-Event"X-Veza-Event"X-Veza-Timestamp"X-Veza-Timestamp"Webhook delivery failed, retrying"Webhook delivery failed, retrying"webhook delivery failed after %d attempts: %w"webhook delivery failed after %d attempts: %w"300Webhook delivered successfully"Webhook delivered successfully""event"Webhook returned non-200 status"Webhook returned non-200 status"webhook delivery failed"webhook delivery failed"active = ? AND events @> ARRAY[?]"active = ? AND events @> ARRAY[?]"failed to fetch webhooks: %w"failed to fetch webhooks: %w"Failed to deliver webhook"Failed to deliver webhook"failed to list webhooks: %w"failed to list webhooks: %w"id = ? AND user_id = ?"id = ? AND user_id = ?"webhook not found"webhook not found"failed to get webhook: %w"failed to get webhook: %w"failed to delete webhook: %w"failed to delete webhook: %w" WebhookService gère les webhooks WebhookPayload représente le payload d'un webhook NewWebhookService crée un nouveau service de webhooks RegisterWebhook enregistre une nouvelle URL de webhook DeliverWebhook envoie un webhook avec retry et signature HMAC Générer signature HMAC Créer la requête HTTP Envoyer avec retry Exponential backoff generateSignature génère une signature HMAC-SHA256 VerifySignature vérifie une signature HMAC TriggerEvent déclenche un événement pour tous les webhooks concernés Récupérer les webhooks actifs pour cet événement Envoyer les webhooks en async GetWebhook récupère un webhook par son ID et userID/home/senke/git/talas/veza/veza-backend-api/internal/testutils/home/senke/git/talas/veza/veza-backend-api/internal/testutils/benchmark.goBenchmarkExampleCleanupDatabaseCleanupDatabaseWithOptionsCleanupOptionsCleanupSpecificTablesCleanupTestDBCleanupWithTransactionCompareGoldenFileCompareGoldenFileWithErrorCreateMultipleTestTracksCreateMultipleTestUsersCreateTestAdminCreateTestMessageCreateTestPlaylistCreateTestRoomCreateTestSessionCreateTestTrackCreateTestTrackWithCustomDataCreateTestUserCreateTestUserWithCustomDataCreateTracksCreateUsersGetDBStatsGetGoldenFilePathGetTestContainerDBGetTestDatabaseURLGetTestRedisClientNewPlaylistFactoryNewTestLockManagerNewTrackFactoryNewUserFactoryPlaylistFactoryRegisterCleanupHookResetTestDBRunBenchmarkWithSetupRunParallelTestsSetupBenchmarkDBSetupParallelTestSetupTestDBStartNamedTimerStartTimerTerminateContainerTerminateRedisContainerTestLockManagerTestTimerTrackFactoryUpdateGoldenFileUserFactoryWithLockcleanupTablescontainerOncegetAllTablesgetDefaultTablesparallelLockpgContainerpgDSNpgErrredisContainerredisErrredisOncesetupPostgresContainersetupRedisContainerupdateGoldenbenchFuncsetupResultteardowntestutilsbenchStateextLenprocessBenchdurationOrCountFlagallowZeroBenchmarkResultMemAllocsMemBytesNsPerOpmbPerSecAllocsPerOpAllocedBytesPerOpMemStringbstatepreviousNpreviousDurationbenchTimemissingBytestimerOnshowAllocResultparallelismstartAllocsstartBytesnetAllocsnetBytesStopTimerResetTimerReportAllocsrunNrun1doBenchlaunchElapsedReportMetricstopOrScaleBLooploopSlowPathtrimOutputRunParallelSetParallelismFailed to setup benchmark database: %v"Failed to setup benchmark database: %v"Error closing database: %v"Error closing database: %v"globalNgrainbN SetupBenchmarkDB configure une DB pour benchmarks (T0044) RunBenchmarkWithSetup exécute un benchmark avec setup/teardown (T0044) BenchmarkExample exemple de benchmark (T0044) Code à benchmarkerlocksWarnIfSlowCascadeUseTransactionSkipForeignKeysWithArtistWithDurationMustBuildWithEmailWithRoleWithPasswordHashWithFirstNameWithLastNameWithIsActiveWithIsVerified/home/senke/git/talas/veza/veza-backend-api/internal/testutils/db.godbInstancedriverTypeisPostgreSQLcleanupFunc"gorm.io/gorm/logger"failed to setup test db container: %v"failed to setup test db container: %v"failed to connect to test db: %v"failed to connect to test db: %v"audit_logs"audit_logs"TRUNCATE TABLE %s CASCADE"TRUNCATE TABLE %s CASCADE"DELETE FROM %s"DELETE FROM %s"failed to get sql.DB: %w"failed to get sql.DB: %w"%T"%T"SET session_replication_role = 'replica'"SET session_replication_role = 'replica'"Warning: Failed to disable foreign keys: %v"Warning: Failed to disable foreign keys: %v"SET session_replication_role = 'origin'"SET session_replication_role = 'origin'"Warning: Failed to re-enable foreign keys: %v"Warning: Failed to re-enable foreign keys: %v"PRAGMA foreign_keys = OFF"PRAGMA foreign_keys = OFF"PRAGMA foreign_keys = ON"PRAGMA foreign_keys = ON"Warning: Failed to cleanup table %s: %v"Warning: Failed to cleanup table %s: %v"
			SELECT tablename 
			FROM pg_tables 
			WHERE schemaname = 'public'
			ORDER BY tablename
		`
			SELECT tablename 
			FROM pg_tables 
			WHERE schemaname = 'public'
			ORDER BY tablename
		`Warning: Failed to get table list: %v"Warning: Failed to get table list: %v"Warning: Failed to scan table name: %v"Warning: Failed to scan table name: %v"
			SELECT name 
			FROM sqlite_master 
			WHERE type='table' AND name NOT LIKE 'sqlite_%'
			ORDER BY name
		`
			SELECT name 
			FROM sqlite_master 
			WHERE type='table' AND name NOT LIKE 'sqlite_%'
			ORDER BY name
		`oauth_accounts"oauth_accounts" SetupTestDB creates a connection to the test container database. It ensures the container is running and the schema is migrated. The container is shared across tests (singleton in setup.go), so be mindful of data state. CleanupTestDB closes the SQL connection. Note: It does NOT stop the container. ResetTestDB deletes all data from the database to ensure a clean state. It respects foreign key constraints by deleting in the correct order. Supprimer toutes les données dans l'ordre pour respecter les contraintes de clés étrangères L'ordre inverse de création (ou celui qui respecte les FK) Use TRUNCATE CASCADE for Postgres which is faster and handles FKs better But TRUNCATE cannot be used easily if tables are referenced by others unless CASCADE is used. Also, we need to check if table exists to avoid errors? With the container setup, tables should always exist. For simplicity and safety, we try DELETE or TRUNCATE CASCADE. TRUNCATE table_name CASCADE; If TRUNCATE fails (e.g. permissions?), fallback to DELETE Also ignore if table doesn't exist (though it should) GetDBStats retourne les statistiques de la base de données de test CleanupOptions configure le comportement du cleanup (T0049) Si spécifié, nettoie uniquement ces tables CleanupDatabaseWithOptions nettoie avec options (T0049) SQLite CASCADE est supporté par PostgreSQL Pour SQLite ou sans cascade, utiliser DELETE FROM Continue avec les autres tables contains vérifie si une chaîne contient une sous-chaîne (utilitaire pour détection DB) getAllTables récupère la liste de toutes les tables (T0049) getDefaultTables retourne la liste par défaut des tables (T0049) RegisterCleanupHook enregistre un hook de cleanup (T0049) CleanupWithTransaction nettoie avec une transaction (T0049) CleanupSpecificTables nettoie uniquement les tables spécifiées (T0049)/home/senke/git/talas/veza/veza-backend-api/internal/testutils/db_utils.goTEST_DATABASE_URL"TEST_DATABASE_URL"postgresql://veza:password@localhost:5432/veza_test_db"postgresql://veza:password@localhost:5432/veza_test_db"email_verifications"email_verifications""notifications"follows"follows"admin_logs"admin_logs"totp_configs"totp_configs"schema_migrations"schema_migrations"Note: Could not truncate table %s (may not exist): %v"Note: Could not truncate table %s (may not exist): %v" GetTestDatabaseURL retourne l'URL de la base de données de test (T0041) CleanupDatabase nettoie toutes les tables de la base de données (T0041) Désactiver les foreign keys temporairement pour PostgreSQL Note: PostgreSQL utilise session_replication_role pour désactiver les triggers Supprimer toutes les données dans l'ordre inverse des dépendances Liste basée sur les modèles GORM et les migrations Tables additionnelles qui peuvent exister Utiliser TRUNCATE CASCADE pour supprimer les données et les dépendances Ignorer les erreurs si la table n'existe pas (normal pour certains tests)/home/senke/git/talas/veza/veza-backend-api/internal/testutils/fixtures.gouniqueEmailuniqueIDuniqueSluguniqueUsernamemaxUsernamePartLenemailPartsmaxUsernameLencreatedByfirstNameisActiveisVerifiedfactory-"-"testuser_%s"testuser_%s"test_%s@example.com"test_%s@example.com"testuser-%s"testuser-%s"$2a$10$examplehash"$2a$10$examplehash""Test"@"@"invalid email format: %s"invalid email format: %s"%s_%s@%s"%s_%s@%s"%s-%s"%s-%s"admin_%s"admin_%s"admin_%s@example.com"admin_%s@example.com"admin-%s"admin-%s"Admin"Admin"Test Track"Test Track"Test Artist"Test Artist"uploads/test_track.mp3"uploads/test_track.mp3"1048576Test Playlist"Test Playlist"A test playlist"A test playlist"Test Room"Test Room"A test room"A test room""text"test_hash_"test_hash_"127.0.0.1"127.0.0.1"test-agent"test-agent"testuser%d_%s"testuser%d_%s"test%d_%s@example.com"test%d_%s@example.com"testuser%d-%s"testuser%d-%s"Test Track %d"Test Track %d"testuser"testuser"test@example.com"test@example.com"user%d"user%d"user%d@example.com"user%d@example.com"Test Artist %d"Test Artist %d" CreateTestUser crée un utilisateur de test avec des valeurs par défaut Make username and email unique to avoid constraint violations when tests share the same DB Slug must also be unique - use the same uniqueID to ensure uniqueness Hash bcrypt factice CreateTestUserWithCustomData crée un utilisateur de test avec des données personnalisées Make username and email unique to avoid constraint violations Username must match ^[a-zA-Z0-9_]{3,30}$ (no dashes, only alphanum + underscore) Remove dashes from UUID Ensure username doesn't exceed 30 chars (constraint limit) Truncate username part if needed -1 for underscore Extract email parts and add unique ID Slug must also be unique - generate from username with uniqueID Slugify converts underscores to dashes, so "customuser_abc123" becomes "customuser-abc123" CreateTestAdmin crée un utilisateur administrateur de test CreateTestTrack crée un track de test 3 minutes CreateTestTrackWithCustomData crée un track de test avec des données personnalisées CreateTestPlaylist crée une playlist de test CreateTestRoom crée une room de test CreateTestMessage crée un message de test CreateTestSession crée une session de test CreateMultipleTestUsers crée plusieurs utilisateurs de test CreateMultipleTestTracks crée plusieurs tracks de test pour un créateur UserFactory crée des utilisateurs de test avec pattern Builder NewUserFactory crée un nouveau factory avec valeurs par défaut WithUsername définit le username WithEmail définit l'email WithRole définit le rôle WithPasswordHash définit le hash du mot de passe WithFirstName définit le prénom WithLastName définit le nom WithIsActive définit si l'utilisateur est actif WithIsVerified définit si l'utilisateur est vérifié Build construit l'utilisateur sans sauvegarder MustBuild construit et sauvegarde en DB TrackFactory crée des tracks de test avec pattern Builder NewTrackFactory crée un nouveau factory avec valeurs par défaut WithTitle définit le titre WithArtist définit l'artiste WithDuration définit la durée en secondes Build construit le track sans sauvegarder PlaylistFactory crée des playlists de test avec pattern Builder NewPlaylistFactory crée un nouveau factory avec valeurs par défaut WithName définit le titre (Mapped to Title) WithDescription définit la description Build construit la playlist sans sauvegarder CreateUsers crée N utilisateurs avec factories CreateTracks crée N tracks avec factories/home/senke/git/talas/veza/veza-backend-api/internal/testutils/golden.go"flag""github.com/stretchr/testify/require""update"update golden files"update golden files"testdata"testdata"Skipping golden file update (use -update flag)"Skipping golden file update (use -update flag)"Golden file not found. Run tests with -update flag to create it."Golden file not found. Run tests with -update flag to create it."Golden file mismatch"Golden file mismatch"golden file not found. Run tests with -update flag to create it.: %w"golden file not found. Run tests with -update flag to create it.: %w"golden file mismatch: expected %q, got %q"golden file mismatch: expected %q, got %q" GetGoldenFilePath retourne le chemin vers un fichier golden (T0046) UpdateGoldenFile met à jour un fichier golden (T0046) CompareGoldenFile compare le contenu avec un fichier golden (T0046) Si update flag, mettre à jour Lire le fichier golden CompareGoldenFileWithError compare le contenu avec un fichier golden et retourne une erreur au lieu de faire échouer le test (T0046) Utilisé pour tester que CompareGoldenFile échoue correctement Example usage:
func TestJSONOutput(t *testing.T) {
	data := map[string]interface{}{
		"key": "value",
	}
	jsonBytes, _ := json.MarshalIndent(data, "", "  ")

	CompareGoldenFile(t, "output.json", jsonBytes)
}
/home/senke/git/talas/veza/veza-backend-api/internal/testutils/integration/home/senke/git/talas/veza/veza-backend-api/internal/testutils/integration/integration.goIntegrationTestSetupNewTestClientSetupIntegrationDBSetupIntegrationTestTestClienttestConfigEnableHTTP2StartTLSlogCloseHangDebugInfoCloseClientConnectionsgoServecloseConnChanPostWithBodyPostWithContexthttptestintegrationnet/http/httptest"net/http/httptest"veza-backend-api/internal/testutils"veza-backend-api/internal/testutils"RouterFailed to setup integration database"Failed to setup integration database"ShortSkipping integration test in short mode"Skipping integration test in short mode"NewServerMethodGetNoBodyMethodPostMethodPutMethodDelete IntegrationTestSetup contient les ressources pour un test d'intégration (T0041) SetupIntegrationDB configure une base de données PostgreSQL pour les tests d'intégration (T0041) Utiliser une base de données de test dédiée Nettoyer les tables SetupIntegrationTest configure un environnement de test complet (T0041) Skip si mode short Setup database Setup config avec valeurs de test Setup router Note: routes.SetupRoutes nécessite des services complets Pour les tests d'intégration, on peut créer un router minimal ou utiliser routes.SetupRoutes si tous les services sont configurés routes.SetupRoutes(router, ...) TestClient simplifie les appels HTTP dans les tests (T0041) NewTestClient crée un nouveau client de test (T0041) Get fait une requête GET (T0041) GetWithContext fait une requête GET avec contexte (T0041) Post fait une requête POST (T0041) PostWithBody fait une requête POST avec body (T0041) PostWithContext fait une requête POST avec contexte et body (T0041) Put fait une requête PUT (T0041) Delete fait une requête DELETE (T0041) Close ferme le serveur de test (T0041)/home/senke/git/talas/veza/veza-backend-api/internal/testutils/parallel.gotestFuncs SetupParallelTest configure un test pour exécution parallèle (T0048) Acquérir un lock si ressources partagées parallelLock.Lock() t.Cleanup(func() { parallelLock.Unlock() }) RunParallelTests exécute plusieurs tests en parallèle (T0048) Note: The sub-tests created by t.Run() already call t.Parallel(), so testFuncs should NOT call SetupParallelTest() or t.Parallel() themselves to avoid "t.Parallel called multiple times" panic The parent test must wait for all sub-tests to complete Use t.Run() which automatically waits for all sub-tests to complete Each sub-test calls t.Parallel() to run in parallel t.Run() blocks until all sub-tests complete, so we don't need WaitGroup WithLock exécute une fonction avec un lock partagé (T0048) TestLockManager gère les locks pour les tests parallèles (T0048) NewTestLockManager crée un nouveau gestionnaire de locks (T0048) Lock acquiert un lock nommé (T0048)
func TestParallel(t *testing.T) {
	testFuncs := map[string]func(*testing.T){
		"test1": func(t *testing.T) {
			SetupParallelTest(t)
			// Test code
		},
		"test2": func(t *testing.T) {
			SetupParallelTest(t)
			// Test code
		},
	}

	RunParallelTests(t, testFuncs)
}

func TestWithSharedResource(t *testing.T) {
	t.Parallel()

	WithLock(func() {
		// Code qui nécessite un lock
	})
}

func TestWithNamedLock(t *testing.T) {
	t.Parallel()

	lockManager := NewTestLockManager()
	unlock := lockManager.Lock("resource1")
	defer unlock()

	// Code qui nécessite un lock nommé
}
/home/senke/git/talas/veza/veza-backend-api/internal/testutils/performance.goTest duration: %v"Test duration: %v"WARNING: Test '%s' took %v (threshold: %v)"WARNING: Test '%s' took %v (threshold: %v)" TestTimer mesure la durée d'un test (T0050) StartTimer démarre un timer de test (T0050) StartNamedTimer démarre un timer avec un nom personnalisé (T0050) Stop arrête le timer et log la durée (T0050) WarnIfSlow avertit si le test est lent (T0050) Elapsed retourne la durée écoulée sans arrêter le timer (T0050) Reset réinitialise le timer (T0050)
func TestSlowOperation(t *testing.T) {
	timer := StartTimer(t)
	defer timer.WarnIfSlow(5 * time.Second)

	// Test code
	time.Sleep(2 * time.Second)
}

func TestNamedTimer(t *testing.T) {
	timer := StartNamedTimer(t, "database-operation")
	defer timer.WarnIfSlow(3 * time.Second)

	// Test code
}

func TestMultipleOperations(t *testing.T) {
	timer := StartTimer(t)
	defer timer.Stop()

	// First operation
	operation1(timer)

	// Reset for second operation
	timer.Reset()
	operation2(timer)
}

func operation1(timer *TestTimer) {
	// Operation 1 code
	duration := timer.Elapsed()
	timer.t.Logf("Operation 1 took: %v", duration)
}

func operation2(timer *TestTimer) {
	// Operation 2 code
	duration := timer.Elapsed()
	timer.t.Logf("Operation 2 took: %v", duration)
}
/home/senke/git/talas/veza/veza-backend-api/internal/testutils/servicemocks/home/senke/git/talas/veza/veza-backend-api/internal/testutils/servicemocks/mocks.goMockAuditServiceMockSessionServiceNewMockAuditServiceNewMockSessionServiceSetupMockAuditLogActionSuccessSetupMockAuditLogDeletionSuccessSetupMockAuditLogLoginSuccessSetupMockAuditLogLogoutSuccessSetupMockAuditLogPermissionChangeSuccessSetupMockAuditLogUploadSuccessSetupMockAuditSearchLogsSetupMockAuditSearchLogsErrorSetupMockAuditSuccessSetupMockSessionRevokeSuccessSetupMockSessionSuccessSetupMockSessionValidationErrorSetupMockSessionValidationSuccessmockServiceservicemocks"github.com/stretchr/testify/mock""CreateSession"mock.Anything"ValidateSession""RevokeSession""LogAction""LogLogin""LogLogout""LogUpload""LogPermissionChange""LogDeletion""SearchLogs" MockSessionService est un mock pour SessionService (T0042) NewMockSessionService crée un nouveau mock SessionService (T0042) CreateSession mock (T0042) ValidateSession mock (T0042) RevokeSession mock (T0042) RevokeAllUserSessions mock (T0042) GetUserSessions mock (T0042) CleanupExpiredSessions mock (T0042) RefreshSession mock (T0042) GetSessionStats mock (T0042) MockAuditService est un mock pour AuditService (T0042) NewMockAuditService crée un nouveau mock AuditService (T0042) LogAction mock (T0042) LogLogin mock (T0042) LogLogout mock (T0042) LogUpload mock (T0042) LogPermissionChange mock (T0042) LogDeletion mock (T0042) SearchLogs mock (T0042) GetStats mock (T0042) SetupMockSessionSuccess configure un mock pour succès de création de session (T0042) Utiliser mock.MatchedBy pour matcher n'importe quel req avec le bon userID SetupMockSessionValidationSuccess configure un mock pour validation de session réussie (T0042) SetupMockSessionValidationError configure un mock pour erreur de validation de session (T0042) SetupMockSessionRevokeSuccess configure un mock pour révocation de session réussie (T0042) SetupMockAuditSuccess configure un mock audit pour succès (T0042) SetupMockAuditLogActionSuccess configure un mock pour LogAction spécifique (T0042) SetupMockAuditLogLoginSuccess configure un mock pour LogLogin spécifique (T0042) SetupMockAuditSearchLogs configure un mock pour SearchLogs (T0042) SetupMockAuditSearchLogsError configure un mock pour erreur de recherche (T0042) SetupMockAuditLogLogoutSuccess configure un mock pour LogLogout spécifique (T0042) SetupMockAuditLogUploadSuccess configure un mock pour LogUpload spécifique (T0042) SetupMockAuditLogPermissionChangeSuccess configure un mock pour LogPermissionChange spécifique (T0042) SetupMockAuditLogDeletionSuccess configure un mock pour LogDeletion spécifique (T0042)/home/senke/git/talas/veza/veza-backend-api/internal/testutils/setup.gocontainerErrdsnErrmigrationFilesmigrationsDirprojectRoot"github.com/testcontainers/testcontainers-go""github.com/testcontainers/testcontainers-go/modules/postgres""github.com/testcontainers/testcontainers-go/wait"../.."../.."migrations"migrations"failed to read migrations dir: %w"failed to read migrations dir: %w".sql".sql"000000_cleanup"000000_cleanup"Starting PostgreSQL testcontainer"Starting PostgreSQL testcontainer"migration_files"migration_files"postgres:15-alpine"postgres:15-alpine"veza_test"veza_test"database system is ready to accept connections"database system is ready to accept connections"90000000000PostgreSQL testcontainer started successfully"PostgreSQL testcontainer started successfully"Failed to start PostgreSQL testcontainer, retrying"Failed to start PostgreSQL testcontainer, retrying"Waiting before retry"Waiting before retry""backoff"Failed to start PostgreSQL testcontainer after all retries"Failed to start PostgreSQL testcontainer after all retries"failed to start postgres container after %d attempts: %w"failed to start postgres container after %d attempts: %w"sslmode=disable"sslmode=disable"failed to get connection string: %w"failed to get connection string: %w" GetTestContainerDB ensures the postgres container is running and returns the DSN. It uses a singleton pattern to start the container only once per test run. Find project root relative to this file This file is in internal/testutils/setup.go Collect migration files MOD-P1-001: Exclude cleanup migrations that may fail if tables don't exist yet These migrations are meant to be run on existing databases, not fresh ones Ensure alphabetical order (001_, 002_, ...) MOD-P1-001: Retry container startup with exponential backoff Use a simple logger for testcontainers (zap.L() may not be initialized in tests) Start Postgres container with improved wait strategy Increased timeout from 60s to 90s Success Log retry attempt TerminateContainer allows manual termination if needed (mostly for cleanup)/home/senke/git/talas/veza/veza-backend-api/internal/testutils/setup_redis.goStarting Redis testcontainer"Starting Redis testcontainer"redis:7-alpine"redis:7-alpine"6379/tcp"6379/tcp"Ready to accept connections"Ready to accept connections"Failed to start Redis testcontainer"Failed to start Redis testcontainer"Redis testcontainer started successfully"Redis testcontainer started successfully" GetTestRedisClient ensures the Redis container is running and returns a client. Wait for Redis to be ready TerminateRedisContainer allows manual termination if needed (mostly for cleanup)/home/senke/git/talas/veza/veza-backend-api/internal/types/home/senke/git/talas/veza/veza-backend-api/internal/types/auth.goMagicLinkStatusMagicLinkStatusExpiredMagicLinkStatusInvalidatedMagicLinkStatusPendingMagicLinkStatusUsedinvalidated"invalidated" Auth-related types MagicLinkStatus represents the status of a magic link/home/senke/git/talas/veza/veza-backend-api/internal/types/config.go ConfigReloader interface définit les méthodes de rechargement de configuration Cette interface permet d'éviter les imports cycliques entre config et handlers/home/senke/git/talas/veza/veza-backend-api/internal/types/stats.go`json:"views,omitempty"``json:"likes,omitempty"``json:"comments,omitempty"``json:"total_play_time,omitempty"``json:"downloads,omitempty"``json:"unique_tracks"``json:"total_duration"``json:"followers_count,omitempty"``json:"following_count,omitempty"``json:"tracks_count,omitempty"``json:"playlists_count,omitempty"``json:"likes_count,omitempty"``json:"comments_count,omitempty"` Ce type est partagé entre analytics_service et track_service Champs de analytics_service Champs additionnels de track_service UserStats représente les statistiques d'un utilisateur Ce type est partagé entre analytics_service et user_service Champs additionnels de user_service/home/senke/git/talas/veza/veza-backend-api/internal/types/user.go`json:"in_app"``json:"playlist"``json:"playlists_public"``json:"date_format"``json:"preferences,omitempty"` User-related types shared between handlers and services UserSettingsResponse represents user settings PreferenceSettings represents general preferences UpdateSettingsRequest represents settings update data/home/senke/git/talas/veza/veza-backend-api/internal/utils/home/senke/git/talas/veza/veza-backend-api/internal/utils/math.goBuildOffsetPaginationResponseBuildPaginationResponseCalculateOffsetChunkContainsOnlyAlphanumericContainsOnlyDigitsContainsOnlyLettersContainsStringCreateCursorDecodeCursorEncodeCursorErrCoverURLTooLongErrInvalidCoverURLErrPlaylistDescTooLongErrPlaylistTitleRequiredErrPlaylistTitleTooLongExtractDomainFormatDurationFormatFileSizeFormatNumberGenerateIDGenerateRandomBytesGenerateRandomStringGenerateSlugGenerateUUIDHashSHA256IndexOfIsNotEmptyIsValidURLNewPaginationHelperOffsetPaginationRequestOffsetPaginationResponsePaginationHelperPaginationRequestPaginationResponseParseCursorParseLimitRemoveDuplicatesSanitizeHTMLSupportedLanguagesSupportedThemesTruncateStringValidateCoverURLValidateEmailValidateLanguageValidateOffsetPaginationRequestValidatePaginationRequestValidatePlaylistDescriptionValidatePlaylistTitleValidateThemeValidateTimezoneVerifyPasswordtransliterations Min retourne le minimum de deux entiers Fonction utilitaire partagée pour éviter les duplications Max retourne le maximum de deux entiersPrevCursorjson:"prev_cursor,omitempty"HasPrevjson:"has_prev"json:"page" form:"page"json:"limit" form:"limit"json:"cursor" form:"cursor"GetDefaultLimitGetMaxLimitValidateLimitCreateEmptyResponse/home/senke/git/talas/veza/veza-backend-api/internal/utils/pagination.gocursorStrnextCursorStrprevCursorStrhasNexthasPrevnextCursorprevCursordefaultLimit`json:"limit" form:"limit"``json:"cursor" form:"cursor"``json:"prev_cursor,omitempty"``json:"has_prev"``json:"total,omitempty"`failed to marshal cursor: %w"failed to marshal cursor: %w"failed to decode cursor: %w"failed to decode cursor: %w"failed to unmarshal cursor: %w"failed to unmarshal cursor: %w"failed to encode next cursor: %w"failed to encode next cursor: %w"failed to encode prev cursor: %w"failed to encode prev cursor: %w"`json:"page" form:"page"`! Utilitaires de pagination optimisée! Ce module implémente la pagination cursor-based qui est plus performante! que la pagination offset-based pour les grandes datasets. PaginationRequest représente une requête de pagination PaginationResponse représente une réponse paginée Cursor représente un curseur de pagination EncodeCursor encode un curseur en string base64 DecodeCursor décode un curseur depuis une string base64 CreateCursor crée un nouveau curseur à partir d'un ID et d'une date ValidatePaginationRequest valide une requête de pagination Valeur par défaut BuildPaginationResponse construit une réponse paginée Encoder le curseur suivant Encoder le curseur précédent ParseLimit parse et valide la limite de pagination ParseCursor parse et valide un curseur OffsetPaginationRequest représente une requête de pagination offset-based (legacy) OffsetPaginationResponse représente une réponse paginée offset-based BuildOffsetPaginationResponse construit une réponse paginée offset-based ValidateOffsetPaginationRequest valide une requête de pagination offset-based CalculateOffset calcule l'offset pour la pagination offset-based PaginationHelper contient des méthodes utilitaires pour la pagination NewPaginationHelper crée un nouveau helper de pagination GetDefaultLimit retourne la limite par défaut GetMaxLimit retourne la limite maximale ValidateLimit valide et ajuste une limite CreateEmptyResponse crée une réponse paginée vide/home/senke/git/talas/veza/veza-backend-api/internal/utils/password_validator.gohasLowerhasNumberhasSpecialhasUpper"unicode"password must be at least 8 characters"password must be at least 8 characters"password must be less than 128 characters"password must be less than 128 characters"IsUpperIsLowerIsNumberIsPunctIsSymbolpassword must contain at least one uppercase letter"password must contain at least one uppercase letter"password must contain at least one lowercase letter"password must contain at least one lowercase letter"password must contain at least one number"password must contain at least one number"password must contain at least one special character"password must contain at least one special character" ValidatePasswordStrength validates password strength according to security rules T0197: Validates password with minimum 8 characters, uppercase, lowercase, number, and special character/home/senke/git/talas/veza/veza-backend-api/internal/utils/playlist_validator.gocoverURLplaylist title is required"playlist title is required"playlist title must be less than 200 characters"playlist title must be less than 200 characters"playlist description must be less than 2000 characters"playlist description must be less than 2000 characters"invalid cover URL format"invalid cover URL format"cover URL must be less than 500 characters"cover URL must be less than 500 characters""http"https"https" Erreurs de validation pour les playlists ValidatePlaylistTitle valide le titre d'une playlist T0455: Validation du titre (requis, max 200 caractères) ValidatePlaylistDescription valide la description d'une playlist T0455: Validation de la description (max 2000 caractères) ValidateCoverURL valide l'URL de la couverture d'une playlist T0455: Validation de l'URL (format valide, http/https, max 500 caractères) Optional field/home/senke/git/talas/veza/veza-backend-api/internal/utils/settings_validator.go"ar""hi""nl""sv"pl"pl""tr""cs""ro"hu"hu""fi"dark"dark"unsupported language code: %s. Supported: %v"unsupported language code: %s. Supported: %v"invalid timezone: %s. Must be a valid IANA timezone"invalid timezone: %s. Must be a valid IANA timezone"invalid theme: %s. Allowed: %v"invalid theme: %s. Allowed: %v" SupportedLanguages contains the list of supported ISO 639-1 language codes SupportedThemes contains the list of supported theme values ValidateLanguage validates an ISO 639-1 language code Returns nil if valid or empty, error otherwise ValidateTimezone validates an IANA timezone string ValidateTheme validates a theme enum value/home/senke/git/talas/veza/veza-backend-api/internal/utils/slug.goNewReplacerÀ"À"Á"Á"Â"Â"Ã"Ã"Ä"Ä"Å"Å"Æ"Æ"AE"AE"Ç"Ç""C"È"È""E"É"É"Ê"Ê"Ë"Ë"Ì"Ì""I"Í"Í"Î"Î"Ï"Ï"Ð"Ð""D"Ñ"Ñ""N"Ò"Ò""O"Ó"Ó"Ô"Ô"Õ"Õ"Ö"Ö"Ø"Ø"Ù"Ù""U"Ú"Ú"Û"Û"Ü"Ü"Ý"Ý""Y"Þ"Þ"TH"TH"ß"ß""ss"à"à""a"á"á"â"â"ã"ã"ä"ä"å"å"æ"æ""ae"ç"ç""c"è"è""e"é"é"ê"ê"ë"ë"ì"ì""i"í"í"î"î"ï"ï"ð"ð""d"ñ"ñ""n"ò"ò""o"ó"ó"ô"ô"õ"õ"ö"ö"ø"ø"ù"ù""u"ú"ú"û"û"ü"ü"ý"ý""y"þ"þ""th"ÿ"ÿ"IsLetter' ''-'45"--" Slugify converts a string to a URL-friendly slug It converts letters to lowercase, replaces spaces and special characters with dashes, and removes consecutive dashes and leading/trailing dashes. It also transliterates common accented characters to their ASCII equivalents. Transliterate common accented characters to their ASCII equivalents Remove consecutive dashes Remove leading/trailing dashes/home/senke/git/talas/veza/veza-backend-api/internal/utils/utils.gohashedBytesusernameRegexdangerousTagsurlRegexchunkSizepredicatereducer"regexp"0x0f0x400x3f0x80%x-%x-%x-%x-%x"%x-%x-%x-%x-%x"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"62MustCompile^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`Username must be at least 3 characters long"Username must be at least 3 characters long"Username must be less than 30 characters"Username must be less than 30 characters"^[a-zA-Z0-9_-]+$`^[a-zA-Z0-9_-]+$`Username can only contain letters, numbers, underscores, and hyphens"Username can only contain letters, numbers, underscores, and hyphens"127<script"<script"</script>"</script>"<iframe"<iframe"</iframe>"</iframe>"<object"<object"</object>"</object>"<embed"<embed"</embed>"</embed>"%.0fs"%.0fs"%.0fm"%.0fm"%.1fh"%.1fh"%.1fd"%.1fd"%d B"%d B"%.1f %cB"%.1f %cB"KMGTPE"KMGTPE"smhd"smhd""s"^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$`^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$`http://"http://"https://"https://"[^a-z0-9-]`[^a-z0-9-]`-+`-+`IsDigit GenerateID génère un ID unique GenerateUUID génère un UUID v4 Version 4 Variant bits GenerateRandomString génère une chaîne aléatoire de longueur donnée GenerateRandomBytes génère des bytes aléatoires HashPassword hash un mot de passe avec bcrypt VerifyPassword vérifie un mot de passe contre son hash CheckPasswordHash est un alias pour VerifyPassword (compatibilité) HashSHA256 hash une chaîne avec SHA256 ValidateEmail valide le format d'un email ValidatePasswordStrength is now in password_validator.go T0197: Moved to password_validator.go for better organization ValidateUsername valide le format d'un nom d'utilisateur Supprimer les caractères de contrôle Supprimer les espaces en début et fin SanitizeHTML nettoie du HTML Supprimer les balises HTML dangereuses TruncateString tronque une chaîne à la longueur spécifiée ContainsString vérifie si une chaîne contient une sous-chaîne (insensible à la casse) IsEmpty vérifie si une chaîne est vide ou ne contient que des espaces IsNotEmpty vérifie si une chaîne n'est pas vide FormatDuration formate une durée en chaîne lisible FormatFileSize formate une taille de fichier en chaîne lisible FormatNumber formate un nombre avec des séparateurs de milliers ParseDuration parse une durée depuis une chaîne Supprimer les espaces Ajouter 's' si pas d'unité spécifiée IsValidURL vérifie si une chaîne est une URL valide ExtractDomain extrait le domaine d'une URL Supprimer le protocole Supprimer le chemin GenerateSlug génère un slug à partir d'une chaîne Convertir en minuscules Remplacer les espaces par des tirets Supprimer les caractères non alphanumériques sauf les tirets Supprimer les tirets multiples Supprimer les tirets en début et fin ContainsOnlyDigits vérifie si une chaîne ne contient que des chiffres ContainsOnlyLetters vérifie si une chaîne ne contient que des lettres ContainsOnlyAlphanumeric vérifie si une chaîne ne contient que des caractères alphanumériques RemoveDuplicates supprime les doublons d'une slice de chaînes Contains vérifie si une slice contient un élément IndexOf retourne l'index d'un élément dans une slice Reverse inverse l'ordre d'une slice Chunk divise une slice en chunks de taille donnée Filter filtre une slice selon une condition Map applique une fonction à chaque élément d'une slice Reduce réduit une slice à une seule valeur/home/senke/git/talas/veza/veza-backend-api/internal/validators/home/senke/git/talas/veza/veza-backend-api/internal/validators/email_validator.gogetErrorMessagegetFieldNameregisterCustomValidationsdomainPartlocalPart^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`254253LOWER(email) = ?"LOWER(email) = ?" RFC 5322 compliant email regex (simplified but covers most cases) This regex validates: - Local part: alphanumeric, dots, underscores, hyphens, plus signs - @ symbol - Domain part: alphanumeric, dots, hyphens - TLD: at least 2 characters EmailValidator valide les emails selon RFC 5322 NewEmailValidator crée une nouvelle instance d'EmailValidator ValidateFormat valide le format de l'email selon RFC 5322 RFC 5321: Email addresses are limited to 254 characters Vérifier que l'email n'est pas vide Vérifier le format avec regex Vérifications supplémentaires Local part ne peut pas être vide Domain part ne peut pas être vide Le domaine doit contenir au moins un point Le local part ne peut pas commencer ou finir par un point Le domaine ne peut pas commencer ou finir par un point ou un tiret IsUnique vérifie si l'email est unique en base de données Validate effectue une validation complète de l'email (format + unicité)/home/senke/git/talas/veza/veza-backend-api/internal/validators/password_validator.gostrength[A-Z]`[A-Z]`[a-z]`[a-z]`[0-9]`[0-9]`[!@#$%^&*(),.?":{}|<>]`[!@#$%^&*(),.?":{}|<>]`Password must be at least 12 characters long"Password must be at least 12 characters long"Must contain uppercase letter"Must contain uppercase letter"Must contain lowercase letter"Must contain lowercase letter"Must contain number"Must contain number"Must contain special character"Must contain special character" PasswordValidator valide la force d'un mot de passe NewPasswordValidator crée une nouvelle instance de PasswordValidator PasswordStrength représente le résultat de la validation d'un mot de passe Validate valide la force d'un mot de passe selon les règles définies Length check Upper case check Lower case check Number check Special character check/home/senke/git/talas/veza/veza-backend-api/internal/validators/validator.gofieldErrvalidationErrsstructNamespacefluuidStruuidValidator%v"%v"%s is required"%s is required"%s must be a valid email address"%s must be a valid email address"%s must be at least %s characters"%s must be at least %s characters"%s must be at most %s characters"%s must be at most %s characters"%s must be one of: %s"%s must be one of: %s"%s must equal %s"%s must equal %s"%s must be a valid UUID"%s must be a valid UUID"%s must be a valid URL"%s must be a valid URL"%s must be numeric"%s must be numeric"%s must contain only letters"%s must contain only letters"%s must contain only letters and numbers"%s must contain only letters and numbers"%s must be greater than or equal to %s"%s must be greater than or equal to %s"%s must be less than or equal to %s"%s must be less than or equal to %s"%s must be greater than %s"%s must be greater than %s"%s must be less than %s"%s must be less than %s"%s is invalid"%s is invalid"uuid_string"uuid_string" Validator est un wrapper autour de go-playground/validator GO-013: Validation input centralisée avec go-validator NewValidator crée une nouvelle instance de Validator Enregistrer des validations personnalisées Validate valide une structure et retourne des erreurs formatées ValidateVar valide une variable unique getFieldName extrait le nom du champ depuis l'erreur de validation GO-013: Extrait le tag JSON si disponible via StructNamespace, sinon convertit en camelCase Utiliser StructNamespace qui donne le chemin complet (ex: "TestStruct.Name") et extraire le dernier segment Convertir en camelCase pour JSON (première lettre en minuscule) Fallback: utiliser Field() et convertir en camelCase getErrorMessage génère un message d'erreur lisible depuis l'erreur de validation registerCustomValidations enregistre des validations personnalisées Validation pour username (alphanumeric + underscore, 3-30 chars) Validation pour UUID string Optionnel Utiliser le même validator pour éviter la récursion/home/senke/git/talas/veza/veza-backend-api/internal/workers/home/senke/git/talas/veza/veza-backend-api/internal/workers/analytics_job.goAnalyticsEventAnalyticsEventJobAnalyticsJobEmailJobHLSTranscodeWorkerNewAnalyticsEventJobNewEmailJobNewEmailJobWithTemplateNewHLSTranscodeWorkerNewPlaybackAnalyticsWorkerNewPlaybackRetentionWorkerNewThumbnailJobPlaybackAnalyticsWorkerPlaybackRetentionWorkerThumbnailJobWorkerStatseventNamegorm:"not null;index:idx_analytics_events_name"gorm:"type:uuid;index:idx_analytics_events_user_id"gorm:"type:jsonb"gorm:"autoCreateTime;index:idx_analytics_events_created_at"payloadJSON`gorm:"not null;index:idx_analytics_events_name"``gorm:"type:uuid;index:idx_analytics_events_user_id"``gorm:"type:jsonb"``gorm:"autoCreateTime;index:idx_analytics_events_created_at"`analytics_events"analytics_events"event name is required"event name is required"failed to save analytics event: %w"failed to save analytics event: %w"Analytics event recorded"Analytics event recorded"event_name"event_name"payload_size"payload_size" AnalyticsEventJob représente un job d'enregistrement d'événement analytics générique Nom de l'événement (ex: "track_play", "user_login", "file_upload") ID de l'utilisateur (nullable pour événements anonymes) Données additionnelles de l'événement NewAnalyticsEventJob crée un nouveau job d'analytics générique AnalyticsEvent représente un événement analytics en base de données Stocké en JSONB pour PostgreSQL Execute exécute le job d'analytics générique Valider le nom de l'événement Sérialiser le payload en JSON Créer l'événement analytics Enregistrer en base de donnéesretentionServiceSetPolicyrunRetentionPolicyjson:"running"json:"queue_size"Workersjson:"workers"json:"max_retries"BatchSizejson:"batch_size"BatchTimeoutjson:"batch_timeout"renderTemplateAnalyticsInputPathOutputPathEnqueueBatchcollectBatchprocessBatchretryFailedJobsGetQueueSizepollIntervalprocessNextJobhandleJobErrorJobs/home/senke/git/talas/veza/veza-backend-api/internal/workers/email_job.gotemplateNamerenderedsendertemplateDirtemplatePathtmplContentFailed to render email template"Failed to render email template""template"failed to render template: %w"failed to render template: %w"Failed to send email"Failed to send email"Email job executed successfully"Email job executed successfully"EMAIL_TEMPLATE_DIR"EMAIL_TEMPLATE_DIR"templates/email"templates/email".html".html"failed to read template file %s: %w"failed to read template file %s: %w"failed to parse template: %w"failed to parse template: %w"failed to execute template: %w"failed to execute template: %w" EmailJob représente un job d'envoi d'email Nom du template (ex: "password_reset") Données pour le template NewEmailJob crée un nouveau job d'email NewEmailJobWithTemplate crée un job d'email avec template Execute exécute le job d'email Si un template est spécifié, le rendre Envoyer l'email renderTemplate rend un template email Chercher le template dans templates/email/ Lire le fichier template Parser le template Rendre le template avec les données/home/senke/git/talas/veza/veza-backend-api/internal/workers/hls_transcode_worker.goworkerIDjobCtxdelayretryErrStarting HLS transcode worker"Starting HLS transcode worker""workers"poll_interval"poll_interval"Stopping HLS transcode worker"Stopping HLS transcode worker"worker_id"worker_id"HLS transcode worker started"HLS transcode worker started"HLS transcode worker stopping"HLS transcode worker stopping"Failed to dequeue job"Failed to dequeue job"Processing HLS transcode job"Processing HLS transcode job"Failed to load track"Failed to load track"failed to load track: %w"failed to load track: %w"Transcode failed"Transcode failed"Failed to mark job as completed"Failed to mark job as completed"HLS transcode job completed successfully"HLS transcode job completed successfully"Retrying job"Retrying job"Failed to retry job"Failed to retry job"Failed to retry: %v"Failed to retry: %v"Job will be retried"Job will be retried""delay"Job failed after max retries"Job failed after max retries" HLSTranscodeWorker gère le traitement de la queue de transcodage HLS NewHLSTranscodeWorker crée un nouveau worker de transcodage HLS Start démarre le worker Stop arrête le worker processWorker traite les jobs de la queue processNextJob traite le prochain job disponible Récupérer le prochain job Créer un contexte avec timeout pour le transcodage Marquer le job comme terminé handleJobError gère les erreurs de traitement Vérifier si on peut réessayer Réessayer le job avec exponential backoff Si on ne peut pas réessayer, marquer comme échoué Attendre avant de réessayer (exponential backoff) Max retries atteint, marquer comme échoué/home/senke/git/talas/veza/veza-backend-api/internal/workers/job_worker.goexecErremailJobinputPathjobPayloadwIntwValhInthValthumbnailJobuidStranalyticsJobextraPayload`gorm:"type:uuid;primary_key"``gorm:"not null"``gorm:"serializer:json;not null"``gorm:"not null;default:'pending'"``gorm:"not null;default:2"``gorm:"not null;index"``gorm:"not null;default:0"``gorm:"not null;default:3"``gorm:"type:text"`Failed to enqueue job"Failed to enqueue job"Job enqueued (persisted)"Job enqueued (persisted)"Starting persisted job worker"Starting persisted job worker"Failed to rescue zombie jobs on startup"Failed to rescue zombie jobs on startup"Failed to rescue zombie jobs"Failed to rescue zombie jobs"-15-900000000000status = ? AND started_at < ?"status = ? AND started_at < ?"retries"retries"retries + 1"retries + 1"last_error"last_error"Zombie job rescue: Worker probably crashed"Zombie job rescue: Worker probably crashed"run_at"run_at"Rescued zombie jobs"Rescued zombie jobs"Worker started"Worker started"Worker stopping"Worker stopping"SKIP LOCKED"SKIP LOCKED"status = ? AND run_at <= ?"status = ? AND run_at <= ?"priority ASC, created_at ASC"priority ASC, created_at ASC"Failed to fetch job"Failed to fetch job""retry"Processing job"Processing job"Job execution failed"Job execution failed"Job reached max retries, marked as failed"Job reached max retries, marked as failed"Job scheduled for retry"Job scheduled for retry"Job completed successfully"Job completed successfully"Failed to update job status after execution"Failed to update job status after execution"unknown job type: %s"unknown job type: %s"missing 'to' in payload"missing 'to' in payload""body"template_data"template_data"input_path"input_path"output_path"output_path""width""height""payload"missing paths in payload"missing paths in payload"missing event_name"missing event_name"invalid user_id: %w"invalid user_id: %w"queue_pending"queue_pending"queue_processing"queue_processing"queue_failed"queue_failed" JobWorker gère les tâches en arrière-plan via une queue persistée en DB Job représente une tâche persistée en base de données pending, processing, completed, failed 1=high, 2=medium, 3=low NewJobWorker crée un nouveau worker de jobs persisté queueSize ignoré car persisté AutoMigrate la table Job si nécessaire (optionnel si géré par migrations SQL) db.AutoMigrate(&Job{}) Polling agressif pour réactivité Enqueue ajoute un job dans la table jobs Initialisation des champs par défaut Le mapping GORM gère CreatedAt/UpdatedAt Start démarre les workers de polling Start zombie job rescuer (background loop) rescueZombieJobsLoop runs periodically to reset jobs stuck in processing state Run once immediately on startup rescueZombieJobs atomically resets stuck jobs Threshold: 15 minutes. If a job is "processing" for > 15m, it is likely the worker crashed. We increment retries to prevent infinite loops if the job itself causes the crash Retry immediately processWorker boucle de polling et traitement fetchAndProcessJob récupère UN job en attente (atomiquement) et le traite Transaction pour verrouiller le job (SELECT ... FOR UPDATE SKIP LOCKED) Compatible Postgres (et MySQL 8+). Pour SQLite, le locking est différent mais Gorm gère le basic. Trouver un job 'pending' ou 'failed' (si retry auto géré ici, mais on préfère 'pending' avec RunAt <= Now) On cherche status='pending' AND run_at <= NOW() Order by Priority ASC (1 first), then CreatedAt RecordNotFound est typique ici Update status to 'processing' Pas de job à traiter, on attend le prochain tick Job récupéré, on traite processJob exécute la logique métier et met à jour le statut final Si le payload est une map vide, tenter de le decoder s'il vient de GORM (jsonb) Gorm avec `serializer:json` devrait le faire auto, mais verifions. Timeout per job execution Exécution Update status final Calcul du prochain retry Backoff exponentiel : 5s, 10s, 20s... (lineaire * coefficient) ou 5 * retry Retour en queue Sauvegarde finale On le fait hors transaction "fetch", car le traitement peut être long executeJob exécute la logique selon le type (inchangé) Mapping manuel pour compatibilité avec l'ancien code si nécessaire processEmailJob (inchangé structurellement, mais adapte le payload use) Re-conversion du payload map si nécessaire Gorm serialization handle maps directly Try generic map Helper methods pour enqueuing (inchangés, mais adaptent l'objet Job) EnqueueEmailJob helper EnqueueEmailJobWithTemplate helper EnqueueThumbnailJob helper EnqueueAnalyticsJob helper processThumbnailJob wrapper JSON unmarshal numbers as float64 just in case processAnalyticsJob wrapper Handle nested map from JSON If payload is a string (escaped json), try unmarshal? For now assume standard structure GetStats retourne les stats DB si possible/home/senke/git/talas/veza/veza-backend-api/internal/workers/playback_analytics_worker.goqueueSizeenqueuedbatchCtxjobToRetrybatchErrorAnalytics job enqueued"Analytics job enqueued"Analytics queue full, dropping job"Analytics queue full, dropping job"queue is full"queue is full"Failed to enqueue analytics"Failed to enqueue analytics"Batch enqueued"Batch enqueued""enqueued"Playback analytics worker is already running"Playback analytics worker is already running"Starting playback analytics worker"Starting playback analytics worker"batch_size"batch_size"batch_timeout"batch_timeout"Stopping playback analytics worker"Stopping playback analytics worker"Playback analytics worker started"Playback analytics worker started"Playback analytics worker stopping"Playback analytics worker stopping"Playback analytics worker stopping (stop requested)"Playback analytics worker stopping (stop requested)"Processing analytics batch"Processing analytics batch"Batch processing failed"Batch processing failed"Batch processed successfully"Batch processed successfully"failed_jobs"failed_jobs"Retrying failed analytics jobs"Retrying failed analytics jobs"Job exceeded max retries, dropping"Job exceeded max retries, dropping"Job re-enqueued for retry"Job re-enqueued for retry"Queue full, cannot retry job"Queue full, cannot retry job"`json:"running"``json:"queue_size"``json:"workers"``json:"max_retries"``json:"batch_size"``json:"batch_timeout"` PlaybackAnalyticsWorker gère le traitement par lots des analytics de playback T0387: Create Playback Analytics Batch Processing AnalyticsJob représente un job d'analytics à traiter 1 = haut, 2 = moyen, 3 = bas Batch représente un lot d'analytics à traiter NewPlaybackAnalyticsWorker crée un nouveau worker d'analytics Taille par défaut de la queue Nombre par défaut de workers Nombre par défaut de retries Taille par défaut du batch Timeout par défaut pour former un batch Enqueue ajoute un job d'analytics à la queue EnqueueBatch ajoute plusieurs analytics à la queue IsRunning retourne si le worker est en cours d'exécution processWorker traite les jobs de la queue par lots Collecter les jobs pour former un batch collectBatch collecte les jobs pour former un batch Timeout atteint, traiter le batch même s'il n'est pas plein Réinitialiser le timeout si le batch est vide Si le batch est plein, le traiter immédiatement processBatch traite un lot d'analytics Convertir les jobs en analytics Créer un contexte avec timeout pour le traitement du batch Traiter le batch Retry les jobs individuellement si le batch échoue retryFailedJobs réessaie les jobs qui ont échoué Vérifier si on peut encore retry Incrémenter le compteur de retries Exponential backoff via time.AfterFunc (non-blocking) Capture variable for usage in closure Ré-enqueue le job GetQueueSize retourne la taille actuelle de la queue GetStats retourne les statistiques du worker/home/senke/git/talas/veza/veza-backend-api/internal/workers/playback_retention_worker.goretentionCtxRetention worker is already running"Retention worker is already running"Starting playback retention worker"Starting playback retention worker"archive_after"archive_after"delete_after"delete_after"Stopping playback retention worker"Stopping playback retention worker"Stopping playback retention worker (stop requested)"Stopping playback retention worker (stop requested)""worker"playback_retention"playback_retention"Running playback retention policy"Running playback retention policy"Failed to apply retention policy"Failed to apply retention policy"Playback retention policy applied successfully"Playback retention policy applied successfully" PlaybackRetentionWorker gère l'exécution périodique de la politique de rétention Intervalle d'exécution NewPlaybackRetentionWorker crée un nouveau worker de rétention Par défaut, exécuter quotidiennement SetPolicy définit la politique de rétention à utiliser Start démarre le worker de rétention Puis exécuter périodiquement Stop arrête le worker de rétention runRetentionPolicy exécute la politique de rétention Créer un contexte avec timeout pour éviter les blocages Appliquer la politique de rétention/home/senke/git/talas/veza/veza-backend-api/internal/workers/thumbnail_job.goinput file does not exist: %s"input file does not exist: %s"failed to create output directory: %w"failed to create output directory: %w"failed to open image: %w"failed to open image: %w"failed to save thumbnail: %w"failed to save thumbnail: %w"Thumbnail generated successfully"Thumbnail generated successfully""input" ThumbnailJob représente un job de génération de thumbnail Chemin du fichier source Chemin du fichier thumbnail à générer Largeur du thumbnail (0 = auto, conserve ratio) Hauteur du thumbnail (0 = auto, conserve ratio) NewThumbnailJob crée un nouveau job de thumbnail Valeurs par défaut si non spécifiées Largeur par défaut Hauteur par défaut Execute exécute le job de génération de thumbnail Créer le répertoire de destination s'il n'existe pas Ouvrir l'image source Générer le thumbnail avec l'algorithme Lanczos (qualité élevée) Déterminer le format de sortie depuis l'extension Ajuster l'extension si nécessaire Sauvegarder le thumbnail (imaging.Save détecte automatiquement le format depuis l'extension)/home/senke/git/talas/veza/veza-backend-api/internal/workers/webhook_worker.godeliveryCtxdaysOldWebhook job enqueued"Webhook job enqueued"webhook_url"webhook_url"Webhook queue full, dropping job"Webhook queue full, dropping job"Starting webhook worker"Starting webhook worker"Webhook worker started"Webhook worker started"Webhook worker stopping"Webhook worker stopping"Processing webhook job"Processing webhook job"Webhook delivery failed"Webhook delivery failed"Retrying webhook delivery (enqueued)"Retrying webhook delivery (enqueued)"new_retries"new_retries"Webhook delivery failed after max retries"Webhook delivery failed after max retries"Failed to log webhook failure"Failed to log webhook failure"queue_size"queue_size"failed to cleanup old failures: %w"failed to cleanup old failures: %w"Cleaned up old webhook failures"Cleaned up old webhook failures"rows_deleted"rows_deleted"days_old"days_old"failed to fetch webhook: %w"failed to fetch webhook: %w"Requeued failed webhook"Requeued failed webhook" WebhookWorker gère les webhooks en arrière-plan WebhookJob représente une tâche de webhook à traiter NewWebhookWorker crée un nouveau worker de webhooks Enqueue ajoute un job au queue processWorker traite les jobs du queue processJob traite un job individuel Créer un contexte avec timeout pour la livraison Tenter de livrer le webhook Enregistrer l'échec dans la table de logs Retry si pas atteint max retries logFailedDelivery enregistre un échec de livraison CleanupOldFailures supprime les anciennes pannes de livraison RequeueFailed retente les webhooks en échec Récupérer le webhook Enqueue à nouveau On perd les données originales/home/senke/git/talas/veza/veza-backend-api/templates/email/password_reset.html/home/senke/git/talas/veza/veza-backend-api/templates/email/home/senke/git/talas/veza/veza-backend-api/templates

font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 0; background-color: #f4f4f4;
    max-width: 600px; margin: 20px auto; padding: 20px; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        color: #999; font-size: 11px; text-align: center;
            This is an automated message from Veza. Please do not reply to this email.
        hrborder: none; border-top: 1px solid #eee; margin: 20px 0;margin-top: 30px; color: #666; font-size: 12px;
            This link will expire in 1 hour. If you didn't request this, please ignore this email.
        word-break: break-all; color: #666; background-color: #f9f9f9; padding: 10px; border-radius: 4px; font-size: 12px;{{.ResetURL}}Or copy and paste this link into your browser:text-align: center; margin: 30px 0;
            hrefbackground-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block; font-weight: bold;
                Reset Password
            You requested to reset your Veza account password. Click the button below to continue.Hello {{.Username}},color: #4CAF50; margin-top: 0;Reset your passwordviewportwidth=device-width, initial-scale=1.0UTF-8/home/senke/git/talas/veza/veza-backend-api/templates/email/welcome.html
            This link will expire in 24 hours. If you didn't create an account, please ignore this email.
        {{.VerifyURL}}
                Verify Email Address
            To get started, please verify your email address by clicking the button below:Thank you for signing up for Veza! We're excited to have you join our community of creators.Welcome to Veza!Welcome to VezaCSSErrAmbigContextErrBadHTMLErrBranchEndErrEndContextErrJSTemplateErrNoSuchTemplateErrOutputContextErrPartialCharsetErrPartialEscapeErrPredefinedEscaperErrRangeLoopReentryErrSlashAmbigHTMLAttrHTMLEscapeStringHTMLEscaperIsTrueJSEscapeJSEscapeStringJSEscaperJSStrURLQueryEscaper_attr_index_attr_name_delim_index_delim_name_element_index_element_name_jsCtx_index_jsCtx_name_state_index_state_name_urlPart_index_urlPart_nameappendCmdasciiAlphaasciiAlphaNumattrEscaperattrNoneattrScriptattrScriptTypeattrSrcsetattrStartStatesattrStyleattrTypeMapattrURLblockCommentEndcommentEndcommentEscapercommentStartcontainsSpecialScriptTagcontentTypeCSScontentTypeHTMLcontentTypeHTMLAttrcontentTypeJScontentTypeJSStrcontentTypePlaincontentTypeSrcsetcontentTypeURLcontentTypeUnsafecontextAfterTextcssEscapercssReplacementTablecssValueFilterdebugAllowActionJSTmpldecodeCSSdelimDoubleQuotedelimEndsdelimNonedelimSingleQuotedelimSpaceOrTagEnddoctypeByteseatAttrNameeatTagNameeatWhiteSpaceelementContentTypeelementNameMapelementNoneelementScriptelementStyleelementTextareaelementTitleendsWithCSSKeywordensurePipelineContainsequivEscapersescFnsEqescapeOKescapeSpecialScriptTagsevalArgsexpressionBytesfilterFailsafefilterSrcsetElementfmtStringerTypefuncMaphexDecodehtmlEscaperhtmlNameFilterhtmlNormReplacementTablehtmlNospaceEscaperhtmlNospaceNormReplacementTablehtmlNospaceReplacementTablehtmlReplacementTablehtmlReplacerhtmlSpaceAndASCIIAlnumBytesindexTagEndindirectToJSONMarshalerindirectToStringerOrErrorisCSSNmcharisCSSSpaceisHTMLSpaceisHTMLSpaceOrASCIIAlnumisInScriptLiteralisInTagisJSIdentPartisJSTypeisSafeURLjoinRangejsBqStrReplacementTablejsCtxDivOpjsCtxRegexpjsCtxUnknownjsRegexpEscaperjsRegexpReplacementTablejsStrEscaperjsStrNormReplacementTablejsStrReplacementTablejsTmplLitEscaperjsValEscaperjsWhitespacejsonMarshalTypelowUnicodeReplacementTablemakeEscapermozBindingBytesnewIdentCmdnextJSCtxnormalizeEscFnnudgeparseFSparseGlobpredefinedEscapersprocessURLOntorcdataEscaperreadFileFSreadFileOSredundantFuncsregexpPrecederKeywordsscriptTagReskipCSSSpacespecialScriptTagREspecialScriptTagReplacementspecialTagEndMarkersspecialTagEndPrefixsrcsetFilterAndEscaperstateAfterNamestateAttrNamestateBeforeValuestateCSSstateCSSBlockCmtstateCSSDqStrstateCSSDqURLstateCSSLineCmtstateCSSSqStrstateCSSSqURLstateCSSURLstateDeadstateHTMLCmtstateJSstateJSBlockCmtstateJSDqStrstateJSHTMLCloseCmtstateJSHTMLOpenCmtstateJSLineCmtstateJSRegexpstateJSSqStrstateJSTmplLitstateRCDATAstateSrcsetstateTagstateTextstateURLstripTagstAfterNametAttrtAttrNametBeforeValuetBlockCmttCSStCSSStrtErrortHTMLCmttJStJSDelimitedtJSTmpltLineCmttSpecialTagEndtTagtTexttURLtagEndSeparatorstransitionFuncurlEscaperurlFilterurlNormalizerurlPartNoneurlPartPreQueryurlPartQueryOrFragurlPartUnknownurlProcessorentityMapsPlan9WebSafeimage/color/paletteAlpha16Alpha16ModelAlphaModelCMYKCMYKModelCMYKToRGBGray16Gray16ModelGrayModelModelFuncNRGBA64NRGBA64ModelNRGBAModelNYCbCrANYCbCrAModelRGBA64ModelRGBAModelRGBToCMYKRGBToYCbCrTransparentYCbCrYCbCrModelYCbCrToRGBalpha16ModelalphaModelcmykModelgray16ModelgrayModelmodelFuncnYCbCrAModelnrgba64ModelnrgbaModelrgba64ModelrgbaModelsqDiffyCbCrModelCbimage/colorDrawMaskFloydSteinbergOverRGBA64ImageclipdrawCMYKdrawCopyOverdrawCopySrcdrawFillOverdrawFillSrcdrawGlyphOverdrawGraydrawGrayMaskOverdrawNRGBAOverdrawNRGBASrcdrawPaletteddrawRGBAdrawRGBA64ImageMaskOverdrawRGBAMaskOverfloydSteinbergprocessBackwardRGBAAtSetRGBAAlphaAtSetAlphaCMYKAtSetCMYKUniformdrawimage/drawDisposalBackgroundDisposalNoneDisposalPreviousblockReaderblockWritereApplicationeCommenteGraphicControleTextencodeColorTableerrBadPixelerrNotEnougherrTooMuchfColorTablefColorTableBitsMaskfInterlacegcBlockSizegcDisposalMethodMaskgcLabelgcTransparentColorSetinterlaceScaninterlacinglog2log2LookupsExtensionsImageDescriptorsTraileruninterlacePalettedColorIndexAtSetColorIndexloopCountdelayTimebackgroundIndexdisposalMethodimageFieldstransparentIndexhasTransparentIndexglobalColorTabledisposalreadHeaderAndScreenDescriptorreadColorTablereadExtensionreadGraphicControlreadImageDescriptornewImageFromDescriptorLoopCountDisposalBackgroundIndexglobalCTlocalColorTablecolorTablesMatchwriteImageBlockNumColorsDrawYCbCrYCbCrSubsampleRatioYStrideCStrideSubsampleRatioYCbCrAtYOffsetCOffsetimageutilimage/internal/imageutilDefaultQualityacTableadobeTransformUnknownadobeTransformYCbCradobeTransformYCbCrKapp0Markerapp14Markerapp15MarkercenterJSamplecomMarkerconstBitsdcTabledhtMarkerdqtMarkerdriMarkereoiMarkererrMissingFF00errShortHuffmanDataerrUnsupportedSubsamplingRatiofdctfix_0_298631336fix_0_390180644fix_0_541196100fix_0_765366865fix_0_899976223fix_1_175875602fix_1_501321110fix_1_847759065fix_1_961570560fix_2_053119869fix_2_562915447fix_3_072711026grayToYhuffIndexhuffIndexChrominanceAChuffIndexChrominanceDChuffIndexLuminanceAChuffIndexLuminanceDChuffmanhuffmanLUThuffmanSpecidctlutSizemaxComponentsmaxNCodesmaxTcmaxThmaxTqnHuffIndexnQuantIndexpass1BitsquantIndexquantIndexChrominancequantIndexLuminancer2rgbaToYCbCrrst0Markerrst7Markersof0Markersof1Markersof2MarkersoiMarkersosHeaderYsosHeaderYCbCrsosMarkertheHuffmanLUTtheHuffmanSpectoYCbCrunscaledQuantunzigw1w1mw7w1pw7w2w2mw6w2pw6w3w3mw5w3pw5w5w6w7yCbCrToYCbCrquantemitHuffemitHuffRLEwriteMarkerHeaderwriteDQTwriteSOF0writeDHTwriteSOSnCodeslutminCodesmaxCodesvalsIndicesnUnreadabletqimg1img3blackPixblackStridenCompbaselineprogressivejfifadobeTransformValidadobeTransformeobRuncompprogCoeffshuffensureNBitsreceiveExtendprocessDHTdecodeHuffmandecodeBitdecodeBitsunreadByteStuffedBytereadByteStuffedByteprocessSOFprocessDQTprocessDRIprocessApp0MarkerprocessApp14MarkerapplyBlackconvertToRGBmakeImgprocessSOSrefinerefineNonZeroesreconstructProgressiveImagereconstructBlockfindRSTEncoderBufferEncoderBufferPoolabs8cbG1cbG16cbG2cbG4cbG8cbGA16cbGA8cbInvalidcbP1cbP2cbP4cbP8cbPalettedcbTC16cbTC8cbTCA16cbTCA8cbTrueColorchunkOrderErrorctGrayscalectGrayscaleAlphactPalettedctTrueColorctTrueColorAlphadsSeenIDATdsSeenIENDdsSeenIHDRdsSeenPLTEdsSeentRNSdsStartfilterPaethftAverageftNoneftPaethftSubftUpintSizeitAdam7itNonelevelToZlibnFilteropaquerpaethxFactoryFactorxOffsetyOffsetfooterprzwzwLevelwriteIHDRwritePLTEAndTRNSwriteImagewriteIDATswriteIENDidatLengthinterlaceuseTransparenttransparentparseIHDRparsePLTEparsetRNSreadImagePassmergePassIntoparseIDATparseIENDparseChunkverifyChecksumcheckHeaderNewAlphaNewAlpha16NewCMYKNewGrayNewGray16NewNRGBANewNRGBA64NewNYCbCrANewPalettedNewRGBANewRGBA64NewUniformNewYCbCrPalettedImagePtRegisterFormatYCbCrSubsampleRatio410YCbCrSubsampleRatio411YCbCrSubsampleRatio420YCbCrSubsampleRatio422YCbCrSubsampleRatio440YCbCrSubsampleRatio444ZPZRadd2NonNegasReaderatomicFormatsformatsMumul3NonNegpixelBufferLengthsniffyCbCrSizeNRGBA64AtSetNRGBA64Gray16AtSetGray16Alpha16AtSetAlpha16AStrideNYCbCrAAtAOffsetArgsSizeUnknownBothDirCommonSizeEffectiveFloatRegSizeEmptyInterfaceFUNCDATA_ArgInfoFUNCDATA_ArgLiveInfoFUNCDATA_ArgsPointerMapsFUNCDATA_InlTreeFUNCDATA_LocalsPointerMapsFUNCDATA_OpenCodedDeferInfoFUNCDATA_StackObjectsFUNCDATA_WrapInfoFloatArgRegsFuncFlagAsmFuncFlagSPWriteFuncFlagTopFrameFuncIDNormalFuncIDWrapperFuncID_abortFuncID_asmcgocallFuncID_asyncPreemptFuncID_cgocallbackFuncID_corostartFuncID_debugCallV2FuncID_gcBgMarkWorkerFuncID_goexitFuncID_gogoFuncID_gopanicFuncID_handleAsyncEventFuncID_mcallFuncID_morestackFuncID_mstartFuncID_panicwrapFuncID_rt0_goFuncID_runfinqFuncID_runtime_mainFuncID_sigpanicFuncID_systemstackFuncID_systemstack_switchFuncPCABI0FuncPCABIInternalFuncTabBucketSizeITabTypeOffIntArgRegBitmapIntArgRegsInterfaceSwitchInterfaceSwitchCacheInterfaceSwitchCacheEntryInvalidDirKindDirectIfaceKindMaskMINFUNCMaxPtrmaskBytesNewNameNoEscapeOldMapBucketCountOldMapBucketCountBitsOldMapMaxElemBytesOldMapMaxKeyBytesOldMapTypePCDATA_ArgLiveIndexPCDATA_InlTreeIndexPCDATA_StackMapIndexPCDATA_UnsafePointRF_DONERF_EXHAUSTEDRF_MISSING_PANICRF_PANICRF_READYRF_StateRecvDirRegArgsSendDirStackBigStackNosplitBaseStackSmallStructFieldSizeSwissMapCtrlEmptySwissMapGroupSlotsSwissMapGroupSlotsBitsSwissMapHashMightPanicSwissMapIndirectElemSwissMapIndirectKeySwissMapMaxElemBytesSwissMapMaxKeyBytesSwissMapNeedKeyUpdateTFlagExtraStarTFlagGCMaskOnDemandTFlagNamedTFlagOffTFlagRegularMemoryTFlagUncommonTraceArgsDotdotdotTraceArgsEndAggTraceArgsEndSeqTraceArgsLimitTraceArgsMaxDepthTraceArgsMaxLenTraceArgsOffsetTooLargeTraceArgsSpecialTraceArgsStartAggTypeAssertTypeAssertCacheTypeAssertCacheEntryTypeForUncommonSizeUnsafePointRestart1UnsafePointRestart2UnsafePointRestartAtEntryUnsafePointSafeUnsafePointUnsafeUseInterfaceSwitchCacheZeroValSizeaddCheckedalwaysFalsebitsetLSBctrlEmptyescapeSinkgo122InterfaceSwitchCachekindNamesstructTypeUncommonwriteVarintItabFloatsPtrsReturnIsPtrIntRegArgAddrNCasesCasesValueSizeReflexiveKeyCanFailabiinternal/abiasaninternal/asanAppendMarkerCutMarkerMarkerPrintMarkerappendFileLinededupfnvStringfnvUint32fnvUint64printFileLineprintStackverbosequietenableMarkerOnlyShouldEnableShouldPrintmatchResultfileLinerecentseenLossybisectinternal/bisectDefaultGO386DefaultGOAMD64DefaultGOARMDefaultGOARM64DefaultGOEXPERIMENTDefaultGOFIPS140DefaultGOMIPSDefaultGOMIPS64DefaultGOPPC64DefaultGORISCV64ExperimentExperimentFlagsFramePointerEnabledGO386GOAMD64GOARMGOARM64GOFIPS140GOGOARCHGOMIPSGOMIPS64GOPPC64GORISCV64GOWASMGO_LDSOGetgoextlinkenabledGoarm64FeaturesGoarmFeaturesParseGOEXPERIMENTParseGoarm64defaultGOARCHdefaultGOEXPERIMENTdefaultGOOSdefaultGO_EXTLINK_ENABLEDdefaultGO_LDSOexpListexperimentTagsgoamd64goarmgoarm64gofips140gogoarchTagsgomipsgomips64goppc64goriscv64gowasmgowasmFeaturesisFIPSVersionskipNumtoolTagsLSESupportsSatConvSignExtSoftFloatFieldTrackPreemptibleLoopsStaticLockRankingRegabiWrappersRegabiArgsHeapMinimum512KiBCoverageRedesignArenasCgoCheck2LoopVarCacheProgNewInlinerRangeFuncAliasTypeParamsSwissMapSpinbitMutexSyncHashTrieMapSynctestbuildcfginternal/buildcfgCompareStringCountStringCutoverHashStrHashStrRevIndexByteStringIndexRabinKarpIndexStringLastIndexByteStringLastIndexRabinKarpMakeNoZeroMaxBruteForcePrimeRKabigen_runtime_cmpstringabigen_runtime_memequalabigen_runtime_memequal_varlencountGenericcountGenericStringoffsetPPC64HasPOWER9offsetS390xHasVXoffsetX86HasAVX2offsetX86HasPOPCNToffsetX86HasSSE42bytealginternal/bytealgBEUint16LEAppendUint16LEAppendUint32LEAppendUint64LEPutUint16LEPutUint32LEUint32internal/byteorderblock_genericctrIncctrMaxerrUnmarshalChaCha8reseedInit64Refillchacha8randinternal/chacha8randAddMetaCovCounterBlobCovMetaBlobCountersPkgIDCounterModeCounterGranularityPkgMaphardCodedListNeedsUpdatingrtcovinternal/coverage/rtcovCacheLinePadSizeCacheLineSizeDebugOptionscpuid_ADXcpuid_AEScpuid_AVXcpuid_AVX2cpuid_AVX512BWcpuid_AVX512Fcpuid_AVX512VLcpuid_BMI1cpuid_BMI2cpuid_ERMScpuid_FMAcpuid_FSRMcpuid_OSXSAVEcpuid_PCLMULQDQcpuid_POPCNTcpuid_RDTSCPcpuid_SHAcpuid_SSE3cpuid_SSE41cpuid_SSE42cpuid_SSSE3getGOAMD64levelindexBytemaxExtendedFunctionInformationHasKDSAHasECDSAHasEDDSAHasFSRMHasRDTSCPHasSHAIsNeoverseIsPOWER10HasV7Atomicsinternal/cpuCleanFromSlashIsLocalIsPathSeparatorListSeparatorLocalizeToSlashVolumeNameVolumeNameLenerrInvalidPathisLocallazybuflocalizepostCleanreplaceStringByteunixIsLocalvolumeNameLenvolAndPathvolLenprependfilepathliteinternal/filepathliteSortedMapnilComparefmtsortinternal/fmtsortArchFamilyArchFamilyTypeDefaultPhysPageSizeI386Int64AlignIs386IsAmd64IsAmd64p32IsArmIsArm64IsArm64beIsArmbeIsLoong64IsMipsIsMips64IsMips64leIsMips64p32IsMips64p32leIsMipsleIsPpcIsPpc64IsPpc64leIsRiscvIsRiscv64IsS390IsS390xIsSparcIsSparc64IsWasmLOONG64MIPSMIPS64MinFrameSizePCQuantumPtrSizeStackAlignWASM_ArchFamily_DefaultPhysPageSize_MinFrameSize_PCQuantum_StackAligngoarchinternal/goarchnewIncNonDefaultregisterMetricruntimeStderrsetNewIncNonDefaultsetUpdateupdateMuinternal/godebuggodebugsinternal/godebugsAliasTypeParamsIntArenasIntBoringCryptoIntCacheProgIntCgoCheck2IntCoverageRedesignIntFieldTrackIntHeapMinimum512KiBIntLoopVarIntNewInlinerIntPreemptibleLoopsIntRangeFuncIntRegabiArgsIntRegabiWrappersIntSpinbitMutexIntStaticLockRankingIntSwissMapIntSyncHashTrieMapIntSynctestIntgoexperimentinternal/goexperimentIsAixIsAndroidIsDarwinIsDragonflyIsFreebsdIsHurdIsIllumosIsIosIsJsIsLinuxIsNaclIsNetbsdIsOpenbsdIsPlan9IsSolarisIsUnixIsWasip1IsZosgoosinternal/goosIsStandardPackagegccgoDirsgccgoSearchgdisStandardinternal/gorootCmpIntDecIntIsLangcutIntgoverinternal/govergoversioninternal/goversionUitoaUitoxinternal/itoainternal/lazyregexpMallocmsaninternal/msanLookupIPAltResolverKeyTraceKeynettraceinternal/nettraceErrExistErrNotExistErrPermissionoserrorinternal/oserrorASanSupportedBrokenBuildModeSupportedCgoSupportedDefaultPIEExecutableHasDWARFFirstClassFuzzInstrumentedFuzzSupportedInternalLinkPIESupportedMSanSupportedMustLinkExternalOSArchRaceDetectorSupporteddistInfoosArchInfointernal/platformAccept4FuncAcceptFuncCloseFuncDeadlineExceededErrorDupCloseOnExecErrDeadlineExceededErrFileClosingErrNetClosingErrNoDeadlineErrNotPollableIsPollDescriptorSendFileTestHookDidSendFileTestHookDidWritevconvertErrdestroyPipedupCloexecUnsupporteddupCloseOnExecOlderrClosingerrNetClosinggetPipehandleCopyFileRangeErrignoringEINTRignoringEINTR2ignoringEINTRIOisKernelVersionGE53maxCopyFileRangeRoundmaxRWmaxSpliceSizemutexClosedmutexRLockmutexRMaskmutexRWaitmutexRefmutexRefMaskmutexWLockmutexWMaskmutexWWaitnewIovecWithBasenewPipenewPoolPipeoverflowMsgpollErrClosingpollErrNotPollablepollErrTimeoutpollNoErrorputPiperuntimeNanoruntime_Semacquireruntime_Semreleaseruntime_isPollServerDescriptorruntime_pollCloseruntime_pollOpenruntime_pollResetruntime_pollServerInitruntime_pollSetDeadlineruntime_pollUnblockruntime_pollWaitruntime_pollWaitCanceledsendFilesendFileChunkserverInitsetDeadlineImplsplicespliceDrainspliceNonblocksplicePipesplicePipeFieldssplicePipePoolsplicePumpsupportCopyFileRangerfdwfdpollinternal/pollBlockProfileRecordMemProfileRecordStackRecordCyclesAllocBytesAllocObjectsFreeObjectsInUseBytesInUseObjectsprofilerecordinternal/profilerecordReadObjectPCReadPCReadRangeReleaseMergeWriteObjectPCWritePCWriteRangeraceinternal/raceSwapperarrayAtchanlendirectlyAssignabledummyescapesflagEmbedROflagIndirflagKindWidthflagMethodflagMethodShiftflagStickyROhaveIdenticalTypehaveIdenticalUnderlyingTypeifaceE2ImaplenmethodNamepackEfacepkgPathptrTyperesolveNameOffresolveTypeOffrtypetoRTypetoTypetypeOffuncommonTypeunpackEfaceunsafe_NewexportedMethodsreadVarintreflectliteinternal/reflectliteAnd32And64And8AnduintptrCas64CasRelCasint32Casint64Casp1CasuintptrLoadAcqLoadAcq64LoadAcquintptrLoadint32Loadint64LoadpLoaduintLoaduintptrOr32Or64Or8OruintptrStore8StoreRelStoreRel64StoreReluintptrStoreint32Storeint64StorepNoWBStoreuintptrXaddXadd64Xaddint32Xaddint64XadduintptrXchgXchg64Xchg8Xchgint32Xchgint64XchguintptrcasPointerpanicUnalignedstorePointerStoreNoWBCompareAndSwapNoWBLoadAcquireStoreReleaseCompareAndSwapReleaseatomicinternal/runtime/atomicGoidGoschedThrowexitErrorlockedrunGoidRunOnFailureexithookinternal/runtime/exithookNewEmptyMapalignUpalignUpPow2bitsetDeletedbitsetEmptybitsetFirstbitsetLowestSetbitsetMSBbitsetRemoveBelowbitsetShiftOutLowestctrlDeletedctrlGroupMatchEmptyctrlGroupMatchEmptyOrDeletedctrlGroupMatchFullctrlGroupMatchH2ctrlGroupsSizedepthToShifterrNilAssigngroupSlotsOffsetlocalDepthMasklongStringQuickEqualityTestmakeProbeSeqmapKeyErrormaxAvgGroupLoadmaxTableCapacitynewGroupsnewTablenewobjectprobeSeqruntime_mapaccess1runtime_mapaccess1_fast32runtime_mapaccess1_fast64runtime_mapaccess1_faststrruntime_mapaccess2runtime_mapaccess2_fast32runtime_mapaccess2_fast64runtime_mapaccess2_faststrruntime_mapassignruntime_mapassign_fast32runtime_mapassign_fast32ptrruntime_mapassign_fast64runtime_mapassign_fast64ptrruntime_mapassign_faststrruntime_mapdelete_fast32runtime_mapdelete_fast64runtime_mapdelete_faststrstringPtrzeroValinternal/runtime/mapsAdd64MaxUintptrMul64MulUintptrinternal/runtime/mathBswap32Bswap64DITEnabledDITSupportedDisableDITEnableDITGetCallerPCGetCallerSPGetClosurePtrLeadingZeros64LeadingZeros8Len64Len8OnesCount64PrefetchPrefetchStreamedStackGuardMultiplierTrailingZeros32TrailingZeros64TrailingZeros8deBruijn32deBruijn32tabdeBruijn64deBruijn64tabisRacelen8tabm0m1m2ntz8tabinternal/runtime/sysinternal/runtime/syscallReadDataReadDataAtSliceCapSliceCapWithSizesaferiointernal/saferiosingleflightinternal/singleflightstringsliteinternal/stringslitemutexLockedmutexStarvingmutexWaiterShiftmutexWokennChildrennChildrenLog2nChildrenMasknewEntryNodenewIndirectNoderuntime_SemacquireMutexruntime_canSpinruntime_doSpinruntime_nanotimestarvationThresholdNsthrowinternal/syncexecenvinternal/syscall/execenvEaccessFcntlGetRandomGetRandomFlagHasNonblockFlagIsNonblockNoFollowErrnoPidFDOpenPidFDSendSignalRecvfromInet4RecvfromInet6RecvmsgInet4RecvmsgInet6SendmsgNInet4SendmsgNInet6SendtoInet4SendtoInet6SiginfoChildTcsetpgrp_CLD_CONTINUED_CLD_DUMPED_CLD_EXITED_CLD_KILLED_CLD_STOPPED_CLD_TRAPPEDcontinuedcopyFileRangeTrapfstatatTrapgetrandomTrapgetrandomUnsupportedis64bitmkdiratTrapnoFollowErrnoopenat2TrapopenatTrappidfdOpenTrappidfdSendSignalTrapreadlinkatTrapsiErrnoCodeunlinkatTrapinternal/syscall/unixCPUNameosCPUInfoNamereadLinuxProcCPUInfosysinfointernal/sysinfoKnownArchKnownOSUnixOSsyslistinternal/syslistPanicOnExit0SetPanicOnExit0panicOnExit0testloginternal/testlogAmbiguousSelectorBadDotDotDotSyntaxBadImportPathBadOffsetofSyntaxBadRecvBadTypeKeywordBlankIfaceMethodBlankPkgNameBrokenImportCannotInferTypeArgsDivByZeroDuplicateCaseDuplicateDeclDuplicateDefaultDuplicateFieldAndMethodDuplicateLabelDuplicateLitFieldDuplicateLitKeyDuplicateMethodImportCRenamedImpossibleAssertIncomparableMapKeyIncompatibleAssignInvalidAppendInvalidArrayLenInvalidAssertInvalidBlankInvalidCallInvalidCapInvalidChanAssignInvalidClearInvalidCloseInvalidComplexInvalidCondInvalidConstInitInvalidConstTypeInvalidConstValInvalidConversionInvalidCopyInvalidDeclCycleInvalidDeferInvalidDeleteInvalidDotDotDotInvalidExprSwitchInvalidGoInvalidIfaceAssignInvalidImagInvalidIndexInvalidIndirectionInvalidInitCycleInvalidInitDeclInvalidInitSigInvalidInstanceCycleInvalidIotaInvalidIterVarInvalidLenInvalidLitInvalidLitFieldInvalidLitIndexInvalidMainDeclInvalidMakeInvalidMethodExprInvalidMethodTypeParamsInvalidMinMaxOperandInvalidOffsetofInvalidPkgUseInvalidPostDeclInvalidPtrEmbedInvalidRangeExprInvalidRealInvalidReceiveInvalidRecvInvalidSelectCaseInvalidSendInvalidShiftCountInvalidShiftOperandInvalidSliceExprInvalidStructLitInvalidSyntaxTreeInvalidTypeArgInvalidTypeCycleInvalidTypeSwitchInvalidUnionInvalidUnsafeAddInvalidUnsafeSliceInvalidUnsafeSliceDataInvalidUnsafeStringInvalidUntypedConversionJumpIntoBlockJumpOverDeclMismatchedPkgNameMismatchedTypesMisplacedBreakMisplacedConstraintIfaceMisplacedContinueMisplacedDotDotDotMisplacedFallthroughMisplacedLabelMisplacedTypeParamMissingFieldOrMethodMissingInitBodyMissingLitFieldMissingLitKeyMissingReturnMixedStructLitMultiValAssignOpNoNewVarNonIndexableOperandNonNumericIncDecNonSliceableOperandNonVariadicDotDotDotNotAGenericTypeNotATypeNotAnExprNumericOverflowOutOfScopeResultOversizeArrayLitRepeatedDeclSwappedMakeArgsSwappedSliceIndicesTooManyValuesTooNewTruncatedFloatTypeTooLargeUnaddressableFieldAssignUnaddressableOperandUnassignableOperandUncalledBuiltinUndeclaredImportedNameUndeclaredLabelUndeclaredNameUndefinedOpUnexportedLitFieldUnexportedNameUnsupportedFeatureUntypedLitUntypedNilUseUnusedExprUnusedImportUnusedLabelUnusedResultsUnusedVarWrongArgCountWrongAssignCountWrongResultCountWrongTypeArgCount_Code_index_1_Code_index_2_Code_index_3_Code_index_4_Code_index_5_Code_name_0_Code_name_1_Code_name_2_Code_name_3_Code_name_4_Code_name_527internal/types/errorsunsafeheaderinternal/unsafeheaderFileInfoToDirEntryFormatDirEntryFormatFileInfoGlobFSModeAppendModeCharDeviceModeDeviceModeDirModeExclusiveModeIrregularModeNamedPipeModePermModeSetgidModeSetuidModeSocketModeStickyModeSymlinkModeTemporaryModeTypePathErrorReadDirFSReadDirFileReadFileFSSkipAllSkipDirStatFSSubFSValidPathWalkDirWalkDirFunccleanGlobPathdirInfoerrExisterrNotExisterrPermissionglobglobWithLimithasMetasubFSfsysshortenfixErrio/fsNopCloserTempFileioutilio/ioutilCopyBufferCopyNErrClosedPipeErrNoProgressErrShortBufferErrShortWriteLimitReaderLimitedReaderMultiReaderNewOffsetWriterNewSectionReaderOffsetWriterReadAtLeastReadSeekCloserReadWriteSeekerReaderFromSeekCurrentSeekEndSeekStartStringWriterTeeReaderWriteSeekerWriterAtWriterToblackHolePoolcopyBuffererrInvalidWriteerrOffseterrWhencemultiReadernopClosernopCloserWriterToteeReaderwritersreaderswriteToWithBufferPullPull2corocoroswitchgoexitPanicValuenewcoroDefaultOutputlog/internallog/slog/internal/bufferIgnorePClog/slog/internalAnyValueDiscardHandlerDurationValueGroupValueHandlerOptionsJSONHandlerKindAnyKindBoolKindDurationKindFloat64KindGroupKindInt64KindLogValuerKindStringKindTimeKindUint64LevelVarLevelWarnLevelerNewJSONHandlerNewLogLoggerNewRecordNewTextHandlerSetDefaultSetLogLoggerLevelSourceKeyTextHandlerappendEscapedJSONStringappendJSONMarshalappendJSONTimeappendJSONValueappendRFC3339MillisappendTextValueargsToAttrargsToAttrSlicebadKeybyteSlicecountAttrscountEmptyGroupsdefaultHandlerdefaultLoggerdiscardHandlergroupPoolgroupptrhandleStatehandlerWriterkeyComponentSepkindStringslogLoggerLevelmaxLogValuesnAttrsInlinenewDefaultHandlertimeLocationtimeTimeAddSourceReplaceAttrpreformattedAttrsnOpenGroupswithAttrswithGroupattrSepnewHandleStatefreeBufappendNonBuiltInsopenGroupsopenGroupcloseGroupappendAttrsappendAttrappendKeyappendTimecapturePCsloglog/slogLUTCLdateLlongfileLmicrosecondsLmsgprefixLshortfileLstdFlagsLtimeformatHeaderputBufferDeleteFuncEqualFuncV1M1M2AboveAwayFromZeroBelowErrNaNJacobiMaxBaseMaxExpMaxPrecMinExpNewRatToNearestAwayToNearestEvenToNegativeInfToPositiveInfToZero_Accuracy_index_Accuracy_name_B_M_RoundingMode_index_RoundingMode_nameaddAtaddMulVVW_gaddVVaddVV_gaddVWaddVW_gaddVWlargeappendZerosbasicMulbasicSqrbasicSqrThresholdbigEndianWordcacheBase10debugFloatdivRecursiveThresholddivWVWdivWWdivisorserrInvalSeperrNoDigitseuclidUpdatefinitefloatGobVersionfloatZerofmtEfmtFfnormgetNatgreaterThaninfintGobVersionintOnekaratsubakaratsubaAddkaratsubaLenkaratsubaSqrkaratsubaSqrThresholdkaratsubaSubkaratsubaThresholdleafSizelehmerSimulatelehmerUpdatelow32low64makeAccmaxBaseSmallmaxPowmaxShiftmsb32msb64mulAddVWWmulAddVWW_gmulAddWWW_gmulDenommulWWnatFivenatOnenatPoolnatTennatTwonlzpowpow5tabputNatquotToFloat32quotToFloat64ratGobVersionratTokratZeroreciprocalWordroundShortestsamescanExponentscanSignshlVUshlVU_gshouldRoundUpshrVUshrVU_gsubVVsubVV_gsubVWsubVW_gsubVWlargesupport_adxthreethreeOnceumax32validateBinaryOperandswriteMultipleroundDownAdd32Div32Div64LeadingZerosLeadingZeros16LeadingZeros32Len16Len32Mul32OnesCountOnesCount16OnesCount32OnesCount8Rem32Rem64Reverse16Reverse32Reverse64Reverse8ReverseBytesReverseBytes16ReverseBytes32ReverseBytes64RotateLeftRotateLeft16RotateLeft32RotateLeft64RotateLeft8Sub32Sub64TrailingZerosTrailingZeros16UintSizedivideErrorm3m4overflowErrorpop8tabrev8tabmath/bitsChaCha8Int32NInt64NIntNNewChaCha8NewPCGNewZipfPCGUint32NUint64NUintNZipfabsInt32cutPrefixerrUnmarshalPCGglobalRandkeknrnruntimeSourcewewnuint64nuint32nimaxoneminusQoneminusQinvhxmhx0minusHxmhinvreadLenmath/rand/v2NewSourceglobalRandGeneratorint32maxlockedSourcenewSourcerandautoseedrandseednoprngCookedrngLenrngMaskrngMaxrngSourcerngTapseedrand607taplkseedPosAcosAcoshAsinAsinhAtanAtan2AtanhCbrtCeilCopysignCosCoshErfErfcErfcinvErfinvExp2Expm1FMAFloat32bitsFloat32frombitsFloat64bitsFloat64frombitsFloorFrexpGammaHypotIlogbJ0JnLdexpLgammaLn10Ln2Log10ELog1pLog2ELogbMaxFloat32MaxFloat64MaxIntMaxInt16MaxInt32MaxInt64MaxInt8MaxUintMaxUint16MaxUint32MaxUint64MaxUint8MinIntMinInt16MinInt32MinInt64MinInt8ModfNextafterNextafter32PhiPiPow10RemainderRoundToEvenSincosSinhSmallestNonzeroFloat32SmallestNonzeroFloat64SqrtESqrtPhiSqrtPiTanTanhTruncY0Y1Yn_cos_gamP_gamQ_gamS_lgamA_lgamR_lgamS_lgamT_lgamU_lgamV_lgamW_sin_tanP_tanQa0a6a7acosacosharchAcosarchAcosharchAsinarchAsinharchAtanarchAtan2archAtanharchCbrtarchCeilarchCosarchCosharchErfarchErfcarchExparchExp2archExpm1archFloorarchFrexparchHypotarchLdexparchLogarchLog10archLog1parchLog2archMaxarchMinarchModarchModfarchPowarchRemainderarchSinarchSinharchTanarchTanharchTruncasinasinhatanatan2atanhb0b1b2b3b4b5b6b7biasc0c1c2c3c4c5c6c7cbrtceilcoscoshd0d1d3d4d5d6d7e0e1e2e3e4e5e6e7efxefx8erfcerxexp2expm1expmultif0f1f2f3f4f5f6f7floorfracMaskfrexphaveArchAcoshaveArchAcoshhaveArchAsinhaveArchAsinhhaveArchAtanhaveArchAtan2haveArchAtanhhaveArchCbrthaveArchCeilhaveArchCoshaveArchCoshhaveArchErfhaveArchErfchaveArchExphaveArchExp2haveArchExpm1haveArchFloorhaveArchFrexphaveArchHypothaveArchLdexphaveArchLoghaveArchLog10haveArchLog1phaveArchLog2haveArchMaxhaveArchMinhaveArchModhaveArchModfhaveArchPowhaveArchRemainderhaveArchSinhaveArchSinhhaveArchTanhaveArchTanhhaveArchTrunchypotilogbisNegIntisOddIntldexplog10log1plzmPi4modfnonzerop0R2p0R3p0R5p0R8p0S2p0S3p0S5p0S8p1R2p1R3p1R5p1R8p1S2p1S3p1S5p1S8pa0pa1pa2pa3pa4pa5pa6ponepow10negtab32pow10postab32pow10tabpp0pp1pp2pp3pp4pzeroq0R2q0R3q0R5q0R8q0S2q0S3q0S5q0S8q1R2q1R3q1R5q1R8q1S2q1S3q1S5q1S8qa1qa2qa3qa4qa5qa6qoneqq1qq2qq3qq4qq5qzerora0ra1ra2ra3ra4ra5ra6ra7rb0rb1rb2rb3rb4rb5rb6reduceThresholdremaindersa1sa2sa3sa4sa5sa6sa7sa8satansb1sb2sb3sb4sb5sb6sb7shrcompresssignMasksinsinPisinhstirlingtantanhtanhPtanhQtrigReduceuseFMAuvinfuvnanuvneginfuvonexatanErrMessageTooLargeemptyParamsmatchAfterPrefixmaxMIMEHeaderSizemaxMIMEHeadersmimeHeaderSizemultipartfilesmultipartmaxheadersmultipartmaxpartsnewPartpartReaderpeekBufferSizerandomBoundaryreadMIMEHeaderscanUntilBoundarysectionReadCloserskipLWSPCharstickyErrorReaderboundarylastpartBoundarySetBoundaryFormDataContentTypeCreatePartCreateFormFileCreateFormFielddotReaderReadLineBytesreadLineSliceReadContinuedLineReadContinuedLineBytesreadContinuedLineSlicereadCodeLineReadCodeLineReadResponseDotReadercloseDotReadDotBytesReadDotLinesReadMIMEHeaderupcomingHeaderKeysfromHexisQPDiscardWhitespacelflineMaxLenreadHexBytesoftSuffixupperhex78checkLastByteinsertSoftLineBreakinsertCRLFquotedprintablemime/quotedprintableAddExtensionTypeBEncodingErrInvalidMediaParameterExtensionsByTypeFormatMediaTypeParseMediaTypeQEncodingTypeByExtensionWordDecoderWordEncoderbuiltinTypesLowercheckMediaTypeDispositioncloseWordconsumeMediaParamconsumeValuedecode2231EncerrInvalidWordextensionsMuhasNonWhitespaceinitMimeinitMimeForTestsinitMimeUnixisNotTokenCharisTSpecialisTokenCharishexloadMimeFileloadMimeGlobsFilemaxBase64LenmaxContentLenmaxEncodedWordLenmimeGlobsmimeTypesmimeTypesLowerneedsEncodingosInitMimepercentHexUnescapeqDecodesetExtensionTypesetMimeTypestestInitMimetypeFilesunhexwriteQStringencodeWordbEncodeqEncodeopenWordsplitWordDecodeHeaderDefaultRemoteAddrNewRecorderNewTLSServerNewUnstartedServerResponseRecordercloseIdleTransportnewLocalListenerparseContentLengthserveFlagstrSliceContainsPrefixHeaderMapContextClientTraceclientEventContextKeyhttptracenet/http/httptraceDumpRequestDumpRequestOutDumpResponseErrLineTooLongErrPersistEOFErrPipelineNewChunkedReaderNewChunkedWriterNewProxyClientConnNewSingleHostReverseProxyProxyRequestReverseProxycleanQueryParamscopyHeaderdelegateReaderdrainBodydumpConnemptyBodyerrNoBodyfailureToReadBodyhopHeadersinOurTestsjoinURLPathmaxLatencyWriterneverEndingremoveHopByHopHeadersreqWriteExcludeHeaderDumprewriteRequestURLshouldPanicOnCopyErrorsingleJoiningSlashswitchProtocolCopierupgradeTypevalueOrDefaultProtocolErrorErrorStringStartRequestEndRequestStartResponseEndResponselastbodynreadnwrittenpipereqwriteReqSetURLSetXForwardedRewriteDirectorModifyResponsegetErrorHandlermodifyResponsecopyResponsehandleUpgradeResponsecopyFromBackendcopyToBackendflushPendingdelayedFlushnet/http/httputilIsPrintnet/http/internal/asciiLocalhostCertLocalhostKeytestingKeytestcertnet/http/internal/testcertFlushAfterChunkWriterchunkedReaderchunkedWritermaxLineLengthparseHexUintreadChunkLineremoveChunkExtensionsemitrimTrailingWhitespacecheckEndexcessbeginChunkchunkHeaderAvailablenet/http/internalAllowQuerySemicolonsCanonicalHeaderKeyDefaultMaxHeaderBytesDefaultMaxIdleConnsPerHostDefaultServeMuxDefaultTransportErrAbortHandlerErrBodyNotAllowedErrBodyReadAfterCloseErrContentLengthErrHandlerTimeoutErrHeaderTooLongErrHijackedErrMissingBoundaryErrMissingContentLengthErrMissingFileErrNoCookieErrNoLocationErrNotMultipartErrSchemeMismatchErrShortBodyErrSkipAltProtocolErrUnexpectedTrailerErrUseLastResponseErrWriteAfterFlushFileServerFileServerFSHandleFuncLocalAddrContextKeyMaxBytesHandlerMethodConnectMethodHeadMethodOptionsMethodPatchMethodTraceNewFileTransportNewFileTransportFSNewResponseControllerNewServeMuxNotFoundHandlerParseCookieParseHTTPVersionParseSetCookieParseTimeProxyFromEnvironmentProxyURLReadRequestRedirectHandlerResponseControllerSameSiteDefaultModeSameSiteLaxModeSameSiteNoneModeSameSiteStrictModeServeContentServeFileServeFileFSServeMuxServerContextKeyStateActiveStateHijackedStateNewStatusAlreadyReportedStatusContinueStatusEarlyHintsStatusExpectationFailedStatusGoneStatusHTTPVersionNotSupportedStatusIMUsedStatusLengthRequiredStatusLoopDetectedStatusMethodNotAllowedStatusMisdirectedRequestStatusMovedPermanentlyStatusMultiStatusStatusMultipleChoicesStatusNetworkAuthenticationRequiredStatusNoContentStatusNonAuthoritativeInfoStatusNotAcceptableStatusNotExtendedStatusNotModifiedStatusPartialContentStatusPaymentRequiredStatusPermanentRedirectStatusPreconditionFailedStatusPreconditionRequiredStatusProcessingStatusProxyAuthRequiredStatusRequestEntityTooLargeStatusRequestHeaderFieldsTooLargeStatusRequestTimeoutStatusRequestURITooLongStatusRequestedRangeNotSatisfiableStatusResetContentStatusSeeOtherStatusSwitchingProtocolsStatusTeapotStatusTooEarlyStatusUnavailableForLegalReasonsStatusUnsupportedMediaTypeStatusUpgradeRequiredStatusUseProxyStatusVariantAlsoNegotiatesStripPrefixTimeFormatTimeoutHandleraLongTimeAgoadjustNextProtosanyDirsappendSortedawaitLegacyCancelbadRequestErrorbadRoundTripbadServeHTTPbadStringErrorbodyEOFSignalbodyLockedbufferBeforeChunkingSizebufioFlushWriterbufioReaderPoolbufioWriter2kPoolbufioWriter4kPoolbufioWriterPoolcancelTimerBodycanonicalAddrcheckConnErrorWritercheckIfMatchcheckIfModifiedSincecheckIfNoneMatchcheckIfRangecheckIfUnmodifiedSincecheckPreconditionschunkedcloneMultipartFileHeadercloneMultipartFormcloneOrMakeHeadercloneURLcloseWritercolonSpacecombineRelationshipscommonPathcompareSegmentscondFalsecondNonecondResultcondTruecontainsDotDotcookieNameSanitizercookieNumWithinMaxcopyBufPoolcopyBufPoolSizecopyValuescountingWriterdebugServerConnectionsdefaultCheckRedirectdefaultCookieMaxNumdefaultMaxMemorydefaultServeMuxdefaultTransportDialContextdescribeConflictdifferencePathdirEntryDirsdirListdoubleCRLFenvProxyFuncenvProxyFuncValueenvProxyOnceerrBlankCookieerrCallerOwnsConnerrCannotRewinderrCloseIdleerrCloseIdleConnserrConnBrokenerrCookieNumLimitExceedederrEqualNotFoundInCookieerrIdleConnTimeouterrInvalidCookieNameerrInvalidCookieValueerrKeepAlivesDisablederrMissingHosterrMissingReadDirerrMissingSeekerrNoOverlaperrNotSupportederrReadLoopExitingerrReadOnClosedResBodyerrRequestCanceledConnerrRequestDoneerrSeekererrServerClosedIdleerrTooLargeerrTooManyIdleerrTooManyIdleHosterrTrailerEOFetagStrongMatchetagWeakMatchexactSigexcludedHeadersNoBodyexpectContinueReaderextraHeaderextraHeaderKeysfakeLockerfileHandlerfileInfoDirsfileTransportfinishAsyncByteReadfirstSegmentfixLengthfixPragmaCacheControlfixTrailergetCopyBufglobalOptionsHandlerhasPorthasTokenheaderContentLengthheaderDateheaderNewlineToSpaceheaderSorterPoolhexEscapeNonASCIIhtmlEscapehtmlSighttp1ServerSupportsRequesthttp2ClientConnhttp2ClientConnPoolhttp2ClientConnStatehttp2ClientPrefacehttp2ConfigureServerhttp2ConfigureTransporthttp2ConfigureTransportshttp2ConnectionErrorhttp2ContinuationFramehttp2DataFramehttp2DebugGoroutineshttp2ErrCodehttp2ErrCodeCancelhttp2ErrCodeCompressionhttp2ErrCodeConnecthttp2ErrCodeEnhanceYourCalmhttp2ErrCodeFlowControlhttp2ErrCodeFrameSizehttp2ErrCodeHTTP11Requiredhttp2ErrCodeInadequateSecurityhttp2ErrCodeInternalhttp2ErrCodeNohttp2ErrCodeProtocolhttp2ErrCodeRefusedStreamhttp2ErrCodeSettingsTimeouthttp2ErrCodeStreamClosedhttp2ErrFrameTooLargehttp2ErrNoCachedConnhttp2ErrPushLimitReachedhttp2ErrRecursivePushhttp2FlagContinuationEndHeadershttp2FlagDataEndStreamhttp2FlagDataPaddedhttp2FlagHeadersEndHeadershttp2FlagHeadersEndStreamhttp2FlagHeadersPaddedhttp2FlagHeadersPriorityhttp2FlagPingAckhttp2FlagPushPromiseEndHeadershttp2FlagPushPromisePaddedhttp2FlagSettingsAckhttp2Flagshttp2Framehttp2FrameContinuationhttp2FrameDatahttp2FrameGoAwayhttp2FrameHeaderhttp2FrameHeadershttp2FramePinghttp2FramePriorityhttp2FramePushPromisehttp2FrameRSTStreamhttp2FrameSettingshttp2FrameTypehttp2FrameWindowUpdatehttp2FrameWriteRequesthttp2Framerhttp2GoAwayErrorhttp2GoAwayFramehttp2HeadersFramehttp2HeadersFrameParamhttp2MetaHeadersFramehttp2NewFramerhttp2NewPriorityWriteSchedulerhttp2NewRandomWriteSchedulerhttp2NextProtoTLShttp2OpenStreamOptionshttp2PingFramehttp2PriorityFramehttp2PriorityParamhttp2PriorityWriteSchedulerConfighttp2PushPromiseFramehttp2PushPromiseParamhttp2RSTStreamFramehttp2ReadFrameHeaderhttp2RoundTripOpthttp2ServeConnOptshttp2Serverhttp2Settinghttp2SettingEnableConnectProtocolhttp2SettingEnablePushhttp2SettingHeaderTableSizehttp2SettingIDhttp2SettingInitialWindowSizehttp2SettingMaxConcurrentStreamshttp2SettingMaxFrameSizehttp2SettingMaxHeaderListSizehttp2SettingsFramehttp2StreamErrorhttp2TrailerPrefixhttp2Transporthttp2UnknownFramehttp2WindowUpdateFramehttp2WriteSchedulerhttp2actualContentLengthhttp2addConnCallhttp2adjustHTTP1MaxHeaderSizehttp2asciiEqualFoldhttp2asciiToLowerhttp2authorityAddrhttp2bodyAllowedForStatushttp2bodyReadMsghttp2bufPoolIndexhttp2bufPoolshttp2bufWriterPoolhttp2bufWriterPoolBufferSizehttp2bufferedWriterhttp2bufferedWriterTimeoutWriterhttp2buildCommonHeaderMapshttp2buildCommonHeaderMapsOncehttp2canRetryErrorhttp2canonicalHeaderhttp2checkConnHeadershttp2checkValidHTTP2RequestHeadershttp2checkWriteHeaderCodehttp2chunkWriterhttp2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256http2cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256http2cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHAhttp2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHAhttp2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256http2cipher_TLS_DHE_PSK_WITH_AES_128_CCMhttp2cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384http2cipher_TLS_DHE_PSK_WITH_AES_256_CCMhttp2cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_DHE_PSK_WITH_NULL_SHAhttp2cipher_TLS_DHE_PSK_WITH_NULL_SHA256http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHAhttp2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_DHE_RSA_WITH_AES_128_CCMhttp2cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8http2cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256http2cipher_TLS_DHE_RSA_WITH_AES_256_CCMhttp2cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8http2cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHAhttp2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHAhttp2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHAhttp2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHAhttp2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHAhttp2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHAhttp2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_DH_anon_WITH_DES_CBC_SHAhttp2cipher_TLS_DH_anon_WITH_RC4_128_MD5http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHAhttp2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCMhttp2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCMhttp2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHAhttp2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHAhttp2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHAhttp2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHAhttp2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384http2cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHAhttp2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHAhttp2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHAhttp2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHAhttp2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_ECDH_RSA_WITH_NULL_SHAhttp2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHAhttp2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHAhttp2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHAhttp2cipher_TLS_ECDH_anon_WITH_NULL_SHAhttp2cipher_TLS_ECDH_anon_WITH_RC4_128_SHAhttp2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSVhttp2cipher_TLS_FALLBACK_SCSVhttp2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHAhttp2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHAhttp2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHAhttp2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_KRB5_WITH_DES_CBC_MD5http2cipher_TLS_KRB5_WITH_DES_CBC_SHAhttp2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHAhttp2cipher_TLS_KRB5_WITH_RC4_128_MD5http2cipher_TLS_KRB5_WITH_RC4_128_SHAhttp2cipher_TLS_NULL_WITH_NULL_NULLhttp2cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8http2cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_PSK_WITH_AES_128_CBC_SHAhttp2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256http2cipher_TLS_PSK_WITH_AES_128_CCMhttp2cipher_TLS_PSK_WITH_AES_128_CCM_8http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256http2cipher_TLS_PSK_WITH_AES_256_CBC_SHAhttp2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384http2cipher_TLS_PSK_WITH_AES_256_CCMhttp2cipher_TLS_PSK_WITH_AES_256_CCM_8http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_PSK_WITH_NULL_SHAhttp2cipher_TLS_PSK_WITH_NULL_SHA256http2cipher_TLS_PSK_WITH_NULL_SHA384http2cipher_TLS_PSK_WITH_RC4_128_SHAhttp2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHAhttp2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHAhttp2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHAhttp2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256http2cipher_TLS_RSA_PSK_WITH_NULL_SHAhttp2cipher_TLS_RSA_PSK_WITH_NULL_SHA256http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHAhttp2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256http2cipher_TLS_RSA_WITH_AES_128_CCMhttp2cipher_TLS_RSA_WITH_AES_128_CCM_8http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256http2cipher_TLS_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256http2cipher_TLS_RSA_WITH_AES_256_CCMhttp2cipher_TLS_RSA_WITH_AES_256_CCM_8http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHAhttp2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHAhttp2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384http2cipher_TLS_RSA_WITH_DES_CBC_SHAhttp2cipher_TLS_RSA_WITH_IDEA_CBC_SHAhttp2cipher_TLS_RSA_WITH_NULL_MD5http2cipher_TLS_RSA_WITH_NULL_SHAhttp2cipher_TLS_RSA_WITH_NULL_SHA256http2cipher_TLS_RSA_WITH_RC4_128_MD5http2cipher_TLS_RSA_WITH_RC4_128_SHAhttp2cipher_TLS_RSA_WITH_SEED_CBC_SHAhttp2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHAhttp2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHAhttp2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHAhttp2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHAhttp2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHAhttp2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHAhttp2clienthttp2clientConnIdleStatehttp2clientConnPoolhttp2clientConnPoolIdleCloserhttp2clientConnReadLoophttp2clientPrefacehttp2clientStreamhttp2cloneHeaderhttp2closeWaiterhttp2commaSeparatedTrailershttp2commonBuildOncehttp2commonCanonHeaderhttp2commonLowerHeaderhttp2configFromServerhttp2configFromTransporthttp2configureTransportshttp2connErrorhttp2connHeadershttp2connectionStaterhttp2curGoroutineIDhttp2cutoff64http2dataBufferhttp2dataChunkPoolshttp2defaultMaxConcurrentStreamshttp2defaultMaxReadFrameSizehttp2defaultMaxStreamshttp2defaultUserAgenthttp2dialCallhttp2dialOnMisshttp2disableExtendedConnectProtocolhttp2duplicatePseudoHeaderErrorhttp2encKVhttp2encodeHeadershttp2errChanPoolhttp2errClientConnClosedhttp2errClientConnGotGoAwayhttp2errClientConnNotEstablishedhttp2errClientConnUnusablehttp2errClientDisconnectedhttp2errClosedBodyhttp2errClosedPipeWritehttp2errClosedResponseBodyhttp2errCodeNamehttp2errDepStreamIDhttp2errExtendedConnectNotSupportedhttp2errFromPeerhttp2errHandlerCompletehttp2errHandlerPanickedhttp2errMixPseudoHeaderTypeshttp2errNilRequestURLhttp2errPadByteshttp2errPadLengthhttp2errPrefaceTimeouthttp2errPseudoAfterRegularhttp2errReadEmptyhttp2errReqBodyTooLonghttp2errRequestCanceledhttp2errRequestHeaderListSizehttp2errResponseHeaderListSizehttp2errStopReqBodyWritehttp2errStopReqBodyWriteAndCancelhttp2errStreamClosedhttp2errStreamIDhttp2errTimeouthttp2errUninitializedPipeWritehttp2erringRoundTripperhttp2errnohttp2errorReaderhttp2fhByteshttp2fillNetHTTPConfighttp2fillNetHTTPServerConfighttp2fillNetHTTPTransportConfighttp2filterOutClientConnhttp2firstSettingsTimeouthttp2flagNamehttp2flushFrameWriterhttp2foreachHeaderElementhttp2frameCachehttp2frameHeaderLenhttp2frameNamehttp2frameParserhttp2frameParsershttp2frameWriteResulthttp2getDataBufferChunkhttp2goAwayFlowErrorhttp2goAwayTimeouthttp2goroutineLockhttp2goroutineSpacehttp2got1xxFuncForTestshttp2gracefulShutdownMsghttp2gzipReaderhttp2h1ServerKeepAlivesDisabledhttp2handleHeaderListTooLonghttp2handlerChunkWriteSizehttp2handlerDoneMsghttp2handlerPanicRSThttp2headerFieldNameErrorhttp2headerFieldValueErrorhttp2headerOrDataFramehttp2headersEnderhttp2headersOrContinuationhttp2http2Confighttp2httpCodeStringhttp2httpErrorhttp2idleTimerMsghttp2inTestshttp2incomparablehttp2inflowhttp2inflowMinRefreshhttp2initialHeaderTableSizehttp2initialMaxConcurrentStreamshttp2initialMaxFrameSizehttp2initialWindowSizehttp2isASCIIPrinthttp2isBadCipherhttp2isClosedConnErrorhttp2isConnectionCloseRequesthttp2isEOFOrNetReadErrorhttp2isNoCachedConnErrorhttp2littleBufhttp2logFrameReadshttp2logFrameWriteshttp2lowerhttp2lowerHeaderhttp2maxCachedCanonicalHeadersKeysSizehttp2maxFrameSizehttp2maxQueuedControlFrameshttp2minMaxFrameSizehttp2missingBodyhttp2mustUint31http2new400Handlerhttp2newBufferedWriterhttp2newGoroutineLockhttp2newRoundRobinWriteSchedulerhttp2nextProtoUnencryptedHTTP2http2noBodyhttp2noBodyReaderhttp2noCachedConnErrorhttp2noDialClientConnPoolhttp2noDialH2RoundTripperhttp2noDialOnMisshttp2notHeaderOrDataFramehttp2outflowhttp2padZeroshttp2parseContinuationFramehttp2parseDataFramehttp2parseGoAwayFramehttp2parseHeadersFramehttp2parsePingFramehttp2parsePriorityFramehttp2parsePushPromisehttp2parseRSTStreamFramehttp2parseSettingsFramehttp2parseUintByteshttp2parseUnknownFramehttp2parseWindowUpdateFramehttp2pipehttp2pipeBufferhttp2prefaceTimeouthttp2priorityDefaultWeighthttp2priorityNodehttp2priorityNodeClosedhttp2priorityNodeIdlehttp2priorityNodeOpenhttp2priorityNodeStatehttp2priorityWriteSchedulerhttp2pseudoHeaderErrorhttp2putDataBufferChunkhttp2randomWriteSchedulerhttp2readBytehttp2readFrameHeaderhttp2readFrameResulthttp2readIdleTimerMsghttp2readUint32http2registerHTTPSProtocolhttp2requestBodyhttp2requestParamhttp2resAndErrorhttp2responseWriterhttp2responseWriterStatehttp2responseWriterStatePoolhttp2roundRobinWriteSchedulerhttp2serverhttp2serverConnhttp2serverConnBaseContexthttp2serverInternalStatehttp2serverMessagehttp2setConfigDefaultshttp2setDefaulthttp2settingNamehttp2settingsTimerMsghttp2shouldRetryDialhttp2shouldRetryRequesthttp2shouldSendReqContentLengthhttp2shutdownEnterWaitStateHookhttp2shutdownTimerMsghttp2sortPriorityNodeSiblingshttp2sorterhttp2sorterPoolhttp2splitHeaderBlockhttp2startPushRequesthttp2stateClosedhttp2stateHalfClosedLocalhttp2stateHalfClosedRemotehttp2stateIdlehttp2stateNamehttp2stateOpenhttp2stickyErrWriterhttp2strSliceContainshttp2streamhttp2streamEnderhttp2streamErrorhttp2streamStatehttp2stringWriterhttp2summarizeFramehttp2synctestGroupInterfacehttp2takeInflowshttp2terminalReadFrameErrorhttp2testHookGetServerConnhttp2testHookOnConnhttp2testHookOnPanichttp2testHookOnPanicMuhttp2timeTimerhttp2timerhttp2traceFirstResponseBytehttp2traceGetConnhttp2traceGot100Continuehttp2traceGot1xxResponseFunchttp2traceGotConnhttp2traceHasWroteHeaderFieldhttp2traceWait100Continuehttp2traceWroteHeaderFieldhttp2traceWroteHeadershttp2traceWroteRequesthttp2transportDefaultConnFlowhttp2transportDefaultStreamFlowhttp2transportResponseBodyhttp2transportTestHookshttp2typeFrameParserhttp2unencryptedNetConnFromTLSConnhttp2unencryptedTransporthttp2unstartedHandlerhttp2validPseudoPathhttp2validStreamIDhttp2validStreamIDOrZerohttp2validWireHeaderFieldNamehttp2validateHeadershttp2write100ContinueHeadersFramehttp2writeContexthttp2writeDatahttp2writeDataPoolhttp2writeEndsStreamhttp2writeFramerhttp2writeGoAwayhttp2writePinghttp2writePingAckhttp2writePushPromisehttp2writeQueuehttp2writeQueuePoolhttp2writeResHeadershttp2writeSettingshttp2writeSettingsAckhttp2writeWindowUpdatehttp2writeWithByteTimeouthttpRangehttpcookiemaxnumhttplaxcontentlengthhttpmuxgo121httpservecontentkeepheadersidnaASCIIidnaASCIIFromURLinitALPNRequestinverseRelationshipioFSioFileis408MessageisCommonNetReadErrorisCookieDomainNameisCookieNameValidisDomainOrSubdomainisIdentityisKnownInMemoryReaderisLitOrSingleisNotTokenisProtocolSwitchHeaderisProtocolSwitchResponseisSlashRuneisTTisTokenBoundaryisUnsupportedTEErrorisValidWildcardNameisZeroTimeknownRoundTripperImpllocalRedirectloggingConnmapOpenErrormaskedSigmaxBytesReadermaxInt64maxPostHandlerReadBytesmaxSlicemaxWriteWaitBeforeConnReusemergeSetHeadermoreGeneralmoreSpecificmp4Sigmp4ftypemultipartByReadermuxEntrynewBufioReadernewBufioWriterSizenewLoggingConnnewPopulateResponseWriternewReadWriteCloserBodynewTextprotoReadernewTransferWriternoResponseBodyExpectednopCloserTypenopCloserWriterToTypenothingWrittenErrornumLeadingCRorLFomitBundledHTTP2onceCloseListeneroverlapsparseBasicAuthparseCookieValueparsePatternparsePostFormparseRequestLinepersistConnWriterpopulateResponseportMapprotoHTTP1protoHTTP2protoUnencryptedHTTP2putBufioReaderputBufioWriterputCopyBufputTextprotoReaderrangesMIMESizereadCookiesreadSetCookiesreadTrackingBodyreadTransferreadWriteCloserBodyredirectBehaviorredirectHandlerrefererForURLregisterOnHitEOFrelevantCallerremoveEmptyPortremoveZonereqWriteExcludeHeaderrequestBodyReadErrorrequestBodyRemainsrequestMethodUsuallyLacksBodyresetProxyConfigrespExcludeHeaderrewindBodyroutingIndexroutingIndexKeyroutingNoderstAvoidanceDelayrunHooksrwUnwrappersanitizeCookieNamesanitizeCookiePathsanitizeCookieValuesanitizeOrWarnscanETagseeUpcomingDoubleCRLFserveContentserveFileserveMux121serverHandlersetLastModifiedsetRequestCancelsetupRewindBodyshouldCloseshouldCopyHeaderOnRedirectshutdownPollIntervalMaxsingleCRLFskipHookssniffLensniffSigsniffSignaturessocksAddrsocksAddrTypeFQDNsocksAddrTypeIPv4socksAddrTypeIPv6socksAuthMethodsocksAuthMethodNoAcceptableMethodssocksAuthMethodNotRequiredsocksAuthMethodUsernamePasswordsocksCmdConnectsocksCommandsocksConnsocksDialersocksNewDialersocksReplysocksStatusSucceededsocksUsernamePasswordsocksVersion5socksaLongTimeAgosocksauthStatusSucceededsocksauthUsernamePasswordVersionsockscmdBindsocksnoDeadlinesockssplitHostPortstatusErrorstringContainsCTLBytestripHostPortstripPasswordsumRangesSizesuppressedHeaderssuppressedHeaders304suppressedHeadersNoBodytLogKeytestHookClientDoResulttestHookEnterRoundTriptestHookMutestHookPostPendingDialtestHookPrePendingDialtestHookProxyConnectTimeouttestHookReadLoopBeforeNextReadtestHookRoundTripRetriedtestHookServerServetestHookWaitResLooptextSigtextprotoReaderPooltimeBeforeContextDeadlinetimeFormatstimeoutHandlertimeoutWritertlsHandshakeTimeoutErrortlsRecordHeaderLooksLikeHTTPtoHTTPErrortransferReadertransferWritertransportReadFromServerErrorunencryptedHTTP2RequestunencryptedNetConnInTLSConnunencryptedTLSConnuniqNameMuuniqNameNextunsupportedTEErrorunwrapNopCloserurlErrorOpuse121validCookieDomainvalidCookieExpiresvalidCookiePathBytevalidCookieValueBytevalidMethodvalidNextProtowriteMatchingPathwriteNotModifiedwriteSegmentwriteStatusLinewriterOnlyzeroDialereachPairmultiChildemptyChildaddPatternaddSegmentsfindChildmatchMethodAndPathmatchPathmatchingMethodsmatchingMethodsPathmultispossiblyConflictingPatternshostshandleFuncfindHandlerredirectToPathSlashshouldRedirectRLockedmux121matchOrRedirectregisterErrnet/http.invalidatenet/http.staysWithinBuffernet/http.writeFramenet/http.matchcontentRangemimeHeaderskipWSproxyNetworkproxyAddressProxyDialAuthMethodsDialWithConnvalidateTargetpathAddrsearlyCloseFncondfnBodyCloserResponseToHEADIsResponsebodyReadErrorFlushHeadersByteReadChshouldSendChunkedRequestBodyprobeRequestBodyshouldSendContentLengthwriteBodydoBodyCopyunwrapBodynet/http.closeIdleConnectionsecrdoEarlyCloseearlyCloseonHitEOFreadLockedreadTrailerunreadDataSizeLockeddidEarlyClosebodyRemainsreqDidTimeouthasContentsentResponsepwsendResponseUnencryptedNetConndidReaddidClosewriteHeaderLockedtransferEncodingRequestMethodChunkedprotoAtLeastparseTransferEncodingboundAddrBoundAddroctestContexterrorBodyauthoritynweusterhnet/http.isDirnet/http.lennet/http.nameAddrFrom16AddrFrom4AddrFromSliceAddrPortFromIPv4UnspecifiedIPv6LinkLocalAllNodesIPv6LinkLocalAllRoutersIPv6LoopbackIPv6UnspecifiedMustParseAddrMustParseAddrPortMustParsePrefixParseAddrParseAddrPortParsePrefixPrefixFromaddrDetailappendDecimalappendHexappendHexPadmask6parseAddrErrorparseIPv4parseIPv4FieldsparseIPv6parsePrefixErrorsplitAddrPortz0z4z6nozisV6zoneV6netipnet/netipDefaultDebugPathDefaultRPCPathDefaultServerDialHTTPDialHTTPPathHandleHTTPNewClientWithCodecServeCodecServeRequestServerErrorconnecteddebugHTTPdebugMethoddebugServicedebugTextgobClientCodecgobServerCodecinvalidRequestisExportedOrBuiltinTypelogRegisterErrormethodArraymethodTypeserviceArraysuitableMethodstypeOfErrorArgTypeReplyTypenumCallsNumCallsrcvrencBufserviceMapreqLockfreeReqrespLockfreeRespgetRequestfreeRequestgetResponsefreeResponsereadRequestHeaderreqMutexnet/rpcCRAMMD5AuthcramMD5AuthdataCloserisLocalhostplainAuthtestHookStartTLSvalidateLinedotWriterPrintfLineDotWriterdidHellohelloErrorheloehloTLSConnectionStateMailRcptNoopCanonicalMIMEHeaderKeyTrimBytesTrimStringcanonicalMIMEHeaderKeycommonHeadercommonHeaderOncecrnldotcrnlerrMessageTooLargeinitCommonHeaderisASCIILetterisASCIISpacemustHaveFieldNameColonnoValidationparseCodeLinevalidHeaderFieldBytevalidHeaderValueBytewstateBeginwstateBeginLinewstateCRwstateDatatextprotonet/textprotoInvalidHostErrorParseQueryParseRequestURIPathEscapePathUnescapeQueryUnescapeUserPasswordbadSetPathencodeHostencodePathSegmentencodeZonegetSchemeparseAuthorityparseHostparseQueryresolvePathvalidEncodedvalidOptionalPortvalidUserinfoAddrErrorCIDRMaskDNSConfigErrorDNSErrorDefaultResolverDialIPDialUDPDialUnixErrWriteToConnectedFileConnFileListenerFilePacketConnFlagBroadcastFlagLoopbackFlagMulticastFlagPointToPointFlagRunningFlagUpIPConnIPv4IPv4MaskIPv4allrouterIPv4allsysIPv4bcastIPv4lenIPv4zeroIPv6interfacelocalallnodesIPv6lenIPv6linklocalallnodesIPv6linklocalallroutersIPv6loopbackIPv6unspecifiedIPv6zeroInterfaceAddrsInterfaceByIndexInterfaceByNameInvalidAddrErrorJoinHostPortListenConfigListenIPListenMulticastUDPListenPacketListenUDPListenUnixgramOpErrorPacketConnParseCIDRParseIPParseMACResolveIPAddrResolveTCPAddrResolveUDPAddrResolveUnixAddrTCPAddrFromAddrPortTCPConnTCPListenerUDPAddrUDPAddrFromAddrPortUDPConnUnixAddrUnixConnUnixListenerUnknownNetworkError_C2func_getaddrinfo_C2func_getnameinfo_C_AF_INET_C_AF_INET6_C_AF_UNSPEC_C_EAI_ADDRFAMILY_C_EAI_AGAIN_C_EAI_NODATA_C_EAI_NONAME_C_EAI_OVERFLOW_C_EAI_SERVICE_C_EAI_SYSTEM_C_IPPROTO_TCP_C_IPPROTO_UDP_C_SOCK_DGRAM_C_SOCK_STREAM_C_ai_addr_C_ai_family_C_ai_flags_C_ai_next_C_ai_protocol_C_ai_socktype_C_char_C_free_C_freeaddrinfo_C_gai_strerror_C_getaddrinfo_C_malloc_C_res_nclose_C_res_ninit_C_res_nsearch_C_socklen_t_C_struct___res_state_C_struct_addrinfo_C_struct_sockaddr_C_uchar_C_uint_Cfunc_freeaddrinfo_Cfunc_gai_strerror_Cfunc_getaddrinfo_Cfunc_getnameinfo_Cfunc_res_search_Ciconst_AF_INET_Ciconst_AF_INET6_Ciconst_AF_UNSPEC_Ciconst_AI_ALL_Ciconst_AI_CANONNAME_Ciconst_AI_V4MAPPED_Ciconst_EAI_ADDRFAMILY_Ciconst_EAI_AGAIN_Ciconst_EAI_NODATA_Ciconst_EAI_NONAME_Ciconst_EAI_OVERFLOW_Ciconst_EAI_SERVICE_Ciconst_EAI_SYSTEM_Ciconst_IPPROTO_TCP_Ciconst_IPPROTO_UDP_Ciconst_NI_NAMEREQD_Ciconst_SOCK_DGRAM_Ciconst_SOCK_STREAM_Ctype___socklen_t_Ctype_sa_family_t_Ctype_socklen_t_Ctype_struct_addrinfo_Ctype_struct_sockaddr_Ctype_ushort_IPPROTO_MPTCP_MPTCP_INFO_SOL_MPTCP__cgofn__cgo_77133bf98b3a_C2func_getaddrinfo__cgofn__cgo_77133bf98b3a_C2func_getnameinfo__cgofn__cgo_77133bf98b3a_Cfunc__Cmalloc__cgofn__cgo_77133bf98b3a_Cfunc_free__cgofn__cgo_77133bf98b3a_Cfunc_freeaddrinfo__cgofn__cgo_77133bf98b3a_Cfunc_gai_strerror__cgofn__cgo_77133bf98b3a_Cfunc_getaddrinfo__cgofn__cgo_77133bf98b3a_Cfunc_getnameinfo__cgofn__cgo_77133bf98b3a_Cfunc_res_search_cgo_77133bf98b3a_C2func_getaddrinfo_cgo_77133bf98b3a_C2func_getnameinfo_cgo_77133bf98b3a_Cfunc__Cmalloc_cgo_77133bf98b3a_Cfunc_free_cgo_77133bf98b3a_Cfunc_freeaddrinfo_cgo_77133bf98b3a_Cfunc_gai_strerror_cgo_77133bf98b3a_Cfunc_getaddrinfo_cgo_77133bf98b3a_Cfunc_getnameinfo_cgo_77133bf98b3a_Cfunc_res_searchabsDomainNameacquireThreadaddrPortToSockaddrInet4addrPortToSockaddrInet6addrPortUDPAddraddrTableaddrinfoErrnoallFFavoidDNSboolintbuffersWriterbyPrefbyPriorityWeightbyRFC6724InfocacheMaxAgecanceledErrorcgoAddrInfoFlagscgoAvailablecgoLookupAddrPTRcgoLookupCNAMEcgoLookupHostcgoLookupHostIPcgoLookupIPcgoLookupPTRcgoLookupPortcgoLookupServicePortcgoNameinfoPTRcgoResSearchcgoSockaddrcgoSockaddrInet4cgoSockaddrInet6checkResponseclassAMaskclassBMaskclassCMaskclassifyScopecommonPrefixLencompareByRFC6724concurrentThreadsLimitconfOnceconfValconnectFunccopyIPcountAnyBytedefaultMPTCPEnabledDialdefaultMPTCPEnabledListendefaultTCPKeepAliveCountdefaultTCPKeepAliveIdledefaultTCPKeepAliveIntervaldnsDefaultSearchdnsPacketRoundTripdnsReadConfigdnsStreamRoundTripdnsWaitGroupdoBlockingWithCtxdtoidupSocketensureRootedequalASCIINameerrCancelederrCannotMarshalDNSMessageerrCannotUnmarshalDNSMessageerrInvalidDNSResponseerrInvalidInterfaceerrInvalidInterfaceIndexerrInvalidInterfaceNameerrLameReferralerrMalformedDNSRecordsDetailerrMissingAddresserrNoAnswerFromDNSServererrNoSuchHosterrNoSuchInterfaceerrNoSuchMulticastInterfaceerrNoSuitableAddresserrServerMisbehavingerrServerTemporarilyMisbehavingerrUnknownPortextractExtendedRCodefavoriteAddrFamilyfileAddrfileConnfileListenerfilePacketConnfilterAddrListflagNamesforeachFieldgenericReadFromgenericWriteTogetHostnamegetSystemDNSConfiggetSystemNSSgetsockoptIntFuncgoDebugNetDNSgoLookupIPFilesgoLookupPortgoosPrefersCgohasFallenBackhasSOLMPTCPhasUpperCasehostLookupCgohostLookupDNShostLookupDNSFileshostLookupFileshostLookupFilesDNShostsFilePathinitConfValinitMPTCPavailableinterfaceAddrTableinterfaceByIndexinterfaceMulticastAddrTableinterfaceTableinterfaceToIPv4AddrinternetSocketipAddrsEfaceipAttripAttrOfipEmptyStringipStackCapabilitiesipStackCapsipToSockaddripToSockaddrInet4ipToSockaddrInet6ipVersionipv4onlyipv6ZoneCacheipv6onlyisClosedChanisConnErrorisDomainNameisGatewayisNotIPv4isOutboundisUsingMPTCPProtoisUsingMultipathTCPisZerosjoinIPv4GroupjoinIPv6GrouplinkFlagslistenFunclistenIPv4MulticastUDPlistenIPv6MulticastUDPlistenerBackloglistenerBacklogCachelookupIPReturnlookupOrderNamelookupPortMaplookupPortMapWithNetworklookupProtocollookupProtocolMaplookupStaticAddrlookupStaticHostloopbackIPlowerASCIIBytesmakePipeDeadlinemapErrmaxAckBacklogmaxDNSPacketSizemaxListenerBacklogmaxNameinfoLenmaxPortBufSizemaxProtoLengthmdnsAssumeDoesNotExistmdnsAssumeExistsmdnsFromSystemmdnsTestminNonzeroTimemptcpAvailablemptcpDisabledDialmptcpDisabledListenmptcpEnabledDialmptcpEnabledListenmptcpOncemptcpStatusListenmptcpUseDefaultDialmptcpUseDefaultListenmultipathtcpnameinfoLennetCgoBuildTagnetFDnetGoBuildTagnetdnsnetedns0networkNumberAndMasknewAddrnewDNSErrornewFDnewFileFDnewIPConnnewLinknewRawConnnewRawListenernewRequestnewTCPConnnewUDPConnnewUnixConnnewUnixFilenoCancelnoReadFromnoWriteTonssConfnssConfignssConfigPathnssCriterionnssSourcensswitchConfigonceReadProtocolsonceReadServicesonlyValuesCtxparseCNAMEFromResourcesparseCriteriaparseLiteralIPparseNSSConfparseNSSConfFileparseNetworkparseProcNetIGMPparseProcNetIGMP6partialDeadlinepipeAddrpipeDeadlinepolicyTablepolicyTableEntrypollSplicerandIntrandIntnrawConnrawListenerreadFromSyscallNamereadHostsreadMsgFlagsreadMsgSyscallNamereadProtocolsreadServicesreadSyscallNamereleaseThreadremoveCommentresSearchresolvConfresolverConfigreverseaddrrfc6724policyTableroundDurationUpscopeAdminLocalscopeGlobalscopeInterfaceLocalscopeLinkLocalscopeOrgLocalscopeSiteLocalselfConnectsetDefaultListenerSockoptssetDefaultMulticastSockoptssetDefaultSockoptssetIPv4MreqToInterfacesetIPv4MulticastInterfacesetIPv4MulticastLoopbacksetIPv6MulticastInterfacesetIPv6MulticastLoopbacksetKeepAlivesetKeepAliveCountsetKeepAliveIdlesetKeepAliveIntervalsetLingersetNoDelaysetReadBuffersetReadMsgCloseOnExecsetWriteBuffersimpleMaskLengthskipToAnswersockaddrToIPsockaddrToTCPsockaddrToUDPsockaddrToUnixsockaddrToUnixgramsockaddrToUnixpacketsocketFuncsortByRFC6724sortByRFC6724withSrcssotypeToNetspliceFromspliceTosplitAtBytessplitHostZonespuriousENOTAVAILsrcAddrsstringsEqualFoldstringsHasSuffixFoldstripIPv4HeadersupportsIPv4supportsIPv4mapsupportsIPv6supportsMultipathTCPsupportsSendfilesysARPHardwareGREIPv4sysARPHardwareGREIPv6sysARPHardwareIPv4IPv4sysARPHardwareIPv6IPv4sysARPHardwareIPv6IPv6sysDialersysListenersysSocketsystemConftcpConnWithoutReadFromtcpConnWithoutWriteTotemporaryErrortestHookCanceledDialtestHookDialTCPtestHookLookupIPtestHookSetKeepAlivetestHookStepTimetestPreHookSetKeepAlivethreadLimitthreadOncetrimSpaceunixSocketuseTCPOnlyuseUDPOrTCPv4InV6PrefixwithUnexpiredValuesPreservedwrapSyscallErrorwriteMsgSyscallNamewriteSyscallNamewriteToSyscallNamextoixtoi2zoneCachesa_familysa_dataai_flagsai_familyai_socktypeai_protocolai_addrlenai_addrai_canonnameai_nextsotypeisConnectedsetAddrreadFromInet4readFromInet6readMsgreadMsgInet4readMsgInet6writeToInet4writeToInet6writeMsgwriteMsgInet4writeMsgInet6ctrlNetworklistenStreamlistenDatagramaddrFuncwriteBuffersnetGonetCgodnsDebugLevelpreferCgomustUseGoResolveraddrLookupOrderlookupOrderSetReadBufferSetWriteBufferReadFromUDPreadFromUDPReadFromUDPAddrPortReadMsgUDPReadMsgUDPAddrPortWriteToUDPWriteToUDPAddrPortWriteMsgUDPWriteMsgUDPAddrPortreadFromAddrPortwriteToAddrPortwriteMsgAddrPortnegatestandardStatusActioncriteriastandardCriteriasourceslookupValuesovclistenIPlistenMPTCPlistenTCPlistenTCPProtolistenUDPlistenMulticastUDPlistenUnixlistenUnixgramcanonicalNamebyAddrReadFromIPReadMsgIPWriteToIPWriteMsgIPlastCheckedtryUpdateacquireSematryAcquireSemareleaseSemaCloseReadReadFromUnixReadMsgUnixWriteToUnixWriteMsgUnixNetlinkRouteAttrnet.writeBufferslastFetchedtoNamezcPollFDshuffleByWeightaddrAttrsrcAttrSetLingerSetKeepAliveSetKeepAlivePeriodSetNoDelaySetKeepAliveConfigClassifygetLineFromDataAcceptTCPNetlinkMessageipv4Enabledipv6Enabledipv4MappedIPv6EnabledproberdRxrdTxwrTxwrRxlocalDoneremoteDoneunlinkunlinkOnceAcceptUnixSetUnlinkOnCloseUnwrapErrIsTimeoutIsTemporaryeaiisAddrinfoErrnodialParalleldialSerialdialSingledialIPdialMPTCPdialTCPdoDialTCPdoDialTCPProtodialUDPdialUnixX__ifi_padErrDotErrWaitDelayaddCriticalEnvcloseDescriptorsdedupEnvdedupEnvCaseexecerrdotexecwaitfindExecutableinterfaceEquallookExtensionsprefixSuffixSaverskipStdinCopyErrorvalidateLookPathwrappedErrorsuffixOffNotifyContextdisableSignalenableSignalignoreSignalnumSigsignalCtxsignalIgnoredsignalWaitUntilIdlesignal_disablesignal_enablesignal_ignoresignal_ignoredsignal_recvsignumstoppingwatchSignalLoopwatchSignalLoopOnceLookupGroupIdLookupIdUnknownGroupErrorUnknownGroupIdErrorUnknownUserErrorUnknownUserIdError_C_GoString_C__SC_GETGR_R_SIZE_MAX_C__SC_GETPW_R_SIZE_MAX_C_getgrgid_r_C_getgrnam_r_C_getpwnam_r_C_getpwuid_r_C_gid_t_C_gr_gid_C_gr_name_C_pw_dir_C_pw_gecos_C_pw_gid_C_pw_gidp_C_pw_name_C_pw_uid_C_pw_uidp_C_size_t_C_struct_group_C_struct_passwd_C_sysconf_C_uid_t_Cfunc_mygetgrgid_r_Cfunc_mygetgrnam_r_Cfunc_mygetgrouplist_Cfunc_mygetpwnam_r_Cfunc_mygetpwuid_r_Cfunc_sysconf_Ciconst__SC_GETGR_R_SIZE_MAX_Ciconst__SC_GETPW_R_SIZE_MAX_Ctype___gid_t_Ctype___uid_t_Ctype_gid_t_Ctype_struct_group_Ctype_struct_passwd_Ctype_uid_t__cgofn__cgo_9bef24737d87_Cfunc_mygetgrgid_r__cgofn__cgo_9bef24737d87_Cfunc_mygetgrnam_r__cgofn__cgo_9bef24737d87_Cfunc_mygetgrouplist__cgofn__cgo_9bef24737d87_Cfunc_mygetpwnam_r__cgofn__cgo_9bef24737d87_Cfunc_mygetpwuid_r__cgofn__cgo_9bef24737d87_Cfunc_sysconf_cgo_9bef24737d87_Cfunc_mygetgrgid_r_cgo_9bef24737d87_Cfunc_mygetgrnam_r_cgo_9bef24737d87_Cfunc_mygetgrouplist_cgo_9bef24737d87_Cfunc_mygetpwnam_r_cgo_9bef24737d87_Cfunc_mygetpwuid_r_cgo_9bef24737d87_Cfunc_sysconfbufferKindbuildGroupbuildUsergetGroupListgroupBuffergroupFilegroupImplementedgroupListImplementedgroupRetryisSizeReasonablelistGroupslookupGroupIdlookupUnixGidlookupUnixUidlookupUserlookupUserIdmaxGroupsretryWithBufferstructPasswdForNegativeTestuserBufferuserFileuserImplementedHomeDirGroupIdsgr_namegr_passwdgr_gidgr_meminitialSizepw_namepw_passwdpw_uidpw_gidpw_gecospw_dirpw_shellos/userCopyFSDevNullDirFSErrProcessDoneExpandEnvFindProcessIsExistIsPermissionLinkErrorLookupEnvMkdirTempNewSyscallErrorO_CREATEOpenInRootOpenRootPathListSeparatorProcAttrSameFileStartProcessSyscallErrorUserCacheDirUserConfigDirUserHomeDir_UTIME_OMITatimecheckClonePidfdcheckPidfdcheckPidfdOncecheckSymlinkcheckWrapErrconvertESRCHdirBufPooldirFSdirentTypedoInRootendsWithDotensurePidfdepipecheckerrDeadlineExceedederrENOMEMerrENOSYSerrERANGEerrNoDeadlineerrPathEscapeserrPatternHasSeparatorerrSymlinkerrWriteAtInAppendModeexecutablefileStatfileWithoutReadFromfileWithoutWriteTofillFileStatFromSysfindProcessfixCountfixLongPathgetPidfdgetPollFDAndNetworkgetShellNamegetwdCacheignoreSIGSYSisNoFollowErrisShellSpecialVarisUnixOrTCPisValidRootFSPathkindNewFilekindNoPollkindOpenFilekindPipekindSocklstatlstatNologmkdiratmodeHandlemodePIDnet_newUnixFilenewDoneProcessnewFilenewFileKindnewHandleProcessnewPIDProcessnewUnixDirentnextRandomopenDirAtopenDirNologopenFileNologopenRootInRootopenRootNologpidReleasedpidUnsetpidfdFindpidfdWorkspollCopyFileRangeprefixAndSuffixprocessStatusMaskreadFileContentsreaddirDirEntryreaddirFileInforeaddirNamereadlinkreadlinkatremoveAllremoveAllFromremoveatrenamerestoreSIGSYSrootCleanPathrootFSrootMaxSymlinksrootMkdirrootOpenDirrootOpenFileNologrootRemoverootStatruntime_argsruntime_beforeExitsetStickyBitsigpipesplitPathsplitPathInRootstartProcessstatNologstatusDonestatusOKstatusReleasedsupportsCloseOnExecsupportsCreateWithStickyBitsyscallErrorTypesyscallModesysfdTypetestingForceReadDirLstattryLimitedReaderunderlyingErrorunderlyingErrorIsunixDirentlogOpenlogStatbufprfsErrBadPatternEvalSymlinksSplitListcleanGlobPathWindowsevalSymlinksgetEscmatchChunkreadDirNamessameWordscanChunksplitListunixAbswalkSymlinksArrayOfChanOfDeepEqualFuncOfMakeChanMakeFuncMakeMapMakeMapWithSizeMapOfNewAtPointerToPtrToSelectCaseSelectDefaultSelectDirSelectRecvSelectSendSliceAtSliceHeaderSliceOfStringHeaderStructOfVisibleFieldsaNameOffaTextOffaTypeOffabiDescabiSeqabiStepabiStepBadabiStepFloatRegabiStepIntRegabiStepKindabiStepPointerabiStepStackaddReflectOffaddTypeBitsarchFloat32FromRegarchFloat32ToRegbadlinkname_Value_pointerbadlinkname_rtype_Alignbadlinkname_rtype_AssignableTobadlinkname_rtype_Bitsbadlinkname_rtype_ChanDirbadlinkname_rtype_Comparablebadlinkname_rtype_ConvertibleTobadlinkname_rtype_Elembadlinkname_rtype_Fieldbadlinkname_rtype_FieldAlignbadlinkname_rtype_FieldByIndexbadlinkname_rtype_FieldByNamebadlinkname_rtype_FieldByNameFuncbadlinkname_rtype_Implementsbadlinkname_rtype_Inbadlinkname_rtype_IsVariadicbadlinkname_rtype_Keybadlinkname_rtype_Kindbadlinkname_rtype_Lenbadlinkname_rtype_Methodbadlinkname_rtype_MethodByNamebadlinkname_rtype_Namebadlinkname_rtype_NumFieldbadlinkname_rtype_NumInbadlinkname_rtype_NumMethodbadlinkname_rtype_NumOutbadlinkname_rtype_Outbadlinkname_rtype_PkgPathbadlinkname_rtype_Sizebadlinkname_rtype_Stringbadlinkname_rtype_ptrTobitVectorcallGCcallReflectcanRangeFunccanRangeFunc2chancapchanclosechanrecvchansendchansend0contentEscapesconvertOpcopyValcvtBytesStringcvtComplexcvtDirectcvtFloatcvtFloatIntcvtFloatUintcvtI2IcvtIntcvtIntFloatcvtIntStringcvtRunesStringcvtSliceArraycvtSliceArrayPtrcvtStringBytescvtStringRunescvtT2IcvtUintcvtUintFloatcvtUintStringdebugReflectCalldeepValueEqualdumpPtrBitMapembeddedIfaceMethStubemitGCMaskfieldScanfloatArgRegsfloatFromRegfloatRegSizefloatToRegfnv1funcLayoutfuncLookupCachefuncStrfuncTypesfuncTypesMutexgetStaticuint64sgroupAndSlotOfhashMightPanicinitFuncTypesintArgRegsintFromRegintToRegisPaddedFieldisReflexiveisRegularMemoryisValidFieldNamelayoutCachelayoutKeylayoutTypelookupCachemakeBytesmakeFloat32makeFuncCtxtmakeFuncImplmakeFuncStubmakeMethodValuemakeRunesmakeStringmakechanmapIterNextmapIterStartmapaccessmapaccess_faststrmapassign0mapassign_faststr0mapclearmapdelete_faststrmethodReceivermethodValuemethodValueCallmethodValueCallCodePtrmoveMakeFuncArgPtrsnameFornameOffForneedKeyUpdatenewAbiDescnewNamenonEmptyInterfaceoverflowFloat32pkgPathForptrMapptrTorangeNumresolveReflectNameresolveReflectTextresolveReflectTyperesolveTextOffrselectrtypeOfrtypeOffruntimeSelectruntimeStructFieldspecialChannelAssignabilitystoreRcvrstringForstructLookupCachetextOffFortypeOffFortypedarraycleartypedmemclrpartialtypehashtypeptrdatatypesByStringtypesMustMatchunsafe_NewArrayunsafesliceunusedIfaceIndirvalueMethodNameverifyNotInHeapPtrvisibleFieldsWalkerstkOffiregfregvalueStartstackBytesiregsfregsstepsForValueaddArgaddRcvrregAssignassignIntNassignFloatNstackAssignstackCallArgsSizeretOffsetspillstackPtrsinRegPtrsoutRegPtrsvisitingargLenregPtrsitabwordframePoolabidt2reflectClassNLCompileDotNLEmptyBeginLineEmptyBeginTextEmptyEndLineEmptyEndTextEmptyNoWordBoundaryEmptyOpContextEmptyWordBoundaryErrInternalErrorErrInvalidCharClassErrInvalidCharRangeErrInvalidEscapeErrInvalidNamedCaptureErrInvalidPerlOpErrInvalidRepeatOpErrInvalidRepeatSizeErrInvalidUTF8ErrLargeErrMissingParenErrMissingRepeatArgumentErrNestingDepthErrTrailingBackslashErrUnexpectedParenInstAltInstAltMatchInstCaptureInstEmptyWidthInstFailInstMatchInstNopInstRuneInstRune1InstRuneAnyInstRuneAnyNotNLIsWordCharLiteralMatchNLNonGreedyOneLineOpAlternateOpAnyCharOpAnyCharNotNLOpBeginLineOpBeginTextOpCaptureOpCharClassOpConcatOpEmptyMatchOpEndLineOpEndTextOpLiteralOpNoMatchOpNoWordBoundaryOpPlusOpQuestOpRepeatOpStarOpWordBoundaryPOSIXPerlXUnicodeGroupsWasDollar_Op_index_0_Op_name_0_Op_name_1addSpananyRuneanyRuneNotNLanyTableappendClassappendFoldedClassappendFoldedRangeappendLiteralappendNegatedClassappendNegatedTableappendRangeappendTablecalcFlagscharGroupcheckUTF8cleanAltcleanClasscode1code10code11code12code13code14code15code16code17code2code3code4code5code6code7code8code9compilerdumpInstdumpProgflagIflagMflagOffflagPrecflagSfraginCharClassinstOpNamesinstSizeisCharClassisValidCaptureNameisalnumliteralRegexpmakePatchListmatchRunemaxFoldmaxHeightmaxRunesmergeCharClassminFoldminFoldRunenegShiftnegateClassnoMatchopLeftParenopPseudoopVerticalBarpatchListperlGroupposixGroupprintFlagsrepeatIsValidruneSizesimplify1unicodeTablewriteRegexpSub0Rune0MaxCapCapNamescapNamesSimplifynumCapwholeRegexptmpClassnumRegexpnumRunesnewRegexpreusecheckLimitscheckSizecalcSizecheckHeightcalcHeightmaybeConcatalternatefactorleadingStringremoveLeadingStringleadingRegexpremoveLeadingRegexpparseRepeatparsePerlFlagsparseVerticalBarswapVerticalBarparseRightParenparseEscapeparseClassCharparsePerlClassEscapeparseNamedClassparseUnicodeClassparseClassracatqueststarregexp/syntaxCompilePOSIXMustCompilePOSIXQuoteMetaarrayNoIntsbitStatePoolcleanupOnePasscompileOnePassendOfTextfreeBitStatefreeOnePassMachineiopmakeOnePassmatchPoolmatchSizemaxBacktrackProgmaxBacktrackVectormergeFailedmergeRuneSetsnewBitStatenewLazyFlagnewOnePassMachinenewQueuenoNextnoRuneonePassCopyonePassMachineonePassNextonePassPoolonePassPrefixqueueOnePassquoteshouldBacktrackspecialBytesstartSizevisitedBitsnextIndexinsertNewNewHandle_cgo_bindm_cgo_callers_cgo_getstackbound_cgo_init_cgo_libc_setegid_cgo_libc_seteuid_cgo_libc_setgid_cgo_libc_setgroups_cgo_libc_setregid_cgo_libc_setresgid_cgo_libc_setresuid_cgo_libc_setreuid_cgo_libc_setuid_cgo_mmap_cgo_munmap_cgo_notify_runtime_init_done_cgo_panic_cgo_pthread_key_created_cgo_set_context_function_cgo_setenv_cgo_sigaction_cgo_sys_thread_create_cgo_thread_start_cgo_unsetenv_cgo_yield_crosscall2_ptr_iscgo_runtime_cgo_panic_internal_set_crosscall2cgo_libc_setegidcgo_libc_seteuidcgo_libc_setgidcgo_libc_setgroupscgo_libc_setregidcgo_libc_setresgidcgo_libc_setresuidcgo_libc_setreuidcgo_libc_setuidhandleIdxset_crosscall2x_cgo_bindmx_cgo_callersx_cgo_getstackboundx_cgo_initx_cgo_mmapx_cgo_munmapx_cgo_notify_runtime_init_donex_cgo_pthread_key_createdx_cgo_set_context_functionx_cgo_setenvx_cgo_sigactionx_cgo_sys_thread_createx_cgo_thread_startx_cgo_unsetenvx_crosscall2_ptrcstrruntime/cgoCrashOptionsFreeOSMemoryParseBuildInfoPrintStackReadBuildInfoReadGCStatsSetCrashOutputSetGCPercentSetMaxStackSetMaxThreadsSetMemoryLimitSetPanicOnFaultSetTracebackWriteHeapDumpfreeOSMemorymodinfoquoteKeyquoteValuereadGCStatsruntime_setCrashFDsetGCPercentsetMaxStacksetMaxThreadssetMemoryLimitsetPanicOnFaultPauseTotalPauseQuantilesKindBadKindFloat64HistogramallDescruntime_readMetricsruntime/metricsNewTaskStartRegionWithRegionbgTaskfromContextlastTaskIDnewIDnoopRegionregionEndCoderegionStartCodetraceContextKeytracinguserLoguserRegionuserTaskCreateuserTaskEndregionTyperuntime/traceAddCleanupBlockProfileBreakpointCPUProfileCallersCallersFramesFuncForPCGOMAXPROCSGoexitGoroutineProfileLockOSThreadMemProfileMemProfileRateMutexProfileNumCgoCallPanicNilErrorPinnerReadTraceSetBlockProfileRateSetCPUProfileRateSetCgoTracebackSetFinalizerSetMutexProfileFractionStartTraceStopTraceThreadCreateProfileTypeAssertionErrorUnlockOSThread_64bit_AF_UNIX_AT_NULL_AT_PAGESZ_AT_PLATFORM_AT_RANDOM_AT_SECURE_AT_SYSINFO_EHDR_BUS_ADRALN_BUS_ADRERR_BUS_OBJERR_CLOCK_THREAD_CPUTIME_ID_CLONE_CHILD_CLEARTID_CLONE_CHILD_SETTID_CLONE_FILES_CLONE_FS_CLONE_NEWIPC_CLONE_NEWNS_CLONE_NEWUTS_CLONE_PARENT_CLONE_PARENT_SETTID_CLONE_PTRACE_CLONE_SETTLS_CLONE_SIGHAND_CLONE_STOPPED_CLONE_SYSVSEM_CLONE_THREAD_CLONE_UNTRACED_CLONE_VFORK_CLONE_VM_DT_GNU_HASH_DT_HASH_DT_NULL_DT_STRTAB_DT_SYMTAB_DT_VERDEF_DT_VERSYM_DebugGC_EACCES_EAGAIN_EINTR_EINVAL_EI_NIDENT_ELF_ST_BIND_ELF_ST_TYPE_ENOMEM_ExternalCode_FD_CLOEXEC_FPE_FLTDIV_FPE_FLTINV_FPE_FLTOVF_FPE_FLTRES_FPE_FLTSUB_FPE_FLTUND_FPE_INTDIV_FPE_INTOVF_FUTEX_PRIVATE_FLAG_FUTEX_WAIT_PRIVATE_FUTEX_WAKE_PRIVATE_F_SETFD_FinBlockSize_FixAllocChunk_GC_GCmark_GCmarktermination_GCoff_Gcopystack_Gdead_Genqueue_unused_Gidle_Gmoribund_unused_GoidCacheBatch_Gpreempted_Grunnable_Grunning_Gscan_Gscanpreempted_Gscanrunnable_Gscanrunning_Gscansyscall_Gscanwaiting_Gsyscall_Gwaiting_ITIMER_PROF_ITIMER_REAL_ITIMER_VIRTUAL_KindSpecialCleanup_KindSpecialFinalizer_KindSpecialPinCounter_KindSpecialProfile_KindSpecialReachable_KindSpecialWeakHandle_LostContendedRuntimeLock_LostExternalCode_LostSIGPROFDuringAtomic64_MADV_COLLAPSE_MADV_DONTNEED_MADV_FREE_MADV_HUGEPAGE_MADV_NOHUGEPAGE_MAP_ANON_MAP_FIXED_MAP_PRIVATE_MaxGcproc_MaxSmallSize_NSIG_NumSizeClasses_NumStackOrders_O_CLOEXEC_O_CREAT_O_NONBLOCK_O_RDONLY_O_TRUNC_O_WRONLY_PROT_EXEC_PROT_NONE_PROT_READ_PROT_WRITE_PT_DYNAMIC_PT_LOAD_PageMask_PageShift_PageSize_Pdead_Pgcstop_Pidle_Prunning_Psyscall_SA_ONSTACK_SA_RESTART_SA_RESTORER_SA_SIGINFO_SEGV_ACCERR_SEGV_MAPERR_SHN_UNDEF_SHT_DYNSYM_SIGABRT_SIGALRM_SIGBUS_SIGCHLD_SIGCONT_SIGEV_THREAD_ID_SIGFPE_SIGHUP_SIGILL_SIGINT_SIGIO_SIGKILL_SIGPIPE_SIGPROF_SIGPWR_SIGQUIT_SIGRTMIN_SIGSEGV_SIGSTKFLT_SIGSTOP_SIGSYS_SIGTRAP_SIGTSTP_SIGTTIN_SIGTTOU_SIGURG_SIGUSR1_SIGUSR2_SIGVTALRM_SIGWINCH_SIGXCPU_SIGXFSZ_SIG_BLOCK_SIG_DFL_SIG_IGN_SIG_SETMASK_SIG_UNBLOCK_SI_KERNEL_SI_TIMER_SI_TKILL_SI_USER_SOCK_DGRAM_SS_DISABLE_STB_GLOBAL_STB_WEAK_STT_FUNC_STT_NOTYPE_SYS_SECCOMP_SigDefault_SigGoExit_SigIgn_SigKill_SigNotify_SigPanic_SigSetStack_SigThrow_SigUnblock_StackCacheSize_System_TinySize_TinySizeClass_VDSO_VER_FLG_BASE_WorkbufSize_cgo_panic_internal_defer_panic_si_max_size_sigev_max_size_type_typePairacquireLockRankAndMacquireSudogacquiremacquirepactiveModulesactiveSweepactive_spinactive_spin_cntadd1addCleanupaddCovMetaaddExtraMaddbaddfinalizeraddmoduledataaddrBitsaddrRangeaddrRangesaddrsToSummaryRangeaddrspace_vecaddspecialadjustSignalStackadjustSignalStack2adjustSignalStack2IndirectadjustctxtadjustdefersadjustframeadjustinfoadjustpanicsadjustpointeradjustpointersadjustsudogsadviseUnusedaeskeyschedaixAddrBitsaixStaticDataBaseaixTagBitsalginitalignDownallDloggersallGsSnapshotallZeroallfinallgaddallglenallglockallgptrallgsallmallocmallocmLockallocmcacheallpallpLockancestorInfoappendIntStrarchauxvarenaBasearenaBaseOffsetarenaBaseOffsetUintptrarenaBitsarenaHintarenaIdxarenaIndexarenaL1BitsarenaL1ShiftarenaL2Bitsarena_arena_Freearena_arena_Newarena_arena_Slicearena_heapifyarena_newArenaargcargsetargsliceargv_indexarm64HasATOMICSarmHasVFPv4arraytypeasanenabledasanpoisonasanreadasanregisterglobalsasanunpoisonasanwriteasmcgocallasmcgocall_landingpadasmcgocall_no_gasminitassertE2IassertE2I2assertLockHeldassertRankHeldassertWorldStoppedassertWorldStoppedOrLockHeldasyncPreemptasyncPreempt2asyncPreemptStackatoiatoi32atoi64atomicAllGatomicAllGIndexatomicHeadTailIndexatomicMSpanPointeratomicOffAddratomicScavChunkDataatomicSpanSetSpinePointeratomic_casPointeratomic_storePointeratomicstorepatomicwbauxvauxvreadbufavxSupportedbadDeferbadFuncInfoEntrybadPointerbadSrcFuncbadSrcFuncNamebadTimerbadcgocallbackbadctxtbadmcallbadmcall2badmorestackg0badmorestackgsignalbadreflectcallbadsignalbadsystemstackbadunlockosthreadbbucketsbeforeIdlebgscavengebgsweepbias32bias64binarySearchTreebitCursorblockAlignSummaryRangeblockProfileblockProfileInternalblockRecordblockTimerChanblockUntilEmptyFinalizerQueueblockableSigblockeventblockprofilerateblocksampledbootstrapRandbootstrapRandReseedboringCachesboring_registerCacheboring_runtime_arg0boundsConvertboundsErrorboundsErrorCodeboundsErrorFmtsboundsIndexboundsNegErrorFmtsboundsSlice3AcapboundsSlice3AlenboundsSlice3BboundsSlice3CboundsSliceAcapboundsSliceAlenboundsSliceBbreakpointbswapIfBigEndianbuckHashSizebucketTypebuckhashbuckhashArraybuildGCMaskbuildInterfaceSwitchCachebuildTypeAssertCachebulkBarrierBitmapbulkBarrierPreWritebulkBarrierPreWriteSrcOnlybytealg_MakeNoZerobytesHashc128equalc128hashc64equalc64hashcall1024call1048576call1073741824call128call131072call134217728call16call16384call16777216call2048call2097152call256call262144call268435456call32call32768call33554432call4096call4194304call512call524288call536870912call64call65536call67108864call8192call8388608callCgoMmapcallCgoMunmapcallCgoSigactioncallCgoSymbolizercallbackUpdateSystemStackcanCreateFilecanPreemptMcanpaniccansemacquirecapacityPerProccasGFromPreemptedcasGToPreemptScancasGToWaitingcasGToWaitingForSuspendGcasfrom_GscanstatuscasgstatuscasgstatusAlwaysTrackcastogscanstatuscgoAlwaysFalsecgoBindMcgoCallerscgoCheckArgcgoCheckBitscgoCheckMemmovecgoCheckMemmove2cgoCheckPointercgoCheckPointerFailcgoCheckPtrWritecgoCheckResultcgoCheckSliceCopycgoCheckTypedBlockcgoCheckUnknownPointercgoCheckUsingTypecgoContextcgoContextArgcgoContextPCscgoHasExtraMcgoInRangecgoIsGoPointercgoKeepAlivecgoNoCallbackcgoResultFailcgoSigtrampcgoSymbolizercgoSymbolizerArgcgoThreadStartcgoTracebackcgoTracebackArgcgoUsecgoWriteBarrierFailcgo_yieldcgocallcgocallbackcgocallbackgcgocallbackg1cgothreadstartcgounimplchanbufchanparkcommitchanrecv1chanrecv2chanrecvpcchansend1chansendpcchantypecheaprandcheaprand64cheaprandncheckASMcheckIdleGCNoPcheckRunqsNoPcheckTimeoutscheckTimersNoPcheckdeadcheckfdscheckmarksMapcheckmcountcheckptrAlignmentcheckptrArithmeticcheckptrBasecheckptrStraddleschildInfochunkBasechunkIdxchunkIndexchunkPageIndexclass_to_allocnpagesclass_to_divmagicclass_to_sizeclearSignalHandlersclearpoolsclobberdeadPtrclobberfreecloneFlagsclosechanclosefdcloseonexeccomplex128divcompute0concatbyte2concatbyte3concatbyte4concatbyte5concatbytesconcatstring2concatstring3concatstring4concatstring5concatstringsconcurrentSweepconsistentHeapStatsconvTconvT16convT32convT64convTnoptrconvTsliceconvTstringcopyBlockProfileRecordcopyMemProfileRecordcopysigncopystackcoroexitcorostartcoroswitch_mcountSubcountrunescoverage_getCovCounterListcpuProfilecpuStatscpuStatsAggregatecpuStatsDepcpuinitcpuprofcputickscrashcrashFDcrashStackImplementedcrashingcrashingGcreatefingdbgVardbgvarsdeadlockdebugCallCheckdebugCallPanickeddebugCallRuntimedebugCallSystemStackdebugCallUnknownFuncdebugCallUnsafePointdebugCallV2debugCallWrapdebugCallWrap1debugCallWrap2debugCallWrapArgsdebugChandebugCheckBPdebugLogBoolFalsedebugLogBoolTruedebugLogBufdebugLogBytesdebugLogConstStringdebugLogHeaderSizedebugLogHexdebugLogIntdebugLogPCdebugLogPtrdebugLogReaderdebugLogStringdebugLogStringLimitdebugLogStringOverflowdebugLogSyncSizedebugLogTracebackdebugLogUintdebugLogUnknowndebugLogWriterdebugPclndebugPinnerKeepUnpindebugPinnerV1debugPtrmaskdebugScanConservativedebugSelectdebugTraceReentrancydebug_modinfodebuglockdecoderunedeductAssistCreditdeductSweepCreditdefaultGOROOTdefaultHeapMinimumdefaultTraceAdvancePerioddeferconvertdeferprocdeferprocStackdeferprocatdeferrangefuncdidothersdieFromSignaldisableMemoryProfilingdisableSigChandivRoundUpdivludlogdlog1dlogEnableddlogFakedlogImpldlogPerMdloggerdloggerFakedloggerImpldoInitdoInit1doRecordGoroutineProfiledoSigPreemptdolockOSThreaddopanic_mdoubleCheckHeapPointersdoubleCheckHeapPointersInteriordoubleCheckHeapSetTypedoubleCheckHeapTypedoubleCheckMallocdoubleCheckReadMemStatsdoubleCheckTypePointersOfTypedounlockOSThreaddrainCheckThresholddropgdropmduffcopyduffzerodumpGCProgdumpStacksRecdumpTypePointersdumpTypesRecdumpbooldumpbvdumpfddumpfieldsdumpfinalizerdumpframedumpgoroutinedumpgsdumpgstatusdumphdrdumpintdumpitabsdumpmemprofdumpmemprof_callbackdumpmemrangedumpmemstatsdumpmsdumpobjdumpobjsdumpotherrootdumpparamsdumpregsdumprootsdumpslicedumpstrdumptypedwritedwritebyteefaceHashefaceOfefaceeqelfDynelfEhdrelfPhdrelfShdrelfSymelfVerdauxelfVerdefelideWrapperCallingemptyInterfaceSwitchCacheemptyTypeAssertCacheemptymspanenableSigChanenableWERencoderuneendCheckmarksensureSigMentersyscallentersyscall_gcwaitentersyscall_sysmonentersyscallblockentersyscallblock_handoffenvKeyEqualenvsepfdeqsliceerrorAddressStringexecLockexitsyscallexitsyscall0exitsyscallfastexitsyscallfast_pidleexitsyscallfast_reacquiredexpandCgoFramesexpandFramesexpbits32expbits64extraMextraMInUseextraMLengthextraMWaitersf32equalf32hashf32to64f32toint32f32toint64f32touint64f64equalf64hashf64to32f64tointf64toint32f64toint64f64touint64fInffNegInffadd32fadd64failallocatestackfailthreadcreatefaketimefandbitsfastexprandfastlog2fastlog2TablefastlogNumBitsfatalpanicfatalsignalfatalthrowfcmp64fdiv32fdiv64feq32feq64fge32fge64fgt32fgt64fieldKindEfacefieldKindEolfieldKindIfacefieldKindPtrfillAlignedfillstackfinalizerfinalizer1finalizercommitfinblockfincfindBitRange64findObjectfindRunnablefindfuncfindfuncbucketfindmoduledatapfindnullfindnullwfindsghifingfingCreatedfingRunningFinalizerfingStatusfingUninitializedfingWaitfingWakefinishsweep_mfinlockfinptrmaskfinqfinq_callbackfint32to32fint32to64fint64to32fint64to64fintto32fintto64fips_fatalfips_getIndicatorfips_setIndicatorfipstls_runtime_arg0firstmoduledatafixallocfixedRootCountfixedRootFinalizersfixedRootFreeGStacksfixedStackfixedStack0fixedStack1fixedStack2fixedStack3fixedStack4fixedStack5fixedStack6float64Inffloat64NegInffloat64bitsfloat64frombitsfloatErrorfloatyflushallmcachesflushmcachefmaxfmax32fmax64fminfmin32fmin64fmtNSAsMSfmul32fmul64fneg64forEachGforEachGRaceforEachPforEachPInternalforbitsforcePreemptNSforcegcforcegchelperforcegcperiodforcegcstatefpTracebackPCsfpTracebackPartialExpandfpack32fpack64fpreg1fpstatefpstate1fpunwindExpandfpxregfpxreg1framepointer_enabledfreeChunkSumfreeMReffreeMStackfreeMWaitfreeSomeWbufsfreeSpecialfreeStackSpansfreeUserArenaChunkfreemarkfreemcachefreezeStopWaitfreezetheworldfreezingfsub64fuint64to32fuint64to64funcMaxSPDeltafuncNameForPrintfuncNamePiecesForPrintfuncdatafuncfilefuncinlfunclinefuncline1funcpkgpathfuncspdeltafunctypefuncvalfunpack32funpack64futexfutexsleepfutexwakeupfwdSigg0gListgQueuegStatusStringsgTraceStategTrackingPeriodgcAssistAllocgcAssistAlloc1gcAssistTimeSlackgcBackgroundModegcBackgroundUtilizationgcBgMarkPreparegcBgMarkStartWorkersgcBgMarkWorkergcBgMarkWorkerCountgcBgMarkWorkerNodegcBgMarkWorkerPoolgcBitsgcBitsArenagcBitsArenasgcBitsChunkBytesgcBitsHeadergcBitsHeaderBytesgcBlackenEnabledgcCPULimitergcCPULimiterStategcCPULimiterUpdatePeriodgcComputeStartingStackSizegcControllergcControllerCommitgcControllerStategcCreditSlackgcDebugMarkDonegcDraingcDrainFlagsgcDrainFlushBgCreditgcDrainFractionalgcDrainIdlegcDrainMarkWorkerDedicatedgcDrainMarkWorkerFractionalgcDrainMarkWorkerIdlegcDrainNgcDrainUntilPreemptgcDumpObjectgcFlushBgCreditgcForceBlockModegcForceModegcGoalUtilizationgcMarkgcMarkDonegcMarkDoneFlushedgcMarkRootCheckgcMarkRootPreparegcMarkTerminationgcMarkTinyAllocsgcMarkWorkAvailablegcMarkWorkerDedicatedModegcMarkWorkerFractionalModegcMarkWorkerIdleModegcMarkWorkerModegcMarkWorkerModeStringsgcMarkWorkerNotWorkergcModegcOverAssistWorkgcPaceScavengergcPaceSweepergcParkAssistgcParkStrongFromWeakgcResetMarkStategcStartgcStatsAggregategcStatsDepgcSweepgcTestIsReachablegcTestMoveStackOnNextCallgcTestPointerClassgcTriggergcTriggerCyclegcTriggerHeapgcTriggerKindgcTriggerTimegcWaitOnMarkgcWakeAllAssistsgcWakeAllStrongFromWeakgcWorkgcWriteBarrier1gcWriteBarrier2gcWriteBarrier3gcWriteBarrier4gcWriteBarrier5gcWriteBarrier6gcWriteBarrier7gcWriteBarrier8gcWriteBarrierBPgcWriteBarrierBXgcWriteBarrierCXgcWriteBarrierDXgcWriteBarrierR8gcWriteBarrierR9gcWriteBarrierSIgcallersgcdgcenablegcinitgclinkgclinkptrgcmarknewobjectgcountgcphasegcrashgcsemagcstopmgdestroygetCachedDloggergetExtraMgetGCMaskgetGCMaskOnDemandgetGodebugEarlygetHugePageSizegetLockRankgetMCachegetOrAddWeakHandlegetWeakHandlegetcallerfpgetemptygetfpgetggetitabgetmgetpidgetproccountgetsiggettidgfgetgfpurgegfputglobalAllocglobrunqgetglobrunqputglobrunqputbatchglobrunqputheadgoPanicIndexgoPanicIndexUgoPanicSlice3AcapgoPanicSlice3AcapUgoPanicSlice3AlengoPanicSlice3AlenUgoPanicSlice3BgoPanicSlice3BUgoPanicSlice3CgoPanicSlice3CUgoPanicSliceAcapgoPanicSliceAcapUgoPanicSliceAlengoPanicSliceAlenUgoPanicSliceBgoPanicSliceBUgoPanicSliceConvertgoStatusToTraceGoStatusgoargsgoarmsoftfpgobufgobytesgodebugDefaultgodebugEnvgodebugIncgodebugNewIncNonDefaultgodebugNotifygodebugUpdategodebug_registerMetricgodebug_setNewIncNonDefaultgodebug_setUpdategoenvsgoenvs_unixgoexitgoexit0goexit1gogetenvgogogomaxprocsgopanicgoparkgoparkunlockgopreempt_mgoreadygorecovergoroutineProfilegoroutineProfileAbsentgoroutineProfileInProgressgoroutineProfileInternalgoroutineProfileSatisfiedgoroutineProfileStategoroutineProfileStateHoldergoroutineProfileWithLabelsgoroutineProfileWithLabelsConcurrentgoroutineProfileWithLabelsSyncgoroutineReadygoroutineheadergoschedIfBusygoschedImplgosched_mgoschedguardedgoschedguarded_mgostartcallgostartcallfngostringgostringngostringnocopygostringwgotracebackgoyieldgoyield_mgreyobjectgsignalStackguintptrgwritehandlingSighandoffhandoffphashLoadhashRandomByteshashkeyhaveHighResSleephaveSysmonhchanhchanSizeheadTailIndexheapAddrBitsheapArenaheapArenaBitmapWordsheapArenaBytesheapArenaWordsheapBitsInSpanheapBitsSliceheapObjectsCanMoveheapRetainedheapSetTypeLargeheapSetTypeNoHeaderheapSetTypeSmallHeaderheapStatsAggregateheapStatsDeltaheapStatsDepheldLockInfohexdumpWordsidlepMaskifaceHashifaceeqinForkedChildinHeapOrStackinPersistentAllocinProgressinRangeinUserArenaChunkinVDSOPageincidlelockedinf2oneinf32inf64inheapinitAlgAESinitMetricsinitSecureModeinitSigmaskinitsiginittraceinjectglistinlineFrameinlineUnwinderinlinedCallint32Hashint64HashinterequalinterfaceSwitchinterfacetypeinterhashinternal_sync_fatalinternal_sync_nanotimeinternal_sync_runtime_SemacquireMutexinternal_sync_runtime_Semreleaseinternal_sync_runtime_canSpininternal_sync_runtime_doSpininternal_sync_throwinternal_syscall_gostringinternal_weak_runtime_makeStrongFromWeakinternal_weak_runtime_registerWeakPointerintstringisAbortPCisAsyncSafePointisDirectIfaceisExportedRuntimeisFiniteisGoPointerWithoutSpanisIdleInSynctestisInfisIntelisPinnedisPowerOfTwoisSbrkPlatformisSecureModeisShrinkStackSafeisSweepDoneisSystemGoroutineisWaitingForSuspendGisarchiveiscgoislibraryitabAdditabHashFuncitabInititabInitSizeitabLockitabTableitabTableInititabTableTypeitab_callbackitabsinititerate_finqiterate_itabsiterate_memprofitimerspecitimervalitoaDivkey32key8labelSynclargeSizeDivlastmoduledataplegacy_fastrandlegacy_fastrand64legacy_fastrandnlevelBitslevelIndexToOffAddrlevelLogPageslevelShiftlfnodelfnodeValidatelfstacklfstackPacklfstackUnpacklibcalllibpreinitlimiterEventlimiterEventBitslimiterEventIdlelimiterEventIdleMarkWorklimiterEventMarkAssistlimiterEventNonelimiterEventScavengeAssistlimiterEventStamplimiterEventStampNonelimiterEventTypelimiterEventTypeMasklinearAlloclinknameIterliveUserArenaChunkloadFactorDenloadFactorNumlock2lockInitlockNameslockOSThreadlockPartialOrderlockRanklockRankAllglockRankAllocmRlockRankAllocmRInternallockRankAllocmWlockRankAllplockRankAssistQueuelockRankCpuproflockRankDeadlocklockRankDeferlockRankExecRlockRankExecRInternallockRankExecWlockRankFinlockRankForcegclockRankGcBitsArenaslockRankGlobalAlloclockRankGscanlockRankHchanlockRankHchanLeaflockRankItablockRankLeafRanklockRankMayQueueFinalizerlockRankMayTraceFlushlockRankMheaplockRankMheapSpeciallockRankMspanSpeciallockRankNetpollInitlockRankNotifyListlockRankPaniclockRankPollCachelockRankPollDesclockRankProfBlocklockRankProfInsertlockRankProfMemActivelockRankProfMemFuturelockRankRaceFinilockRankReflectOffslockRankRootlockRankScavengelockRankSchedlockRankSpanSetSpinelockRankStackLargelockRankStackpoollockRankStrongFromWeakQueuelockRankStructlockRankSudoglockRankSweeplockRankSweepWaiterslockRankSynctestlockRankSysmonlockRankTestRlockRankTestRInternallockRankTestWlockRankTimerlockRankTimerSendlockRankTimerslockRankTracelockRankTraceBuflockRankTraceStackTablockRankTraceStringslockRankTraceTypeTablockRankUnknownlockRankUserArenaStatelockRankWakeableSleeplockRankWbufSpanslockTimerlockVerifyMSizelockWithRanklockWithRankMayAcquirelockedOSThreadlockextralogHeapArenaByteslogMaxPackedValuelogPallocChunkByteslogPallocChunkPageslogScavChunkInUseMaxlogicalStackSentinelloong64HasLAMCASloong64HasLAM_BHloong64HasLSXm5mLockProfilemOSmParkmProfCyclemProfCycleHoldermProfCycleWrapmProfStackInitmProf_FlushmProf_FlushLockedmProf_FreemProf_MallocmProf_NextCyclemProf_PostSweepmReserveIDmSpanDeadmSpanInUsemSpanListmSpanManualmSpanStatemSpanStateBoxmSpanStateNamesmStackIsSystemAllocatedmTraceStatemWaitListmadvisemadviseUnsupportedmainStartedmain_init_donemain_mainmakeAddrRangemakeHeadTailIndexmakeLimiterEventStampmakeProfStackmakeProfStackFPmakeSpanClassmakeStatDepSetmakeTraceFramemakeTraceFramesmakechan64makeheapobjbvmakemap64makemap_smallmakeslicemakeslice64makeslicecopymalgmallocHeaderSizemallocgcLargemallocgcSmallNoscanmallocgcSmallScanHeadermallocgcSmallScanNoHeadermallocgcTinymallocinitmantbits32mantbits64mapKeyError2mapaccess1mapaccess1_fast32mapaccess1_fast64mapaccess1_faststrmapaccess1_fatmapaccess2_fatmapclonemapclone2mapdelete_fast32mapdelete_fast64mapinitnoopmaps_errNilAssignmaps_fatalmaps_mapKeyErrormaps_newarraymaps_newobjectmaps_randmaps_typedmemclrmaps_typedmemmovemaptypemarkBitsmarkBitsForAddrmarkBitsForSpanmarkrootmarkrootBlockmarkrootFreeGStacksmarkrootSpansmask2mask3mask4maskUpdatedChanmaskxmaxAlignmaxAllocmaxCPUProfStackmaxObjsPerSpanmaxObletBytesmaxOffAddrmaxPackedValuemaxPagesPerPhysPagemaxPhysHugePageSizemaxPhysPageSizemaxProfStackDepthmaxRunemaxSearchAddrmaxSkipmaxSmallSizemaxStackScanSlackmaxTinySizemaxTraceStringLenmaxTriggerRatioNummaxUint64maxWhenmaxstackceilingmaxstacksizemayMoreStackMovemayMoreStackPreemptmbucketsmcachemcache0mcallmcentralmcommoninitmcontextmcountmdestroymdumpmemProfilememProfileInternalmemRecordmemRecordCyclememclrHasPointersmemclrNoHeapPointersmemclrNoHeapPointersChunkedmemequalmemequal0memequal128memequal16memequal32memequal64memequal8memequal_varlenmemhashmemhash0memhash128memhash16memhash32memhash32Fallbackmemhash64memhash64Fallbackmemhash8memhashFallbackmemhash_varlenmemmoveBitsmemoryErrormemoryLimitHeapGoalHeadroomPercentmemoryLimitMinHeapGoalHeadroommergeSummariesmethodValueCallFrameObjsmetricDatametricFloat64HistogrammetricKindmetricKindBadmetricKindFloat64metricKindFloat64HistogrammetricKindUint64metricNamemetricReadermetricSamplemetricValuemetricsInitmetricsLockmetricsSemametricsUnlockmexitmgetmheapmheap_minHeapAlignminHeapForMetadataHugePagesminLegalPointerminOffAddrminPhysPageSizeminScavWorkTimeminSizeForMallocHeaderminTagBitsminTimeForTicksPerSecondminTriggerRatioNummincoreminhexdigitsminitminitSignalMaskminitSignalStackminitSignalsmixmlinkmoduledataverifymoduledataverify1modulesSlicemodulesinitmorestackmorestack_noctxtmorestackcmpreinitmprotectmputmrandinitmsanenabledmsanfreemsanmallocmsanmovemsanreadmsanwritemsigrestoremspanmspinningmstartmstart0mstart1mstartm0mstatsmuintptrmullumutexActiveSpinCountmutexActiveSpinSizemutexContendedmutexMMaskmutexMOffsetmutexPassiveSpinCountmutexPreferLowLatencymutexProfilemutexProfileInternalmutexSleepingmutexSpinningmutexStackLockedmutexTailWakePeriodmutexWaitListHeadmutexeventmutexprofileratenan32nan64nanotime1ncgocallncpuneedAndBindMneedSysmonWorkaroundneedmneg32neg64netpollnetpollAdjustWaitersnetpollAnyWaitersnetpollBreaknetpollDeadlinenetpollEventFdnetpollGenericInitnetpollInitLocknetpollInitednetpollIsPollDescriptornetpollReadDeadlinenetpollWaitersnetpollWakeSignetpollWriteDeadlinenetpollarmnetpollblocknetpollblockcommitnetpollcheckerrnetpollclosenetpolldeadlineimplnetpollgoreadynetpollinitnetpollinitednetpollopennetpollreadynetpollunblockneverCallThisFunctionnewAllocBitsnewArenaMayUnlocknewBucketnewInlineUnwindernewMarkBitsnewProfBufnewSpecialsIternewUserArenanewUserArenaChunknewWakeableSleepnewdefernewextramnewmnewm1newmHandoffnewosprocnewosproc0newprocnewproc1newprocsnewstacknextFreeFastnextMarkBitArenaEpochnextSamplenextSampleNoFPnextslicecapnilfuncnilinterequalnilinterhashnoEscapePtrnoSignalStacknoescapenonblockingPipenotInHeapnotInHeapSlicenotenoteclearnotesleepnotetsleepnotetsleep_internalnotetsleepgnotewakeupnotifyListAddnotifyListChecknotifyListNotifyAllnotifyListNotifyOnenotifyListWaitnsToSecnumSpanClassesnumStatsDepsnumSweepClassesoffAddroffAddrToLevelIndexoffsetARMHasIDIVAoffsetLOONG64HasLSXoffsetMIPS64XHasMSAoffsetX86HasAVXoffsetX86HasERMSoffsetX86HasRDTSCPoneNewExtraMoneptrmaskosArchInitosHasLowResClockosHasLowResClockIntosHasLowResTimerosPreemptExtEnterosPreemptExtExitosRelaxosRelaxMinNSosSetupTLSosStackAllocosStackFreeos_beforeExitos_runtime_argsos_sigpipeosinitosyieldosyield_no_goverflowTagoverrideWritepMaskpTraceStatepackPallocSumpageAllocpageAlloc32BitpageAlloc64BitpageBitspageCachepageCachePagespageIndexOfpageShiftpagesPerArenapagesPerReclaimerChunkpagesPerSpanRootpallocBitspallocChunkBytespallocChunkPagespallocChunksL1BitspallocChunksL1ShiftpallocChunksL2BitspallocDatapallocSumpallocSumBytespanicCheck1panicCheck2panicIndexpanicIndexUpanicSlice3AcappanicSlice3AcapUpanicSlice3AlenpanicSlice3AlenUpanicSlice3BpanicSlice3BUpanicSlice3CpanicSlice3CUpanicSliceAcappanicSliceAcapUpanicSliceAlenpanicSliceAlenUpanicSliceBpanicSliceBUpanicSliceConvertpanicdividepanicdottypeEpanicdottypeIpanicfloatpaniclkpanicmakeslicecappanicmakeslicelenpanicmempanicmemAddrpanicnilpanicnildottypepanicoverflowpanicrangestatepanicshiftpanicunsafeslicelenpanicunsafeslicelen1panicunsafeslicenilptrpanicunsafeslicenilptr1panicunsafestringlenpanicunsafestringnilptrpanicwrappark_mparkunlock_cparseByteCountparsedebugvarsparsegodebugpausepcdatastartpcdatavaluepcdatavalue1pcdatavalue2pcvaluepcvalueCachepcvalueCacheEntpcvalueCacheKeypdEfacepdNilpdReadypdTypepdWaitpendingPreemptSignalsperThreadSyscallperThreadSyscallArgspersistentAllocpersistentChunkSizepersistentChunkspersistentallocpersistentalloc1physHugePageShiftphysHugePageSizephysPageAlignedStacksphysPageSizepiControllerpidlegetpidlegetSpinningpidleputpinStatepinnedTypemapspinnerpinnerBitspinnerGetPinCounterpinnerGetPtrpinnerLeakPanicpinnerRefStoreSizepinnerSizeplainErrorplugin_lastmoduleinitpluginftabverifypointerMaskpollBlockSizepollCachepollClosingpollEventErrpollExpiredReadDeadlinepollExpiredWriteDeadlinepollFDSeqpollFDSeqBitspollFDSeqMaskpollFractionalWorkerExitpollInfopollWorkpoll_runtime_Semacquirepoll_runtime_Semreleasepoll_runtime_isPollServerDescriptorpoll_runtime_pollClosepoll_runtime_pollOpenpoll_runtime_pollResetpoll_runtime_pollServerInitpoll_runtime_pollSetDeadlinepoll_runtime_pollUnblockpoll_runtime_pollWaitpoll_runtime_pollWaitCanceledpollcachepoolcleanuppopDeferpostMallocgcDebugpprof_blockProfileInternalpprof_cyclesPerSecondpprof_fpunwindExpandpprof_goroutineProfileWithLabelspprof_makeProfStackpprof_memProfileInternalpprof_mutexProfileInternalpprof_threadCreateInternalpreMallocgcDebugpreemptMpreemptMSupportedpreemptParkpreemptallpreemptoneprepGoExitFrameprepareFreeWorkbufspreprintpanicsprintAncestorTracebackprintAncestorTracebackFuncInfoprintArgsprintBacklogprintBacklogIndexprintCgoTracebackprintDebugLogprintDebugLogImplprintDebugLogPCprintFuncNameprintOneCgoTracebackprintScavTraceprintanycustomtypeprintboolprintcomplexprintcreatedbyprintcreatedby1printefaceprintfloatprinthexprintifaceprintindentedprintintprintlockprintnlprintpanicsprintpanicvalprintpointerprintsliceprintspprintstringprintuintprintuintptrprintunlockprocPinprocUnpinprocessorVersionInfoprocresizeprocyieldprofprofAtomicprofBlockLockprofBufprofBufBlockingprofBufNonBlockingprofBufReadModeprofBufTagCountprofBufWordCountprofIndexprofInsertLockprofMemActiveLockprofMemFutureLockprofReaderSleepingprofWriteExtraprofileallocprogToPointerMaskptrBitsptrnamesptrtypepublicationBarrierpuintptrputCachedDloggerputExtraMputemptyputfullqueuefinalizerr4r8raceFiniLockraceReadObjectPCraceWriteObjectPCraceacquireraceacquirectxraceacquiregracecgosyncracectxendracefingoracefiniracefreeracegoendracegostartraceinitracemallocracemapshadowracenotifyraceproccreateraceprocctx0raceprocdestroyracereadpcracereadrangepcracereleaseracereleaseacquireracereleaseacquiregracereleasegracereleasemergeracereleasemergegracesyncracewritepcracewriterangepcraiseraisebadsignalraiseprocrand32rand_fatalrandinitrandnrandomEnumrandomOrderrandomizeSchedulerrangeDoneErrorrangeExhaustedErrorrangeMissingPanicErrorrangePanicErrorrawbyteslicerawruneslicerawstringrawstringtmpreadGCStats_mreadGOGCreadGOMEMLIMITreadMetricNamesreadMetricsreadMetricsLockedreadRandomreadRandomFailedreadTimeRandomreadTrace0readUintptrreadUnaligned32readUnaligned64readgstatusreadmemstats_mreadvarintreadvarintUnsafereadyWithTimerecordForPanicrecordspanrecoveryrecvDirectredZoneSizereduceExtraPercentreentersyscallreflectMethodValuereflectOffsreflectOffsLockreflectOffsUnlockreflect_addReflectOffreflect_chancapreflect_chanclosereflect_chanlenreflect_chanrecvreflect_chansendreflect_gcbitsreflect_growslicereflect_ifaceE2Ireflect_makechanreflect_makemapreflect_mapaccessreflect_mapaccess_faststrreflect_mapassignreflect_mapassign_faststrreflect_mapclearreflect_mapdeletereflect_mapdelete_faststrreflect_mapiterelemreflect_mapiterinitreflect_mapiterkeyreflect_mapiternextreflect_maplenreflect_memclrNoHeapPointersreflect_memmovereflect_resolveNameOffreflect_resolveTextOffreflect_resolveTypeOffreflect_rselectreflect_typedarrayclearreflect_typedmemclrreflect_typedmemclrpartialreflect_typedmemmovereflect_typedslicecopyreflect_typehashreflect_typelinksreflect_unsafe_Newreflect_unsafe_NewArrayreflect_unsafeslicereflect_verifyNotInHeapPtrreflectcallreflectcallmovereflectlite_chanlenreflectlite_ifaceE2Ireflectlite_maplenreflectlite_resolveNameOffreflectlite_resolveTypeOffreflectlite_typedmemmovereflectlite_unsafe_NewreleaseLockRankAndMreleaseSudogreleasemreleasepreleasepNoTraceremovefinalizerremovespecialreparsedebugvarsrepmovsPreferredresetForSleepresetTimerresetspinningrestoreGsignalStackresumeGretainExtraPercentretakeretpolineAXretpolineBPretpolineBXretpolineCXretpolineDIretpolineDXretpolineR10retpolineR11retpolineR12retpolineR13retpolineR14retpolineR15retpolineR8retpolineR9retpolineSIretryOnEAGAINreturn0riscv64AddrBitsriscv64TagBitsrootBlockBytesround2roundupsizert0_gort_sigactionrtsigprocmaskrunExitHooksrunGCProgrunPerThreadSyscallrunSafePointFnrune1Maxrune2Maxrune3MaxruneSelfrunfinqrunningPanicDefersrunqdrainrunqemptyrunqgetrunqgrabrunqputrunqputbatchrunqputslowrunqstealruntimeInitTimeruntime_FrameStartLineruntime_FrameSymbolNameruntime_debug_WriteHeapDumpruntime_debug_freeOSMemoryruntime_expandFinalInlineFrameruntime_getProfLabelruntime_inittasksruntime_pprof_readProfileruntime_setProfLabelrwmutexrwmutexMaxReaderssavesaveAncestorssaveBlockEventStacksaveblockeventsavedOpenDeferStatesavegsbrk0scanConservativescanblockscanframeworkerscanobjectscanstackscasescavChunkDatascavChunkFlagsscavChunkFlagsMaskscavChunkHasFreescavChunkHiOccFracscavChunkHiOccPagesscavChunkInUseMaskscavChunkMaxFlagsscavengescavengeCostRatioscavengeIndexscavengePercentscavengerscavengerStateschedschedEnableUserschedEnabledsched_getaffinityschedinitschedtschedtraceschedulesecuresecureEnvsecureModeselectDefaultselectDirselectRecvselectSendselectgoselectnbrecvselectnbsendselectsetpcsellockselparkcommitselunlocksemTabSizesemTablesemaBlockProfilesemaMutexProfilesemaProfileFlagssemaRootsemacquiresemacquire1semacreatesemasleepsemawakeupsemreleasesemrelease1semtablesendDirectsetCheckmarksetCrashFDsetGCPhasesetGNoWBsetGsignalStacksetMNoWBsetPinnedsetProcessCPUProfilersetProcessCPUProfilerTimersetSignalstackSPsetThreadCPUProfilersetThreadCPUProfilerHzsetTracebacksetcpuprofileratesetenv_csetgsetprofilebucketsetsigsetsigsegvsetsigstacksettlsshadeshiftErrorshouldPushSigpanicshowframeshowfuncinfoshrinkstacksigFetchGsigIdlesigInitIgnoredsigInstallGoHandlersigNotOnStacksigNoteSetupsigNoteSleepsigNoteWakeupsigPerThreadSyscallsigPreemptsigReceivingsigSendingsigTabTsigactionsigactiontsigaddsetsigaltstacksigblocksigcontextsigctxtsigdelsetsigdisablesigenablesigeventsigeventFieldssigfillsetsigfwdsigfwdgosighandlersigignoresiginfosiginfoFieldssignalDuringForksignalMsignalsOKsignalstacksignamesigpanicsigpanic0sigprocmasksigprofsigprofCallerssigprofCallersUsesigprofNonGosigprofNonGoPCsigreturn__sigactionsigsavesigsendsigsetsigsetAllExitingsigset_allsigsysIgnoredsigtablesigtrampsigtrampgosizeClassBucketssize_to_class128size_to_class8sliceEfacesliceInterfacePtrslicebytetostringslicebytetostringtmpslicecopyslicerunetostringslicetypesmallSizeDivsmallSizeMaxsockaddr_unspanAllocHeapspanAllocPtrScalarBitsspanAllocStackspanAllocTypespanAllocWorkBufspanClassspanHasNoSpecialsspanHasSpecialsspanOfHeapspanOfUncheckedspanSetspanSetBlockspanSetBlockAllocspanSetBlockEntriesspanSetBlockPoolspanSetInitSpineCapspanSetSpinePointerspecialCleanupspecialPinCounterspecialReachablespecialWeakHandlespecialfinalizerspecialprofilespecialsIterspillArgsstackDebugstackFaultOnFreestackForceMovestackForkstackFromSystemstackGuardstackLargestackMinstackNoCachestackNosplitstackObjectstackObjectBufstackObjectBufHdrstackObjectRecordstackPoisonCopystackPoisonMinstackPreemptstackScanStatestackSystemstackTraceDebugstackWorkBufstackWorkBufHdrstackallocstackcache_clearstackcacherefillstackcachereleasestackcheckstackfreestackfreeliststackinitstacklog2stackmapstackmapdatastackpoolstackpoolItemstackpoolallocstackpoolfreestacktstartCheckmarksstartPCForTracestartTemplateThreadstartTheWorldstartTheWorldGCstartTheWorldWithSemastartingScavSleepRatiostartingStackSizestartlockedmstartmstartpanic_mstarttimestartupRandstatAggregatestatDepstatDepSetstaticLockRankingstaticuint64sstealOrderstealWorkstkbucketstkframestkobjinitstopTheWorldstopTheWorldContextstopTheWorldGCstopTheWorldWithSemastopTimerstoplockedmstopmstrequalstrhashstrhashFallbackstringDataOnStackstringEfacestringHashstringInterfacePtrstringStructstringStructDWARFstringStructOfstringtoslicebytestringtoslicerunestrmaxstrminstructtypestwAllGoroutinesStackstwAllThreadsSyscallstwForTestCountPagesInUsestwForTestPageCachePagesLeakedstwForTestReadMemStatsSlowstwForTestReadMetricsSlowstwForTestResetDebugLogstwGCMarkTermstwGCSweepTermstwGOMAXPROCSstwGoroutineProfilestwGoroutineProfileCleanupstwReadMemStatsstwReasonstwReasonStringsstwStartTracestwStopTracestwUnknownstwWriteHeapDumpsubtract1subtractbsudogsummaryL0BitssummaryLevelBitssummaryLevelssurrogateMaxsurrogateMinsuspendGsuspendGStatesweepsweepClasssweepClassDonesweepDrainedMasksweepLockedsweepLockersweepMinHeapDistancesweepdatasweeponeswitchToCrashStackswitchToCrashStack0sync_atomic_CompareAndSwapPointersync_atomic_CompareAndSwapUintptrsync_atomic_StorePointersync_atomic_StoreUintptrsync_atomic_SwapPointersync_atomic_SwapUintptrsync_atomic_runtime_procPinsync_atomic_runtime_procUnpinsync_fatalsync_runtime_Semacquiresync_runtime_SemacquireRWMutexsync_runtime_SemacquireRWMutexRsync_runtime_SemacquireWaitGroupsync_runtime_Semreleasesync_runtime_canSpinsync_runtime_doSpinsync_runtime_procPinsync_runtime_procUnpinsync_runtime_registerPoolCleanupsync_throwsyncadjustsudogssynctestGroupsynctestRunsynctestWaitsynctest_acquiresynctest_inBubblesynctest_releasesynctestidle_csynctestwait_csysAllocsysAllocOSsysFaultsysFaultOSsysFreesysFreeOSsysHugePagesysHugePageCollapsesysHugePageCollapseOSsysHugePageOSsysMapsysMapOSsysMemStatsysMmapsysMunmapsysNoHugePagesysNoHugePageOSsysReservesysReserveAlignedsysReserveAlignedSbrksysReserveOSsysSigactionsysStatsAggregatesysStatsDepsysTHPSizePathsysUnusedsysUnusedOSsysUsedsysUsedOSsysargssysauxvsyscall_Exitsyscall_Getpagesizesyscall_cgocallersyscall_runtimeSetenvsyscall_runtimeUnsetenvsyscall_runtime_AfterExecsyscall_runtime_AfterForksyscall_runtime_AfterForkInChildsyscall_runtime_BeforeExecsyscall_runtime_BeforeForksyscall_runtime_doAllThreadsSyscallsyscall_runtime_envssysmonsysmonticksysrand_fatalsystemstacksystemstack_switcht3t4t5tagAllocSampletagBSStagBitstagDatatagDefertagEOFtagFinalizertagGoroutinetagItabtagMemProftagMemStatstagOSThreadtagObjecttagOtherRoottagPanictagParamstagQueuedFinalizertagStackFrametaggedPointertaggedPointerBitstaggedPointerPacktemplateThreadtestAtomic64testSPWritetestSigtraptestSigusr1testSmallBuftest_x64test_z64tgkillthreadCreateProfileInternalthrowTypethrowTypeNonethrowTypeRuntimethrowTypeUserticksticksPerSecondticksTypetimeHistBucketstimeHistMaxBucketBitstimeHistMinBucketBitstimeHistNumBucketstimeHistNumSubBucketstimeHistSubBucketBitstimeHistTotalBucketstimeHistogramtimeHistogramMetricsBucketstimeSleeptimeSleepUntiltime_nowtime_runtimeNanotime_runtimeNowtimedivtimerDebugtimerHeapNtimerHeapedtimerModifiedtimerWhentimerZombietimer_createtimer_deletetimer_settimetimerchandraintimerpMasktimespectimevaltinySizeClasstinySpanClasstlsSizetlsSlotstmpBuftmpStringBufSizetmpbuftotalMutexWaitTimeNanostraceAcquiretraceAcquireEnabledtraceAdvancetraceAdvanceSematraceAdvancertraceAdvancerStatetraceAllocFreeEnabledtraceAllocFreeInfoBatchtraceAllocFreeTypesBatchtraceArgtraceBlockChanRecvtraceBlockChanSendtraceBlockCondWaittraceBlockDebugCalltraceBlockForevertraceBlockGCMarkAssisttraceBlockGCSweeptraceBlockGCWeakToStrongWaittraceBlockGenerictraceBlockNettraceBlockPreemptedtraceBlockReasontraceBlockReasonStringstraceBlockSelecttraceBlockSleeptraceBlockSynctraceBlockSynctesttraceBlockSystemGoroutinetraceBlockUntilGCEndstraceBuftraceBufFlushtraceBufHeadertraceBufQueuetraceBytesPerNumbertraceCPUFlushtraceCPUSampletraceClockNowtraceClockUnitsPerSecondtraceCompressStackSizetraceEnabledtraceEvtraceEvCPUSampletraceEvCPUSamplestraceEvEventBatchtraceEvExperimentalBatchtraceEvFrequencytraceEvGCActivetraceEvGCBegintraceEvGCEndtraceEvGCMarkAssistActivetraceEvGCMarkAssistBegintraceEvGCMarkAssistEndtraceEvGCSweepActivetraceEvGCSweepBegintraceEvGCSweepEndtraceEvGoBlocktraceEvGoCreatetraceEvGoCreateBlockedtraceEvGoCreateSyscalltraceEvGoDestroytraceEvGoDestroySyscalltraceEvGoLabeltraceEvGoStarttraceEvGoStatustraceEvGoStatusStacktraceEvGoStoptraceEvGoSwitchtraceEvGoSwitchDestroytraceEvGoSyscallBegintraceEvGoSyscallEndtraceEvGoSyscallEndBlockedtraceEvGoUnblocktraceEvGoroutineStacktraceEvGoroutineStackAlloctraceEvGoroutineStackFreetraceEvHeapAlloctraceEvHeapGoaltraceEvHeapObjecttraceEvHeapObjectAlloctraceEvHeapObjectFreetraceEvNonetraceEvProcStarttraceEvProcStatustraceEvProcStealtraceEvProcStoptraceEvProcsChangetraceEvSTWBegintraceEvSTWEndtraceEvSpantraceEvSpanAlloctraceEvSpanFreetraceEvStacktraceEvStackstraceEvStringtraceEvStringstraceEvUserLogtraceEvUserRegionBegintraceEvUserRegionEndtraceEvUserTaskBegintraceEvUserTaskEndtraceEventWritertraceExitedSyscalltraceExitingSyscalltraceExperimenttraceExperimentAllocFreetraceFrametraceFrequencytraceGoBadtraceGoRunnabletraceGoRunningtraceGoStatustraceGoStopGenerictraceGoStopGoSchedtraceGoStopPreemptedtraceGoStopReasontraceGoStopReasonStringstraceGoSyscalltraceGoWaitingtraceGoroutineStackIDtraceHeapObjectIDtraceInitReadCPUtraceLockInittraceLockertraceMaptraceMapNodetraceNextGentraceNoExperimenttraceNumExperimentstraceProcBadtraceProcIdletraceProcRunningtraceProcStatustraceProcSyscalltraceProcSyscallAbandonedtraceReadCPUtraceReadertraceReaderAvailabletraceRegionAlloctraceRegionAllocBlocktraceRegionAllocBlockDatatraceRegionAllocBlockHeadertraceRegisterLabelsAndReasonstraceReleasetraceSchedResourceStatetraceShutdownSematraceShuttingDowntraceSnapshotMemorytraceSpanIDtraceSpanTypeAndClasstraceStacktraceStackSizetraceStackTabletraceStartReadCPUtraceStopReadCPUtraceStringTabletraceThreadDestroytraceTimetraceTimeDivtraceTypeTabletraceWritertrace_userLogtrace_userRegiontrace_userTaskCreatetrace_userTaskEndtracebacktraceback1traceback2tracebackAlltracebackCrashtracebackHexdumptracebackInnerFramestracebackOuterFramestracebackPCstracebackShifttraceback_cachetraceback_envtracebackotherstracebacktraptracefpunwindofftracestattriggerRatioDentryRecordGoroutineProfiletryRecordGoroutineProfileWBtrygetfulltypeAsserttypeBitsBulkBarriertypeCacheAssoctypeCacheBuckettypeCacheBucketstypePointerstypecachetypelinksinittypesEqualucontextuint16Efaceuint16InterfacePtruint32Efaceuint32InterfacePtruint64Efaceuint64InterfacePtruintptrMaskunblockTimerChanunblocksiguncommontypeuniqueMapCleanupunique_runtime_registerUniqueMapCleanupunlock2unlock2WakeunlockOSThreadunlockWithRankunlockextraunminitunminitSignalsunpackScavChunkDataunreachableMethodunsafeTraceExpWriterunsafeTraceWriterunsafeslice64unsafeslicecheckptrunsafestringunsafestring64unsafestringcheckptrunsetenv_cunspillArgsunwindFlagsunwindJumpStackunwindPrintErrorsunwindSilentErrorsunwindTrapunwinderunwindmurandom_devuseAeshashuseCheckmarkuserArenauserArenaChunkBytesuserArenaChunkBytesMaxuserArenaChunkMaxAllocBytesuserArenaChunkPagesuserArenaChunkReserveBytesuserArenaHeapBitsSetSliceTypeuserArenaHeapBitsSetTypeuserArenaStateusesLRusesLibcallusigsetusleepusleep_no_gvalidSIGPROFvdsoArrayMaxvdsoBloomSizeScalevdsoClockgettimeSymvdsoDynSizevdsoFindVersionvdsoGetrandomSymvdsoGettimeofdaySymvdsoHashSizevdsoInfovdsoInitFromSysinfoEhdrvdsoLinuxVersionvdsoLoadEndvdsoLoadStartvdsoParseSymbolsvdsoSymStringsSizevdsoSymTabSizevdsoSymbolKeyvdsoSymbolKeysvdsoVerSymSizevdsoVersionKeyvdsoauxvverifyTimersvgetrandom1vgetrandomAllocvgetrandomDestroyvgetrandomGetStatevgetrandomInitwaitReasonwaitReasonChanReceivewaitReasonChanReceiveNilChanwaitReasonChanSendwaitReasonChanSendNilChanwaitReasonCoroutinewaitReasonDebugCallwaitReasonDumpingHeapwaitReasonFinalizerWaitwaitReasonFlushProcCacheswaitReasonForceGCIdlewaitReasonGCAssistMarkingwaitReasonGCAssistWaitwaitReasonGCMarkTerminationwaitReasonGCScavengeWaitwaitReasonGCSweepWaitwaitReasonGCWeakToStrongWaitwaitReasonGCWorkerActivewaitReasonGCWorkerIdlewaitReasonGarbageCollectionwaitReasonGarbageCollectionScanwaitReasonIOWaitwaitReasonPageTraceFlushwaitReasonPanicWaitwaitReasonPreemptedwaitReasonSelectwaitReasonSelectNoCaseswaitReasonSemacquirewaitReasonSleepwaitReasonStoppingTheWorldwaitReasonStringswaitReasonSyncCondWaitwaitReasonSyncMutexLockwaitReasonSyncRWMutexLockwaitReasonSyncRWMutexRLockwaitReasonSyncWaitGroupWaitwaitReasonSynctestChanReceivewaitReasonSynctestChanSendwaitReasonSynctestRunwaitReasonSynctestSelectwaitReasonSynctestWaitwaitReasonTraceGoroutineStatuswaitReasonTraceProcStatuswaitReasonTraceReaderBlockedwaitReasonWaitForGCCyclewaitReasonZerowaitqwakeNetPollerwakeableSleepwakefingwakepwantAsyncPreemptwbBufwbBufEntrieswbBufFlushwbBufFlush1wbMaxEntriesPerCallwbMovewbZerowinlibcallwirepworkTypeworkbufworkbufAllocworkbufhdrworldStartedworldStopworldStoppedworldsemawrite1writeBarrierwriteErrDatawriteErrStrwriteUserArenaHeapBitswriteheapdump_mx86HasFMAx86HasPOPCNTx86HasSSE41xbucketsxmmregxmmreg1zerobasesa_handlersa_flagssa_restorersa_maskcontinpclrfpvarpargpargBytesargMapInternalgetStackMapcascgoCtxtcalleeFuncIDinitAtresolveInternalfinishInternalsymPCinsertBackbytepbitpsizeclassnoscanlessThanlessEqualsubtracttakeFromFronttakeFromBackremoveGreaterEqualstartAddrnpagesmanualFreeListfreeindexnelemsfreeIndexForScanallocCacheallocBitsgcmarkBitssweepgendivMulallocCountspanclassneedzeroisUserArenaChunkallocCountBeforeCachespeciallockspecialsuserArenaChunkFreelargeTypeuserArenaNextFreeisUnusedUserArenaChunksetUserArenaChunkToFaulttypePointersOftypePointersOfUncheckedtypePointersOfTypeobjBaseinitHeapBitsheapBitsheapBitsSmallForAddrwriteHeapBitsSmallallocBitsForIndexrefillAllocCachenextFreeIndexdivideByElemSizeobjIndexmarkBitsForIndexmarkBitsForBasecountAllocensureSweptreportZombieslayoutinListspecialFindSplicePointpinnerBitSizenewPinnerBitsgetPinnerBitssetPinnerBitsrefreshPinnerBitsincPinCounterdecPinCounterfaultptrBytesgcdataoffsetRecordst_namest_infost_otherst_shndxst_valuest_sizestartPCstartSPretpcdeferBitsPtrslotsPtrrecoverednextDefernextFrameinitOpenCodedDefersrangefuncstackguard0stackguard1stktopspschedticksyscalltickschedwhensyscallwhen136memProfRatescanAlloctinytinyoffsettinyAllocsstackcacheflushGennextFreeallocLargereleaseAllprepareForSweepscavallocNpushAllchangegstatussgincActivedecActivemaybeWakeLockedraceaddrzombiesraceCtxminWhenHeapminWhenModifiedsyncGroupaddHeapdeleteMincleanHeadadjustwakeTimeupdateMinWhenHeapupdateMinWhenModifiedsiftUpsiftDowninitHeapastateisChanisFakeblockedsendLockisSendingtrace1updateHeapmaybeRunAsyncmodifyneedsAddmaybeAddunlockAndRunmaybeRunChanenqueuedequeuedequeueSudoGqcountdataqsizsynctestelemtypesendxrecvxrecvqsendqsortkeyacquiretimereleasetimeisSelectwaitlinkwaittailrefStoreunpinstatusTracedacquireStatusreadyNextGenstatusWasTracedsetStatusTracednextSeqmSyscallIDmaySweepinSweepsweptreclaimedstamppushcntnobjchecknonemptycheckemptywbuf1wbuf2bytesMarkedheapScanWorkflushedWorkputFastputBatchtryGettryGetFastdisposebalanceget1get2pcacheraceprocctxdeferpooldeferpoolbufgoidcachegoidcacheendrunqheadrunqtailrunqrunnextgFreesudogcachesudogbufmspancachepinnerCachepallocgcAssistTimegcFractionalMarkTimegcMarkWorkerStartTimegcwstatsSeqmaxStackScanDeltascannedStackSizescannedStackspreemptgcStopTimecyclescyclesLosthaveStackrecordLockrecordUnlockcaptureStacklastTimelenPos65504varintReservestringDatavarintAtseqlockreenteredoldthrowsplitr1targetpcvalPCprofileTimerprofileTimerValidneedPerThreadSyscallvgetrandomStatewaitsemaranklockAddrmorebufdivmodprocidgsignalgoSigStacksigmaskmstartfncurgcaughtsignextpoldpmallocingthrowingpreemptoffdyingprofilehzspinningnewSigstackincgoisextraisExtraInCisExtraInSigfreeWaitneedextramg0StackAccurateallpSnapshotncgocgoCallersUseparkalllinkschedlinklockedgcreatestacklockedExtlockedIntprofStackwaitunlockfwaitlockwaitTraceSkipwaitTraceBlockReasonfreelinklibcallpclibcallsplibcallgwinsyscallvdsoSPvdsoPCpreemptGensignalPendingchacha8locksHeldLenlocksHeldbecomeSpinningsnapshotAllpclearAllpSnapshothasCgoOnStackisMutexWaitgoidgopcsyscallspsyscallpcsyscallbpatomicstatusstackLockwaitsincewaitreasonpreemptStoppreemptShrinkasyncSafePointpaniconfaultgcscandonethrowsplitactiveStackChansparkingOnChaninMarkAssistraceignorenocgocallbacktrackingtrackingSeqtrackingStamprunnableTimelockedmfipsIndicatorwritebufsigcode0sigcode1sigpcparentGoidancestorsstartpcracectxsleepWhenselectDonegoroutineProfiledcoroarggcAssistBytesuftv_sectv_usecset_usecit_intervalit_valuedataCounttagCountaddCountsAndClearFlagsisGCstartedStoppingfinishedStoppingstoppingCPUTimemarkDrainedsweepersparkedcentralIndexerrIntegralinputOverflowsh_namesh_typesh_flagssh_addrsh_offsetsh_sizesh_linksh_infosh_addralignsh_entsizefastForwardsummarizefind1findSmallNfindLargeNallocRangeallocAllfree1freeAllpages64allocPages64block64setRangesetAllsetBlock64clearRangeclearAllclearBlock64popcntRangescavengedfindScavengeCandidatefdseqatomicInforrunwrunrseqwseqwtpublishInfosetEventErrmakeArgpkgpathStoreMinStoreUnmarkStoreMarkedfloat64HistOrInitwakeupwakess_spss_flagspad_cgo_0ss_sizesi_signosi_errnosi_codesi_addrminHeapIdxsearchAddrBgsearchAddrForcefreeHWMnextGensysGrowsysInitsetNonEmptylastInUseshouldScavengesignificandcwdswdftwfopriprdpmxcsrmxcr_mask_st_xmmr9r10r11r12r13r14r15rdirsirbprbxrdxraxrcxrspeflags__pad0trapnooldmaskcr2__reserved1tv_nsecsetNsecGCAssistTimeGCDedicatedTimeGCIdleTimeGCPauseTimeGCTotalTimeScavengeAssistTimeScavengeBgTimeScavengeTotalTimeTotalTimeaccumulateGCPauseTimeaccumulatecomputespinAfterRaggedBarrierrestartedDueTo27993overflowTimehdrsizerNextoverflowBufhasOverflowtakeOverflowincrementOverflowcanWriteRecordcanWriteTwoRecordswakeupExtraonnumExtralostExtralostAtomicaddNonGoaddExtrareleasedinHeapinStacksinWorkBufsinPtrScalarBitstinyAllocCountlargeAlloclargeAllocCountsmallAllocCountlargeFreelargeFreeCountsmallFreeCountnoPLockunsafeReadunsafeCleard_tagd_valbusypushBackAllpopListwbufSpansmarkrootNextmarkrootJobsnproctstartnwaitnDataRootsnBSSRootsnSpanRootsnStackRootsbaseDatabaseBSSbaseSpansbaseStacksbaseEndstackRootsstartSemamarkDoneSemabgMarkDoneuserForcedinitialHeapLiveassistQueuesweepWaitersstrongFromWeakstwprocsmaxprocstSweepTermtMarktMarkTermtEndpauseNSheap0heap1heap2RuntimeErrorinObjectsnumObjectstotalAllocatedtotalFreedtotalAllocstotalFreesstacksSysmSpanSysmCacheSysmCacheInUsebuckHashSysgcMiscSysotherSysheapGoalgcCyclesDonegcCyclesForcedheapScanstackScanglobalsScantotalScanensuredheapStatssysStatsgcStatsgcEnabledtransitioningassistTimePoolidleMarkTimePoolidleTimePoollastUpdatelastEnabledCyclenprocslimitingstartGCTransitionfinishGCTransitionneedUpdateaddAssistTimeaddIdleTimeupdateLockedtryLockresetCapacitytreaprotateLeftrotateRightrootForunderflownbiti8i16i32uptru8u16ofObjectnanoreadUint16LEAtreadUint64LEAtuvarintprintValwriteFrameAtwriteSyncwriteUint64LEallLinkownedrLockreaderPasswLockreadRankrlockrunlockPinUnpinSpanExistsSpanAllocSpanFreeHeapObjectExistsHeapObjectAllocHeapObjectFreeGoroutineStackExistsGoroutineStackAllocGoroutineStackFreeeventWriteruniqueStringexpWriterGomaxprocsProcStartProcStopGCActiveGCStartGCDoneSTWStartSTWDoneGCSweepStartGCSweepSpanGCSweepDoneGCMarkAssistStartGCMarkAssistDoneGoCreateGoStartGoEndGoSchedGoPreemptGoStopGoParkGoUnparkGoSwitchemitUnblockStatusGoSysCallGoSysExitProcStealHeapGoalGoCreateSyscallGoDestroySyscallwriteGoStatuswriteProcStatusForPwriteProcStatus469124961184421125899906842623562949953421311vd_versionvd_flagsvd_ndxvd_cntvd_hashvd_auxvd_nextloadAddrloadOffsetsymtabsymstringssymOffisGNUHashversymverdefverHashdeltasghiallocsargoffarglenallnextnstksysmonWakeprintControllerResettargetCPUFractionsleepRatiosleepControllercontrollerCooldownsleepStubshouldStopcontrollerFailedsetFlushedmanualStack0retvalfixsigcodesigFromUsersigFromSeccompsetsigpcsigspsiglrpreparePanicpushCallregsrflagssigcodesigaddrset_ripset_rspset_sigcodeset_sigaddrbyteValisMultiPinnedsetMultiPinnedminv65520gcPercentmemoryLimitheapMinimumrunwayconsMarklastConsMarkgcPercentHeapGoalsweepDistMinTriggertriggeredlastHeapGoalheapLivelastHeapScanlastStackScanmaxStackScanheapMarkedstackScanWorkglobalsScanWorkbgScanCreditassistTimededicatedMarkTimefractionalMarkTimeidleMarkTimemarkStartTimededicatedMarkWorkersNeededidleMarkWorkersassistWorkPerByteassistBytesPerWorkfractionalUtilizationGoalheapInUseheapReleasedheapFreetotalAlloctotalFreemappedReadystartCyclereviseendCycleenlistWorkerfindRunnableGCWorkerresetLivemarkWorkerStopaddScannableStackheapGoalInternalmemoryLimitHeapGoaltriggeraddIdleMarkWorkerneedIdleMarkWorkerremoveIdleMarkWorkersetMaxIdleMarkWorkersnretfintot101fin__valnchunknallocinusealignmetryAllocp_typep_flagsp_offsetp_vaddrp_paddrp_fileszp_memszp_alignsweepGentryAcquire252cbufnobjsputPtrgetPtraddObjectparentPcinlTree_interfaceconcreteassertedstacks_sysmspan_sysmcache_sysbuckhash_sysother_syslast_gc_unixpause_total_nspause_nspause_endnumgcnumforcedgcgc_cpu_fractionlast_gc_nanotimelastHeapInUseenablegcsymHashgnuHashdeferBitsOffsetslotsOffsettotalBytesfindSuccfindAddrGreaterEqualremoveLastcloneIntoreleasedBgreleasedEagersearchAddrmheapLocksummaryMappedReadychunkHugePagesscavengeOnetryChunkOfchunkOfenableChunkHugePagesfindMappedAddrallocToCachepageInUsepageMarkspageSpecialscheckmarkszeroedBasemapMemoryincHeaddecHeadincTailspineLockspinespineLenspineCappartialpartialUnsweptpartialSweptfullUnsweptfullSweptcacheSpanuncacheSpanarenaHintsquarantineListreadyListpagesallspanspagesInUsepagesSweptpagesSweptBasissweepHeapLiveBasissweepPagesPerBytereclaimIndexreclaimCreditarenasarenasHugePagesheapArenaAllocarenaallArenassweepArenasmarkArenascurArenacentralspanalloccacheallocspecialfinalizerallocspecialCleanupAllocspecialprofileallocspecialReachableAllocspecialPinCounterAllocspecialWeakHandleAllocarenaHintAlloccleanupIDunusedallocUserArenaChunkenableMetadataHugePagesnextSpanForSweepreclaimreclaimChunkallocManualsetSpansallocNeedsZerotryAllocMSpanallocMSpanLockedfreeMSpanLockedallocSpaninitSpanfreeSpanfreeManualfreeSpanLockedscavengeAllsignosigev_notify_thread_idonestrapcoprimese_idente_typee_machinee_versione_entrye_phoffe_shoffe_flagse_ehsizee_phentsizee_phnume_shentsizee_shnume_shstrndxwanteddeliveringpprevunlinkAndNextreachabledroppingdropstealIDnewTraceMapNodereadingworkAvailablereaderGenflushedGendoneSemastackTabstringTabtypeTabcpuLogReadsignalLockcpuLogWritecpuSleepcpuLogDonecpuBufmarkWorkerLabelsgoStopReasonsgoBlockReasonsenabledWithAllocFreelastNonZeroGenexitingSyscallseqGCminPageHeapAddrdebugMallocvda_namevda_nextstartTickslinenomoreisMarkedsetMarkedsetMarkedNonAtomicclearMarkedgcPercentGoalmemoryLimitGoalbackgroundTime249freesalloc_bytesfree_bytesfuturesubbucketshzpopped35179999fullListdefunctrunnablenoStackgoidgenlastpollpollUntilmidlenmidlenmidlelockedmnextmaxmcountnmsysnmfreedngsyspidlenpidlenmspinningneedspinningrunqsizesudoglockdeferlockfreemgcwaitingstopwaitstopnotesysmonwaitsysmonnotesafePointFnsafePointWaitsafePointNoteprocresizetimetotaltimesysmonlocktimeToRunidleTimetotalMutexWaitTimestwStoppingTimeGCstwStoppingTimeOtherstwTotalTimeGCstwTotalTimeOthertotalRuntimeLockWaitTimesigContextcallingGhaveTemplateThreadcgocheckdisablethpdontfreezetheworldefencegccheckmarkgcpacertracegcshrinkstackoffgcstoptheworldgctraceinvalidptrmadvdontneedruntimeContentionStacksscavtracescheddetailtracebackancestorsasyncpreemptoffharddecommitadaptivestackstarttraceadvanceperiodtraceCheckStackOwnershipprofstackdepthdataindependenttimingmallocsbrktraceallocfreeasynctimerchaneventErrexpiredReadDeadlineexpiredWriteDeadlinetimeRatetimeStarttickStartgregsfpregsuc_flagsuc_linkuc_stackuc_mcontextuc_sigmask__fpregs_memstatesLockstateSizemmapProtmmapFlagsAppendSeqBackwardBinarySearchBinarySearchFuncClipCompactFuncCompareFuncConcatIsSortedIsSortedFuncMaxFuncMinFuncSortFuncSortStableFuncSortedFuncSortedStableFuncbreakPatternsCmpFuncbreakPatternsOrderedchoosePivotCmpFuncchoosePivotOrdereddecreasingHintheapSortCmpFuncheapSortOrderedincreasingHintinsertionSortCmpFuncinsertionSortOrderedmedianAdjacentCmpFuncmedianAdjacentOrderedmedianCmpFuncmedianOrderednextPowerOfTwoorder2CmpFuncorder2OrderedpartialInsertionSortCmpFuncpartialInsertionSortOrderedpartitionCmpFuncpartitionEqualCmpFuncpartitionEqualOrderedpartitionOrderedpdqsortCmpFuncpdqsortOrderedreverseRangeCmpFuncreverseRangeOrderedrotateCmpFuncrotateOrderedsiftDownCmpFuncsiftDownOrderedsortedHintstableCmpFuncstableOrderedswapRangeCmpFuncswapRangeOrderedsymMergeCmpFuncsymMergeOrderedunknownHintxorshiftE1S1E2S2slicesFloat64sAreSortedIntsAreSortedSearchFloat64sSearchIntsSearchStringsSliceIsSortedSliceStableStableStringsAreSortedbreakPatternsbreakPatterns_funcchoosePivotchoosePivot_funcheapSortheapSort_funcinsertionSortinsertionSort_funclessSwapmedianmedianAdjacentmedianAdjacent_funcmedian_funcorder2order2_funcpartialInsertionSortpartialInsertionSort_funcpartitionEqualpartitionEqual_funcpartition_funcpdqsortpdqsort_funcreverseRangereverseRange_funcrotate_funcsiftDown_funcstablestable_funcswapRangeswapRange_funcsymMergesymMerge_funcAppendQuoteAppendQuoteRuneAppendQuoteRuneToASCIIAppendQuoteRuneToGraphicAppendQuoteToASCIIAppendQuoteToGraphicCanBackquoteFormatComplexFormatFloatFormatUintIntSizeIsGraphicNumErrorParseComplexQuoteRuneQuoteRuneToASCIIQuoteRuneToGraphicQuoteToASCIIQuoteToGraphicQuotedPrefixUnquoteUnquoteCharappendEscapedRuneappendQuotedRuneWithappendQuotedWithatof32atof32exactatof64atof64exactatofHexbaseErrorbigFtoabitSizeErrorbsearchcommonPrefixLenIgnoreCasecomputeBoundsconvErrdecimalSlicedetailedPowersOfTendetailedPowersOfTenMaxExp10detailedPowersOfTenMinExp10digitZerodivisibleByPower5divmod1e9eiselLemire32eiselLemire64fastSmallsfloat32infofloat64infofloatInfofnParseComplexfnParseFloatformatBitsformatDecimalformatDigitsgenericFtoahost32bitisGraphicisInGraphicListisNotPrint16isNotPrint32isPrint16isPrint32leftCheatleftShiftleftcheatslowerhexmulByLog10Log2mulByLog2Log10mult128bitPow10mult64bitPow10nSmallsoptimizeparseFloatPrefixpowtabprefixIsLessThanquoteRuneWithquoteWithrangeErrorryuDigitsryuDigits32ryuFtoaFixed32ryuFtoaFixed64ryuFtoaShortestsmallsmallsStringunderscoreOKexpbitsnddp800RoundDownRoundUpRoundedInteger696appendSliceWriterbyteReplacerbyteStringReplacercountCutOffgenericReplacergetStringWriterlongestCommonSuffixmakeGenericReplacermakeSingleStringReplacermakeStringFinderrepeatedDashesrepeatedEqualsrepeatedSpacesrepeatedTabsrepeatedZeroessingleStringReplacerstringFindertrieNodebadCharSkipgoodSuffixSkipfinderreplacementstoReplaceAndInt32AndInt64AndUint32AndUint64AndUintptrCompareAndSwapInt32CompareAndSwapInt64CompareAndSwapPointerCompareAndSwapUint32CompareAndSwapUint64CompareAndSwapUintptrLoadInt32LoadInt64LoadPointerLoadUint32LoadUint64LoadUintptrOrInt32OrInt64OrUint32OrUint64OrUintptrStoreInt32StoreInt64StorePointerStoreUint32StoreUint64StoreUintptrSwapInt32SwapInt64SwapPointerSwapUint32SwapUint64SwapUintptrefaceWordsfirstStoreInProgressruntime_procPinruntime_procUnpinsync/atomicNewCondOnceFuncOnceValueOnceValuesallPoolsallPoolsMudequeueBitsdequeueLimitdequeueNilindexLocaloldPoolspoolCleanuppoolRaceAddrpoolRaceHashrlockerruntime_LoadAcquintptrruntime_SemacquireRWMutexruntime_SemacquireRWMutexRruntime_SemacquireWaitGroupruntime_StoreReluintptrruntime_notifyListAddruntime_notifyListCheckruntime_notifyListNotifyAllruntime_notifyListNotifyOneruntime_notifyListWaitruntime_randnruntime_registerPoolCleanupsyscall_hasWaitingReadersT1T2ARPHRD_IEEE802154_PHYAllThreadsSyscallAllThreadsSyscall6AttachLsfDetachLsfEPOLL_NONBLOCKForkExecForkLockIFLA_MAXLsfJumpLsfSocketLsfStmtNetlinkRIBNetlinkRouteRequestParseNetlinkMessageParseNetlinkRouteAttrSIGUNUSEDSetLsfPromiscSetegidSeteuidSlicePtrFromStringsStringBytePtrStringByteSliceStringSlicePtr_AT_EACCESS_AT_EMPTY_PATH_AT_FDCWD_AT_REMOVEDIR_AT_SYMLINK_NOFOLLOW_LINUX_CAPABILITY_VERSION_3_NT_PRSTATUS_SYS_clone3_SYS_faccessat2_SYS_fchmodat2_SYS_setgroupsacquireForkLockadjustFileLimitcapDatacapHeadercapToIndexcapToMaskcapscgocallercloneArgscopyenvdarwin64BitdoCheckClonePidfdenvLockenvOnceexecveDarwinexecveLibcexecveOpenBSDfaccessat2faketimeWriteforceClone3forkAndExecFailureCleanupforkAndExecInChildforkAndExecInChild1forkExecforkExecPipeforkingforkingLockformatIDMappingsfstatathasWaitingReadersiflagslinkatminus1netbsd32BitnetlinkMessageHeaderAndDatanetlinkRouteAttrAndValuenewNetlinkRouteRequestnlmAlignOforigRlimitNofileos_checkClonePidfdpageBufPoolpollFdprlimitprlimit1rawSyscallNoErrorrawVforkSyscallreadlenrecvfromInet4recvfromInet6recvmsgInet4recvmsgInet6releaseForkLockrtaAlignOfruntimeSetenvruntimeUnsetenvruntime_AfterExecruntime_AfterForkruntime_AfterForkInChildruntime_BeforeExecruntime_BeforeForkruntime_doAllThreadsSyscallruntime_entersyscallruntime_envsruntime_exitsyscallsendmsgNInet4sendmsgNInet6sendtoInet4sendtoInet6setrlimitsizeofIntsizeofLongsizeofLongLongsizeofPtrsizeofShortsymlinkatsys_GETEUIDsys_SETGIDsys_SETREGIDsys_SETRESGIDsys_SETRESUIDsys_SETREUIDsys_SETUIDunlinkatwriteIDMappingswriteSetgroupswriteUidGidMappingszeroProcAttrzeroSysProcAttreffectivepermittedinheritablePad_cgo_0Pad_cgo_1X__valPad_cgo_2Pad_cgo_3X_ftoWireFormatpidFDchildTIDparentTIDexitSignalstackSizesetTIDsetTIDSizecgroupAllocsPerRunBenchmarkCoverBlockCoverModeInternalBenchmarkInternalExampleInternalFuzzTargetInternalTestMainStartRegisterCoverRunBenchmarksRunExamplesRunTestsTestingallMatcheralternationMatchbenchmarkLockbenchmarkMemorybenchmarkNameblockProfileRatecallerNamechattyFlagcorpusDircorpusEntrycovercover2coverProfilecoverReportcoverReport2coverage2cpuListcpuListStrerrMainerrNilPanicOrGoexitfRunnerfailFastfmtDurationfuzzCacheDirfuzzCoordinatorfuzzCrashErrorfuzzDurationfuzzModefuzzResultfuzzStatefuzzWorkerfuzzWorkerExitCodegocoverdirhaveExampleshideStdoutForTestinghighPrecisionTimeNowhighPrecisionTimeSinceindenterinitBenchmarkFlagsinitFuzzFlagsinitRanisFuzzWorkerisWindowsRetryablelabelsOncelistTestsloopPoisonMaskloopPoisonTimermarkermatchBenchmarksmatchFuzzmatchListmatchMutexmatchStringOnlymaxStackLenmemProfileRatememStatsminimizeDurationmustBeNilmutexProfileFractionnewChattyPrinternewTestStatenormalPanicnumFailedparallelConflictparseCpuListparseSubtestNumberpcToNamepredictNrealStderrrecoverAndReturnPanicregisterCover2runBenchmarksrunExamplerunExamplesrunFuzzTestsrunFuzzingrunTestsrunningListseedCorpusOnlyshouldFailFastshufflesimpleMatchsortLinessplitRegexptRunnertestBinarytestDepstestingTestingtestlogFiletoOutputDirtraceFileIsSeedCheckCorpusCoordinateFuzzingInitRuntimeCoverageReadCorpusResetCoverageRunFuzzWorkerSnapshotCoverageStartCPUProfileStartTestLogStopCPUProfileStopTestLogWriteProfileTofstatecorpusfuzzCalledFuzzprocessRunResultegtestsbenchmarksfuzzTargetsexamplesafterOncenumRunexitCodewriteProfilesstartAlarmstopAlarmLine0Col0Line1Col1CoveredPackagestearDownsnapshotcovCrashPathCharGoTokensGoWhitespaceScanCharsScanFloatsScanIdentsScanIntsScanRawStringsScanStringsSkipCommentsTokenStringskipCommentsrcBufsrcPossrcEndsrcBufOffsetlastLineLenlastCharLentokBuftokPostokEndWhitespaceIsIdentRuneisIdentRunescanDigitsscanCharTokenTexttext/scannerAlignRightDiscardEmptyColumnsFilterHTMLStripEscapecellhbarosErrortabsvbarhtabminwidthtabwidthpadbytesendCharwidthsaddLinewrite0writeNwriteLinesupdateWidthstartEscapeendEscapeterminateCellhandlePanicflushNoDeferstabwritertext/tabwriterIdentifierNodeIsEmptyTreeNodeActionNodeBoolNodeBreakNodeChainNodeCommandNodeCommentNodeContinueNodeDotNodeFieldNodeIdentifierNodeIfNodeNilNodeNumberNodePipeNodeRangeNodeStringNodeTemplateNodeTextNodeVariableNodeWithSkipFuncCheckhasLeftTrimMarkerhasRightTrimMarkerisAlphaNumericitemAssignitemBlockitemBoolitemBreakitemCharitemCharConstantitemComplexitemContinueitemDeclareitemDefineitemDotitemElseitemEnditemFielditemIdentifieritemIfitemKeyworditemLeftDelimitemLeftParenitemNilitemNumberitemPipeitemRangeitemRawStringitemRightDelimitemRightParenitemSpaceitemStringitemTemplateitemTextitemVariableitemWithleftCommentleftTrimLengthlexCharlexFieldlexFieldOrVariablelexIdentifierlexInsideActionlexLeftDelimlexNumberlexQuotelexRawQuotelexRightDelimlexSpacelexTextlexVariablenodeElsenodeEndrightCommentrightTrimLengthspaceCharstextFormattrimMarkertrimMarkerLenSetPosSetTreetext/template/parseExecErroraddFuncsaddValueFuncsbasicKindboolKindbuiltinFuncsbuiltinFuncsOncebuiltinscanComparecomplexKindcreateValueFuncsdoublePercentemptyCallerrBadComparisonerrBadComparisonTypeerrNoComparisonfindFunctionfloatKindgegoodFuncgoodNamehtmlAmphtmlAposhtmlGthtmlLthtmlNullhtmlQuotindexArgindirectInterfaceinitMaxExecDepthintKindintLikeisHexIntisMissingisRuneIntisTruejsAmpjsAposjsBackslashjsEqjsGtjsIsSpecialjsLowUnijsLtjsQuotmapErrormapInvalidmapZeroValuemaxExecDepthmissingValmissingValReflectTypemissingValTypeneprepareArgprintableValuereflectValueTypesafeCallstringKindtruthuintKindwalkBreakwalkContinuesetVarsetTopVarvarValuewalkIfOrWithwalkRangewalkTemplateevalPipelinenotAFunctionevalCommandidealConstantevalFieldNodeevalChainNodeevalVariableNodeevalFieldChainevalFunctionevalFieldevalCallvalidateTypeevalArgevalBoolevalStringevalIntegerevalUnsignedIntegerevalFloatevalComplexevalEmptyInterfacetext/templateANSICAprilAugustDateOnlyDecemberFebruaryFixedZoneFridayJanuaryJulyJuneKitchenLayoutLoadLocationFromTZDataMarchMayMicrosecondNovemberOctoberRFC1123ZRFC3339NanoRFC822RFC822ZRFC850RubyDateSaturdaySeptemberStampStampMicroStampMilliStampNanoThursdayTimeOnlyTuesdayUnixDateWednesdayabsoluteToInternalabsoluteToUnixabsoluteYearsappendNanobyteStringcommaOrPeriodcutspacedataIOdateToAbsDaysdaysPer400YearsdigitsLenerrAtoierrBaderrBadDataerrLeadingInterrLocationfileSizeErrorfindZonefixedZonefmtFracfmtIntget4getnumgetnum3goFuncgorootZoneSourcehasMonotonicinitLocalinternalToAbsoluteinternalToUnixinternalYearinterruptleadingFractionleadingIntlegacyAbsClocklegacyAbsDatelegacyTimeTimeAbslessThanHalfloadFromEmbeddedTZDataloadLocationloadTzinfoloadTzinfoFromDirOrZiploadTzinfoFromTzdataloadTzinfoFromZiplocalLoclocalOncelongDayNameslongMonthNamesmarchThruDecembermaxWallminWallnewParseErrornextStdChunknsecMasknsecShiftomegaparseGMTparseNanosecondsparseRFC3339parseSignedOffsetparseStrictRFC3339parseTimeZoneplatformZoneSourcespreadnregisterLoadFromEmbeddedTZDataruleDOYruleJulianruleKindruleMonthWeekDayruntimeNowsecondsPerDaysecondsPerHoursecondsPerMinutesecondsPerWeekseekCurrentseekEndseekStartsendTimeshortDayNamesshortMonthNamesstartNanostartsWithLowerCasestd0xstdArgShiftstdDaystdFracSecondstdFracSecond0stdFracSecond9stdHourstdHour12stdISO8601ColonSecondsTZstdISO8601ColonTZstdISO8601SecondsTZstdISO8601ShortTZstdISO8601TZstdLongMonthstdLongWeekDaystdLongYearstdMaskstdMinutestdMonthstdNeedClockstdNeedDatestdNeedYdaystdNumColonSecondsTZstdNumColonTZstdNumMonthstdNumSecondsTzstdNumShortTZstdNumTZstdPMstdSecondstdSeparatorShiftstdTZstdUnderDaystdUnderYearDaystdWeekDaystdYearstdZeroDaystdZeroHour12stdZeroMinutestdZeroMonthstdZeroSecondstdZeroYearDaystdpmsubMonosyncTimertimeBinaryVersionV1timeBinaryVersionV2tzruleTimetzsettzsetNametzsetNumtzsetOffsettzsetRuleunixTimeunixToAbsoluteunixToInternalunnamedFixedZonesunnamedFixedZonesOnceutcLocwallToInternalzoneinfozoneinfoOncebig4big8restmonLayoutElemValueElemAppendRuneDecodeRuneEncodeRuneIsSurrogateRuneLenreplacementCharsurr1surr2surr3surrSelfutf16unicode/utf16DecodeLastRuneDecodeLastRuneInStringDecodeRuneInStringFullRuneFullRuneInStringMaxRuneRuneCountRuneCountInStringRuneErrorRuneSelfRuneStartUTFMaxValidRuneappendRuneNonASCIIencodeRuneNonASCIIruneErrorByte0runeErrorByte1runeErrorByte2utf8unicode/utf8ASCII_Hex_DigitAdlamAhomAnatolian_HieroglyphsAvestanAzeriCaseBalineseBamumBassa_VahBatakBhaiksukiBidi_ControlBopomofoBrahmiBrailleBugineseBuhidCanadian_AboriginalCarianCaseRangesCategoriesCaucasian_AlbanianCfChakmaChamCherokeeChorasmianCoCopticCuneiformCypriotCypro_MinoanCyrillicDashDeseretDevanagariDiacriticDigitDives_AkuruDograDuployanEgyptian_HieroglyphsElbasanElymaicEthiopicExtenderFoldCategoryFoldScriptGlagoliticGothicGranthaGraphicRangesGunjala_GondiGurmukhiHanHangulHanifi_RohingyaHanunooHatranHex_DigitHiraganaHyphenIDS_Binary_OperatorIDS_Trinary_OperatorIdeographicImperial_AramaicInheritedInscriptional_PahlaviInscriptional_ParthianIsControlIsMarkIsOneOfIsSpaceIsTitleJavaneseJoin_ControlKaithiKatakanaKawiKayah_LiKharoshthiKhitan_Small_ScriptKhojkiKhudawadiLatinLepchaLetterLimbuLinear_ALinear_BLisuLlLmLogical_Order_ExceptionLuLycianLydianMahajaniMakasarMandaicManichaeanMarchenMasaram_GondiMaxASCIIMaxCaseMaxLatin1McMeMedefaidrinMeetei_MayekMende_KikakuiMeroitic_CursiveMeroitic_HieroglyphsMiaoModiMroMultaniMyanmarNabataeanNag_MundariNandinagariNdNew_Tai_LueNewaNkoNlNoncharacter_Code_PointNushuNyiakeng_Puachue_HmongOghamOl_ChikiOld_HungarianOld_ItalicOld_North_ArabianOld_PermicOld_PersianOld_SogdianOld_South_ArabianOld_TurkicOld_UyghurOriyaOsageOsmanyaOtherOther_AlphabeticOther_Default_Ignorable_Code_PointOther_Grapheme_ExtendOther_ID_ContinueOther_ID_StartOther_LowercaseOther_MathOther_UppercasePahawh_HmongPalmyrenePattern_SyntaxPattern_White_SpacePau_Cin_HauPcPdPePfPhags_PaPhoenicianPoPrepended_Concatenation_MarkPrintRangesPsalter_PahlaviPunctQuotation_MarkRadicalRegional_IndicatorRejangReplacementCharRunicSTermSamaritanSaurashtraScSentence_TerminalSharadaShavianSiddhamSignWritingSimpleFoldSkSmSoSoft_DottedSogdianSora_SompengSoyomboSundaneseSyloti_NagriSyriacTagalogTagbanwaTai_LeTai_ThamTai_VietTakriTangsaTangutTerminal_PunctuationThaanaTibetanTifinaghTirhutaTitleCaseTotoTurkishCaseUgariticUnified_IdeographUpperCaseUpperLowerVaiVariation_SelectorVithkuqiWanchoWarang_CitiWhite_SpaceYezidiYiZanabazar_SquareZlZpZs_ASCII_Hex_Digit_Adlam_Ahom_Anatolian_Hieroglyphs_Arabic_Armenian_Avestan_Balinese_Bamum_Bassa_Vah_Batak_Bengali_Bhaiksuki_Bidi_Control_Bopomofo_Brahmi_Braille_Buginese_Buhid_C_Canadian_Aboriginal_Carian_CaseRanges_Caucasian_Albanian_Cc_Cf_Chakma_Cham_Cherokee_Chorasmian_Co_Common_Coptic_Cs_Cuneiform_Cypriot_Cypro_Minoan_Cyrillic_Dash_Deprecated_Deseret_Devanagari_Diacritic_Dives_Akuru_Dogra_Duployan_Egyptian_Hieroglyphs_Elbasan_Elymaic_Ethiopic_Extender_Georgian_Glagolitic_Gothic_Grantha_Greek_Gujarati_Gunjala_Gondi_Gurmukhi_Han_Hangul_Hanifi_Rohingya_Hanunoo_Hatran_Hebrew_Hex_Digit_Hiragana_Hyphen_IDS_Binary_Operator_IDS_Trinary_Operator_Ideographic_Imperial_Aramaic_Inherited_Inscriptional_Pahlavi_Inscriptional_Parthian_Javanese_Join_Control_Kaithi_Kannada_Katakana_Kawi_Kayah_Li_Kharoshthi_Khitan_Small_Script_Khmer_Khojki_Khudawadi_L_Lao_Latin_Lepcha_Limbu_Linear_A_Linear_B_Lisu_Ll_Lm_Lo_Logical_Order_Exception_Lt_Lu_Lycian_Lydian_Mahajani_Makasar_Malayalam_Mandaic_Manichaean_Marchen_Masaram_Gondi_Mc_Me_Medefaidrin_Meetei_Mayek_Mende_Kikakui_Meroitic_Cursive_Meroitic_Hieroglyphs_Miao_Mn_Modi_Mongolian_Mro_Multani_Myanmar_N_Nabataean_Nag_Mundari_Nandinagari_Nd_New_Tai_Lue_Newa_Nko_Nl_No_Noncharacter_Code_Point_Nushu_Nyiakeng_Puachue_Hmong_Ogham_Ol_Chiki_Old_Hungarian_Old_Italic_Old_North_Arabian_Old_Permic_Old_Persian_Old_Sogdian_Old_South_Arabian_Old_Turkic_Old_Uyghur_Oriya_Osage_Osmanya_Other_Alphabetic_Other_Default_Ignorable_Code_Point_Other_Grapheme_Extend_Other_ID_Continue_Other_ID_Start_Other_Lowercase_Other_Math_Other_Uppercase_P_Pahawh_Hmong_Palmyrene_Pattern_Syntax_Pattern_White_Space_Pau_Cin_Hau_Pc_Pd_Pe_Pf_Phags_Pa_Phoenician_Pi_Po_Prepended_Concatenation_Mark_Ps_Psalter_Pahlavi_Quotation_Mark_Radical_Regional_Indicator_Rejang_Runic_Samaritan_Saurashtra_Sc_Sentence_Terminal_Sharada_Shavian_Siddham_SignWriting_Sinhala_Sk_Sm_So_Soft_Dotted_Sogdian_Sora_Sompeng_Soyombo_Sundanese_Syloti_Nagri_Syriac_Tagalog_Tagbanwa_Tai_Le_Tai_Tham_Tai_Viet_Takri_Tamil_Tangsa_Tangut_Telugu_Terminal_Punctuation_Thaana_Thai_Tibetan_Tifinagh_Tirhuta_Toto_TurkishCase_Ugaritic_Unified_Ideograph_Vai_Variation_Selector_Vithkuqi_Wancho_Warang_Citi_White_Space_Yezidi_Yi_Z_Zanabazar_Square_Zl_Zp_ZsasciiFoldcaseOrbitconvertCasefoldCommonfoldGreekfoldInheritedfoldLfoldLlfoldLtfoldLufoldMfoldMnfoldPairis16is32isExcludingLatinlinearMaxlookupCaseRangepCpLlpLmaskpLopLupNpPpSpZaddUniqueMapbuildArrayCloneSeqbuildStructCloneSeqcleanupFuncscleanupFuncsMucleanupNotifycloneSeqmakeCloneSeqregisterCleanupruntime_registerUniqueMapCleanupsetupMakesingleStringCloneuniqueMapuniqueMapsstringOffsetscomplexcomplex128complex64float32imagrealuintptrOffsetofSliceDataStringDataunsafevendor/golang.org/x/crypto/chacha20NewXchacha20Poly1305Openchacha20Poly1305Sealchacha20poly1305setupStatewriteWithPaddingxchacha20poly1305vendor/golang.org/x/crypto/chacha20poly1305BIT_STRINGENUMGeneralStringGeneralizedTimeIA5StringNULLOBJECT_IDENTIFIEROCTET_STRINGPrintableStringSEQUENCESETT61StringUTCTimeUTF8StringclassConstructedclassContextSpecificvendor/golang.org/x/crypto/cryptobyte/asn1BuildErrorNewFixedBuilderasn1Signedasn1UnsignedcheckASN1IntegerdefaultUTCTimeFormatStrgeneralizedTimeFormatStrisValidOIDcryptobytevendor/golang.org/x/crypto/cryptobytevendor/golang.org/x/crypto/internal/aliasvendor/golang.org/x/crypto/internal/poly1305ClassANYClassCHAOSClassCSNETClassHESIODClassINETErrNotStartedErrSectionDoneMustNewNameRCodeFormatErrorRCodeNameErrorRCodeNotImplementedRCodeRefusedRCodeServerFailureRCodeSuccessTypeATypeAAAATypeALLTypeAXFRTypeCNAMETypeHINFOTypeMINFOTypeMXTypeNSTypeOPTTypePTRTypeSOATypeSRVTypeTXTTypeWKSclassNamesedns0DNSSECOKedns0DNSSECOKMaskedns0VersionednsVersionMaskerrBaseLenerrCalcLenerrInvalidNameerrInvalidPtrerrNameTooLongerrNilResouceBodyerrNonCanonicalNameerrResTooLongerrResourceLenerrSegTooLongerrStringTooLongerrTooManyAdditionalserrTooManyAnswerserrTooManyAuthoritieserrTooManyPtrerrTooManyQuestionserrZeroSegLenheaderBitAAheaderBitADheaderBitCDheaderBitQRheaderBitRAheaderBitRDheaderBitTCheaderLennestedErrornonEncodedNameMaxpackBytespackClasspackStartingCappackTextpackTypepackUint16packUint32printByteSliceprintPaddedUint8printStringprintUint16printUint32printUint8BytesrCodeNamessectionAdditionalssectionAnswerssectionAuthoritiessectionDonesectionHeadersectionNamessectionNotStartedsectionQuestionsskipClassskipNameskipTypeskipUint16skipUint32typeNamesuint16Lenuint32LenunpackAAAAResourceunpackAResourceunpackBytesunpackCNAMEResourceunpackClassunpackMXResourceunpackNSResourceunpackOPTResourceunpackPTRResourceunpackResourceBodyunpackSOAResourceunpackSRVResourceunpackTXTResourceunpackTextunpackTypeunpackUint16unpackUint32unpackUnknownResourcestartCheckStartQuestionsStartAnswersStartAuthoritiesStartAdditionalsincrementSectionCountcheckResourceSectionQuestionsAnswersAuthoritiesAdditionalsPackAppendPackdnsmessagevendor/golang.org/x/net/dns/dnsmessagevendor/golang.org/x/net/http/httpgutsFromEnvironmentallMatchcidrMatchdomainMatchgetEnvAnyipMatchparseProxyvendor/golang.org/x/net/http/httpproxy.matchCGIProxyFunchttpsProxyhttpProxyipMatchersdomainMatchersproxyForURLuseProxycidrmatchHosthttpproxyvendor/golang.org/x/net/http/httpproxyvendor/golang.org/x/net/http2/hpackvendor/golang.org/x/net/idnavendor/golang.org/x/sys/cpuvendor/golang.org/x/text/secure/bidirulevendor/golang.org/x/text/transformvendor/golang.org/x/text/unicode/bidivendor/golang.org/x/text/unicode/normveza-backend-api/cmd/apiveza-backend-api/cmd/generate-config-docsveza-backend-api/cmd/migrate_toolveza-backend-api/cmd/modern-serverveza-backend-api/cmd/tools/hash_genveza-backend-api/internal/api/adminveza-backend-api/internal/api/chatveza-backend-api/internal/api/collaborationveza-backend-api/internal/api/contestveza-backend-api/internal/api/educationveza-backend-api/internal/api/graphqlveza-backend-api/internal/api/grpcveza-backend-api/internal/api/handlersveza-backend-api/internal/api/listingveza-backend-api/internal/api/messageveza-backend-api/internal/api/offerveza-backend-api/internal/api/production_challengeveza-backend-api/internal/api/roomveza-backend-api/internal/api/searchveza-backend-api/internal/api/shared_resourcesveza-backend-api/internal/api/sound_design_contestveza-backend-api/internal/api/tagveza-backend-api/internal/api/trackveza-backend-api/internal/api/userveza-backend-api/internal/api/voting_systemveza-backend-api/internal/api/websocketveza-backend-api/internal/benchmarksveza-backend-api/internal/core/collaborationveza-backend-api/internal/featuresveza-backend-api/internal/infrastructure/eventbusveza-backend-api/internal/infrastructure/eventsveza-backend-api/internal/infrastructure/sslveza-backend-api/internal/interfacesveza-backend-api/internal/jobsveza-backend-api/internal/repositoryveza-backend-api/internal/securityveza-backend-api/internal/testutils/integrationveza-backend-api/internal/testutils/servicemocksveza-backend-api/tests/integrationtransactionsveza-backend-api/tests/transactionsveza-backend-api/testsruntime_makeStrongFromWeakruntime_registerWeakPointerweak                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                % Ϊi    