Add admin panel, WebSocket support, and API versioning
CI / Lint & Format (push) Failing after 28s
CI / Tests (push) Has been skipped
CI / Security Scan (push) Failing after 8s
CI / Docker Build (push) Has been skipped

Introduce an admin portal (React + Nginx), WebSocket routing, and
API versioning middleware with `/api/v1/` prefix deprecation.
Add master API key authentication, new Prometheus metrics for AI
token consumption and active WebSockets, and extend S3 config
with a public endpoint URL. Update test paths and fixtures to
align with the new routing structure.
This commit is contained in:
2026-06-22 11:25:22 -04:00
parent d68deb9c74
commit 2f2a5e9b4a
158 changed files with 64811 additions and 503 deletions
+4 -1
View File
@@ -127,6 +127,7 @@ class S3Storage(StorageBackend):
endpoint_url: str = "",
access_key: str = "",
secret_key: str = "",
endpoint_public: str = "",
) -> None:
self._bucket = bucket
self._prefix = prefix.rstrip("/")
@@ -134,6 +135,7 @@ class S3Storage(StorageBackend):
self._endpoint_url = endpoint_url or None
self._access_key = access_key
self._secret_key = secret_key
self._endpoint_public = endpoint_public or self._endpoint_url
def _s3_key(self, path: str) -> str:
if self._prefix:
@@ -178,7 +180,7 @@ class S3Storage(StorageBackend):
async def get_signed_url(self, path: str, expires_in: int = 900) -> str:
"""Génère une URL présignée S3."""
session = self._get_session()
async with session.client("s3", endpoint_url=self._endpoint_url) as client:
async with session.client("s3", endpoint_url=self._endpoint_public) as client:
url = await client.generate_presigned_url(
"get_object",
Params={"Bucket": self._bucket, "Key": self._s3_key(path)},
@@ -238,6 +240,7 @@ def get_storage_backend() -> StorageBackend:
endpoint_url=settings.S3_ENDPOINT_URL,
access_key=settings.S3_ACCESS_KEY,
secret_key=settings.S3_SECRET_KEY,
endpoint_public=settings.S3_ENDPOINT_PUBLIC,
)
else:
_backend = LocalStorage(