Skip to content

feat: add isomer-admin tooling scripts#1904

Merged
dcshzj merged 3 commits intomainfrom
feat/isomer-admin-scripts
Mar 30, 2026
Merged

feat: add isomer-admin tooling scripts#1904
dcshzj merged 3 commits intomainfrom
feat/isomer-admin-scripts

Conversation

@dcshzj
Copy link
Copy Markdown
Contributor

@dcshzj dcshzj commented Mar 20, 2026

Problem

Administrative operations (adding collaborators, exporting/importing page JSONs, uploading assets, validating schemas) were previously handled through scattered personal scripts outside the repository. This made it difficult for other team members to use them, and the scripts lacked proper typing, interactive prompts, and consistent patterns.

Solution

Adds a new isomer-admin script suite under tooling/scripts/isomer-admin/, following the patterns established in PR #1725 (ndf-collection) and PR #1805 (streamline). All scripts are converted from JavaScript to TypeScript with interactive prompts via @inquirer/prompts.

Breaking Changes

  • Yes - this PR contains breaking changes
  • No - this PR is backwards compatible

Features:

  • Add Isomer Collaborators: Adds Isomer admins/migrators as collaborators to sites (single or batch)
  • Bulk Upload Assets: Prepares assets for S3 upload with UUID assignment and CSV mapping
  • Export Individual JSONs: Exports JSON blobs for specific resource IDs
  • Export Site JSONs: Exports all JSON blobs for a given site ID
  • Extract Folder JSONs: Exports JSON blobs for all children of a parent resource
  • Find Invalid Schema: Validates page content against the schema downloaded from schema.isomer.gov.sg
  • Import Folder JSONs: Imports JSON files to update existing resources, with optional publishing

Improvements:

  • All scripts use interactive prompts instead of hardcoded values, making them reusable without code edits
  • Shared withDbClient utility handles DB connection lifecycle and prompts for npm run db:connect confirmation
  • Parameterized SQL queries instead of string interpolation
  • Typed query results throughout
  • Single entry point via npm run isomer-admin with script selection menu

Tests

Run from tooling/scripts:

npm run isomer-admin

Verify the interactive menu appears and each script prompts for the required inputs.

New scripts:

  • isomer-admin: Runs dotenv tsx isomer-admin/index.ts — interactive script selector for all admin operations

New dependencies:

  • @inquirer/prompts: Interactive CLI prompts for script inputs
  • @paralleldrive/cuid2: CUID2 ID generation (for add-isomer-collaborators)
  • ajv: JSON Schema validation (for find-invalid-schema)
  • dotenv: Environment variable loading from .env
  • papaparse: CSV parsing (currently unused after script removal, can be cleaned up)
  • pg: PostgreSQL client for database operations

New dev dependencies:

  • @isomer/tsconfig: Shared TypeScript configuration
  • @types/papaparse: Type definitions for papaparse
  • @types/pg: Type definitions for pg

@dcshzj dcshzj requested a review from a team as a code owner March 20, 2026 02:16
Copilot AI review requested due to automatic review settings March 20, 2026 02:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new tooling/scripts/isomer-admin TypeScript-based admin script suite to centralize common Isomer operational tasks (DB maintenance, content export/import, schema validation, asset prep) behind an interactive CLI menu.

Changes:

  • Introduces an interactive script runner (npm run isomer-admin) and multiple admin scripts (collaborators, assets, export/import JSONs, schema validation).
  • Adds shared DB client lifecycle utility (withDbClient) and script-local typing (types.ts).
  • Adds a dedicated TS config for tooling/scripts and updates the workspace package name/dependencies + lockfile.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
tooling/scripts/tsconfig.json Adds TS config for scripts package (extends shared @isomer/tsconfig).
tooling/scripts/package.json Renames package to @isomer/scripts, adds isomer-admin entrypoint + dependencies.
tooling/scripts/isomer-admin/utils/db.ts Adds DB client helper with dotenv loading + connection lifecycle wrapper.
tooling/scripts/isomer-admin/types.ts Adds shared row/script-type definitions for scripts.
tooling/scripts/isomer-admin/index.ts Adds interactive script selector and dispatch.
tooling/scripts/isomer-admin/apps/add-isomer-collaborators.ts Adds collaborator provisioning script (single-site or batch-from-ID).
tooling/scripts/isomer-admin/apps/bulk-upload-assets.ts Adds asset copying/UUID-path mapping + CSV generation.
tooling/scripts/isomer-admin/apps/export-individual-jsons.ts Adds DB export for specific resource IDs.
tooling/scripts/isomer-admin/apps/export-site-jsons.ts Adds DB export for all resources in a site.
tooling/scripts/isomer-admin/apps/extract-folder-jsons.ts Adds DB export for children under a parent resource.
tooling/scripts/isomer-admin/apps/find-invalid-schema.ts Adds AJV-based schema validation for DB blobs or local JSON files.
tooling/scripts/isomer-admin/apps/import-folder-jsons.ts Adds JSON import/update with optional publish behavior.
tooling/scripts/isomer-admin/README.md Documents script suite usage and individual scripts.
tooling/scripts/isomer-admin/.env.example Adds example env vars for scripts.
package-lock.json Adds workspace link + dependency lock updates for new scripts package.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@adriangohjw adriangohjw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skimmed through and LGTM, left some non-blocking comments

Comment on lines +42 to +47
const csvContent = Object.entries(fileMapping)
.map(
([originalFileName, newFilePath]) =>
`"${originalFileName}","${newFilePath}"`
)
.join("\n");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if filenames contain special characters like " or ,, then this will cause issue. But given that the list of files are provided by isoengs, non-blocker for me to assume that it should not contain them

Comment on lines +24 to +40
const allResources = await client.query<ResourceRow>(
`SELECT "Resource".id, "Resource".permalink, "Blob".content
FROM "Resource"
JOIN "Blob" ON "Resource"."draftBlobId" = "Blob".id
WHERE "Resource"."draftBlobId" IS NOT NULL
AND "Resource"."id" IN (${placeholders})
AND "Resource".type NOT IN ('Folder', 'Collection', 'IndexPage')
UNION
SELECT "Resource".id, "Resource".permalink, "Blob".content
FROM "Resource"
JOIN "Version" ON "Resource"."publishedVersionId" = "Version".id
JOIN "Blob" ON "Version"."blobId" = "Blob".id
WHERE "Resource"."id" IN (${placeholders})
AND "Resource"."draftBlobId" IS NULL
AND "Resource".type NOT IN ('Folder', 'Collection', 'IndexPage')`,
resourceIds
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can use without union by joining both and coalesce the content e..g COALESCE(draftBlob.content, publishedBlob.content) to reduce logic duplication

same for the other files

non-blocker for me, just FYI!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we can reuse apps/studio/prisma/scripts/addUsersToSite.ts

@dcshzj dcshzj force-pushed the feat/isomer-admin-scripts branch from 38f0dc2 to 1b0b0f3 Compare March 30, 2026 02:46
@dcshzj dcshzj enabled auto-merge (squash) March 30, 2026 02:47
@dcshzj dcshzj disabled auto-merge March 30, 2026 02:53
@dcshzj dcshzj enabled auto-merge (squash) March 30, 2026 02:53
@dcshzj dcshzj merged commit 86118d2 into main Mar 30, 2026
16 checks passed
@dcshzj dcshzj deleted the feat/isomer-admin-scripts branch March 30, 2026 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants