"use strict"; const path = require("node:path"); const MODULE_KEYS = Object.freeze([ "portal_notifications", "workflow_approvals", "reimbursements_invoices", "payments_ap", "procurement", "contracts", "projects", "assets_inventory", "leave_wecom_history", "attendance_presence", "weekly_reports", "todos", "announcements", "budgets", "travel", "people_lifecycle", "payroll", "performance", "system_configuration", "integrations", ]); const SAFE_RESULT_KEYS = Object.freeze([ "moduleKey", "totalRows", "created30d", "created90d", "activity30d", "activity90d", "latestActivityAt", "humanActors30d", "humanActors90d", "humanEvents30d", "humanEvents90d", "smokeEvents30d", "smokeEvents90d", "systemEvents30d", "systemEvents90d", "unknownEvents30d", "unknownEvents90d", "auditEvents30d", "auditEvents90d", "auditHumanActors30d", "auditHumanActors90d", "auditHumanEvents30d", "auditHumanEvents90d", "auditSmokeEvents30d", "auditSmokeEvents90d", "auditUnknownEvents30d", "auditUnknownEvents90d", "navigationMode", "effectiveFlagState", "queryStatus", ]); const USAGE_SQL = String.raw` WITH module_keys(module_key) AS ( VALUES ('portal_notifications'), ('workflow_approvals'), ('reimbursements_invoices'), ('payments_ap'), ('procurement'), ('contracts'), ('projects'), ('assets_inventory'), ('leave_wecom_history'), ('attendance_presence'), ('weekly_reports'), ('todos'), ('announcements'), ('budgets'), ('travel'), ('people_lifecycle'), ('payroll'), ('performance'), ('system_configuration'), ('integrations') ), record_events(module_key, record_id, created_at, activity_at, actor_id, forced_kind) AS ( SELECT 'portal_notifications', id::text, created_at, created_at, recipient_employee_id, 'system' FROM notifications UNION ALL SELECT 'workflow_approvals', id::text, created_at, updated_at, submitter_id, NULL FROM workflow_instances UNION ALL SELECT 'reimbursements_invoices', id::text, created_at, updated_at, owner_id, NULL FROM reimbursement_forms UNION ALL SELECT 'reimbursements_invoices', id::text, created_at, updated_at, uploaded_by_employee_id, NULL FROM invoice_pool UNION ALL SELECT 'reimbursements_invoices', id::text, created_at, created_at, NULL::uuid, 'system' FROM ocr_results UNION ALL SELECT 'payments_ap', id::text, created_at, updated_at, created_by, NULL FROM payment_batches UNION ALL SELECT 'payments_ap', id::text, created_at, created_at, uploaded_by, NULL FROM payment_batch_receipt_attachments UNION ALL SELECT 'procurement', id::text, created_at, updated_at, applicant_id, NULL FROM purchase_requests UNION ALL SELECT 'contracts', id::text, created_at, updated_at, owner_employee_id, NULL FROM contract_registry UNION ALL SELECT 'projects', id::text, created_at, updated_at, owner_employee_id, NULL FROM projects UNION ALL SELECT 'assets_inventory', id::text, created_at, updated_at, created_by, NULL FROM asset_cards UNION ALL SELECT 'assets_inventory', id::text, created_at, updated_at, created_by, NULL FROM inventory_checks UNION ALL SELECT 'leave_wecom_history', id::text, created_at, updated_at, owner_id, NULL FROM leave_requests UNION ALL SELECT 'leave_wecom_history', id::text, created_at, updated_at, applicant_employee_id, 'system' FROM wecom_approval_archives UNION ALL SELECT 'attendance_presence', id::text, created_at, updated_at, owner_id, NULL FROM attendance_corrections UNION ALL SELECT 'attendance_presence', id::text, created_at, updated_at, employee_id, 'system' FROM wecom_checkin_records UNION ALL SELECT 'attendance_presence', id::text, created_at, updated_at, updated_by, NULL FROM employee_presence UNION ALL SELECT 'weekly_reports', id::text, created_at, updated_at, employee_id, NULL FROM weekly_reports UNION ALL SELECT 'todos', id::text, created_at, updated_at, created_by, NULL FROM todo_items UNION ALL SELECT 'announcements', id::text, created_at, updated_at, created_by, NULL FROM portal_announcements UNION ALL SELECT 'announcements', id::text, created_at, COALESCE(acknowledged_at, created_at), actor_id, NULL FROM portal_announcement_acknowledgements UNION ALL SELECT 'budgets', id::text, created_at, updated_at, created_by, NULL FROM budget_pools UNION ALL SELECT 'travel', id::text, created_at, updated_at, applicant_employee_id, NULL FROM travel_requests UNION ALL SELECT 'travel', id::text, created_at, updated_at, created_by, NULL FROM travel_orders UNION ALL SELECT 'people_lifecycle', id::text, created_at, created_at, created_by, NULL FROM employee_lifecycle_events UNION ALL SELECT 'people_lifecycle', id::text, created_at, updated_at, created_by, NULL FROM employee_contracts UNION ALL SELECT 'people_lifecycle', id::text, created_at, updated_at, created_by, NULL FROM employee_trainings UNION ALL SELECT 'payroll', id::text, created_at, updated_at, created_by, NULL FROM payslips UNION ALL SELECT 'performance', id::text, created_at, updated_at, reviewer_employee_id, NULL FROM performance_reviews UNION ALL SELECT 'system_configuration', id::text, created_at, updated_at, updated_by, NULL FROM feature_flags UNION ALL SELECT 'system_configuration', id::text, created_at, updated_at, updated_by, NULL FROM cutover_scopes UNION ALL SELECT 'integrations', id::text, created_at, updated_at, created_by, 'system' FROM integration_outbox ), classified_records AS ( SELECT r.*, CASE WHEN r.forced_kind = 'system' THEN 'system' WHEN r.actor_id IS NULL OR e.id IS NULL THEN 'unknown' WHEN lower(split_part(e.email, '@', 1)) ~ '^(smoke[-_.]|oa[-_.]?smoke[-_.]?)' OR e.employee_no ~* '^(SMOKE|OSMOKE|WFULL|PRELAUNCH|LAUNCHAUTO|HRWDTEST)' OR e.name ~ '(测试|试运行)' THEN 'smoke' ELSE 'human' END AS actor_kind FROM record_events r LEFT JOIN employees e ON e.id = r.actor_id ), audit_mapped AS ( SELECT CASE WHEN action ~ '^(APPROVAL_|DELEGATION_|WORKFLOW_)' THEN 'workflow_approvals' WHEN action ~ '^(REIMBURSEMENT_|INVOICE_)' OR action = 'EXPORT_REIMBURSEMENTS' THEN 'reimbursements_invoices' WHEN action ~ '^PAYMENT_' OR action = 'EXPORT_AP_OPERATIONS' THEN 'payments_ap' WHEN action ~ '^PURCHASE_' THEN 'procurement' WHEN action ~ '^CONTRACT_' OR action = 'EXPORT_CONTRACTS_REGISTRY' THEN 'contracts' WHEN action ~ '^PROJECT_' THEN 'projects' WHEN action ~ '^(ASSET_|INVENTORY_)' THEN 'assets_inventory' WHEN action ~ '^(ATTENDANCE_|PRESENCE_)' THEN 'attendance_presence' WHEN action ~ '^PORTAL_ANNOUNCEMENT_' THEN 'announcements' WHEN action ~ '^BUDGET_' THEN 'budgets' WHEN action ~ '^TRAVEL_' THEN 'travel' WHEN action ~ '^(EMPLOYEE_|SYSTEM_USER|DEPARTMENT_)' THEN 'people_lifecycle' WHEN action ~ '^(CREATE_SALARY_|UPDATE_SALARY_|UPSERT_EMPLOYEE_SALARY_|GENERATE_PAYSLIPS|ISSUE_PAYSLIPS|UPDATE_PAYSLIP|EXPORT_PAYSLIPS)' THEN 'payroll' WHEN action ~ '^PERFORMANCE_' THEN 'performance' WHEN action ~ '^(FEATURE_FLAG_|WORKSPACE_)' THEN 'system_configuration' WHEN action ~ '^ERP_' THEN 'integrations' ELSE NULL END AS module_key, a.actor_id, a.created_at, CASE WHEN e.id IS NULL THEN 'unknown' WHEN lower(split_part(e.email, '@', 1)) ~ '^(smoke[-_.]|oa[-_.]?smoke[-_.]?)' OR e.employee_no ~* '^(SMOKE|OSMOKE|WFULL|PRELAUNCH|LAUNCHAUTO|HRWDTEST)' OR e.name ~ '(测试|试运行)' THEN 'smoke' ELSE 'human' END AS actor_kind FROM audit_logs a LEFT JOIN employees e ON e.id = a.actor_id ), record_metrics AS ( SELECT module_key, count(*)::int AS total_rows, count(*) FILTER (WHERE created_at >= now() - interval '30 days')::int AS created_30d, count(*) FILTER (WHERE created_at >= now() - interval '90 days')::int AS created_90d, count(*) FILTER (WHERE activity_at >= now() - interval '30 days')::int AS activity_30d, count(*) FILTER (WHERE activity_at >= now() - interval '90 days')::int AS activity_90d, max(activity_at) AS latest_activity_at, count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND activity_at >= now() - interval '30 days')::int AS human_actors_30d, count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND activity_at >= now() - interval '90 days')::int AS human_actors_90d, count(*) FILTER (WHERE actor_kind = 'human' AND activity_at >= now() - interval '30 days')::int AS human_events_30d, count(*) FILTER (WHERE actor_kind = 'human' AND activity_at >= now() - interval '90 days')::int AS human_events_90d, count(*) FILTER (WHERE actor_kind = 'smoke' AND activity_at >= now() - interval '30 days')::int AS smoke_events_30d, count(*) FILTER (WHERE actor_kind = 'smoke' AND activity_at >= now() - interval '90 days')::int AS smoke_events_90d, count(*) FILTER (WHERE actor_kind = 'system' AND activity_at >= now() - interval '30 days')::int AS system_events_30d, count(*) FILTER (WHERE actor_kind = 'system' AND activity_at >= now() - interval '90 days')::int AS system_events_90d, count(*) FILTER (WHERE actor_kind = 'unknown' AND activity_at >= now() - interval '30 days')::int AS unknown_events_30d, count(*) FILTER (WHERE actor_kind = 'unknown' AND activity_at >= now() - interval '90 days')::int AS unknown_events_90d FROM classified_records GROUP BY module_key ), audit_metrics AS ( SELECT module_key, count(*) FILTER (WHERE created_at >= now() - interval '30 days')::int AS audit_events_30d, count(*) FILTER (WHERE created_at >= now() - interval '90 days')::int AS audit_events_90d, count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '30 days')::int AS audit_human_actors_30d, count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '90 days')::int AS audit_human_actors_90d, count(*) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '30 days')::int AS audit_human_events_30d, count(*) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '90 days')::int AS audit_human_events_90d, count(*) FILTER (WHERE actor_kind = 'smoke' AND created_at >= now() - interval '30 days')::int AS audit_smoke_events_30d, count(*) FILTER (WHERE actor_kind = 'smoke' AND created_at >= now() - interval '90 days')::int AS audit_smoke_events_90d, count(*) FILTER (WHERE actor_kind = 'unknown' AND created_at >= now() - interval '30 days')::int AS audit_unknown_events_30d, count(*) FILTER (WHERE actor_kind = 'unknown' AND created_at >= now() - interval '90 days')::int AS audit_unknown_events_90d FROM audit_mapped WHERE module_key IS NOT NULL GROUP BY module_key ) SELECT k.module_key AS "moduleKey", COALESCE(r.total_rows, 0) AS "totalRows", COALESCE(r.created_30d, 0) AS "created30d", COALESCE(r.created_90d, 0) AS "created90d", COALESCE(r.activity_30d, 0) AS "activity30d", COALESCE(r.activity_90d, 0) AS "activity90d", r.latest_activity_at AS "latestActivityAt", COALESCE(r.human_actors_30d, 0) AS "humanActors30d", COALESCE(r.human_actors_90d, 0) AS "humanActors90d", COALESCE(r.human_events_30d, 0) AS "humanEvents30d", COALESCE(r.human_events_90d, 0) AS "humanEvents90d", COALESCE(r.smoke_events_30d, 0) AS "smokeEvents30d", COALESCE(r.smoke_events_90d, 0) AS "smokeEvents90d", COALESCE(r.system_events_30d, 0) AS "systemEvents30d", COALESCE(r.system_events_90d, 0) AS "systemEvents90d", COALESCE(r.unknown_events_30d, 0) AS "unknownEvents30d", COALESCE(r.unknown_events_90d, 0) AS "unknownEvents90d", COALESCE(a.audit_events_30d, 0) AS "auditEvents30d", COALESCE(a.audit_events_90d, 0) AS "auditEvents90d", COALESCE(a.audit_human_actors_30d, 0) AS "auditHumanActors30d", COALESCE(a.audit_human_actors_90d, 0) AS "auditHumanActors90d", COALESCE(a.audit_human_events_30d, 0) AS "auditHumanEvents30d", COALESCE(a.audit_human_events_90d, 0) AS "auditHumanEvents90d", COALESCE(a.audit_smoke_events_30d, 0) AS "auditSmokeEvents30d", COALESCE(a.audit_smoke_events_90d, 0) AS "auditSmokeEvents90d", COALESCE(a.audit_unknown_events_30d, 0) AS "auditUnknownEvents30d", COALESCE(a.audit_unknown_events_90d, 0) AS "auditUnknownEvents90d" FROM module_keys k LEFT JOIN record_metrics r ON r.module_key = k.module_key LEFT JOIN audit_metrics a ON a.module_key = k.module_key ORDER BY k.module_key `; const AUTH_SQL = String.raw` WITH classified AS ( SELECT a.actor_id, a.created_at, CASE WHEN e.id IS NULL THEN 'unknown' WHEN lower(split_part(e.email, '@', 1)) ~ '^(smoke[-_.]|oa[-_.]?smoke[-_.]?)' OR e.employee_no ~* '^(SMOKE|OSMOKE|WFULL|PRELAUNCH|LAUNCHAUTO|HRWDTEST)' OR e.name ~ '(测试|试运行)' THEN 'smoke' ELSE 'human' END AS actor_kind FROM audit_logs a LEFT JOIN employees e ON e.id = a.actor_id WHERE a.action IN ('AUTH_LOGIN_SUCCESS', 'AUTH_EMAIL_LOGIN_SUCCESS', 'AUTH_OIDC_LOGIN_SUCCESS') ) SELECT count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '30 days')::int AS "humanActors30d", count(DISTINCT actor_id) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '90 days')::int AS "humanActors90d", count(*) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '30 days')::int AS "humanEvents30d", count(*) FILTER (WHERE actor_kind = 'human' AND created_at >= now() - interval '90 days')::int AS "humanEvents90d", count(*) FILTER (WHERE actor_kind = 'smoke' AND created_at >= now() - interval '30 days')::int AS "smokeEvents30d", count(*) FILTER (WHERE actor_kind = 'smoke' AND created_at >= now() - interval '90 days')::int AS "smokeEvents90d", count(*) FILTER (WHERE actor_kind = 'unknown' AND created_at >= now() - interval '30 days')::int AS "unknownEvents30d", count(*) FILTER (WHERE actor_kind = 'unknown' AND created_at >= now() - interval '90 days')::int AS "unknownEvents90d" FROM classified `; function isSmokeLikeValue(value) { const text = String(value ?? "").trim(); if (!text) return false; const lower = text.toLowerCase(); const emailLocal = lower.includes("@") ? lower.split("@")[0] : lower; return ( /^(smoke[-_.]|oa[-_.]?smoke[-_.]?)/u.test(emailLocal) || /^(SMOKE|OSMOKE|WFULL|PRELAUNCH|LAUNCHAUTO|HRWDTEST)[A-Z0-9_-]*/iu.test(text) || /测试|试运行/u.test(text) ); } function classifyFixtureActor(actor, forcedKind = null) { if (forcedKind === "system") return "system"; if (!actor) return "unknown"; if ([actor.employeeNo, actor.email, actor.name].some(isSmokeLikeValue)) return "smoke"; return "human"; } function createReadOnlyAdapter(client) { return { featureFlag: { async findUnique({ where }) { const result = await client.query( "SELECT flag_key, override_mode, rollout_type, department_ids, note, version, created_at, created_by, updated_at, updated_by FROM feature_flags WHERE flag_key = $1", [where.flag_key], ); return result.rows[0] ?? null; }, async findMany({ where }) { const result = await client.query( "SELECT flag_key, override_mode, rollout_type, department_ids, note, version, created_at, created_by, updated_at, updated_by FROM feature_flags WHERE flag_key = ANY($1::text[]) ORDER BY flag_key ASC", [where.flag_key.in], ); return result.rows; }, }, workspaceSetting: { async findFirst() { const result = await client.query( "SELECT profile, org_mode, primary_entry_mode, notification_strategy, device_priority, module_visibility_json, created_at, updated_at, updated_by FROM workspace_settings ORDER BY created_at ASC LIMIT 1", ); return result.rows[0] ?? null; }, }, }; } function effectiveFlagState(item) { if (item.requiresDepartment && item.effectiveReason === "department_deferred") return "partial"; return item.effectiveEnabled ? "on" : "off"; } function applyExposure(metrics, workspace, flags) { const flagState = new Map(flags.map((item) => [item.flagKey, effectiveFlagState(item)])); const moduleExposure = { portal_notifications: ["portal", "portal_home_v1"], workflow_approvals: ["workflowTasks", null], reimbursements_invoices: ["reimbursements", null], payments_ap: ["paymentBatches", "payment_batch_v1"], procurement: ["purchaseRequests", null], contracts: ["contractsRegistry", "project_linking_v1"], projects: ["projects", "project_domain_v1"], assets_inventory: ["assets", null], leave_wecom_history: ["leaveRequests", null], attendance_presence: ["attendance", "attendance_unified_v1"], weekly_reports: ["weeklyReports", "weekly_report_v1"], todos: ["todos", "todo_board_v1"], announcements: ["announcements", "announcements_v1"], budgets: ["budgets", null], travel: ["travelRequests", null], people_lifecycle: ["people", "employee_lifecycle_v1"], payroll: [null, null], performance: [null, null], system_configuration: ["featureFlags", null], integrations: [null, "erp_sync"], }; return metrics.map((metric) => { const [navigationKey, flagKey] = moduleExposure[metric.moduleKey] ?? [null, null]; const navigationMode = navigationKey ? workspace.moduleVisibility[navigationKey] ?? "unknown" : "no_navigation"; const effectiveState = flagKey ? flagState.get(flagKey) ?? "unknown" : "not_applicable"; return { ...metric, latestActivityAt: metric.latestActivityAt?.toISOString?.() ?? metric.latestActivityAt ?? null, navigationMode, effectiveFlagState: effectiveState, queryStatus: "PASS", }; }); } function assertSafeResult(metrics) { if (!Array.isArray(metrics) || metrics.length !== MODULE_KEYS.length) { throw new Error("result_module_count_invalid"); } const seen = new Set(); for (const item of metrics) { if (!MODULE_KEYS.includes(item.moduleKey) || seen.has(item.moduleKey)) { throw new Error("result_module_key_invalid"); } seen.add(item.moduleKey); const keys = Object.keys(item).sort(); const expected = [...SAFE_RESULT_KEYS].sort(); if (JSON.stringify(keys) !== JSON.stringify(expected)) { throw new Error("result_field_contract_invalid"); } } } async function run() { const appRoot = path.resolve(process.env.USAGE_CENSUS_APP_ROOT || process.cwd()); const { Client } = require(path.join(appRoot, "node_modules/pg")); const { getConfig } = require(path.join(appRoot, "src/config.js")); const { listFeatureFlags } = require(path.join(appRoot, "src/services/featureFlags/index.js")); const { getWorkspaceSetting } = require(path.join(appRoot, "src/services/workspaceSettings.js")); const config = getConfig(); const client = new Client({ connectionString: process.env.DATABASE_URL }); let inTransaction = false; try { await client.connect(); await client.query("BEGIN TRANSACTION READ ONLY"); inTransaction = true; await client.query("SET LOCAL statement_timeout = '30s'"); await client.query("SET LOCAL lock_timeout = '2s'"); const readOnly = await client.query("SELECT current_setting('transaction_read_only') AS value"); if (readOnly.rows[0]?.value !== "on") throw new Error("transaction_not_read_only"); const adapter = createReadOnlyAdapter(client); const [metricResult, authResult, flags, workspace] = await Promise.all([ client.query(USAGE_SQL), client.query(AUTH_SQL), listFeatureFlags(adapter, config), getWorkspaceSetting(adapter), ]); const metrics = applyExposure(metricResult.rows, workspace, flags); assertSafeResult(metrics); await client.query("COMMIT"); inTransaction = false; process.stdout.write(`${JSON.stringify({ status: "PASS", transactionReadOnly: true, sourceBuildSha: config.buildSha, generatedAt: new Date().toISOString(), authentication: authResult.rows[0], modules: metrics, }, null, 2)}\n`); } catch { if (inTransaction) { try { await client.query("ROLLBACK"); } catch { /* fail closed */ } } process.stderr.write("[usage-census][FAILED] code=QUERY_FAILED\n"); process.exitCode = 1; } finally { await client.end().catch(() => {}); } } module.exports = { AUTH_SQL, MODULE_KEYS, SAFE_RESULT_KEYS, USAGE_SQL, applyExposure, assertSafeResult, classifyFixtureActor, effectiveFlagState, isSmokeLikeValue, }; // `node -` names stdin as argv[1] and leaves require.main unset. Production // streams this task-scoped file through stdin so it never lands on the host. if (require.main === module || process.argv[1] === "-") { run(); }