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

@@ -1,7 +1,7 @@
"""
插件模型 — 第三方节点扩展
"""
from sqlalchemy import Column, String, Text, Boolean, DateTime, JSON, Integer, func
from sqlalchemy import Column, String, Text, Boolean, DateTime, JSON, Integer, ForeignKey, func
from sqlalchemy.dialects.mysql import CHAR
from app.core.database import Base
import uuid
@@ -40,6 +40,7 @@ class NodePlugin(Base):
icon = Column(String(256), comment="图标URL")
tags = Column(JSON, comment="标签列表")
user_id = Column(CHAR(36), nullable=True, comment="上传者ID")
workspace_id = Column(CHAR(36), ForeignKey("workspaces.id"), nullable=True, index=True, comment="工作区ID")
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")