docs: audit housekeeping people workflows
This commit is contained in:
1 parent
a619f89106
commit
eb9f01d6fe
4 files changed
+968
No files matched your search
@@ -0,0 +1,36 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { PERMS } from "@/lib/permission-slugs";
|
||||||
|
import { operationsMigrationEntries } from "./operations";
|
||||||
|
|
||||||
|
describe("operationsMigrationEntries", () => {
|
||||||
|
it("covers the legacy dashboard once", () => {
|
||||||
|
expect(operationsMigrationEntries).toHaveLength(1);
|
||||||
|
expect(operationsMigrationEntries[0]).toMatchObject({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin",
|
||||||
|
sourceFile: "src/app/admin/page.tsx",
|
||||||
|
targetDomain: "operations",
|
||||||
|
targetPath: "/admin/work",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.ADMIN_DASHBOARD], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"users",
|
||||||
|
"active bans",
|
||||||
|
"website articles",
|
||||||
|
"staff activities",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
requiredTests: ["integration", "e2e", "visual"],
|
||||||
|
parityEvidence: [],
|
||||||
|
status: "PLANNED",
|
||||||
|
notes: [
|
||||||
|
"Replace metric dashboard with capability-derived operational home",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { PERMS } from "@/lib/permission-slugs";
|
||||||
|
import type { MigrationEntry } from "./types";
|
||||||
|
|
||||||
|
export const operationsMigrationEntries: readonly MigrationEntry[] = [
|
||||||
|
{
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin",
|
||||||
|
sourceFile: "src/app/admin/page.tsx",
|
||||||
|
targetDomain: "operations",
|
||||||
|
targetPath: "/admin/work",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.ADMIN_DASHBOARD], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: ["users", "active bans", "website articles", "staff activities"],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
requiredTests: ["integration", "e2e", "visual"],
|
||||||
|
parityEvidence: [],
|
||||||
|
status: "PLANNED",
|
||||||
|
notes: [
|
||||||
|
"Replace metric dashboard with capability-derived operational home",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { discoverLegacyPages } from "./discover-legacy-pages";
|
||||||
|
import { operationsMigrationEntries } from "./operations";
|
||||||
|
import { peopleMigrationEntries } from "./people";
|
||||||
|
import { validateMigrationEntries } from "./validate-matrix";
|
||||||
|
|
||||||
|
const PEOPLE_PREFIXES = [
|
||||||
|
"/admin/users",
|
||||||
|
"/admin/online",
|
||||||
|
"/admin/guilds",
|
||||||
|
"/admin/applications",
|
||||||
|
"/admin/teams",
|
||||||
|
"/admin/bans",
|
||||||
|
"/admin/ip",
|
||||||
|
"/admin/vpn",
|
||||||
|
"/admin/wordfilter",
|
||||||
|
"/admin/moderation",
|
||||||
|
"/admin/tickets",
|
||||||
|
"/admin/help-tickets",
|
||||||
|
"/mod",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
describe("peopleMigrationEntries", () => {
|
||||||
|
it("merges every mod page into a people workflow", () => {
|
||||||
|
const modRows = peopleMigrationEntries.filter(
|
||||||
|
(row) => row.surface === "mod",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(modRows).toHaveLength(13);
|
||||||
|
expect(modRows.every((row) => row.decision === "MERGE")).toBe(true);
|
||||||
|
expect(
|
||||||
|
modRows.every((row) => row.targetPath?.startsWith("/admin/people/")),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("merges duplicate user detail and edit aliases", () => {
|
||||||
|
for (const legacyPath of ["/admin/users/:id", "/admin/users/:id/edit"]) {
|
||||||
|
expect(peopleMigrationEntries).toContainEqual(
|
||||||
|
expect.objectContaining({ legacyPath, decision: "MERGE" }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps planned rows free of unverified parity claims", () => {
|
||||||
|
expect(
|
||||||
|
peopleMigrationEntries.every(
|
||||||
|
(row) => row.status === "PLANNED" && row.parityEvidence.length === 0,
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("covers every Operations and People legacy page exactly once", () => {
|
||||||
|
const expected = discoverLegacyPages().filter(
|
||||||
|
(page) =>
|
||||||
|
page.legacyPath === "/admin" ||
|
||||||
|
PEOPLE_PREFIXES.some(
|
||||||
|
(prefix) =>
|
||||||
|
page.legacyPath === prefix ||
|
||||||
|
page.legacyPath.startsWith(`${prefix}/`),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateMigrationEntries(expected, [
|
||||||
|
...operationsMigrationEntries,
|
||||||
|
...peopleMigrationEntries,
|
||||||
|
]),
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,835 @@
|
|||||||
|
import { PERMS } from "@/lib/permission-slugs";
|
||||||
|
import type { MigrationEntry } from "./types";
|
||||||
|
|
||||||
|
type PlannedPeopleEntry = Omit<
|
||||||
|
MigrationEntry,
|
||||||
|
"targetDomain" | "requiredTests" | "parityEvidence" | "status" | "notes"
|
||||||
|
> & {
|
||||||
|
requiredTests?: MigrationEntry["requiredTests"];
|
||||||
|
notes?: MigrationEntry["notes"];
|
||||||
|
};
|
||||||
|
|
||||||
|
function plannedPeopleEntry(entry: PlannedPeopleEntry): MigrationEntry {
|
||||||
|
return {
|
||||||
|
...entry,
|
||||||
|
targetDomain: "people",
|
||||||
|
requiredTests: entry.requiredTests ?? ["integration", "e2e", "visual"],
|
||||||
|
parityEvidence: [],
|
||||||
|
status: "PLANNED",
|
||||||
|
notes: entry.notes ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const peopleMigrationEntries: readonly MigrationEntry[] = [
|
||||||
|
// Batch 1: users, aliases, online users, guilds, and applications.
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users",
|
||||||
|
sourceFile: "src/app/admin/users/page.tsx",
|
||||||
|
targetPath: "/admin/people/users",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_EDIT, PERMS.USERS_BAN],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["fetchAdminList", "User"],
|
||||||
|
mutations: [
|
||||||
|
"createUser",
|
||||||
|
"bulkAdjustCurrency",
|
||||||
|
"bulkBan",
|
||||||
|
"bulkGiveBadge",
|
||||||
|
"bulkUnban",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users/edit/:id",
|
||||||
|
sourceFile: "src/app/admin/users/edit/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/:id/edit",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_EDIT],
|
||||||
|
mutate: [PERMS.USERS_EDIT, PERMS.USERS_BAN, PERMS.USERS_RESET_PASSWORD],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["loadUserById", "getWatchedUserIds", "permissions"],
|
||||||
|
mutations: [
|
||||||
|
"updateUser",
|
||||||
|
"giveBadge",
|
||||||
|
"removeBadge",
|
||||||
|
"banUser",
|
||||||
|
"unbanUser",
|
||||||
|
"alertUser",
|
||||||
|
"disconnectUser",
|
||||||
|
"muteUser",
|
||||||
|
"unmuteUser",
|
||||||
|
"resetPassword",
|
||||||
|
"sendCredits",
|
||||||
|
"setTradeLock",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users/multi-accounts",
|
||||||
|
sourceFile: "src/app/admin/users/multi-accounts/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/multi-accounts",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.USERS_VIEW], mutate: [] },
|
||||||
|
dependencies: { queries: ["detectMultiAccounts"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users/show/:id",
|
||||||
|
sourceFile: "src/app/admin/users/show/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/:id",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_EDIT, PERMS.USERS_BAN, PERMS.USERS_RESET_PASSWORD],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["loadUserById", "loadUserSanctions", "getWatchedUserIds"],
|
||||||
|
mutations: [
|
||||||
|
"alertUser",
|
||||||
|
"disconnectUser",
|
||||||
|
"muteUser",
|
||||||
|
"unmuteUser",
|
||||||
|
"resetPassword",
|
||||||
|
"sendCredits",
|
||||||
|
"setTradeLock",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users/:id",
|
||||||
|
sourceFile: "src/app/admin/users/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/:id",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: { read: [PERMS.USERS_VIEW], mutate: [] },
|
||||||
|
dependencies: { queries: [], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "COMPLETE",
|
||||||
|
requiredTests: ["e2e"],
|
||||||
|
notes: ["Redirect-only duplicate of the canonical user detail route"],
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/users/:id/edit",
|
||||||
|
sourceFile: "src/app/admin/users/[id]/edit/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/:id/edit",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: { read: [PERMS.USERS_EDIT], mutate: [] },
|
||||||
|
dependencies: { queries: [], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "COMPLETE",
|
||||||
|
requiredTests: ["e2e"],
|
||||||
|
notes: ["Redirect-only duplicate of the canonical user edit route"],
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/online",
|
||||||
|
sourceFile: "src/app/admin/online/page.tsx",
|
||||||
|
targetPath: "/admin/people/community/online",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.USERS_VIEW], mutate: [] },
|
||||||
|
dependencies: { queries: ["fetchAdminList", "User"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/guilds",
|
||||||
|
sourceFile: "src/app/admin/guilds/page.tsx",
|
||||||
|
targetPath: "/admin/people/community/guilds",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.USERS_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: ["Guilds", "GuildsMembers", "User"],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/guilds/:id",
|
||||||
|
sourceFile: "src/app/admin/guilds/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/community/guilds/:id",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["Guilds", "GuildsForumsThreads", "GuildsMembers", "User"],
|
||||||
|
mutations: ["disbandGuild"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/applications",
|
||||||
|
sourceFile: "src/app/admin/applications/page.tsx",
|
||||||
|
targetPath: "/admin/people/staff/applications",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["WebsiteStaffApplications", "User"],
|
||||||
|
mutations: ["dismissApplication"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Batch 2: staff, moderation, CFH, bans, IP, VPN, and word filter.
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/teams",
|
||||||
|
sourceFile: "src/app/admin/teams/page.tsx",
|
||||||
|
targetPath: "/admin/people/staff/teams",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.USERS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["WebsiteTeams"],
|
||||||
|
mutations: ["createTeam", "deleteTeam"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/moderation",
|
||||||
|
sourceFile: "src/app/admin/moderation/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.MODERATION_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"AdminAuditLog",
|
||||||
|
"Ban",
|
||||||
|
"SupportTickets",
|
||||||
|
"User",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/moderation/actions",
|
||||||
|
sourceFile: "src/app/admin/moderation/actions/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/actions",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MODERATION_EDIT],
|
||||||
|
mutate: [PERMS.MODERATION_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [],
|
||||||
|
mutations: [
|
||||||
|
"broadcastAlert",
|
||||||
|
"quickAlert",
|
||||||
|
"quickKick",
|
||||||
|
"quickMute",
|
||||||
|
"quickRoomKick",
|
||||||
|
"quickUnmute",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/moderation/cfh",
|
||||||
|
sourceFile: "src/app/admin/moderation/cfh/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/cfh",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.MODERATION_VIEW], mutate: [] },
|
||||||
|
dependencies: { queries: ["SupportTickets", "User"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/moderation/cfh/:id",
|
||||||
|
sourceFile: "src/app/admin/moderation/cfh/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/cfh/:id",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MODERATION_VIEW],
|
||||||
|
mutate: [PERMS.MODERATION_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["Ban", "SupportTickets", "User"],
|
||||||
|
mutations: [
|
||||||
|
"assignCfhTicket",
|
||||||
|
"closeCfhTicket",
|
||||||
|
"quickAlert",
|
||||||
|
"quickKick",
|
||||||
|
"quickMute",
|
||||||
|
"updateCfhState",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/moderation/team",
|
||||||
|
sourceFile: "src/app/admin/moderation/team/page.tsx",
|
||||||
|
targetPath: "/admin/people/staff/moderation-team",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.MODERATION_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"AdminAuditLog",
|
||||||
|
"SupportTickets",
|
||||||
|
"User",
|
||||||
|
"WebsiteTicket",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/bans",
|
||||||
|
sourceFile: "src/app/admin/bans/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/bans",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.BANS_VIEW],
|
||||||
|
mutate: [PERMS.USERS_BAN],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["Ban"],
|
||||||
|
mutations: ["createBan", "liftBan"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/ip",
|
||||||
|
sourceFile: "src/app/admin/ip/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/ip",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.SETTINGS_VIEW],
|
||||||
|
mutate: [PERMS.SETTINGS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["WebsiteIpBlacklist", "WebsiteIpWhitelist"],
|
||||||
|
mutations: [
|
||||||
|
"addBlacklist",
|
||||||
|
"addWhitelist",
|
||||||
|
"deleteBlacklist",
|
||||||
|
"deleteWhitelist",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/vpn",
|
||||||
|
sourceFile: "src/app/admin/vpn/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/vpn",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.SETTINGS_VIEW],
|
||||||
|
mutate: [PERMS.SETTINGS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["siteSettings.getMany"],
|
||||||
|
mutations: ["saveVpn"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/wordfilter",
|
||||||
|
sourceFile: "src/app/admin/wordfilter/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/word-filter",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.WORDFILTER_VIEW],
|
||||||
|
mutate: [PERMS.WORDFILTER_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["WebsiteWordfilter"],
|
||||||
|
mutations: ["addWord", "deleteWord"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Batch 3: website tickets and help-center tickets.
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/tickets",
|
||||||
|
sourceFile: "src/app/admin/tickets/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.TICKETS_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: ["fetchUnifiedTicketInbox", "fetchTicketQueueOpenCounts"],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/tickets/desk",
|
||||||
|
sourceFile: "src/app/admin/tickets/desk/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets/desk",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.TICKETS_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: ["fetchTicketQueueOpenCounts", "User", "WebsiteTicket"],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/tickets/templates",
|
||||||
|
sourceFile: "src/app/admin/tickets/templates/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets/templates",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.TICKETS_EDIT],
|
||||||
|
mutate: [PERMS.TICKETS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["WebsiteTicketTemplate"],
|
||||||
|
mutations: ["createTemplate", "deleteTemplate", "updateTemplate"],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/tickets/:id",
|
||||||
|
sourceFile: "src/app/admin/tickets/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets/:id",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [PERMS.TICKETS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteTicket",
|
||||||
|
],
|
||||||
|
mutations: [
|
||||||
|
"adminReplyTicket",
|
||||||
|
"assignTicket",
|
||||||
|
"updateTicketPriority",
|
||||||
|
"updateTicketStatus",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/help-tickets",
|
||||||
|
sourceFile: "src/app/admin/help-tickets/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/help-tickets",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: { read: [PERMS.TICKETS_VIEW], mutate: [] },
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteHelpCenterTicketReplies",
|
||||||
|
"WebsiteHelpCenterTickets",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "admin",
|
||||||
|
legacyPath: "/admin/help-tickets/:id",
|
||||||
|
sourceFile: "src/app/admin/help-tickets/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/help-tickets/:id",
|
||||||
|
decision: "REBUILD",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [PERMS.TICKETS_EDIT, PERMS.USERS_BAN],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"Ban",
|
||||||
|
"User",
|
||||||
|
"WebsiteHelpCenterCategories",
|
||||||
|
"WebsiteHelpCenterTicketReplies",
|
||||||
|
"WebsiteHelpCenterTickets",
|
||||||
|
],
|
||||||
|
mutations: [
|
||||||
|
"closeHelpCenterTicket",
|
||||||
|
"liftBanFromHelpTicket",
|
||||||
|
"reopenHelpCenterTicket",
|
||||||
|
"replyHelpCenterTicket",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Batch 4: merge all moderator routes into the People workflows.
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod",
|
||||||
|
sourceFile: "src/app/mod/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [
|
||||||
|
PERMS.MOD_CFH_VIEW,
|
||||||
|
PERMS.MODERATION_VIEW,
|
||||||
|
PERMS.MOD_ACTIONS,
|
||||||
|
PERMS.MODERATION_EDIT,
|
||||||
|
PERMS.MOD_BANS_VIEW,
|
||||||
|
PERMS.BANS_VIEW,
|
||||||
|
PERMS.MOD_TICKETS_VIEW,
|
||||||
|
PERMS.TICKETS_VIEW,
|
||||||
|
PERMS.MOD_TEAM_VIEW,
|
||||||
|
PERMS.MOD_USERS_VIEW,
|
||||||
|
PERMS.USERS_VIEW,
|
||||||
|
],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"Ban",
|
||||||
|
"SupportTickets",
|
||||||
|
"User",
|
||||||
|
"WebsiteHelpCenterTickets",
|
||||||
|
"WebsiteTicket",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
notes: ["Merge the moderator dashboard into capability-gated People work"],
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/actions",
|
||||||
|
sourceFile: "src/app/mod/actions/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/actions",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_ACTIONS, PERMS.MODERATION_EDIT],
|
||||||
|
mutate: [PERMS.MOD_ACTIONS, PERMS.MODERATION_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [],
|
||||||
|
mutations: [
|
||||||
|
"broadcastAlert",
|
||||||
|
"quickAlert",
|
||||||
|
"quickKick",
|
||||||
|
"quickMute",
|
||||||
|
"quickRoomKick",
|
||||||
|
"quickUnmute",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/bans",
|
||||||
|
sourceFile: "src/app/mod/bans/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/bans",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_BANS_VIEW, PERMS.BANS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: { queries: ["Ban"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/cfh",
|
||||||
|
sourceFile: "src/app/mod/cfh/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/cfh",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_CFH_VIEW, PERMS.MODERATION_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: { queries: ["SupportTickets", "User"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/cfh/:id",
|
||||||
|
sourceFile: "src/app/mod/cfh/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/moderation/cfh/:id",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_CFH_VIEW, PERMS.MODERATION_VIEW],
|
||||||
|
mutate: [PERMS.MOD_CFH_EDIT, PERMS.MODERATION_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["Ban", "SupportTickets", "User"],
|
||||||
|
mutations: [
|
||||||
|
"assignCfhTicket",
|
||||||
|
"closeCfhTicket",
|
||||||
|
"quickAlert",
|
||||||
|
"quickKick",
|
||||||
|
"quickMute",
|
||||||
|
"updateCfhState",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/help-tickets",
|
||||||
|
sourceFile: "src/app/mod/help-tickets/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/help-tickets",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TICKETS_VIEW, PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteHelpCenterTicketReplies",
|
||||||
|
"WebsiteHelpCenterTickets",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/help-tickets/:id",
|
||||||
|
sourceFile: "src/app/mod/help-tickets/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/help-tickets/:id",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TICKETS_VIEW, PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [PERMS.MOD_TICKETS_EDIT, PERMS.TICKETS_EDIT, PERMS.USERS_BAN],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteHelpCenterTicketReplies",
|
||||||
|
"WebsiteHelpCenterTickets",
|
||||||
|
],
|
||||||
|
mutations: [
|
||||||
|
"closeHelpCenterTicket",
|
||||||
|
"liftBanFromHelpTicket",
|
||||||
|
"reopenHelpCenterTicket",
|
||||||
|
"replyHelpCenterTicket",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/team",
|
||||||
|
sourceFile: "src/app/mod/team/page.tsx",
|
||||||
|
targetPath: "/admin/people/staff/moderation-team",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TEAM_VIEW, PERMS.MODERATION_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"AdminAuditLog",
|
||||||
|
"SupportTickets",
|
||||||
|
"User",
|
||||||
|
"WebsiteTicket",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "PARTIAL",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/tickets",
|
||||||
|
sourceFile: "src/app/mod/tickets/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TICKETS_VIEW, PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: ["fetchUnifiedTicketInbox", "fetchTicketQueueOpenCounts"],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/tickets/desk",
|
||||||
|
sourceFile: "src/app/mod/tickets/desk/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets/desk",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TICKETS_VIEW, PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteTicket",
|
||||||
|
"WebsiteTicketMessage",
|
||||||
|
],
|
||||||
|
mutations: [],
|
||||||
|
},
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/tickets/:id",
|
||||||
|
sourceFile: "src/app/mod/tickets/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/support/tickets/:id",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_TICKETS_VIEW, PERMS.TICKETS_VIEW],
|
||||||
|
mutate: [PERMS.MOD_TICKETS_EDIT, PERMS.TICKETS_EDIT],
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
queries: [
|
||||||
|
"getMinStaffRank",
|
||||||
|
"fetchTicketQueueOpenCounts",
|
||||||
|
"User",
|
||||||
|
"WebsiteTicket",
|
||||||
|
"WebsiteTicketMessage",
|
||||||
|
],
|
||||||
|
mutations: [
|
||||||
|
"adminReplyTicket",
|
||||||
|
"assignTicket",
|
||||||
|
"updateTicketPriority",
|
||||||
|
"updateTicketStatus",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
auditRequirement: "PRIVILEGED_MUTATION",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/users",
|
||||||
|
sourceFile: "src/app/mod/users/page.tsx",
|
||||||
|
targetPath: "/admin/people/users",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_USERS_VIEW, PERMS.USERS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: { queries: ["User"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
plannedPeopleEntry({
|
||||||
|
surface: "mod",
|
||||||
|
legacyPath: "/mod/users/:id",
|
||||||
|
sourceFile: "src/app/mod/users/[id]/page.tsx",
|
||||||
|
targetPath: "/admin/people/users/:id",
|
||||||
|
decision: "MERGE",
|
||||||
|
capabilities: {
|
||||||
|
read: [PERMS.MOD_USERS_VIEW, PERMS.USERS_VIEW],
|
||||||
|
mutate: [],
|
||||||
|
},
|
||||||
|
dependencies: { queries: ["User"], mutations: [] },
|
||||||
|
auditRequirement: "NONE",
|
||||||
|
localization: "COMPLETE",
|
||||||
|
accessibility: "PARTIAL",
|
||||||
|
}),
|
||||||
|
];
|
||||||
Reference in new issue
Block a user