feat: v3.1.0 — Live Platform Foundation (Track E.1-E.3)

Major release introducing the Live Platform architecture:

- SQLite database backend with async operations and migrations (E.1)
- AES-256-GCM credential encryption with HKDF key derivation (E.1)
- OAuth Social Login with GitHub and Google (E.2)
- Site management API with encrypted credential storage (E.3)
- Per-user MCP endpoints at /u/{user_id}/{alias}/mcp (E.3)
- User API keys with bcrypt hashing (E.3)
- Auto-generated config snippets for 5 MCP clients (E.3)
- Dashboard: dark/light mode, RBAC, My Sites, Connect page
- Active background health checks
- 452 tests (up from 303), all passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-23 23:20:03 +03:30
parent 42ea75bcb3
commit 9e6f06d933
53 changed files with 8654 additions and 1820 deletions

View File

@@ -1,9 +1,9 @@
<!-- Projects Table Rows -->
{% if projects_health %}
{% for project_id, project in projects_health.items() %}
<tr class="hover:bg-gray-700/30 transition-colors">
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors">
<td class="px-6 py-4">
<span class="text-white font-medium">{{ project_id }}</span>
<span class="text-gray-900 dark:text-white font-medium">{{ project_id }}</span>
</td>
<td class="px-6 py-4">
{% if project.healthy or project.status == 'healthy' %}
@@ -17,7 +17,7 @@
{% endif %}
</td>
<td class="px-6 py-4">
<span class="text-gray-300">{{ project.response_time_ms|round(2) }} ms</span>
<span class="text-gray-700 dark:text-gray-300">{{ project.response_time_ms|round(2) }} ms</span>
</td>
<td class="px-6 py-4">
<span class="{% if project.error_rate_percent > 10 %}text-red-400{% elif project.error_rate_percent > 5 %}text-yellow-400{% else %}text-green-400{% endif %}">
@@ -25,14 +25,14 @@
</span>
</td>
<td class="px-6 py-4">
<span class="text-sm text-gray-400">{{ project.last_check[:19] if project.last_check else '-' }}</span>
<span class="text-sm text-gray-500 dark:text-gray-400">{{ project.last_check[:19] if project.last_check else '-' }}</span>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="5" class="px-6 py-12 text-center">
<p class="text-gray-400">
<p class="text-gray-500 dark:text-gray-400">
{% if lang == 'fa' %}هیچ پروژه‌ای برای بررسی یافت نشد{% else %}No projects found for health check{% endif %}
</p>
</td>