feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements

- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 01:00:22 +08:00
parent 51eafb23f3
commit 876789fac1
93 changed files with 8803 additions and 669 deletions

View File

@@ -3,7 +3,8 @@
"""
import uuid
from datetime import datetime
from sqlalchemy import Column, String, Text, Integer, DateTime, Boolean, JSON, Float, Index
from sqlalchemy import Column, String, Text, Integer, DateTime, Boolean, JSON, Float, Index, ForeignKey
from sqlalchemy.dialects.mysql import CHAR
from app.core.database import Base
@@ -13,6 +14,7 @@ class KnowledgeEntry(Base):
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
agent_id = Column(String(36), nullable=True, index=True, comment="所属 Agent IDNULL=全Agent共享")
workspace_id = Column(CHAR(36), ForeignKey("workspaces.id"), nullable=True, index=True, comment="工作区ID")
title = Column(String(500), nullable=False, comment="知识标题(一句话概括)")
category = Column(String(30), nullable=False, index=True,
comment="类别: bug_fix/best_practice/workaround/optimization/insight")
@@ -55,6 +57,7 @@ class KnowledgeEntry(Base):
return {
"id": self.id,
"agent_id": self.agent_id,
"workspace_id": self.workspace_id,
"title": self.title,
"category": self.category,
"tags": self.tags or [],