Files
TX/artifacts/tx-os/package.json
T
Riyadh 89f2f9d640 Add automated tests for audit log readable summaries
Original task: add unit tests for the new `formatAuditSummary` formatter
and an API-level test asserting the enriched group sub-resource audit
metadata, and wire both into the existing `test` workflow.

What changed:
- Extracted `formatAuditSummary` and its helpers (`asRecord`, `asString`,
  `asNumber`, `unitLabel`, `appName`, `linkedAppName`, `plainName`,
  `changeCount`) out of `artifacts/tx-os/src/pages/admin.tsx` into a new
  `artifacts/tx-os/src/lib/audit-summary.ts` module so the pure formatter
  can be unit-tested without the React tree. `admin.tsx` now imports the
  helpers from that module.
- Added `artifacts/tx-os/src/__tests__/audit-summary.test.mjs` with 22
  Node test-runner cases covering app rename (EN + AR), app-update
  fallback, group rename, group multi-field update, registration toggle
  (open / close / with-other-changes), and every group.user/app/role
  add/remove name vs id-only branch, plus the unknown-action default.
- Added `pnpm --filter @workspace/tx-os test` (Node 24's native
  TypeScript loader runs the .mjs tests against the .ts module directly).
- Added `artifacts/api-server/tests/group-audit-metadata.test.mjs` using
  the same harness as `groups-crud.test.mjs`. It hits POST/DELETE
  `/api/groups/:id/{users,apps,roles}/:targetId` and reads the resulting
  `audit_logs.metadata`, asserting `username`, `appSlug` /`appNameEn` /
  `appNameAr`, and `roleName` are persisted alongside the raw IDs.
- Updated the `test` workflow to run the tx-os unit tests before the
  api-server tests, then the tx-os e2e tests.

Verification: all 22 tx-os unit tests pass via the new pnpm script, and
all 6 new api-server audit-metadata tests pass against a live server.
The overall api-server suite still has pre-existing flakes
(executive-meetings notifications/status transitions, and the
count-based group invariant in groups-crud.test.mjs) that are unrelated
to this change; both flake clusters are filed as follow-up tasks.
2026-04-30 21:05:22 +00:00

105 lines
3.6 KiB
JSON

{
"name": "@workspace/tx-os",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --config vite.config.ts --host 0.0.0.0",
"build": "vite build --config vite.config.ts",
"serve": "vite preview --config vite.config.ts --host 0.0.0.0",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "node --test 'src/__tests__/**/*.test.mjs'",
"test:e2e": "playwright test --config playwright.config.mjs"
},
"devDependencies": {
"@hookform/resolvers": "^3.10.0",
"@playwright/test": "^1.59.1",
"@radix-ui/react-accordion": "^1.2.4",
"@radix-ui/react-alert-dialog": "^1.1.7",
"@radix-ui/react-aspect-ratio": "^1.1.3",
"@radix-ui/react-avatar": "^1.1.4",
"@radix-ui/react-checkbox": "^1.1.5",
"@radix-ui/react-collapsible": "^1.1.4",
"@radix-ui/react-context-menu": "^2.2.7",
"@radix-ui/react-dialog": "^1.1.7",
"@radix-ui/react-dropdown-menu": "^2.1.7",
"@radix-ui/react-hover-card": "^1.1.7",
"@radix-ui/react-label": "^2.1.3",
"@radix-ui/react-menubar": "^1.1.7",
"@radix-ui/react-navigation-menu": "^1.2.6",
"@radix-ui/react-popover": "^1.1.7",
"@radix-ui/react-progress": "^1.1.3",
"@radix-ui/react-radio-group": "^1.2.4",
"@radix-ui/react-scroll-area": "^1.2.4",
"@radix-ui/react-select": "^2.1.7",
"@radix-ui/react-separator": "^1.1.3",
"@radix-ui/react-slider": "^1.2.4",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-switch": "^1.1.4",
"@radix-ui/react-tabs": "^1.1.4",
"@radix-ui/react-toast": "^1.2.7",
"@radix-ui/react-toggle": "^1.1.3",
"@radix-ui/react-toggle-group": "^1.1.3",
"@radix-ui/react-tooltip": "^1.2.0",
"@replit/vite-plugin-cartographer": "catalog:",
"@replit/vite-plugin-dev-banner": "catalog:",
"@replit/vite-plugin-runtime-error-modal": "catalog:",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "catalog:",
"@tanstack/react-query": "catalog:",
"@types/node": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@vitejs/plugin-react": "catalog:",
"@workspace/api-client-react": "workspace:*",
"class-variance-authority": "catalog:",
"clsx": "catalog:",
"cmdk": "^1.1.1",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.6.0",
"framer-motion": "catalog:",
"i18next": "^26.0.6",
"input-otp": "^1.4.2",
"lucide-react": "catalog:",
"next-themes": "^0.4.6",
"pg": "^8.20.0",
"react": "catalog:",
"react-day-picker": "^9.11.1",
"react-dom": "catalog:",
"react-hook-form": "^7.55.0",
"react-i18next": "^17.0.4",
"react-icons": "^5.4.0",
"react-resizable-panels": "^2.1.7",
"recharts": "^2.15.2",
"socket.io-client": "^4.8.3",
"sonner": "^2.0.7",
"tailwind-merge": "catalog:",
"tailwindcss": "catalog:",
"tw-animate-css": "^1.4.0",
"vaul": "^1.1.2",
"vite": "catalog:",
"wouter": "^3.3.5",
"zod": "catalog:"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@tiptap/core": "^3.22.4",
"@tiptap/extension-color": "^3.22.4",
"@tiptap/extension-font-family": "^3.22.4",
"@tiptap/extension-text-align": "^3.22.4",
"@tiptap/extension-text-style": "^3.22.4",
"@tiptap/extension-underline": "^3.22.4",
"@tiptap/react": "^3.22.4",
"@tiptap/starter-kit": "^3.22.4",
"@types/dompurify": "^3.2.0",
"@uppy/aws-s3": "^5.1.0",
"@uppy/core": "^5.2.0",
"@uppy/dashboard": "^5.1.1",
"@uppy/react": "^5.2.0",
"@workspace/object-storage-web": "workspace:*",
"dompurify": "^3.4.1"
}
}