diff --git a/agent_docs/conventions.md b/agent_docs/conventions.md index cee3dacc9..4cfeee652 100644 --- a/agent_docs/conventions.md +++ b/agent_docs/conventions.md @@ -177,6 +177,8 @@ select: "outputArguments,outputFile" // not "OutputArguments,..." - **Orchestrator**: `createHeaders({ [FOLDER_ID]: folderId })` — numeric folder IDs - **Maestro**: `createHeaders({ [FOLDER_KEY]: folderKey })` — string folder keys +**Header constant naming**: Do **not** add a `_HEADER` suffix to constants in `src/utils/constants/headers.ts` — every constant in that file is already a header. Use `EXTERNAL_USER_ID` not `EXTERNAL_USER_ID_HEADER`. This mirrors the endpoint-group rule: context provides the prefix, names stay short. + ## Constructor JSDoc Service constructors that take dependency parameters (beyond the `UiPath` instance) must have JSDoc comments. Pattern (from `case-instances.ts`): @@ -229,4 +231,4 @@ interface OperationResponse { success: boolean; data: TData; } - **NEVER** leave unused code — unused imports, variables, redundant constructors that only call `super()`. Linter (oxlint) catches these. - **NEVER** commit sensitive files — `.env`, `credentials.json`, `*.key`, `*.pem`, hardcoded API keys/tokens. -- **NEVER** define static lookup tables inside method bodies — move them to module-level constants or `*.internal-types.ts`. A static mapping that doesn't change between calls (e.g., `TaskTypeEndpoints`) rebuilt on every invocation wastes memory and hides structure. +- **NEVER** define static lookup tables or inline regex literals inside method bodies — move them to module-level constants. A static mapping or regex that doesn't change between calls (e.g., `TaskTypeEndpoints`, `GUID_REGEX`) rebuilt on every invocation wastes memory and hides structure. diff --git a/agent_docs/rules.md b/agent_docs/rules.md index 9db77aa68..beb25bc7f 100644 --- a/agent_docs/rules.md +++ b/agent_docs/rules.md @@ -15,6 +15,8 @@ - **Mock factories must return `Raw{Entity}GetResponse`**, not `{Entity}GetResponse`** — mock factories like `createBasicJob()` produce plain data without bound methods. Methods are attached by the service layer via `create{Entity}WithMethods()`, not by mocks. Using the combined type causes compile errors for missing method properties. - **Shared mock setup belongs in `beforeEach`**, not inline in individual tests** — mock creation like `mockApiClient.getValidToken = vi.fn()` must be in the shared setup block, not duplicated inside each test. - **NEVER** leave unused mock methods in mock objects — dead mocks obscure what the test actually exercises and accumulate as the API evolves. +- **NEVER** access private methods via `as any` in tests (e.g., `(service as any)._privateMethod()`). This violates the no-`any` rule and creates brittle tests tied to implementation internals. Test behaviour through the public API instead, or extract the logic to a module-level pure function that can be imported and tested directly. +- Use `let variable!: Type` (definite assignment assertion) for variables initialized in `beforeAll`, not `let variable: Type | undefined`. The `!` signals TypeScript that the value is guaranteed before any test runs, eliminating null-checks throughout the test bodies. The `afterAll` guard (`if (!variable) return`) still works at runtime. - **NEVER** wrap integration test API calls in try/catch — let errors propagate naturally. Silent catches mask real failures and make tests pass when they should fail. - **NEVER** create a separate `afterAll` per describe block if the file already has one — reuse the existing cleanup block by pushing to the shared `createdRecordIds` array. - **Coverage**: 80% minimum for new code, 100% for critical paths (auth, API calls).