This project contains the Title Solutions Agency (TSA) phone list React web application and a supporting Node.js utility script for managing contact data.
This repository houses two main parts:
tsa-phone-list(React Application): A web application (built with Vite, React, shadcn/ui, Tailwind) intended to display contact information and an interactive office map. It is currently undergoing a major refactoring effort (see REFACTOR_PLAN.md).phonelist-canonicalizer(Node.js Utility Script): A command-line tool (located inlib/,scripts/) designed as a stop-gap measure to help synchronize contact data between the canonical JSON data file used by this project and Office 365/Entra ID via CSV export/import.
Data Source of Truth:
src/data/canonicalContactData.json: This is the LIVE, MUTABLE source of truth for the application. It contains merged contact data derived historically from Office 365 and older application code (App.jsx,ArtifactCode.jsx). It should be modified directly or via the--update-from-csvfeature (when implemented) of the canonicalizer script.src/data/reference_example.json: This is a READ-ONLY, STATIC copy representing the initial, correctly merged data state. It serves as a reference and was used to initializecanonicalContactData.json.
Displays contact directory and office map.
- Framework: React 18
- Build Tool: Vite
- Package Manager: PNPM
- UI Library: shadcn/ui (Radix UI + Tailwind CSS)
- Styling: Tailwind CSS
- Deployment: GitHub Pages (
gh-pages)
- Refactoring Required: The application requires significant refactoring as outlined in REFACTOR_PLAN.md.
- Data Source: Currently uses deprecated hardcoded data in
App.jsxandArtifactCode.jsx. Phase 1 of the refactor involves updating components to read fromsrc/data/canonicalContactData.json. - See: PROJECT_STATE.md for detailed progress.
- Clone:
git clone <repository-url> - Install:
pnpm install - Run Dev Server:
pnpm run dev(typicallyhttp://localhost:5173)
- Build:
pnpm run build(outputs todist/) - Deploy:
pnpm run deploy(usesgh-pages)
This CLI script (located in lib/ and scripts/) provides helper functions for managing the live data file (src/data/canonicalContactData.json) and syncing with O365 via CSV.
Current Purpose (Stop-Gap):
- Validate: Read and validate the structure and integrity of
src/data/canonicalContactData.jsonagainst the defined schema (lib/schema.ts). - Export: Generate an O365-compatible CSV file from the data in
src/data/canonicalContactData.json, suitable for manual import/update into O365/Entra. - (Future) Selectively update
src/data/canonicalContactData.jsonwith specific fields from a fresh O365 CSV export (e.g., mobile phone numbers, titles) while preserving existing merged data (desk extensions, locations).
Note: This script does not generate the merged canonicalContactData.json from scratch; it operates on the existing live file which was initialized from reference_example.json.
- Runtime: Node.js
- Language: TypeScript
- Core Libraries:
zod,fast-csv,commander,fs-extra,vitest,execa
Dependencies are shared with the main project. Ensure you have run pnpm install in the root directory.
- Run:
pnpm run build:canon - Output: Compiles TypeScript to JavaScript in
dist/canon/usingtsconfig.canon.json.
It's recommended to run the compiled script directly with node.
Default Mode (Validate Live JSON):
node dist/canon/scripts/canonicalize.js
# OR specify a different live file:
node dist/canon/scripts/canonicalize.js --json path/to/other_live_data.json - Reads the JSON file specified by
--json(defaults tosrc/data/canonicalContactData.json). - Validates its structure against
lib/schema.ts. - Reports success or validation errors.
Export Mode (Live JSON -> O365 CSV):
node dist/canon/scripts/canonicalize.js --export-csv path/to/output_for_o365.csv
# OR using a specific live file as source:
node dist/canon/scripts/canonicalize.js --json path/to/live_data.json --export-csv path/to/output_for_o365.csv- Reads the live JSON (default or specified by
--json). - Validates the JSON (but proceeds with warning on failure).
- Generates a CSV file at the
--export-csvpath with columns suitable for O365 import (Display Name, Mobile Phone, UPN, Title, etc.).
Update Mode (O365 CSV -> Live JSON):
node dist/canon/scripts/canonicalize.js --update-from-csv path/to/new_o365_export.csv
# OR specifying different input/output JSON files:
node dist/canon/scripts/canonicalize.js --json path/to/live_data.json --update-from-csv path/to/new_o365_export.csv --out path/to/updated_live_data.json- Reads the live JSON (
--json). - Reads the new O365 CSV (
--update-from-csv), requiring the presence of theObjectIdcolumn for matching. - Performs a selective update:
- Matches CSV rows to existing entries using the immutable Office 365
ObjectId. - Merges specific fields (like
DisplayName,Department,MobilePhone,Title) from the CSV into the canonical data. - Handles the
Officefield with decoupled logic:- If the CSV
Officefield contains tags (e.g.,cts:ftl,tsa), these tags dictate thebrandandofficestructure of the canonicalrolesarray, potentially replacing existing roles for that entity. - The
Titlefield from CSV is set directly on the ContactEntity, not in the roles.
- If the CSV
- Handles nested structures (
contactPoints,roles) correctly.
- Matches CSV rows to existing entries using the immutable Office 365
- Compares a deterministic hash of the original data vs. the potentially updated data to detect changes.
- If changes are detected and
--dry-runis not specified, writes the updated data to the output JSON file (--out, defaults to the input--jsonfile). - Use
--dry-runto preview changes without writing,--fail-on-diffto exit with error 1 if changes are detected (useful for CI).
Other Options:
--verboseor-v: Enable detailed debug logging.--help: Display help message with all options.
Unit and Integration tests (using vitest) are located in lib/tests/ and scripts/tests/. Run them using:
pnpm test
# OR run specific test files
pnpm test lib/tests/validateCanonical.test.ts
pnpm test scripts/tests/canonicalize.integration.test.ts
pnpm test test/update.test.ts # Tests for the update logicAll tests for implemented features (validation, export, update) are currently passing. Note: 2 tests related to the refactored update logic are currently failing and require investigation.
Please refer to the project state (PROJECT_STATE.md) and refactor plan (REFACTOR_PLAN.md) before making significant changes.