1
0
forked from baron/baron-sso

테넌트 CSV 조직 설정 동기화 보완

This commit is contained in:
2026-05-12 18:02:55 +09:00
parent d4c48da426
commit e8a4d7544f
9 changed files with 252 additions and 14 deletions

View File

@@ -80,7 +80,7 @@ import {
} from "../utils/tenantCsvImport";
const tenantCSVTemplate =
"name,type,parent_tenant_slug,slug,memo,email_domain\n";
"name,type,parent_tenant_slug,slug,memo,email_domain,visibility,org_unit_type\n";
type SortConfig = {
key: keyof TenantSummary | "recursiveMemberCount";

View File

@@ -66,7 +66,7 @@ describe("tenantCsvImport", () => {
it("parses tenant CSV rows with the supported import columns", () => {
const rows = parseTenantCSV(
"tenant_id,name,type,parent_tenant_id,slug,memo,email_domain\n,Hanmac Tech,COMPANY,,hanmac-tech,Memo,hanmac-tech.example.com\n",
"tenant_id,name,type,parent_tenant_id,slug,memo,email_domain,visibility,org_unit_type\n,Hanmac Tech,COMPANY,,hanmac-tech,Memo,hanmac-tech.example.com,internal,센터\n",
);
expect(rows).toEqual([
@@ -80,6 +80,8 @@ describe("tenantCsvImport", () => {
slug: "hanmac-tech",
memo: "Memo",
emailDomain: "hanmac-tech.example.com",
visibility: "internal",
orgUnitType: "센터",
},
]);
});
@@ -109,15 +111,18 @@ describe("tenantCsvImport", () => {
it("serializes selected matches by filling tenant_id before upload", () => {
const rows = parseTenantCSV(
"tenant_id,name,type,parent_tenant_id,slug,memo,email_domain\n,Hanmac Tech,COMPANY,,hanmac-tech,Memo,hanmac-tech.example.com\n",
"tenant_id,name,type,parent_tenant_id,slug,memo,email_domain,visibility,org_unit_type\n,Hanmac Tech,COMPANY,,hanmac-tech,Memo,hanmac-tech.example.com,private,팀\n",
);
const preview = buildTenantImportPreview(rows, tenants);
const csv = serializeTenantImportCSV(preview, {
2: "tenant-1",
});
expect(csv.split("\n")[0]).toBe(
"tenant_id,name,type,parent_tenant_id,parent_tenant_slug,slug,memo,email_domain,visibility,org_unit_type",
);
expect(csv).toContain(
"tenant-1,Hanmac Tech,COMPANY,,,hanmac-tech,Memo,hanmac-tech.example.com",
"tenant-1,Hanmac Tech,COMPANY,,,hanmac-tech,Memo,hanmac-tech.example.com,private,팀",
);
});
@@ -228,7 +233,7 @@ describe("tenantCsvImport", () => {
});
expect(csv.split("\n")[0]).toBe(
"tenant_id,name,type,parent_tenant_id,parent_tenant_slug,slug,memo,email_domain",
"tenant_id,name,type,parent_tenant_id,parent_tenant_slug,slug,memo,email_domain,visibility,org_unit_type",
);
expect(csv).toContain(
"staging-child-id,Child Tenant,ORGANIZATION,staging-parent-id,parent-slug,child-slug,,",

View File

@@ -10,6 +10,8 @@ export type TenantCSVRow = {
slug: string;
memo: string;
emailDomain: string;
visibility: string;
orgUnitType: string;
};
export type TenantCSVParseOptions = {
@@ -76,6 +78,8 @@ const importHeaders = [
"slug",
"memo",
"email_domain",
"visibility",
"org_unit_type",
];
const headerAliases: Record<string, TenantCSVSourceKey> = {
@@ -102,6 +106,16 @@ const headerAliases: Record<string, TenantCSVSourceKey> = {
email_domain: "emailDomain",
domain: "emailDomain",
domains: "emailDomain",
visibility: "visibility",
public_setting: "visibility",
publicsetting: "visibility",
orgunittype: "orgUnitType",
org_unit_type: "orgUnitType",
"org-unit-type": "orgUnitType",
organizationtype: "orgUnitType",
organization_type: "orgUnitType",
orgtype: "orgUnitType",
org_type: "orgUnitType",
};
export function parseTenantCSV(
@@ -159,6 +173,8 @@ export function parseTenantCSV(
slug,
memo: value("memo"),
emailDomain: value("emailDomain"),
visibility: value("visibility"),
orgUnitType: value("orgUnitType"),
};
});
}
@@ -287,6 +303,8 @@ export function serializeTenantImportCSV(
slug,
preview.row.memo,
preview.row.emailDomain,
preview.row.visibility,
preview.row.orgUnitType,
]);
}
return `${lines.map(formatCSVRecord).join("\n")}\n`;