@carecard/validate 3.1.22 → 3.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,179 @@
1
+ # Codex Instructions For pkg-validate
2
+
3
+ These instructions apply to the `pkg-validate` repository. This file is self-contained:
4
+ it includes the workspace-level instructions that were previously read from
5
+ `/Users/pankajpriscilla/SO_CareCardCa/.codex/AGENTS.md`, followed by
6
+ repository-specific guidance. Removing the workspace-level `.codex/AGENTS.md`
7
+ must not change the rules for this repository.
8
+
9
+ ## Embedded Workspace Instructions
10
+
11
+ These instructions apply to the whole workspace. The workspace is a collection of independent repositories, not one monorepo. Treat each `api-*`, `pkg-*`, and `app-dashboard` directory as its own project with its own package scripts, Git status, and test commands.
12
+
13
+ ### Non-Negotiable Instructions
14
+
15
+ - **Never use TypeScript type `any`.** Always use specific domain types, generics, `unknown` with proper narrowing, or existing project types.
16
+ - **Always follow the owner's coding style.** Preserve the existing style in the file and repository you are editing.
17
+ - **Always follow the owner's naming conventions.** Use meaningful function, variable, file, test, and type names that match the surrounding code.
18
+ - **Always follow the existing project structure.** Put code, tests, docs, services, validation, transforms, components, and helpers where the current repository already expects them.
19
+ - **Always use Test-Driven Development.** Write or update focused tests first, verify they fail for the missing behavior when practical, then implement the code.
20
+ - **Never suppress errors, TypeScript errors, linter warnings, or failing tests.** Do not add `eslint-disable`, `@ts-ignore`, broad catches, empty catches, or other suppression unless the user explicitly requests it. Handle the issue properly.
21
+ - **Do not add new dependencies unless they are clearly necessary.** If a dependency might be needed, stop and ask for confirmation first, with a clear reason, tradeoff, and why existing code cannot reasonably solve it.
22
+ - **Before finalizing any response for a repository, run every script in that repository's `.husky` directory.** Do not bypass hooks. If a `.husky` script fails, fix the underlying issue and rerun it. If it cannot run because of environment constraints, report the exact script and reason.
23
+
24
+ ### Core Coding Principles
25
+
26
+ - Prefer minimal dependencies. Do not add libraries or frameworks unless the existing stack cannot reasonably solve the problem.
27
+ - Prefer implementing core logic directly with readable code over adding abstractions or packages.
28
+ - Explain architectural tradeoffs before major changes, especially changes that affect shared packages, API contracts, security, persistence, authentication, or frontend/backend boundaries.
29
+ - Favor readable, maintainable code over short clever code.
30
+ - Preserve the existing project style, file structure, naming style, module system, and test framework.
31
+ - Use Test-Driven Development: write or update focused tests first, then implement the code.
32
+ - Use meaningful function and variable names. Names should expose intent and domain behavior.
33
+ - Use specific types everywhere. Do not use `any`.
34
+ - Keep changes scoped and easy to review. Avoid unrelated formatting churn or opportunistic refactors.
35
+ - Use postgres functions and stored procedures instead of raw SQL.
36
+ - Use postgres and database search and other functionalities instead of doing it in controllers.
37
+ - Use different type postgres searches, like fuzzy search, trigram search, full-text search, and vector search.
38
+ - When possible, push the complexity of data saving, edit and access to the database.
39
+
40
+ ### Repo Workflow
41
+
42
+ - Work from the specific project directory you are changing, such as `api-auth`, `api-contact-us`, `api-institutions`, `pkg-common-util`, or `app-dashboard`.
43
+ - Check local status inside the affected project before editing. These directories are independent Git repositories.
44
+ - Do not revert or overwrite changes you did not make.
45
+ - Before finishing a code change, run the relevant tests and lint/format checks for the affected project.
46
+ - Before finalizing any response after code changes, run all validation commands required by the affected repository. This includes relevant package scripts, all commands in `.husky` hooks, and all scripts or documented validation commands in `.junie`.
47
+ - When a project has a `.junie` directory, read the applicable `.junie` guidance for that repository before editing. Before the final response, run every executable script in `.junie` and every validation/test command explicitly documented there. Fix any issues those commands report before finalizing.
48
+ - When a project has files in `.husky`, run every direct script in `.husky` before finishing. Fix any issue they report before finalizing. Never skip, bypass, or silence these scripts.
49
+ - If a required `.junie` or `.husky` command cannot be run because of a missing dependency, unavailable service, credentials, or environment limitation, clearly report the exact command, the failure reason, and the remaining risk in the final response.
50
+ - Avoid editing generated or heavy-output directories such as `node_modules`, `dist`, `coverage`, `.next`, `logs`, and generated stores unless the task explicitly requires it.
51
+
52
+ ### Backend Microservices
53
+
54
+ The `api-*` directories are independent Express/Postgres backend services. Most JavaScript services use CommonJS, Mocha, Supertest, Docker Compose database tests, `@carecard/*` packages, and `sub-apps` controller/router/model patterns. TypeScript services such as `api-contact-us` and `api-template-ts` use Jest or TypeScript tooling and should keep their existing TS style.
55
+
56
+ - Keep service-specific controllers thin. Controllers should read as a clear workflow: parse input, authorize, validate, call domain/model logic, build response, and pass errors to `next`.
57
+ - Extract multiline chunks into descriptively named functions in the appropriate `controllerLib`, `commonLib`, `sub-apps/lib`, model helper, or shared `pkg-*` package.
58
+ - Avoid defining reusable workflow, validation, mapping, response, authorization, parsing, or domain helpers in the same controller/app file where they are immediately used.
59
+ - Prefer straightforward sequencing of named helper calls over deeply nested conditionals.
60
+ - Preserve current behavior unless fixing a clear bug, security issue, or documented contract problem.
61
+ - Keep application setup files such as `app.js`, `app.ts`, `bin/www`, and routers focused on composition and wiring.
62
+ - Use existing Express middleware patterns: `requestContext`, CORS configuration, Helmet, cookie parsing, body-size limits, rate limits where already present, routers, 404 handling, logging middleware, and centralized error handlers.
63
+ - Use structured, actionable logging for important application events, external calls, state transitions, failures, and security-relevant actions.
64
+ - Do not log secrets, tokens, passwords, credentials, personal identifiers, full request payloads, or stack traces in user-facing responses.
65
+ - Keep logs useful for production monitoring. Avoid noisy logs that fire on every trivial branch unless they are request/access logs already established by the service.
66
+
67
+ ### Shared Packages And API Contracts
68
+
69
+ The `pkg-*` directories are reusable CareCard packages. Shared API response, error, authentication, JWT, and validation behavior belongs there when it is common across services.
70
+
71
+ - Prefer `@carecard/common-util`, `@carecard/auth-util`, `@carecard/jwt-read`, and `@carecard/validate` over duplicated local implementations.
72
+ - For API responses and errors, use the standardized `@carecard/common-util` behavior where possible: `requestContext`, `sendResponse`, `createError`, `notFound404`, `appErrorHandler`, error throw helpers, case converters, and `ApiErrorType`.
73
+ - Do not create or maintain duplicated common response/error helpers inside each `api-*` service. If a reusable capability is missing, add it to the correct `pkg-*` package and update callers.
74
+ - Keep service-local response code limited to service-specific mapping or wiring.
75
+ - Preserve the standard response shape expected by the dashboard: `success`, `status`, `statusCode`, `code`, `message`, `data`, `error`, `details`, and `meta`.
76
+ - Include request/correlation context where available through `requestId`, `traceId`, and `meta`.
77
+ - Error responses must be safe for users and useful for debugging without exposing secrets, tokens, credentials, stack traces, or sensitive personal data.
78
+ - Map validation, authentication, authorization, not-found, conflict, bad input, file, and unexpected failures to distinct machine-readable codes.
79
+ - Prefer current direct exports from shared packages over deprecated nested exports. For example, prefer direct `@carecard/jwt-read` function names and direct `@carecard/auth-util` helpers.
80
+
81
+ ### Validation Rules
82
+
83
+ - Keep request-boundary validation close to the API/controller layer.
84
+ - Use `validateWhitelistProperties()` once per validation boundary unless there is a specific documented reason to validate defensively again.
85
+ - Avoid hidden duplicate validation across controller and library layers for the same logical payload.
86
+ - Keep domain/library functions focused on domain behavior and assume validated inputs when called from validated controller paths.
87
+ - If a public/shared library function still needs defensive validation, document why and avoid repeating the exact same validation already done by the caller.
88
+ - Preserve validation behavior for invalid, missing, extra, and valid fields.
89
+ - Pay attention to nested fields, dot-notation paths, camelCase/snake_case conversion, and frontend response transforms.
90
+
91
+ ### Tests
92
+
93
+ - Write or update tests before implementation whenever changing behavior.
94
+ - Testing is mandatory before finalizing code changes. Do not stop after implementation if tests, `.junie`, or `.husky` checks remain unrun.
95
+ - Keep tests readable and domain-specific. Prefer explicit helper names over generic test utilities that hide important behavior.
96
+ - Use existing test frameworks and layouts:
97
+ - JavaScript `api-*`: usually Mocha, Supertest, `test/index.test.js`, and Docker-backed Postgres scripts.
98
+ - TypeScript `api-*`: usually Jest and `tests/index.test.ts`.
99
+ - `pkg-*`: Mocha plus TypeScript type tests where present.
100
+ - `app-dashboard`: Vitest, React Testing Library, mock API tests, and Selenium for end-to-end flows.
101
+ - For database tests, use existing seed, migration, rollback, and cleanup patterns. Keep tests isolated and make cleanup reliable even after failures.
102
+ - Add tests for API success responses, validation errors, auth/authz errors, JWT errors, not-found/conflict cases, and unexpected error handling when those paths change.
103
+ - For frontend changes, test validation, transforms, query/mutation wrappers, components, and user-visible flows at the narrowest practical level first.
104
+ - If any test or repository check fails, fix the issue and rerun the failing command. Only finalize with failing checks when the failure is unrelated to the change or blocked by environment constraints, and document that explicitly.
105
+
106
+ ### Dashboard Frontend
107
+
108
+ `app-dashboard` is a Next.js App Router TypeScript app using MUI, React Query, `next-intl`, and shared CareCard utilities. It consumes `api-auth`, `api-institutions`, `api-contact-us`, and `api-user-profiles` through service modules.
109
+
110
+ - Keep backend URL definitions centralized in `src/services/api.routes.ts`.
111
+ - Keep fetch behavior centralized in `src/services/common/api`, especially `appFetch`, `api.client`, and `parseApiResponse`.
112
+ - Services should return typed app/domain objects or typed form states, not raw fetch responses.
113
+ - Keep validation in `*.validation.ts`, API calls in `*.queries.ts` or mutation helpers, mapping in `*.transform.ts`, and orchestration in `*.service.ts`.
114
+ - Preserve the standardized `ApiResponse` parsing behavior for both current backend responses and legacy/non-standard responses.
115
+ - Do not expose JWTs, session contents, or sensitive backend details in client components or logs.
116
+ - Respect `basePath: '/secure'`, server actions, middleware session renewal, mock API mode, and existing i18n message patterns.
117
+ - Use existing MUI and app component patterns. Do not introduce a new UI framework.
118
+
119
+ ### Dependency And Version Guidance
120
+
121
+ - Keep CareCard package usage consistent with the service being changed.
122
+ - When standardizing response/error behavior, prefer `@carecard/common-util` `3.1.15` because it contains response and error functions aligned with `api-auth`.
123
+ - If package version changes are required, update lockfiles and verify affected services.
124
+ - Avoid broad dependency upgrades as part of feature or refactor work unless the task is specifically about dependencies.
125
+
126
+ ### Security Requirements
127
+
128
+ - Treat authentication, authorization, JWT, password, email confirmation, recovery, file upload, CORS, rate limits, and error response behavior as security-sensitive.
129
+ - Never log or return secrets, tokens, passwords, credentials, private keys, full JWT payloads, or sensitive personal data.
130
+ - Use safe error messages for users and structured details only when they do not reveal sensitive implementation or data.
131
+ - Keep body-size limits, Helmet, CORS allow-lists, and rate-limit behavior intact unless a task explicitly changes them.
132
+ - Document remaining security concerns that require product, infrastructure, or deployment decisions.
133
+
134
+ ## Repository-Specific Instructions
135
+
136
+ ### Non-Negotiable Instructions
137
+
138
+ - Never use TypeScript type `any`. Use specific value, record, validator, option, result, generic, or `unknown` types with narrowing.
139
+ - Always follow this repository's coding style, naming conventions, and CommonJS project structure.
140
+ - Always use Test-Driven Development: add or update the relevant Mocha or type tests before changing behavior.
141
+ - Never suppress errors, linter warnings, TypeScript errors, or failing tests. Handle the underlying issue.
142
+ - Do not add new dependencies unless they are absolutely needed. Ask for confirmation first with the reason and tradeoff.
143
+ - Before finalizing work in this repository, run every script in `.husky/` and fix anything they report.
144
+
145
+ ### Package Shape
146
+
147
+ - Keep `index.js` as the centralized public export surface.
148
+ - Keep TypeScript declarations in `index.d.ts` aligned with every public export in `index.js`.
149
+ - Keep direct validators in `lib/validate.js`.
150
+ - Keep key-based property sanitization in `lib/validateProperties.js`.
151
+ - Keep whitelist, nested-path, casing, flattening, and CareCard bad-input behavior in `lib/validateWhitelistProperties.js`.
152
+ - Preserve the package's CommonJS module style unless the repository is intentionally migrated.
153
+ - Keep the deprecated `validate` namespace export backward-compatible while preferring direct top-level exports in new code.
154
+
155
+ ### Validation Rules
156
+
157
+ - Low-level validators should be deterministic predicate functions that return `true` or `false`.
158
+ - Password failure-message helpers should return `null` for valid input and a user-readable string for invalid input.
159
+ - `validateProperties` should return a new sanitized object and omit unknown or invalid fields without mutating the input.
160
+ - `validateWhitelistProperties` should reject missing or invalid required fields with CareCard `BAD_INPUT` errors through `@carecard/common-util`.
161
+ - Optional whitelist fields should be ignored when absent and rejected when present but invalid.
162
+ - Preserve supported snake_case and camelCase field aliases unless a task explicitly changes the API contract.
163
+ - Preserve nested dot-path handling, the maximum nesting depth, maximum path count, optional snake_case conversion, and flattening behavior.
164
+ - Avoid broad regular expressions or validation changes without focused tests for accepted values, rejected values, length limits, and edge cases.
165
+
166
+ ### Types And API Contracts
167
+
168
+ - Model input and output records, whitelist options, flattened output behavior, validators, and failure-message helpers explicitly in `index.d.ts`.
169
+ - When existing declarations are too loose, improve them with specific types as part of the touched change instead of adding new loose types.
170
+ - Update `test/types.test.ts` whenever public types, exports, options, return values, or validators change.
171
+ - Keep runtime exports, README examples, and type declarations in sync.
172
+
173
+ ### Tests
174
+
175
+ - Use Mocha for runtime tests under `test/`.
176
+ - Use `test/types.test.ts` for TypeScript declaration coverage through `npm run test:types`.
177
+ - Add focused tests for valid input, invalid input, missing fields, optional fields, array handling, nested paths, casing conversion, flattening, and error messages when those areas change.
178
+ - Keep tests deterministic and avoid relying on real external services.
179
+ - Before pushing or finalizing, run `.husky/pre-commit`; it runs lint fixing, formatting, and `npm run test:All`.
@@ -0,0 +1,14 @@
1
+ # Full repository owner
2
+ * @singh-pankaj-k
3
+
4
+ # Repository workflow and ownership metadata
5
+ .github/ @singh-pankaj-k
6
+ README.md @singh-pankaj-k
7
+ package.json @singh-pankaj-k
8
+ package-lock.json @singh-pankaj-k
9
+
10
+ # Package source, declarations, and tests
11
+ index.js @singh-pankaj-k
12
+ index.d.ts @singh-pankaj-k
13
+ lib/ @singh-pankaj-k
14
+ test/ @singh-pankaj-k
@@ -23,6 +23,8 @@ on:
23
23
  push:
24
24
  branches:
25
25
  - 'feature/**'
26
+ - 'feat/**'
27
+ - 'improvement/**'
26
28
  - 'releases/**'
27
29
  - 'release*'
28
30
  - 'hotfix/**'
@@ -30,6 +32,8 @@ on:
30
32
  - 'fix/**'
31
33
  - 'main-*'
32
34
  - 'main-**'
35
+ - 'data**'
36
+ - 'data/**'
33
37
  paths-ignore:
34
38
  - '**.md'
35
39
  workflow_dispatch:
@@ -1,17 +1,54 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
+ workflow_dispatch:
4
5
  push:
6
+ branches:
7
+ - main
8
+ - develop
9
+ - development
10
+ - dev*
11
+ - feature/**
12
+ - feat/**
13
+ - improvement/**
14
+ - releases/**
15
+ - release*
16
+ - hotfix/**
17
+ - iss/**
18
+ - fix/**
19
+ - data**
20
+ - data/**
21
+ paths-ignore:
22
+ - '**.md'
5
23
  pull_request:
24
+ types: [opened, synchronize, reopened, ready_for_review]
25
+ branches:
26
+ - main
27
+ - develop
28
+ - development
29
+ - dev*
30
+ - feature/**
31
+ - feat/**
32
+ - improvement/**
33
+ - releases/**
34
+ - release*
35
+ - hotfix/**
36
+ - iss/**
37
+ - fix/**
38
+ - data**
39
+ - data/**
40
+ paths-ignore:
41
+ - '**.md'
6
42
 
7
43
  jobs:
8
44
  test:
9
45
  runs-on: ubuntu-latest
10
46
 
11
47
  steps:
12
- - uses: actions/checkout@v4
48
+ - name: Checkout repository
49
+ uses: actions/checkout@v4
13
50
 
14
- - name: Use Node.js
51
+ - name: Set up Node.js
15
52
  uses: actions/setup-node@v4
16
53
  with:
17
54
  node-version: '25'
@@ -20,5 +57,8 @@ jobs:
20
57
  - name: Install dependencies
21
58
  run: npm ci
22
59
 
23
- - name: Run tests and coverage
60
+ - name: Run tests
24
61
  run: npm run test:All
62
+
63
+ - name: Run tests with coverage
64
+ run: npm run test:coverage
package/index.d.ts CHANGED
@@ -106,8 +106,12 @@ export function isBoolValue(inputValue: any): boolean;
106
106
  export function isPostalCodeString(inputString: any): boolean;
107
107
  /** Checks if the string contains only allowed "safe" characters. */
108
108
  export function isSafeString(str: any): boolean;
109
+ /** Checks if the value is non-empty text up to the supported maximum length. */
110
+ export function isTextString(str: any): boolean;
109
111
  /** Checks if a string exists within a given array of strings (case-insensitive). */
110
112
  export function isInStringArray(StringArray: string[], inputString: any): boolean;
113
+ /** Checks if the string is one of the supported user role request statuses. */
114
+ export function isUserRoleRequestStatusString(inputString: any): boolean;
111
115
  /** Checks if the string is a valid country code (e.g., +1). */
112
116
  export function isCountryCodeString(str: any): boolean;
113
117
  /** Checks if the string is a valid domain name. */
@@ -151,7 +155,9 @@ export const validate: {
151
155
  isBoolValue: typeof isBoolValue;
152
156
  isPostalCodeString: typeof isPostalCodeString;
153
157
  isSafeString: typeof isSafeString;
158
+ isTextString: typeof isTextString;
154
159
  isInStringArray: typeof isInStringArray;
160
+ isUserRoleRequestStatusString: typeof isUserRoleRequestStatusString;
155
161
  isCountryCodeString: typeof isCountryCodeString;
156
162
  isValidDomainName: typeof isValidDomainName;
157
163
  isValidTimestampzString: typeof isValidTimestampzString;
package/lib/validate.js CHANGED
@@ -156,6 +156,10 @@ const isSafeString = str => {
156
156
  return /^[\da-zA-Z-_.,#*'()[\]: ]+$/.test(str);
157
157
  };
158
158
 
159
+ const isTextString = str => {
160
+ return typeof str === 'string' && str.length > 0 && str.length <= 10000;
161
+ };
162
+
159
163
  const isInStringArray = (StringArray, inputString) => {
160
164
  if (isNameString(inputString)) {
161
165
  return StringArray.includes(inputString.toLowerCase().trim());
@@ -164,6 +168,11 @@ const isInStringArray = (StringArray, inputString) => {
164
168
  return false;
165
169
  };
166
170
 
171
+ const isUserRoleRequestStatusString = inputString => {
172
+ const statuses = ['pending', 'approved', 'rejected', 'cancelled', 'expired', 'hidden', 'on_hold', 'in_progress', 'info_needed'];
173
+ return isInStringArray(statuses, inputString);
174
+ };
175
+
167
176
  const isCountryCodeString = str => {
168
177
  if (typeof str !== 'string' || str.length === 0 || str.length > 4) return false;
169
178
 
@@ -231,7 +240,9 @@ module.exports = {
231
240
  isBoolValue,
232
241
  isPostalCodeString,
233
242
  isSafeString,
243
+ isTextString,
234
244
  isInStringArray,
245
+ isUserRoleRequestStatusString,
235
246
  isCountryCodeString,
236
247
  isValidDomainName,
237
248
  isValidTimestampzString,
@@ -20,6 +20,8 @@ const {
20
20
  isValidUrl,
21
21
  isValidArrayOfStrings,
22
22
  isStreetString,
23
+ isTextString,
24
+ isUserRoleRequestStatusString,
23
25
  } = require('./validate');
24
26
 
25
27
  function validateProperties(obj = {}) {
@@ -63,6 +65,8 @@ function validateProperties(obj = {}) {
63
65
  case 'entityType':
64
66
  case 'action_type':
65
67
  case 'actionType':
68
+ case 'approved_by_role':
69
+ case 'approvedByRole':
66
70
  case 'city':
67
71
  case 'state':
68
72
  case 'country':
@@ -164,10 +168,34 @@ function validateProperties(obj = {}) {
164
168
  case 'changedBy':
165
169
  case 'request_id':
166
170
  case 'requestId':
171
+ case 'approved_by_user_id':
172
+ case 'approvedByUserId':
167
173
  if (isValidUuidString(value)) {
168
174
  returnObj[key] = value;
169
175
  }
170
176
  break;
177
+ case 'requested_by_name':
178
+ case 'requestedByName':
179
+ case 'requested_by_email':
180
+ case 'requestedByEmail':
181
+ case 'requested_by_phone':
182
+ case 'requestedByPhone':
183
+ case 'approved_by_name':
184
+ case 'approvedByName':
185
+ case 'approved_by_email':
186
+ case 'approvedByEmail':
187
+ case 'approved_by_phone':
188
+ case 'approvedByPhone':
189
+ if (isTextString(value)) {
190
+ returnObj[key] = value;
191
+ }
192
+ break;
193
+ case 'approved_status':
194
+ case 'approvedStatus':
195
+ if (isUserRoleRequestStatusString(value)) {
196
+ returnObj[key] = value;
197
+ }
198
+ break;
171
199
  case 'period':
172
200
  if (isCharactersString(value)) {
173
201
  returnObj[key] = value;
@@ -229,10 +257,14 @@ function validateProperties(obj = {}) {
229
257
  break;
230
258
  case 'expires_at':
231
259
  case 'expiresAt':
260
+ case 'starts_at':
261
+ case 'startsAt':
232
262
  case 'start_time':
233
263
  case 'startTime':
234
264
  case 'end_time':
235
265
  case 'endTime':
266
+ case 'approved_at':
267
+ case 'approvedAt':
236
268
  if (isValidTimestampzString(value) || isValidTimestampString(value)) {
237
269
  returnObj[key] = value;
238
270
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carecard/validate",
3
- "version": "3.1.22",
3
+ "version": "3.1.23",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/CareCard-ca/pkg-validate.git"