Files
ocdp-go/database.md
Ivan087 7f238a3168 refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics
- Add Workspace domain (entity, repository, service, handler, DTO)
- Add multi-tenant K8s client with tenant binding and quota management
- Add K8s diagnostics client (instance diagnostics)
- Add authorization middleware (authz package)
- Restructure frontend to feature-based architecture (features/)
- Add User Management page in configuration
- Add AccessDenied page and route guards
- Refactor shared components (form inputs, layout, UI)
- Update Tailwind config for new design system
- Add comprehensive documentation (docs/, tasks/, plans)
- Improve cluster service with better kubeconfig handling
- Add tests for crypto, config, helm client, tenant binding
2026-05-12 16:15:14 +08:00

598 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OCDP 数据库结构说明
## 概述
OCDP (Open Container Deployment Platform) 是一个多租户容器部署平台,支持:
- 多 Workspace 隔离
- RBAC 权限控制 (Admin / User)
- Kubernetes 集群管理
- OCI Registry 集成 (Harbor)
- Helm Chart 部署
- Values 模板版本管理
- 资源配额控制
- 审计日志
## 数据库配置
```yaml
# PostgreSQL 连接信息
Host: localhost
Port: 5430 (docker) / 5432 (local)
Database: ocdp
User: ocdp
Password: ocdp_password
```
---
## 表结构
### 1. users - 用户表
存储用户账户信息,支持多租户和角色管理。
```sql
CREATE TABLE users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
email VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'user', -- 'admin' | 'user'
workspace_id VARCHAR(36), -- 所属工作空间admin 为 NULL 表示全局
is_active BOOLEAN NOT NULL DEFAULT TRUE, -- 账户是否激活
must_change_password BOOLEAN NOT NULL DEFAULT FALSE, -- 首次登录必须修改密码
revoked_after TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00', -- 全局 Token 撤销时间
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | 550e8400-e29b-41d4-a716-446655440000 |
| username | VARCHAR(255) | 用户名,唯一 | admin |
| password_hash | TEXT | bcrypt 密码哈希 | $2a$10$... |
| email | VARCHAR(255) | 邮箱 | admin@ocdp.local |
| role | VARCHAR(20) | 角色admin/user | admin |
| workspace_id | VARCHAR(36) | 所属工作空间 ID | workspace-uuid |
| is_active | BOOLEAN | 账户是否激活 | true |
| must_change_password | BOOLEAN | 首次登录必须修改密码 | false |
| revoked_after | TIMESTAMP | Token 撤销时间(修改密码后自动撤销旧 Token | 2024-01-01 10:00:00 |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
**索引**:
- `idx_users_username` - 用户名查询
- `idx_users_role` - 角色筛选
- `idx_users_workspace_id` - 工作空间筛选
- `idx_users_is_active` - 激活状态筛选
**角色说明**:
- `admin`: 管理员,可管理所有 Workspace 和资源workspace_id 为 NULL
- `user`: 普通用户,仅可访问自己 Workspace 内的资源
---
### 2. workspaces - 工作空间表
租户/团队隔离单元。
```sql
CREATE TABLE workspaces (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
description TEXT,
created_by VARCHAR(36),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | workspace-uuid |
| name | VARCHAR(255) | 工作空间名称,唯一 | team-alpha |
| description | TEXT | 描述 | Alpha 团队工作空间 |
| created_by | VARCHAR(36) | 创建者用户 ID | user-uuid |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
**索引**:
- `idx_workspaces_name` - 名称查询
---
### 3. workspace_quotas - 工作空间配额表
每个 Workspace 的资源配额限制。
```sql
CREATE TABLE workspace_quotas (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36) NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
resource_type VARCHAR(50) NOT NULL, -- 'cpu' | 'gpu' | 'gpu_memory'
hard_limit DECIMAL(10,2) NOT NULL, -- 硬限制0 表示无限制)
soft_limit DECIMAL(10,2) NOT NULL, -- 软限制(警告阈值)
used DECIMAL(10,2) NOT NULL DEFAULT 0, -- 当前使用量
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, resource_type)
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | quota-uuid |
| workspace_id | VARCHAR(36) | 所属工作空间 ID | workspace-uuid |
| resource_type | VARCHAR(50) | 资源类型cpu/gpu/gpu_memory | cpu |
| hard_limit | DECIMAL(10,2) | 硬限制0=无限制) | 10.00 |
| soft_limit | DECIMAL(10,2) | 软限制(警告阈值) | 8.00 |
| used | DECIMAL(10,2) | 当前使用量 | 5.00 |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
**配额检查逻辑**:
1. 部署实例前检查 `used + new_request <= hard_limit`
2. 超过硬限制返回 403 Forbidden
3. 超过软限制发送警告通知
4. 实例删除后释放配额
---
### 4. clusters - Kubernetes 集群表
管理 Kubernetes 集群连接信息。
```sql
CREATE TABLE clusters (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36), -- 所属工作空间NULL 表示全局共享
owner_id VARCHAR(36), -- 创建者用户 ID
name VARCHAR(255) NOT NULL UNIQUE,
host TEXT NOT NULL, -- Kubernetes API Server URL
ca_data TEXT, -- CA 证书Base64 编码)
cert_data TEXT, -- 客户端证书Base64 编码)
key_data TEXT, -- 客户端密钥Base64 编码)
token TEXT, -- Bearer Token与证书认证二选一
description TEXT,
isolation_mode VARCHAR(20) NOT NULL DEFAULT 'namespace', -- 'namespace' | 'cluster'
default_namespace VARCHAR(255), -- 默认 namespace 前缀
is_shared BOOLEAN NOT NULL DEFAULT FALSE, -- 是否为共享集群
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | cluster-uuid |
| workspace_id | VARCHAR(36) | 所属工作空间 ID | workspace-uuid |
| owner_id | VARCHAR(36) | 创建者用户 ID | user-uuid |
| name | VARCHAR(255) | 集群名称,唯一 | prod-k8s |
| host | VARCHAR(255) | Kubernetes API URL | https://k8s.example.com:6443 |
| ca_data | TEXT | CA 证书 Base64 | LS0tLS1... |
| cert_data | TEXT | 客户端证书 Base64 | LS0tLS1... |
| key_data | TEXT | 客户端密钥 Base64 | LS0tLS1... |
| token | TEXT | Bearer Token | eyJhbGci... |
| description | TEXT | 描述 | 生产环境集群 |
| isolation_mode | VARCHAR(20) | 隔离模式namespace/cluster | namespace |
| default_namespace | VARCHAR(255) | 默认 namespace 前缀 | team-alpha |
| is_shared | BOOLEAN | 是否共享admin 创建供多 Workspace 使用) | false |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
**隔离模式说明**:
- `namespace`: 共享集群模式,多个 Workspace 使用不同 namespace
- 部署时自动分配:`{default_namespace}-{instance_name}`
- `cluster`: 私有集群模式,每个 Workspace 独立集群或独立凭证
**认证方式**:
1. 证书认证:`ca_data` + `cert_data` + `key_data`
2. Token 认证:`token`
---
### 5. registries - OCI Registry 表
管理 Docker/OCI 镜像仓库(支持 Harbor
```sql
CREATE TABLE registries (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36), -- 所属工作空间NULL 表示全局共享
owner_id VARCHAR(36), -- 创建者用户 ID
name VARCHAR(255) NOT NULL UNIQUE,
url TEXT NOT NULL, -- Registry URL
description TEXT,
username VARCHAR(255), -- 认证用户名
password TEXT, -- 认证密码(加密存储)
insecure BOOLEAN DEFAULT FALSE, -- 是否跳过 TLS 验证
is_shared BOOLEAN DEFAULT FALSE, -- 是否为共享 Registry
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | registry-uuid |
| workspace_id | VARCHAR(36) | 所属工作空间 ID | workspace-uuid |
| owner_id | VARCHAR(36) | 创建者用户 ID | user-uuid |
| name | VARCHAR(255) | Registry 名称,唯一 | harbor-prod |
| url | TEXT | Registry URL | https://harbor.example.com |
| description | TEXT | 描述 | 生产环境 Harbor |
| username | VARCHAR(255) | 认证用户名 | admin |
| password | TEXT | 认证密码(加密) | encrypted... |
| insecure | BOOLEAN | 跳过 TLS 验证 | false |
| is_shared | BOOLEAN | 是否共享 | false |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
---
### 6. instances - Helm 实例表
部署的 Helm Release 管理。
```sql
CREATE TABLE instances (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36), -- 所属工作空间
owner_id VARCHAR(36), -- 创建者用户 ID
cluster_id VARCHAR(36) NOT NULL,
registry_id VARCHAR(36) NOT NULL,
chart_reference_id VARCHAR(36), -- 引用的 Chart 引用
values_template_id VARCHAR(36), -- 使用的 Values 模板
name VARCHAR(255) NOT NULL, -- Helm Release 名称
namespace VARCHAR(255) NOT NULL, -- Kubernetes 命名空间
repository TEXT NOT NULL, -- OCI Repository (e.g., charts/app)
chart VARCHAR(255) NOT NULL, -- Chart 名称
version VARCHAR(255) NOT NULL, -- Chart 版本
description TEXT,
values JSONB, -- Helm Values (JSON)
values_yaml TEXT, -- Helm Values (YAML)
user_override_yaml TEXT, -- 用户额外覆盖配置
status VARCHAR(50) NOT NULL, -- 实例状态
status_reason TEXT, -- 状态说明
last_operation VARCHAR(50), -- 最后操作类型
last_error TEXT, -- 最近错误
revision INTEGER NOT NULL DEFAULT 1, -- Helm Release Revision
cpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0, -- CPU 请求量 (cores)
memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi', -- 内存请求量
gpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0, -- GPU 请求量 (cards)
gpu_memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi', -- GPU 内存请求量
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_cluster FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE,
CONSTRAINT fk_registry FOREIGN KEY (registry_id) REFERENCES registries(id) ON DELETE CASCADE,
UNIQUE (cluster_id, name, namespace)
);
```
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| id | VARCHAR(36) | 主键 UUID | instance-uuid |
| workspace_id | VARCHAR(36) | 所属工作空间 ID | workspace-uuid |
| owner_id | VARCHAR(36) | 创建者用户 ID | user-uuid |
| cluster_id | VARCHAR(36) | 所属集群 ID | cluster-uuid |
| registry_id | VARCHAR(36) | 所属 Registry ID | registry-uuid |
| chart_reference_id | VARCHAR(36) | Chart 引用 ID | chart-ref-uuid |
| values_template_id | VARCHAR(36) | Values 模板 ID | template-uuid |
| name | VARCHAR(255) | Release 名称RFC 1123 | my-app |
| namespace | VARCHAR(255) | Kubernetes 命名空间 | team-alpha-my-app |
| repository | TEXT | OCI Repository | harbor.example.com/charts/nginx |
| chart | VARCHAR(255) | Chart 名称 | nginx |
| version | VARCHAR(255) | Chart 版本 | 1.0.0 |
| description | TEXT | 描述 | Nginx 应用 |
| values | JSONB | Values JSON | {"replicas": 2} |
| values_yaml | TEXT | Values YAML | replicas: 2 |
| user_override_yaml | TEXT | 用户覆盖配置 | replicas: 3 |
| status | VARCHAR(50) | 状态 | deployed |
| status_reason | TEXT | 状态说明 | Install complete |
| last_operation | VARCHAR(50) | 最后操作 | install |
| last_error | TEXT | 错误信息 | - |
| revision | INTEGER | Helm Revision | 1 |
| cpu_requested | DECIMAL(10,2) | CPU 请求 | 2.00 |
| memory_requested | VARCHAR(50) | 内存请求 | 1Gi |
| gpu_requested | DECIMAL(10,2) | GPU 请求 | 0 |
| gpu_memory_requested | VARCHAR(50) | GPU 内存 | 0Mi |
| created_at | TIMESTAMP | 创建时间 | 2024-01-01 10:00:00 |
| updated_at | TIMESTAMP | 更新时间 | 2024-01-01 10:00:00 |
**状态说明**:
| 状态 | 说明 |
|------|------|
| deployed | 部署成功 |
| failed | 部署失败 |
| pending-install | 安装中 |
| pending-upgrade | 升级中 |
| pending-rollback | 回滚中 |
| pending-delete | 删除中 |
| uninstalled | 已卸载 |
| superseded | 已被取代 |
| unknown | 未知 |
---
### 7. storage_backends - 存储后端表
NFS/PV/HostPath 存储配置。
```sql
CREATE TABLE storage_backends (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
owner_id VARCHAR(36),
name VARCHAR(255) NOT NULL,
type VARCHAR(50) NOT NULL, -- 'nfs' | 'pv' | 'hostPath'
config JSONB NOT NULL, -- 存储配置
description TEXT,
is_default BOOLEAN NOT NULL DEFAULT FALSE, -- 是否默认存储
is_shared BOOLEAN NOT NULL DEFAULT FALSE, -- 是否共享
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, name)
);
```
**Config 结构**:
```json
// NFS
{"nfs": {"server": "192.168.1.100", "path": "/data"}}
// PV
{"pv": {"storageClassName": "nfs", "capacity": "10Gi", "accessModes": ["ReadWriteMany"]}}
// HostPath
{"hostPath": {"path": "/mnt/data"}}
```
---
### 8. chart_references - Chart 引用表
管理可用的 Helm Chart 引用。
```sql
CREATE TABLE chart_references (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
registry_id VARCHAR(36),
repository VARCHAR(500) NOT NULL, -- OCI repository path
chart_name VARCHAR(255) NOT NULL,
description TEXT,
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, registry_id, repository)
);
```
---
### 9. values_templates - Values 模板表
Helm Values 模板,支持版本管理。
```sql
CREATE TABLE values_templates (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
owner_id VARCHAR(36),
chart_reference_id VARCHAR(36),
name VARCHAR(255) NOT NULL,
description TEXT,
values_yaml TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1, -- 模板版本号
is_default BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(workspace_id, chart_reference_id, name)
);
```
**版本管理**:
- 每次更新创建新版本version + 1
- 支持回滚到历史版本
---
### 10. user_config_overrides - 用户配置覆盖表
用户个人配置覆盖。
```sql
CREATE TABLE user_config_overrides (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
user_id VARCHAR(36),
target_type VARCHAR(50) NOT NULL, -- 'storage' | 'template' | 'global'
target_id VARCHAR(36),
config JSONB NOT NULL, -- 覆盖配置
priority INTEGER NOT NULL DEFAULT 0, -- 优先级
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
---
### 11. audit_logs - 审计日志表
记录所有操作行为。
```sql
CREATE TABLE audit_logs (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36),
user_id VARCHAR(36),
action VARCHAR(100) NOT NULL, -- 'create' | 'update' | 'delete' | 'deploy' | 'scale'
resource_type VARCHAR(50) NOT NULL, -- 'cluster' | 'registry' | 'instance' | ...
resource_id VARCHAR(36),
resource_name VARCHAR(255),
details JSONB,
ip_address VARCHAR(50),
user_agent TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
---
### 12. schema_migrations - 迁移版本表
数据库版本记录。
```sql
CREATE TABLE schema_migrations (
version VARCHAR(50) PRIMARY KEY,
applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
---
## ER 关系图
```
┌─────────────────────────────────────────────────────────────────────────┐
│ workspaces │
│ (id, name, description, created_by, created_at, updated_at) │
└────────────────────────────────────┬────────────────────────────────────┘
│ 1:N
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ workspace_quotas│ │ clusters │ │ registries │
│ (workspace_id, │ │ (workspace_id, │ │ (workspace_id, │
│ resource_type, │ │ owner_id, name, │ │ owner_id, name, │
│ hard_limit, │ │ host, is_shared) │ │ url, is_shared) │
│ soft_limit, used)│ └─────────┬─────────┘ └────────┬─────────┘
└───────────────────┘ │ │
│ │
┌───────────────────────────┼───────────────────────┘
│ │
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ instances │ │ storage_backends│
│ (workspace_id, │ │ (workspace_id, │
│ owner_id, │ │ owner_id, name, │
│ cluster_id, │ │ type, config) │
│ registry_id, │ └───────────────────┘
│ values_template) │
└───────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ users │
│ (id, username, password_hash, email, role, workspace_id, is_active) │
└────────────────────────────────────┬────────────────────────────────────┘
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ chart_references│ │ values_templates │ │ audit_logs │
│ (workspace_id, │ │ (workspace_id, │ │ (user_id, action,│
│ registry_id, │ │ owner_id, │ │ resource_type) │
│ repository) │ │ chart_ref_id) │ └───────────────────┘
└───────────────────┘ └───────────────────┘
```
---
## 资源可见性规则
| 用户角色 | 可见范围 |
|---------|---------|
| Admin | 所有 Workspace 的所有资源workspace_id 为 NULL 或有值都能看到) |
| User | 仅自己 Workspace 的资源 |
| 共享资源 | `is_shared=TRUE` 时,同 Workspace 内可见 |
---
## 常用 SQL 操作
### 查询用户及其 Workspace
```sql
SELECT u.id, u.username, u.role, w.name as workspace_name
FROM users u
LEFT JOIN workspaces w ON u.workspace_id = w.id
WHERE u.is_active = TRUE;
```
### 查询 Workspace 配额使用情况
```sql
SELECT w.name as workspace,
q.resource_type,
q.hard_limit,
q.soft_limit,
q.used,
CASE WHEN q.hard_limit > 0 THEN ROUND(q.used / q.hard_limit * 100, 2) ELSE 0 END as usage_percent
FROM workspace_quotas q
JOIN workspaces w ON q.workspace_id = w.id;
```
### 查询用户可用的集群
```sql
-- Admin: 所有集群
SELECT * FROM clusters;
-- User: 自己 Workspace 的集群 + 共享集群
SELECT * FROM clusters
WHERE workspace_id = 'user-workspace-id'
OR is_shared = TRUE;
```
### 查询实例状态统计
```sql
SELECT status, COUNT(*) as count
FROM instances
WHERE workspace_id = 'workspace-id'
GROUP BY status;
```
### 查询审计日志
```sql
SELECT a.created_at, u.username, a.action, a.resource_type, a.resource_name
FROM audit_logs a
JOIN users u ON a.user_id = u.id
WHERE a.workspace_id = 'workspace-id'
ORDER BY a.created_at DESC
LIMIT 50;
```
---
## 迁移历史
| 版本 | 说明 | 日期 |
|------|------|------|
| v1.0.0 | 初始版本(单租户) | 2024-01 |
| v2.0.0-multi-tenant | 多租户迁移:添加 workspaces, quotas, 扩展 users/clusters/registries/instances | 2025-04 |
---
## 初始数据
### 创建 Admin 用户
```sql
-- 默认密码: admin123 (bcrypt hash 需由应用设置)
INSERT INTO users (id, username, password_hash, email, role, workspace_id, is_active, must_change_password)
VALUES (
'00000000-0000-0000-0000-000000000001',
'admin',
'$2a$10$placeholder', -- 由应用初始化时设置
'admin@ocdp.local',
'admin',
NULL, -- admin 的 workspace_id 为 NULL表示全局
TRUE,
TRUE -- 首次登录必须修改密码
);
```