ken_nogi/NodeSrv/apps/org-master-sync/scripts/_tmp-convert-sample-to-api-json.js
Kenichiro NOGI ce58cb4be4 初回コミット: dev配下(NodeSrv/Pleasanter等)をGitea管理下に統合
GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。
NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは
別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter
インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:37:06 +09:00

86 lines
3.2 KiB
JavaScript

"use strict";
const fs = require("node:fs");
const path = require("node:path");
function parseCsv(text) {
const rows = [];
let row = [], field = "", inQuotes = false;
for (let i = 0; i < text.length; i++) {
const c = text[i];
if (inQuotes) {
if (c === '"') { if (text[i + 1] === '"') { field += '"'; i++; } else inQuotes = false; }
else field += c;
} else {
if (c === '"') inQuotes = true;
else if (c === ",") { row.push(field); field = ""; }
else if (c === "\r") { /* skip */ }
else if (c === "\n") { row.push(field); rows.push(row); row = []; field = ""; }
else field += c;
}
}
if (field.length > 0 || row.length > 0) { row.push(field); rows.push(row); }
const headers = rows.shift() || [];
return rows.filter((r) => !(r.length === 1 && r[0] === "")).map((r) => {
const obj = {};
headers.forEach((h, idx) => { obj[h] = r[idx] !== undefined ? r[idx] : ""; });
return obj;
});
}
function readCsv(filePath) {
const buf = fs.readFileSync(filePath);
let text = buf.toString("utf8");
if (text.charCodeAt(0) === 0xfeff) text = text.slice(1);
return parseCsv(text);
}
const sampleDir = path.join(__dirname, "..", "sample");
const deptRows = readCsv(path.join(sampleDir, "組織_2026_09_03 13_53_35.csv"));
const userRows = readCsv(path.join(sampleDir, "ユーザ_2026_09_03 13_53_13.csv"));
const deptCodeToId = new Map(deptRows.map((d) => [d["組織コード"], d["組織ID"]]));
const depts = deptRows.map((d) => ({
DeptId: Number(d["組織ID"]),
DeptCode: d["組織コード"],
DeptName: d["組織名"],
Disabled: d["無効"] === "1",
}));
const users = userRows.map((u) => {
const deptId = deptCodeToId.get(u["組織コード"]);
const mailField = u["メールアドレス"] || "";
const mailAddresses = mailField ? mailField.split(",").map((s) => s.trim()).filter(Boolean) : [];
return {
UserId: Number(u["ユーザID"]),
LoginId: u["ログインID"] || "",
Name: u["名前"] || "",
UserCode: u["ユーザコード"] || "",
Gender: u["性別"] || "",
Language: u["言語"] || "",
TimeZone: u["タイムゾーン"] || "",
DeptId: deptId !== undefined ? Number(deptId) : 0,
Manager: u["管理者"] || "",
TenantManager: u["テナント管理者"] === "1",
Theme: u["テーマ"] || "",
Body: u["説明"] || "",
AllowCreationAtTopSite: u["サイトトップへの作成を許可"] === "1",
AllowGroupAdministration: u["グループの管理を許可"] === "1",
AllowGroupCreation: u["グループの作成を許可"] === "1",
AllowApi: u["APIを許可"] === "1",
AllowMovingFromTopSite: u["サイトトップからの移動を許可"] === "1",
Disabled: u["無効"] === "1",
Lockout: u["ロック"] === "1",
SecretKey: u["秘密鍵有効"] === "1",
MailAddresses: mailAddresses,
};
});
const outDir = path.join(__dirname, "..", "data", "test-import-maps");
fs.writeFileSync(path.join(outDir, "mock-pleasanter-depts.json"), JSON.stringify(depts), "utf8");
fs.writeFileSync(path.join(outDir, "mock-pleasanter-users.json"), JSON.stringify(users), "utf8");
console.log("depts:", depts.length, "users:", users.length);
console.log("sample dept:", JSON.stringify(depts[0]));
console.log("sample user:", JSON.stringify(users[0]));