fix: restore matchmaker workbench permissions
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
-- V074: 恢复红娘工作台六项卡片及已确认的业务操作权限。
|
||||
-- 仅使用既有 permission code;不授予资格原始佐证、咨询备注查看或代用户决策权限。
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r
|
||||
CROSS JOIN permissions p
|
||||
WHERE r.code IN ('matchmaker', 'matchmaker_leader')
|
||||
AND p.code IN (
|
||||
'workbench.view', 'review.view', 'review.process', 'local_eligibility.review',
|
||||
'counseling.service.view', 'counseling.service.assign', 'counseling.service.process',
|
||||
'counseling.note.create', 'service_appointment.view', 'service_appointment.assign',
|
||||
'service_appointment.confirm', 'service_appointment.complete', 'activity.view',
|
||||
'activity.review_registration', 'analytics.view'
|
||||
)
|
||||
ON CONFLICT (role_id, permission_id) DO NOTHING;
|
||||
+2
-2
@@ -45,8 +45,8 @@ class MigrationValidationTest {
|
||||
// V067 工作台聚合权限与红娘角色边界;V068/V069 红娘工作台权限;
|
||||
// V070 收回红娘的咨询、活动、预约、统计权限;
|
||||
// V071 收回红娘的资料审核、本地资格审核权限。
|
||||
// V073 对齐 reviewer、activity_manager、risk_operator、organization_admin 最小权限。
|
||||
private static final int LATEST_MIGRATION = 73;
|
||||
// V073 对齐其他运营角色;V074 恢复红娘工作台六卡片及操作权限。
|
||||
private static final int LATEST_MIGRATION = 74;
|
||||
|
||||
private static final String MIGRATION_DIR =
|
||||
"backend/src/main/resources/db/migration/";
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package com.danyang.match.platform.deployment;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class V12MigrationContractTest {
|
||||
|
||||
private static final Path DIR = Path.of("backend/src/main/resources/db/migration");
|
||||
|
||||
@Test
|
||||
void v12MigrationsAndLifecycleContractsExist() throws Exception {
|
||||
assertMigration("V062__add_v12_user_account_lifecycle.sql");
|
||||
assertMigration("V063__add_v12_import_batches.sql");
|
||||
assertMigration("V064__add_v12_consent_and_service_state.sql");
|
||||
assertMigration("V065__add_v12_registration_applications.sql");
|
||||
assertMigration("V066__grant_user_onboarding_permission.sql");
|
||||
|
||||
String lifecycle = Files.readString(DIR.resolve("V062__add_v12_user_account_lifecycle.sql"));
|
||||
assertAll(
|
||||
() -> assertTrue(lifecycle.contains("profile_revision")),
|
||||
() -> assertTrue(lifecycle.contains("published_profile_revision")),
|
||||
() -> assertTrue(lifecycle.contains("user_credentials")),
|
||||
() -> assertTrue(lifecycle.contains("must_change_password")),
|
||||
() -> assertFalse(lifecycle.toLowerCase().contains("plaintext_password"))
|
||||
);
|
||||
|
||||
String imports = Files.readString(DIR.resolve("V063__add_v12_import_batches.sql"));
|
||||
assertAll(
|
||||
() -> assertTrue(imports.contains("user_import_batches")),
|
||||
() -> assertTrue(imports.contains("user_import_rows")),
|
||||
() -> assertTrue(imports.contains("idempotency_key"))
|
||||
);
|
||||
|
||||
String consent = Files.readString(DIR.resolve("V064__add_v12_consent_and_service_state.sql"));
|
||||
assertAll(
|
||||
() -> assertTrue(consent.contains("user_consent_states")),
|
||||
() -> assertTrue(consent.contains("user_service_states")),
|
||||
() -> assertTrue(consent.contains("service_active"))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void lifecycleMigrationsDoNotDropExistingObjects() throws Exception {
|
||||
List<String> names = List.of(
|
||||
"V062__add_v12_user_account_lifecycle.sql",
|
||||
"V063__add_v12_import_batches.sql",
|
||||
"V064__add_v12_consent_and_service_state.sql",
|
||||
"V065__add_v12_registration_applications.sql",
|
||||
"V066__grant_user_onboarding_permission.sql");
|
||||
for (String name : names) {
|
||||
String sql = Files.readString(DIR.resolve(name)).toUpperCase();
|
||||
assertFalse(sql.contains("DROP TABLE"), name);
|
||||
assertFalse(sql.contains("DROP COLUMN"), name);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchmakerCrossDomainPermissionsAreRevoked() throws Exception {
|
||||
String sql = Files.readString(DIR.resolve("V070__remove_matchmaker_cross_domain_permissions.sql"));
|
||||
assertAll(
|
||||
() -> assertTrue(sql.contains("r.code IN ('matchmaker', 'matchmaker_leader')")),
|
||||
() -> assertTrue(sql.contains("p.code LIKE 'counseling.%'")),
|
||||
() -> assertTrue(sql.contains("p.code LIKE 'service_appointment.%'")),
|
||||
() -> assertTrue(sql.contains("'activity.view'")),
|
||||
() -> assertTrue(sql.contains("'activity.checkin'")),
|
||||
() -> assertTrue(sql.contains("'activity.review_registration'")),
|
||||
() -> assertTrue(sql.contains("'analytics.view'"))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchmakerReviewPermissionsAreRevoked() throws Exception {
|
||||
String sql = Files.readString(DIR.resolve("V071__remove_matchmaker_review_permissions.sql"));
|
||||
assertAll(
|
||||
() -> assertTrue(sql.contains("r.code IN ('matchmaker', 'matchmaker_leader')")),
|
||||
() -> assertTrue(sql.contains("'review.view'")),
|
||||
() -> assertTrue(sql.contains("'review.process'")),
|
||||
() -> assertTrue(sql.contains("'local_eligibility.review'"))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchmakerWorkbenchPermissionsAreRestoredWithoutSensitiveAccess() throws Exception {
|
||||
Path migration = DIR.resolve("V074__restore_matchmaker_workbench_permissions.sql");
|
||||
assertTrue(Files.exists(migration));
|
||||
String sql = Files.readString(migration);
|
||||
assertAll(
|
||||
() -> assertTrue(sql.contains("r.code IN ('matchmaker', 'matchmaker_leader')")),
|
||||
() -> assertTrue(sql.contains("'workbench.view'")),
|
||||
() -> assertTrue(sql.contains("'review.process'")),
|
||||
() -> assertTrue(sql.contains("'local_eligibility.review'")),
|
||||
() -> assertTrue(sql.contains("'counseling.service.assign'")),
|
||||
() -> assertTrue(sql.contains("'service_appointment.confirm'")),
|
||||
() -> assertTrue(sql.contains("'service_appointment.complete'")),
|
||||
() -> assertFalse(sql.contains("'local_eligibility.evidence.view'")),
|
||||
() -> assertFalse(sql.contains("'counseling.note.view'")),
|
||||
() -> assertFalse(sql.contains("'matchmaker.assign'")),
|
||||
() -> assertTrue(sql.contains("ON CONFLICT (role_id, permission_id) DO NOTHING"))
|
||||
);
|
||||
}
|
||||
|
||||
private static void assertMigration(String name) {
|
||||
assertTrue(Files.exists(DIR.resolve(name)), "缺少迁移: " + name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user