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
+6 -5
View File
@@ -2,7 +2,7 @@ import pytest
import os
import base64
from pathlib import Path
from unittest.mock import patch, MagicMock
from unittest.mock import patch, MagicMock, AsyncMock
from app.services.ai_vision import (
_read_image, _extract_json, _usage_tokens_gemini,
_generate_gemini, _generate_openrouter, _generate,
@@ -10,11 +10,12 @@ from app.services.ai_vision import (
)
from app.config import settings
def test_read_image_variants(tmp_path):
@pytest.mark.asyncio
async def test_read_image_variants(tmp_path):
img_file = tmp_path / "test.png"
img_file.write_bytes(b"fake_png_data")
data, mime = _read_image(str(img_file))
data, mime = await _read_image(str(img_file))
assert data == b"fake_png_data"
assert mime == "image/png"
@@ -67,7 +68,7 @@ async def test_generate_dispatcher_openrouter(mock_settings, mock_gen_or):
@pytest.mark.asyncio
@patch("app.services.ai_vision._generate")
@patch("app.services.ai_vision._read_image")
@patch("app.services.ai_vision._read_image", new_callable=AsyncMock)
@patch("app.services.ai_vision.settings")
async def test_extract_text_with_ai(mock_settings, mock_read_image, mock_generate):
mock_settings.AI_ENABLED = True
@@ -83,7 +84,7 @@ async def test_extract_text_with_ai(mock_settings, mock_read_image, mock_generat
@pytest.mark.asyncio
@patch("app.services.ai_vision._generate")
@patch("app.services.ai_vision._read_image")
@patch("app.services.ai_vision._read_image", new_callable=AsyncMock)
@patch("app.services.ai_vision.settings")
async def test_analyze_image_failure(mock_settings, mock_read_image, mock_generate):
mock_settings.AI_ENABLED = True