diff --git a/account/Makefile b/account/Makefile index 2541559..a7de010 100644 --- a/account/Makefile +++ b/account/Makefile @@ -19,10 +19,10 @@ REPLICATION_MODE ?= pgsync DB_ADMIN_USER ?= $(DB_USER) DB_ADMIN_PASS ?= $(DB_PASS) -SCHEMA_FILE := ./sql/schema.sql -PGLOGICAL_INIT_FILE := ./sql/schema_pglogical_init.sql -PGLOGICAL_PATCH_FILE := ./sql/schema_pglogical_patch.sql -PGLOGICAL_REGION_FILE := ./sql/schema_pglogical_region.sql +SCHEMA_FILE := ../sql/schema.sql +PGLOGICAL_INIT_FILE := ../sql/schema_pglogical_init.sql +PGLOGICAL_PATCH_FILE := ../sql/schema_pglogical_patch.sql +PGLOGICAL_REGION_FILE := ../sql/schema_pglogical_region.sql ACCOUNT_EXPORT_FILE ?= account-export.yaml ACCOUNT_IMPORT_FILE ?= account-export.yaml @@ -165,7 +165,7 @@ create-db-user: migrate-db: @echo ">>> 执行数据库迁移" - @go run ./cmd/migratectl/main.go migrate --dsn "$(DB_URL)" --dir sql/migrations + @go run ./cmd/migratectl/main.go migrate --dsn "$(DB_URL)" --dir ../sql/migrations dump-schema: @echo ">>> 导出 schema 到 $(SCHEMA_FILE)" @@ -215,10 +215,10 @@ drop-db: fi reset-public-schema: - @psql "$(DB_URL)" -v ON_ERROR_STOP=1 -v db_user="$(DB_USER)" -f sql/reset_public_schema.sql + @psql "$(DB_URL)" -v ON_ERROR_STOP=1 -v db_user="$(DB_USER)" -f ../sql/reset_public_schema.sql reinit-db: - @echo ">>> 重置业务 schema (sql/schema.sql)" + @echo ">>> 重置业务 schema ($(SCHEMA_FILE))" @$(MAKE) reset-public-schema @$(MAKE) init-db-core diff --git a/account/cmd/migratectl/main.go b/account/cmd/migratectl/main.go index 2fab8c3..2d0539f 100644 --- a/account/cmd/migratectl/main.go +++ b/account/cmd/migratectl/main.go @@ -16,8 +16,8 @@ import ( ) const ( - defaultMigrationDir = "account/sql/migrations" - defaultSchemaFile = "account/sql/schema.sql" + defaultMigrationDir = "sql/migrations" + defaultSchemaFile = "sql/schema.sql" ) func main() { diff --git a/account/go.mod b/account/go.mod index 7846cd1..2232179 100644 --- a/account/go.mod +++ b/account/go.mod @@ -17,6 +17,7 @@ require ( gorm.io/driver/postgres v1.6.0 gorm.io/driver/sqlite v1.6.0 gorm.io/gorm v1.31.1 + xcontrol v0.0.0 ) require ( @@ -59,3 +60,5 @@ require ( golang.org/x/text v0.31.0 // indirect google.golang.org/protobuf v1.36.9 // indirect ) + +replace xcontrol => .. diff --git a/account/internal/migrate/runner.go b/account/internal/migrate/runner.go index 57520c2..3ce9f7d 100644 --- a/account/internal/migrate/runner.go +++ b/account/internal/migrate/runner.go @@ -13,7 +13,7 @@ import ( "github.com/golang-migrate/migrate/v4" ) -const defaultDir = "account/sql/migrations" +const defaultDir = "sql/migrations" // Runner coordinates golang-migrate operations. type Runner struct { @@ -21,7 +21,7 @@ type Runner struct { } // NewRunner creates a runner that reads migration files from dir. When dir is -// empty, the default directory under account/sql/migrations is used. +// empty, the default directory under sql/migrations is used. func NewRunner(dir string) *Runner { if dir == "" { dir = defaultDir diff --git a/account/internal/migrate/snapshot.go b/account/internal/migrate/snapshot.go index aab1567..548f5a9 100644 --- a/account/internal/migrate/snapshot.go +++ b/account/internal/migrate/snapshot.go @@ -4,7 +4,7 @@ import ( "errors" "time" - accountschema "account/sql" + accountschema "xcontrol/sql" ) // SnapshotVersion identifies the canonical format of exported account snapshots. diff --git a/account/internal/migrate/transfer.go b/account/internal/migrate/transfer.go index 74cf7ec..d480b13 100644 --- a/account/internal/migrate/transfer.go +++ b/account/internal/migrate/transfer.go @@ -12,7 +12,7 @@ import ( "strings" "time" - accountschema "account/sql" + accountschema "xcontrol/sql" ) // AccountDump represents the serialized snapshot of account-related tables. diff --git a/account/internal/migrate/verifier.go b/account/internal/migrate/verifier.go index b98305e..a016a85 100644 --- a/account/internal/migrate/verifier.go +++ b/account/internal/migrate/verifier.go @@ -9,7 +9,7 @@ import ( "account/internal/utils" ) -const defaultSchemaPath = "account/sql/schema.sql" +const defaultSchemaPath = "sql/schema.sql" // Verifier validates that the live database matches the canonical schema.sql. type Verifier struct{} diff --git a/account/scripts/setup_postgres_local.sh b/account/scripts/setup_postgres_local.sh index 97eb7b6..738d603 100644 --- a/account/scripts/setup_postgres_local.sh +++ b/account/scripts/setup_postgres_local.sh @@ -17,7 +17,9 @@ DB_USER="${DB_USER:-shenlan}" DB_PASS="${DB_PASS:-password}" DB_PORT="${DB_PORT:-5432}" DB_HOST="${DB_HOST:-127.0.0.1}" -SCHEMA_FILE="${SCHEMA_FILE:-./sql/schema.sql}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" +SCHEMA_FILE="${SCHEMA_FILE:-${ROOT_DIR}/sql/schema.sql}" PG_SERVICE_NAME="${PG_SERVICE_NAME:-postgresql}" OS=$(uname -s) diff --git a/docs/account-admin-settings.md b/docs/account-admin-settings.md index 9996ef6..f160427 100644 --- a/docs/account-admin-settings.md +++ b/docs/account-admin-settings.md @@ -14,7 +14,7 @@ This document summarizes the new `/api/auth/admin/settings` endpoints for managi ## Storage Model -- The permission matrix is stored in the `admin_settings` table. GORM manages the model via `account/internal/model/admin_setting.go` and a dedicated migration script (`account/sql/20250305-admin-settings.sql`). +- The permission matrix is stored in the `admin_settings` table. GORM manages the model via `account/internal/model/admin_setting.go` and a dedicated migration script (`sql/20250305-admin-settings.sql`). - Each cell records `module_key`, `role`, `enabled`, and a monotonically increasing `version` value. Updates occur inside a single transaction that replaces the existing matrix to guarantee consistency across modules and roles. - The service layer (`account/internal/service/admin_settings.go`) caches the most recent matrix in-memory and invalidates the cache whenever a write occurs or fails due to a version conflict. diff --git a/docs/account-service-deployment.md b/docs/account-service-deployment.md index 3b65f93..5384f8e 100644 --- a/docs/account-service-deployment.md +++ b/docs/account-service-deployment.md @@ -327,7 +327,7 @@ docker compose -f deploy/docker-compose/caddy-stunnel/docker-compose.db.yaml up COMMIT; ``` - > **提示**:如已在 CI/CD 中托管 `account/sql/schema.sql`,也可直接执行 `psql -h ... -f account/sql/schema.sql`,该脚本为幂等实现,会自动跳过已有对象。 + > **提示**:如已在 CI/CD 中托管 `sql/schema.sql`,也可直接执行 `psql -h ... -f sql/schema.sql`,该脚本为幂等实现,会自动跳过已有对象。 3. **验证数据** diff --git a/docs/account-svc-plus.md b/docs/account-svc-plus.md index b309284..4643657 100644 --- a/docs/account-svc-plus.md +++ b/docs/account-svc-plus.md @@ -56,7 +56,7 @@ ### 4.1 表结构草案 -`account/sql/schema.sql` 维护初始建表脚本: +`sql/schema.sql` 维护初始建表脚本: ```sql CREATE TABLE IF NOT EXISTS users ( diff --git a/docs/multi-tenant-rbac.md b/docs/multi-tenant-rbac.md index d2ed955..a711557 100644 --- a/docs/multi-tenant-rbac.md +++ b/docs/multi-tenant-rbac.md @@ -2,7 +2,7 @@ ## 概览 -本次检查聚焦于前后端在多租户环境下的适配度与角色权限控制实现。后端账户服务的数据模型已包含 `role`、`groups`、`permissions` 字段,可支撑细粒度的访问控制,并且前端会话 API 现已补充 `tenantId` 与 `tenants` 元数据,便于后续按照租户维度做隔离控制。【F:account/sql/schema.sql†L27-L67】【F:dashboard/app/api/auth/session/route.ts†L12-L116】 +本次检查聚焦于前后端在多租户环境下的适配度与角色权限控制实现。后端账户服务的数据模型已包含 `role`、`groups`、`permissions` 字段,可支撑细粒度的访问控制,并且前端会话 API 现已补充 `tenantId` 与 `tenants` 元数据,便于后续按照租户维度做隔离控制。【F:sql/schema.sql†L27-L67】【F:dashboard/app/api/auth/session/route.ts†L12-L116】 前端 `userStore` 会解析并缓存上述字段,同时归一化多租户信息,为 React 组件提供统一上下文;新增的 `accessControl` 工具封装了访问信息判定逻辑,使页面与组件能够以声明式的方式定义访问规则。面向用户的首页、Docs 与下载中心保持公开访问,而 `/panel` 下页面默认要求登录,`/panel/management` 进一步限制为管理员与操作员角色访问。【F:dashboard/lib/userStore.tsx†L1-L161】【F:dashboard/lib/accessControl.ts†L1-L99】【F:dashboard/app/page.tsx†L1-L28】【F:dashboard/app/panel/layout.tsx†L1-L115】 diff --git a/account/sql/20251001.migrate.to_uuid.md b/sql/20251001.migrate.to_uuid.md similarity index 100% rename from account/sql/20251001.migrate.to_uuid.md rename to sql/20251001.migrate.to_uuid.md diff --git a/account/sql/embed.go b/sql/embed.go similarity index 100% rename from account/sql/embed.go rename to sql/embed.go diff --git a/account/sql/pgsync.users.example.yaml b/sql/pgsync.users.example.yaml similarity index 100% rename from account/sql/pgsync.users.example.yaml rename to sql/pgsync.users.example.yaml diff --git a/account/sql/readme.md b/sql/readme.md similarity index 95% rename from account/sql/readme.md rename to sql/readme.md index 5734ad1..198e6cd 100644 --- a/account/sql/readme.md +++ b/sql/readme.md @@ -12,10 +12,10 @@ ```bash # 初始化或升级 schema -go run ./cmd/migratectl/main.go migrate --dsn "$DB_URL" +go run ./account/cmd/migratectl/main.go migrate --dsn "$DB_URL" # 对比 CN 与 Global 节点结构一致性 -go run ./cmd/migratectl/main.go check --cn "$CN_DSN" --global "$GLOBAL_DSN" +go run ./account/cmd/migratectl/main.go check --cn "$CN_DSN" --global "$GLOBAL_DSN" ## 仅异步同步(pgsync) @@ -28,13 +28,13 @@ go run ./cmd/migratectl/main.go check --cn "$CN_DSN" --global "$GLOBAL_DSN" make -C account init-db REPLICATION_MODE=pgsync DB_URL="$DEST_DB_URL" ``` -2. 编辑 `account/sql/pgsync.users.example.yaml`,替换源端与目标端 DSN。 +2. 编辑 `sql/pgsync.users.example.yaml`,替换源端与目标端 DSN。 3. 使用 pgsync 持续同步,可结合 cron 运行增量同步: ```bash # 全量初始化 - pgsync --config account/sql/pgsync.users.example.yaml --once + pgsync --config sql/pgsync.users.example.yaml --once # 每分钟增量同步 * * * * * /usr/local/bin/pgsync --config /path/to/pgsync.users.yaml >> /var/log/pgsync.log 2>&1 @@ -126,7 +126,7 @@ psql "$REGION_GLOBAL_DB_URL" -v ON_ERROR_STOP=1 \ -v NODE_DSN='host=global-homepage.svc.plus port=5432 dbname=account user=pglogical password=xxxx' \ -v SUBSCRIPTION_NAME=sub_from_cn \ -v PROVIDER_DSN='host=cn-homepage.svc.plus port=5432 dbname=account user=pglogical password=xxxx' \ - -f account/sql/schema_pglogical_region.sql + -f sql/schema_pglogical_region.sql # CN 节点示例 psql "$REGION_CN_DB_URL" -v ON_ERROR_STOP=1 \ @@ -134,7 +134,7 @@ psql "$REGION_CN_DB_URL" -v ON_ERROR_STOP=1 \ -v NODE_DSN='host=cn-homepage.svc.plus port=5432 dbname=account user=pglogical password=xxxx' \ -v SUBSCRIPTION_NAME=sub_from_global \ -v PROVIDER_DSN='host=global-homepage.svc.plus port=5432 dbname=account user=pglogical password=xxx' \ - -f account/sql/schema_pglogical_region.sql + -f sql/schema_pglogical_region.sql ``` 也可以通过新的 `make init-pglogical-region` 目标自定义变量,例如: diff --git a/account/sql/reset_public_schema.sql b/sql/reset_public_schema.sql similarity index 100% rename from account/sql/reset_public_schema.sql rename to sql/reset_public_schema.sql diff --git a/account/sql/schema.sql b/sql/schema.sql similarity index 100% rename from account/sql/schema.sql rename to sql/schema.sql diff --git a/account/sql/schema_pglogical_init.sql b/sql/schema_pglogical_init.sql similarity index 100% rename from account/sql/schema_pglogical_init.sql rename to sql/schema_pglogical_init.sql diff --git a/account/sql/schema_pglogical_patch.sql b/sql/schema_pglogical_patch.sql similarity index 100% rename from account/sql/schema_pglogical_patch.sql rename to sql/schema_pglogical_patch.sql diff --git a/account/sql/schema_pglogical_region.sql b/sql/schema_pglogical_region.sql similarity index 100% rename from account/sql/schema_pglogical_region.sql rename to sql/schema_pglogical_region.sql