Skip to content

Fix ESLint warnings for server#331

Merged
juanmrad merged 19 commits into
mainfrom
fix-eslint-server
May 22, 2026
Merged

Fix ESLint warnings for server#331
juanmrad merged 19 commits into
mainfrom
fix-eslint-server

Conversation

@pawiecz
Copy link
Copy Markdown
Contributor

@pawiecz pawiecz commented Apr 28, 2026

Context & Requests for Reviewers

This PR consists of several separate commits so that they would be easier to read by Reviewers. These changes were submitted in a single request to keep related patches together instead of making noise in the PR queue.

Fixes: #198

Tests

Running npm run lint in server directory should produce no warnings (with an exception for the ones introduced in #349 which was developed in parallel to this patch set).

Summary by CodeRabbit

  • New Features

    • Added analytics tracking for reporting service and manual review tool operations.
  • Bug Fixes

    • Improved API key and webhook signing key rotation error handling with specific error messages.
    • Enhanced OpenTelemetry exception logging with consistent span attributes.
    • Fixed date handling for materialized view refresh with edge cases.
  • Improvements

    • Refined content API request analytics schema to track item context and request status.

Review Change Stack

pawiecz added 13 commits April 30, 2026 15:52
This patch fixes 5 ESLint warnings.

The max-lines disable in actionStatistics.ts no longer suppresses any
warning and only adds noise.

In apiKey.ts, "||" is replaced with "??" for description and lastUsedAt
fallbacks. "||" coerces any falsy value (including empty string: "") to
the default, whereas "??" only fires on null/undefined - which may be
the actual intent here. An empty-string description would be silently
discarded with "||".

In integrationRegistry/index.ts and RetryFailedNcmecDecisionsJob.ts,
null-guarded assignment blocks (if (x == null) { x = ... }) are
collapsed to "??=" assignments, which is the idiomatic shorthand for
exactly that pattern and makes the intent immediately readable.
…ationResolvers

The Query and Mutation objects in apiKey.ts are typed as any, which
removes all type-checking on resolver arguments and the context object.
The codegen pipeline already produces GQLQueryResolvers and
GQLMutationResolvers with the correct signatures. Using those types
means wrong argument names, missing fields, or context misuse will be
caught at compile time rather than at runtime.

Error names must match a GraphQL union member because gqlErrorResult
uses them as type name. 'InternalServerError' is a valid CoopErrorName
but not a member of the RotateApiKeyResponse or
RotateWebhookSigningKeyResponse unions, so Apollo can't resolve the
type.
…ute any

route.get returns Route<never, ...> which is invariant with Route<any, any>
in ControllerRouteList, so individual routes needed as Route<any, ...> casts.
Move the cast to the routes array level using as ControllerRouteList, which
is already covered by the centralized eslint-disable on the type definition.
The SAML strategy callbacks passed Sequelize model instances to
done(), which expects "Record<string, unknown>". The original code used
"as any" to fix the mismatch; simply removing those casts broke the
build because Sequelize models carry no string index signature.

Use "user.toJSON()" instead - it returns a plain object that
genuinely satisfies "Record<string, unknown>" at runtime.

For serializeUser, augment "Express.User" in decs.d.ts with the
single field it actually accesses ("id: string").
PostgresAnalyticsAdapter and ClickhouseKyselyAdapter declare their
Kysely fields as Kysely<any>, which disables query-builder type-
checking for every table access and column reference in those adapters.

PostgresAnalyticsAdapter is parameterised with Kysely<AnalyticsSchema>
and ClickhouseKyselyAdapter with Kysely<Record<string, unknown>>, so
Kysely can enforce table and column existence at compile time rather
than at runtime. Stub method signatures using ...args: any[] are
replaced with unknown[] so that the interface contract is actually
enforced on the concrete classes.
…icsSchema

RuleExecutionLogger, ReportingRuleExecutionLogger, RoutingRuleExecutionLogger,
and ContentApiLogger cast table-name strings and row arrays to any when calling
bulkWrite because those table names were not yet keys of AnalyticsSchema. The
casts silenced the errors but also prevented the compiler from catching a
misspelled or removed table name.

Adding the missing tables (REPORTING_SERVICE.REPORTING_RULE_EXECUTIONS,
MANUAL_REVIEW_TOOL.ROUTING_RULE_EXECUTIONS) to AnalyticsSchema and widening
CONTENT_API_REQUESTS to {[key:string]:unknown} makes the constraint real and
allows all call-site casts to be deleted or narrowed to their correct types.

PostgresAnalyticsAdapter.flushTable used a cast that typed rows as a union
of all schema table types. Kysely requires an intersection of required fields
across those types, which the open-ended {[key:string]:unknown} entries
(introduced in this commit) cannot satisfy. Instead, bulkWrite now stores a
pre-built, fully-typed insert closure alongside each row buffer while it
still knows the concrete table type (flushTable just calls that closure).
@opentelemetry/semantic-conventions deprecated the SEMATTRS_EXCEPTION_*
identifiers in favor of ATTR_EXCEPTION_*. The two names refer to the same
attribute keys, so this is a pure rename.

Clears three @typescript-eslint/no-deprecated warnings.
Small, mechanical cleanups flagged by
@typescript-eslint/no-unnecessary-condition and
@typescript-eslint/no-unnecessary-type-assertion. Each change either
removes a guard the type system has already proven redundant, or removes
an assertion that doesn't change the inferred type.

* routes/integration_logos/serveIntegrationLogo*.ts: typed the express
  sendFile callback as "(err?: Error)" and simplified "err != null" to a
  truthiness check. Matches express's actual contract.
* routes/reporting/submitReport.ts: dropped an always-truthy "hashes &&"
  guard.
* rule_engine/RuleEngine.ts: dropped "?? []" on a non-nullable return.
* utils/sql.ts: removed two "SelectQueryBuilder<...>" casts the inference
  now handles cleanly.
up a FileAnnotations object one case at a time. That tripped the
complexity rule (max 20) and made the mapping itself hard to audit.

Replaced with a single
"Record<NCMECFileAnnotationType, keyof FileAnnotations>" lookup table
plus a small for-loop. The table is the single source of truth for the
NCMEC-enum -> field-name correspondence, and TypeScript's exhaustiveness
checking on the Record key forces every enum variant to be mapped.
Each case below previously used "any" (or "as any") to paper over a
typing problem. Where a cast is still needed, it goes through the
narrowest meaningful type.

- condition_evaluator/conditionSet.ts: typed the working array as
  "Array<ReadonlyDeep<LeafConditionWithResult | ConditionSetWithResult>>"
  and replaced two "as any" casts with a single documented narrowing
  cast at the return site. The public type is a discriminated union over
  arrays-of-leaves vs arrays-of-sets, which can't be pushed into during
  the loop; runtime contents stay uniform with the input conditions.
- condition_evaluator/leafCondition.ts: typed the signal-result generic
  as "SignalResult<SignalOutputType>", removing both an "as any" and an
  unnecessary "as SignalOutputType" assertion at the call time.
- graphql/datasources/UserApi.ts: typed the login/signUp/logout passport
  glue using the generated "GQLMutation-Args" types and a small
  structural context type (instead of "any").
- services/apiKeyService/apiKeyService.ts: derived "ApiKeyRow" from
  "Selectable<ApiKeyServicePg['public.api_keys']>" (Kysely) and used it
  as the param type of "mapDbRecordToApiKeyRecord".
- services/manualReviewToolService/modules/CommentOperations.ts:
  replaced "as any" / "as any[]" with "as JobId" / "as JobId[]" using
  the existing branded type.
- services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.ts:
  typed warehouse rows as "Record<string, unknown>" with explicit
  field-level casts, and the binding accumulator as "string[]".
- services/ruleAnomalyDetectionService/detectRulePassRateAnomaliesJob.ts:
  preserved the runtime guard against missing org rows by indexing
  through "Partial<typeof orgsForChangedRules>". keyBy's "Record<string, T>"
  return type lies about lookups always succeeding.
- bin/run-worker-or-job.ts: replaced "(container as any)[name]" with a
  typed "container[name as keyof Dependencies] as WorkerOrJob" lookup.
Three locations have "any" casts that can't be replaced today without
upstream typing work that's already tracked by TODOs.

- graphql/modules/insights.ts: resolver maps five times
  "getRulePassingContentSamples" results onto types that require "tags"
  and "policies" fields the datasource doesn't yet populate. The fix
  belongs in the datasource's typing, not in each resolver. Kept the
  localized "as any" cast and the existing TODO comments
- graphql/resolvers.ts: same shape of pre-existing TODO on
  "getAllRuleInsights" return type
- services/analyticsQueries/ItemHistoryQueries.ts: the data warehouse
  schema isn't modeled in TS, so the Kysely instance is intentionally
  "Kysely<any>" (so the string-based column selections pass type-check).
Tests that mock private methods or attach properties to typed services
need escape hatches that production code shouldn't. This patch replaces
"any" with real types where possible.

- condition_evaluator/conditionSet.test.ts: wrap RuleEvaluationContext /
  SafeTracer mock stubs with "eslint-disable" / "eslint-enable" and a
  comment.
- services/derivedFieldsService/helpers.test.ts: the test intentionally
  passes invalid inputs to exercise error paths. Wrapped that block in a
  paired "eslint-disable" / "eslint-enable" for "no-explicit-any" with a
  comment.
- services/manualReviewToolService/modules/CommentOperations.test.ts:
  replaced "as any" on job ids with "as JobId"; switched the
  "(commentOps as any).getRelatedJobIds(...)" private-method probe to
  bracket access ("commentOps['getRelatedJobIds'](...)"). Same access
  pattern at runtime without a need for casting.
- services/orgAwareSignalExecutionService/signalExecutionService.test.ts:
  extended two existing narrow "eslint-disable" directives to also cover
  "no-explicit-any" for jest mock assignments. Added a paired
  "eslint-disable" / "eslint-enable" block where the original
  next-line directive couldn't reach the multi-line cast.
- services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.test.ts:
  typed the mock query's "tracer" parameter as "unknown". Kept the
  unavoidable "jest.fn() as any" for the typed mock fixture and "{} as any"
  for the unused tracer arg, both with narrow per-line disables that name
  the rule and the reason.
- test/extendExpect.ts: replaced "(toMatchSnapshot as any).call" with
  "toMatchSnapshot.call(this as SnapshotContext, ...)" using
  jest-snapshot's exported "Context" type. Added an explicit return type
  to satisfy "promise-function-async" (the inferred sync|async union was
  tripping the rule).
Three switches dispatch on a discriminated union that today has only one
variant: AggregationsService.evaluateAggregation, serializeAggregation,
and the derivedFieldsService recipe-operation reducer. With one variant
each case label is trivially equal to the discriminant, which trips
@typescript-eslint/no-unnecessary-condition.

The switches stay because they're load-bearing: when a new variant is
added to the union, the existing case stops being exhaustive and the
"default: assertUnreachable(...)" branch surfaces the gap at compile
time.
@pawiecz pawiecz force-pushed the fix-eslint-server branch from 6104272 to 7c836be Compare April 30, 2026 13:52
@pawiecz pawiecz force-pushed the fix-eslint-server branch from 73aa227 to 6f6295d Compare April 30, 2026 15:03
pawiecz added 2 commits April 30, 2026 18:03
The two SAML strategy callbacks still called `user.toJSON()` left over
from the Sequelize User instance. `kyselyUserFindByEmail` now returns
a plain `GraphQLUserParent` object.
The "fresh deploy" guard checked "lastTimestamp.last_insert == null",
which triggered @typescript-eslint/no-unnecessary-condition: the Kysely
schema types "last_insert" as a non-null "Date", matching the SQL
column ("NOT NULL DEFAULT '-infinity'").

This patch replaces "== null" with
"Number.isFinite(last_insert.valueOf())". This removes the dead branch
(and the lint warning) and makes the fresh-deploy path actually fall
back to "new Date(0)" as intended.
@pawiecz pawiecz marked this pull request as ready for review April 30, 2026 16:49
Comment thread server/storage/dataWarehouse/IDataWarehouseAnalytics.ts
Comment thread server/bin/run-worker-or-job.ts Outdated
@juanmrad juanmrad requested a review from Copilot May 21, 2026 16:26
@juanmrad
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e7acde72-a44c-4c51-bb1f-9d006f1a0438

📥 Commits

Reviewing files that changed from the base of the PR and between abba19c and 6e2494b.

📒 Files selected for processing (12)
  • server/api.ts
  • server/bin/run-worker-or-job.ts
  • server/condition_evaluator/conditionSet.test.ts
  • server/condition_evaluator/leafCondition.ts
  • server/decs.d.ts
  • server/graphql/datasources/UserApi.ts
  • server/graphql/resolvers.ts
  • server/rule_engine/RuleEngine.ts
  • server/services/derivedFieldsService/helpers.ts
  • server/services/manualReviewToolService/modules/CommentOperations.test.ts
  • server/services/ncmecService/ncmecReporting.ts
  • server/storage/dataWarehouse/IDataWarehouseAnalytics.ts
💤 Files with no reviewable changes (6)
  • server/services/manualReviewToolService/modules/CommentOperations.test.ts
  • server/services/derivedFieldsService/helpers.ts
  • server/services/ncmecService/ncmecReporting.ts
  • server/graphql/resolvers.ts
  • server/rule_engine/RuleEngine.ts
  • server/storage/dataWarehouse/IDataWarehouseAnalytics.ts
✅ Files skipped from review due to trivial changes (3)
  • server/condition_evaluator/conditionSet.test.ts
  • server/condition_evaluator/leafCondition.ts
  • server/bin/run-worker-or-job.ts

📝 Walkthrough

Walkthrough

Comprehensive TypeScript type safety and eslint cleanup across the server codebase. Updates OpenTelemetry exception constants, adds Express.User interface, narrows GraphQL resolver and UserAPI parameter types, refactors condition evaluation accumulation, extends analytics schema with dynamic tables, improves adapter typing, updates route controllers to use type constraints, and documents intentional any-cast escape hatches with eslint directives.

Changes

Authentication and Telemetry Modernization

Layer / File(s) Summary
OpenTelemetry Constants and Passport Typing
server/api.ts, server/decs.d.ts
OpenTelemetry exception attributes switch from SEMATTRS_EXCEPTION_* to ATTR_EXCEPTION_* constants; stacktrace set only when err.stack exists. Passport serialization callback removes explicit any type. Express.User interface augmented with id: string field for type-safe user access.
Express.User Interface and UserAPI Authentication
server/decs.d.ts, server/graphql/datasources/UserApi.ts
UserAPI login and signUp methods narrow parameters from any to generated GQLMutationLoginArgs and GQLMutationSignUpArgs types; unused second parameter narrows from any to unknown.

GraphQL Resolver Type Safety and Error Names

Layer / File(s) Summary
API Key Resolver Types and Error Names
server/graphql/modules/apiKey.ts, server/utils/errors.ts
Query and Mutation resolvers switch from any-typed to generated GQLQueryResolvers and GQLMutationResolvers types. Input and output null handling use nullish coalescing (??). Error responses change from generic InternalServerError to specific RotateApiKeyError and RotateWebhookSigningKeyError. CoopErrorName union extended with new error variants.
Insights Resolver Lint Cleanup
server/graphql/modules/insights.ts, server/graphql/resolvers.ts
Adds eslint-disable/enable directives with TODO comments around intentional any casts in RuleInsights and ReportingRuleInsights sample mappings, Query.getFullRuleResultForItem resolver, and allRuleInsights resolver.

Condition Evaluation Refactoring

Layer / File(s) Summary
Condition Set Result Accumulation
server/condition_evaluator/conditionSet.ts, server/condition_evaluator/conditionSet.test.ts
Refactors getConditionSetResults from mutating pre-allocated result object to using intermediate conditionsWithResult array. Loop pushes evaluated conditions into accumulator; early short-circuit logic and final return build state from accumulated array. Test wraps as any arguments with eslint directives.
Leaf Condition Signal Typing
server/condition_evaluator/leafCondition.ts
Tightens signal result callback typing to use SignalResult instead of any; removes cast when passing outputType to evaluateCondition.

Route Controller Typing and Callbacks

Layer / File(s) Summary
Route Controller Type Satisfies
server/routes/policies/PoliciesRoutes.ts, server/routes/user_scores/UserScoresRoutes.ts
Switches route exports from as Controller assertion to satisfies Controller constraint; removes explicit Route type casts; uses ControllerRouteList for array typing.
Response Callback Signatures
server/routes/integration_logos/serveIntegrationLogo.ts, server/routes/integration_logos/serveIntegrationLogoWithBackground.ts
Updates res.sendFile callback parameter to optional Error with truthiness check instead of null/undefined comparison.
Report Submission Condition Simplification
server/routes/reporting/submitReport.ts
Removes redundant hashes && guard from image-hash bank matching condition.

Analytics Schema Extensibility and Adapter Typing

Layer / File(s) Summary
Analytics Schema Dynamic Tables
server/storage/dataWarehouse/IDataWarehouseAnalytics.ts
Refactors CONTENT_API_REQUESTS from fixed-field to dynamic schema with [key: string]: unknown. Adds REPORTING_SERVICE.REPORTING_RULE_EXECUTIONS and MANUAL_REVIEW_TOOL.ROUTING_RULE_EXECUTIONS as dynamic table entries with logging source annotations.
Analytics Logger Type Improvements
server/services/analyticsLoggers/ContentApiLogger.ts, server/services/analyticsLoggers/ReportingRuleExecutionLogger.ts, server/services/analyticsLoggers/RoutingRuleExecutionLogger.ts, server/services/analyticsLoggers/RuleExecutionLogger.ts
Removes as any casts from logger bulkWrite calls; types RuleExecutionLogger payload using AnalyticsSchema['RULE_EXECUTIONS'][].
PostgresAnalyticsAdapter Buffer Refactor
server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts
Refactors pendingWrites from Map<string, any[]> to Map<string, {rows: unknown[], flush: ...}> with typed per-table flush closures. Tightens constructor to Kysely. Updates stub logging method rest parameters from any[] to unknown[].
ClickhouseAdapter Schema Typing
server/storage/dataWarehouse/ClickhouseAdapter.ts
Updates ClickhouseKyselyAdapter to use Kysely<Record<string, unknown>> instead of Kysely; adds eslint suppression for createIntrospector; updates getKyselyInstance return type.

Service Type Safety and Logic Improvements

Layer / File(s) Summary
Rule Engine Dependency Typing
server/rule_engine/RuleEngine.ts
Removes nullish coalescing fallback in runEnabledRules; uses dependency result directly.
Aggregations Service Exhaustiveness Documentation
server/services/aggregationsService/AggregationsService.ts
Adds comments and eslint suppressions to clarify COUNT-only aggregation union and assertUnreachable default branch intent.
API Key Service Database Typing
server/services/apiKeyService/apiKeyService.ts
Adds ApiKeyRow type derived from ApiKeyServicePg['public.api_keys']; uses it to type mapDbRecordToApiKeyRecord mapper parameter.
Analytics Queries Typing and Documentation
server/services/analyticsQueries/ItemHistoryQueries.ts
Adds comments and eslint suppression explaining Kysely usage for column-name opt-out; removes explicit (it: any) type annotation from results.map callback.
Derived Fields Service Typing
server/services/derivedFieldsService/helpers.ts, server/services/derivedFieldsService/helpers.test.ts
Adds exhaustiveness documentation and eslint directives for DerivedFieldOperationType switch; clarifies intent of any casts in test invalid-spec cases.
Integration Registry Cache Initialization
server/services/integrationRegistry/index.ts
Simplifies cache initialization using nullish-coalescing assignment (??=).
Comment Operations JobId Typing
server/services/manualReviewToolService/modules/CommentOperations.ts, server/services/manualReviewToolService/modules/CommentOperations.test.ts
Imports JobId type and uses it to type job_id/id fields in Kysely queries instead of any; accesses private getRelatedJobIds method via bracket notation in tests.
NCMEC File Annotation Lookup Table
server/services/ncmecService/ncmecReporting.ts
Refactors #fileAnnotationArrayToNCMECFileAnnotation from conditional object spreads to Record lookup table mapping enum values to field names.
Signal Execution Service Test Lint Cleanup
server/services/orgAwareSignalExecutionService/signalExecutionService.test.ts
Reorganizes eslint directives in test mocks into multi-line comment blocks around jest.fn assignments.
Rule Anomaly Detection Typing
server/services/ruleAnomalyDetectionService/detectRulePassRateAnomaliesJob.ts, server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.ts, server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.test.ts
Casts orgsForChangedRules as Partial to preserve possibly-undefined type; types empty bind array as string[] and maps results with explicit per-field casts; updates test with unknown for tracer parameter and adds eslint directives.
SQL Query Builder Type Assertions
server/utils/sql.ts
Removes redundant type assertions from takeLast Kysely query building.

Test Utilities and Matchers

Layer / File(s) Summary
Snapshot Matcher Type Improvements
server/test/extendExpect.ts
Imports jest-snapshot Context type; adds explicit return type to toMatchDynamicSnapshot matcher; uses SnapshotContext type for this argument in toMatchSnapshot delegation.

Background Job Type Improvements

Layer / File(s) Summary
MRT Decisions Backfill Logic Refinement
server/workers_jobs/RefreshMRTDecisionsMaterializedViewJob.ts
Updates backfill detection from null-check on last_insert to Number.isFinite check on computed lastInsertMs; handles -Infinity from fresh deploy seeding.
NCMEC Retry User Cache Optimization
server/workers_jobs/RetryFailedNcmecDecisionsJob.ts
Simplifies user lookup caching using nullish-coalescing assignment (??=).
Worker/Job Container Typing
server/bin/run-worker-or-job.ts
Imports Dependencies and WorkerOrJob types; uses keyof Dependencies when selecting named worker/job from IoC container.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • roostorg/coop#462: Modifies GraphQL/Passport integration in server/api.ts passport/context wiring and server/graphql/datasources/UserApi.ts authentication-related signatures.
  • roostorg/coop#477: Modifies server/services/ncmecService/ncmecReporting.ts including the #fileAnnotationArrayToNCMECFileAnnotation helper refactored in this PR.

Suggested labels

adoption

Suggested reviewers

  • vinaysrao1
  • julietshen
  • dom-notion
  • cassidyjames
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Some changes appear to exceed the scope of merely fixing ESLint warnings. Business logic modifications (e.g., in ncmecReporting.ts, RuleEngine.ts, submitReport.ts) go beyond linting. Review whether business logic changes (null-coalescing refactors, filter guard removals, annotation lookups) should have been submitted as separate functional changes rather than bundled with linting fixes.
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix ESLint warnings for server' clearly and concisely summarizes the main objective of the changeset: resolving ESLint warnings in the server package.
Description check ✅ Passed The PR description provides context, references the linked issue #198, and includes testing instructions. However, it lacks specific detail about which types of warnings were fixed or the categories of changes made.
Linked Issues check ✅ Passed The PR addresses the core objective of issue #198 by fixing ESLint warnings throughout the server codebase. Changes include removing type casts, improving type annotations, adding eslint directives, and refactoring code patterns.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-eslint-server

Comment @coderabbitai help to get the list of available commands and usage tips.

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

This PR addresses ESLint warnings in the server package by tightening types (reducing any), simplifying control flow, and adding narrowly-scoped lint suppressions where intentional.

Changes:

  • Replaced several any usages with more precise types (GraphQL resolvers, Kysely adapters/queries, tests, and utility code).
  • Refactored a few sections to reduce ESLint complexity/unnecessary-condition warnings (e.g., mapping tables, ??= usage, simplified guards).
  • Updated minor runtime logic for edge cases (e.g., -infinity timestamp handling) and improved type declarations (Express User augmentation).

Reviewed changes

Copilot reviewed 40 out of 42 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server/workers_jobs/RetryFailedNcmecDecisionsJob.ts Uses ??= to simplify lazy org-user caching.
server/workers_jobs/RefreshMRTDecisionsMaterializedViewJob.ts Handles -Infinity seed timestamp safely when computing backfill window.
server/utils/sql.ts Removes casts around orderBy loop in takeLast.
server/utils/errors.ts Adds new CoopError name literals for API key rotation errors.
server/test/extendExpect.ts Improves matcher typing and removes any call-site.
server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts Tightens adapter typing and restructures pending write buffering.
server/storage/dataWarehouse/IDataWarehouseAnalytics.ts Relaxes some table schemas to dynamic [key: string]: unknown and adds new table keys.
server/storage/dataWarehouse/ClickhouseAdapter.ts Narrows Kysely instance typing; adds targeted lint suppression for Kysely Dialect signature.
server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.ts Replaces any result mapping with safer Record<string, unknown> casts.
server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.test.ts Replaces any tracer with unknown and adds targeted lint suppressions for test casts.
server/services/ruleAnomalyDetectionService/detectRulePassRateAnomaliesJob.ts Makes index access honestly nullable via Partial<> cast.
server/services/orgAwareSignalExecutionService/signalExecutionService.test.ts Consolidates eslint disables around intentional test mutations/casts.
server/services/ncmecService/ncmecReporting.ts Refactors file annotation mapping to a table-driven approach to reduce complexity.
server/services/manualReviewToolService/modules/CommentOperations.ts Replaces any casts with branded JobId typing in queries.
server/services/manualReviewToolService/modules/CommentOperations.test.ts Uses bracket access for private method testing; updates JobId casts.
server/services/integrationRegistry/index.ts Simplifies cached singleton initialization via ??=.
server/services/derivedFieldsService/helpers.ts Adds rationale + narrow lint suppression for intentional exhaustive switch pattern.
server/services/derivedFieldsService/helpers.test.ts Adds scoped eslint disable to allow constructing invalid inputs in tests.
server/services/apiKeyService/apiKeyService.ts Introduces typed ApiKeyRow for mapping DB rows to domain records.
server/services/analyticsQueries/ItemHistoryQueries.ts Documents/contains intentional any usage for unmodeled warehouse schema; removes any in result mapping.
server/services/analyticsLoggers/RuleExecutionLogger.ts Narrows bulkWrite row typing to AnalyticsSchema['RULE_EXECUTIONS'][].
server/services/analyticsLoggers/RoutingRuleExecutionLogger.ts Removes unnecessary as any table name cast after schema expansion.
server/services/analyticsLoggers/ReportingRuleExecutionLogger.ts Removes unnecessary as any table name cast after schema expansion.
server/services/analyticsLoggers/ContentApiLogger.ts Removes unnecessary as any table name cast after schema relaxation.
server/services/aggregationsService/AggregationsService.ts Adds rationale + narrow lint suppression for exhaustive switches over single-variant unions.
server/rule_engine/RuleEngine.ts Simplifies enabled-rules handling now that query returns an array.
server/routes/user_scores/UserScoresRoutes.ts Replaces broad assertions with satisfies Controller and ControllerRouteList.
server/routes/reporting/submitReport.ts Removes redundant hashes && check before Object.keys(hashes).
server/routes/policies/PoliciesRoutes.ts Replaces broad assertions with satisfies Controller and ControllerRouteList.
server/routes/integration_logos/serveIntegrationLogoWithBackground.ts Tightens sendFile callback error typing/guard.
server/routes/integration_logos/serveIntegrationLogo.ts Tightens sendFile callback error typing/guard.
server/graphql/resolvers.ts Scopes eslint disables around known resolver typing mismatch TODO.
server/graphql/modules/insights.ts Scopes eslint disables around known incomplete typing TODOs.
server/graphql/modules/apiKey.ts Uses generated resolver types; improves nullish handling and uses new error names.
server/graphql/modules/actionStatistics.ts Removes now-unneeded max-lines disable (file is within typical limits).
server/graphql/datasources/UserApi.ts Replaces any args with generated GraphQL arg types and narrows context types.
server/decs.d.ts Augments Express.User with id to avoid per-call casts in passport handlers.
server/condition_evaluator/leafCondition.ts Narrows signal result generic typing and removes an outputType cast.
server/condition_evaluator/conditionSet.ts Refactors condition result collection to reduce unsafe casts while preserving sequential evaluation.
server/condition_evaluator/conditionSet.test.ts Scopes eslint disables around intentional any stubs.
server/bin/run-worker-or-job.ts Replaces container any index with keyof Dependencies cast.
server/api.ts Updates OpenTelemetry semantic convention constant names; removes unnecessary user as any casts.

Comment thread server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
server/services/derivedFieldsService/helpers.test.ts (1)

267-316: ⚡ Quick win

Prefer line-level eslint suppressions over block-level disable/enable.

The block-level eslint-disable/eslint-enable pair spans ~50 lines but only 4 specific lines actually need the suppression (lines 272, 293, 302, 311). As per coding guidelines, use narrowly-scoped // eslint-disable-next-line comments on each line that requires the any cast instead of disabling the rule for the entire block.

♻️ Suggested refactor to line-level suppressions

Remove the block-level disable/enable:

-        // The casts to "any" below intentionally bypass TS so that we can
-        // construct invalid inputs (the very thing parseDerivedFieldSpec is
-        // expected to reject at runtime).
-        /* eslint-disable `@typescript-eslint/no-explicit-any` */
         expect(() => {
           parseDerivedFieldSpec(
             serializeDerivedFieldSpec({
               source: { type: 'CONTENT_FIELD', name: 'hi', contentTypeId: '1' },
+              // Intentional invalid type to test runtime validation
+              // eslint-disable-next-line `@typescript-eslint/no-explicit-any` -- testing runtime rejection of invalid derivationType
               derivationType: 'hasOwnProperty' as any, // invalid, hacking attempt.
             }),
           );

Apply similar line-level suppressions to lines 293, 302, and 311, and remove the closing eslint-enable at line 316.

As per coding guidelines: Use narrowly-scoped // eslint-disable-next-line <rule> comments with explanations instead of block-level disabling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/services/derivedFieldsService/helpers.test.ts` around lines 267 - 316,
The test currently uses a broad block-level
eslint-disable/@typescript-eslint/no-explicit-any around multiple expectations;
replace that with narrowly scoped line-level suppressions: remove the
block-level /* eslint-disable ... */ and /* eslint-enable ... */ and add //
eslint-disable-next-line `@typescript-eslint/no-explicit-any` immediately above
each specific line where an any cast is used (the lines calling
parseDerivedFieldSpec(serializeDerivedFieldSpec({... derivationType: ... as
any})) and the three other casts for source with as any/typed casts), keeping
the calls to parseDerivedFieldSpec and serializeDerivedFieldSpec intact and add
short comments explaining why the any is needed for each suppressed line.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/services/manualReviewToolService/modules/CommentOperations.ts`:
- Line 34: Keep the cast on jobId when filtering
manual_review_tool.job_creations.id (i.e., keep .where('id', '=', jobId as
JobId)) but remove the redundant casts on jobIds (remove jobIds as JobId[]),
because manual_review_tool.job_comments.job_id is a plain string; pass jobIds
directly into the .where(... 'in', jobIds) calls in CommentOperations (the
places using jobIds and jobId variables).

In
`@server/services/orgAwareSignalExecutionService/signalExecutionService.test.ts`:
- Around line 33-36: Replace the block-level eslint disable/enable wrapper with
line-scoped suppressions: remove the /* eslint-disable ... */ and /*
eslint-enable ... */ block that surrounds the two assignments and instead add a
concise // eslint-disable-next-line functional/immutable-data,
`@typescript-eslint/no-explicit-any` comment immediately above the lines that set
(mockTextBankStringsLoader as any).close = jest.fn() and (mockGetImageBank as
any).close = jest.fn(); do the same for the later similar block (the one that
wraps the other mock close assignments) so each offending line has its own
narrowly-scoped eslint-disable-next-line comment preserving the short rationale.

In `@server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts`:
- Line 14: The PostgresAnalyticsAdapter currently imports and types against
Kysely (symbols: sql, InsertObject, Kysely) and must be converted to use Knex
per the server standard: remove Kysely imports, add/import the Knex client type,
replace any Kysely-specific types (InsertObject, Kysely) with the appropriate
Knex types (e.g., Knex, Knex.QueryBuilder) and change sql usages to Knex
query-builder calls inside the PostgresAnalyticsAdapter class and its methods
(search for PostgresAnalyticsAdapter and any methods using sql/InsertObject).
Ensure all query construction, inserts, and type annotations are updated to use
Knex APIs and the adapter still accepts/proxies the same connection/client
instance.
- Around line 105-109: flushTable can lose rows appended during an async flush
because it awaits pending.flush(pending.rows) then clears pending.rows; instead
atomically detach the current batch before awaiting: grab a reference or shallow
copy of pending.rows (e.g., const rowsToFlush = pending.rows), immediately set
pending.rows = [] so subsequent bulkWrite appends go into a fresh array, then
await pending.flush(rowsToFlush); update references to use
pending.flush(rowsToFlush) and ensure this change is applied in the flushTable
method that reads from pendingWrites and calls pending.flush.

---

Nitpick comments:
In `@server/services/derivedFieldsService/helpers.test.ts`:
- Around line 267-316: The test currently uses a broad block-level
eslint-disable/@typescript-eslint/no-explicit-any around multiple expectations;
replace that with narrowly scoped line-level suppressions: remove the
block-level /* eslint-disable ... */ and /* eslint-enable ... */ and add //
eslint-disable-next-line `@typescript-eslint/no-explicit-any` immediately above
each specific line where an any cast is used (the lines calling
parseDerivedFieldSpec(serializeDerivedFieldSpec({... derivationType: ... as
any})) and the three other casts for source with as any/typed casts), keeping
the calls to parseDerivedFieldSpec and serializeDerivedFieldSpec intact and add
short comments explaining why the any is needed for each suppressed line.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2cf569a1-1827-4f57-bd6d-689ac248c7c3

📥 Commits

Reviewing files that changed from the base of the PR and between 72e81bb and abba19c.

📒 Files selected for processing (42)
  • server/api.ts
  • server/bin/run-worker-or-job.ts
  • server/condition_evaluator/conditionSet.test.ts
  • server/condition_evaluator/conditionSet.ts
  • server/condition_evaluator/leafCondition.ts
  • server/decs.d.ts
  • server/graphql/datasources/UserApi.ts
  • server/graphql/modules/actionStatistics.ts
  • server/graphql/modules/apiKey.ts
  • server/graphql/modules/insights.ts
  • server/graphql/resolvers.ts
  • server/routes/integration_logos/serveIntegrationLogo.ts
  • server/routes/integration_logos/serveIntegrationLogoWithBackground.ts
  • server/routes/policies/PoliciesRoutes.ts
  • server/routes/reporting/submitReport.ts
  • server/routes/user_scores/UserScoresRoutes.ts
  • server/rule_engine/RuleEngine.ts
  • server/services/aggregationsService/AggregationsService.ts
  • server/services/analyticsLoggers/ContentApiLogger.ts
  • server/services/analyticsLoggers/ReportingRuleExecutionLogger.ts
  • server/services/analyticsLoggers/RoutingRuleExecutionLogger.ts
  • server/services/analyticsLoggers/RuleExecutionLogger.ts
  • server/services/analyticsQueries/ItemHistoryQueries.ts
  • server/services/apiKeyService/apiKeyService.ts
  • server/services/derivedFieldsService/helpers.test.ts
  • server/services/derivedFieldsService/helpers.ts
  • server/services/integrationRegistry/index.ts
  • server/services/manualReviewToolService/modules/CommentOperations.test.ts
  • server/services/manualReviewToolService/modules/CommentOperations.ts
  • server/services/ncmecService/ncmecReporting.ts
  • server/services/orgAwareSignalExecutionService/signalExecutionService.test.ts
  • server/services/ruleAnomalyDetectionService/detectRulePassRateAnomaliesJob.ts
  • server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.test.ts
  • server/services/ruleAnomalyDetectionService/getRuleAnomalyDetectionStatistics.ts
  • server/storage/dataWarehouse/ClickhouseAdapter.ts
  • server/storage/dataWarehouse/IDataWarehouseAnalytics.ts
  • server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts
  • server/test/extendExpect.ts
  • server/utils/errors.ts
  • server/utils/sql.ts
  • server/workers_jobs/RefreshMRTDecisionsMaterializedViewJob.ts
  • server/workers_jobs/RetryFailedNcmecDecisionsJob.ts
💤 Files with no reviewable changes (2)
  • server/graphql/modules/actionStatistics.ts
  • server/routes/reporting/submitReport.ts

Comment thread server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts
Comment thread server/storage/dataWarehouse/PostgresAnalyticsAdapter.ts
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

Copilot reviewed 40 out of 42 changed files in this pull request and generated no new comments.

juanmrad added 2 commits May 21, 2026 14:06
# Conflicts:
#	server/api.ts
#	server/graphql/datasources/UserApi.ts
#	server/services/ncmecService/ncmecReporting.ts
@juanmrad
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Copilot reviewed 39 out of 41 changed files in this pull request and generated 3 comments.

Comment on lines +94 to 99
// Written by ContentApiLogger. Keep this shape in sync with the
// `bulkWrite('CONTENT_API_REQUESTS', ...)` call there so the analytics
// adapter can type-check the row contents at compile time.
CONTENT_API_REQUESTS: {
ds: string;
ts: number;
Comment on lines +94 to +96
// Written by ContentApiLogger. Keep this shape in sync with the
// `bulkWrite('CONTENT_API_REQUESTS', ...)` call there so the analytics
// adapter can type-check the row contents at compile time.
Comment thread server/utils/sql.ts
typeof SUBQUERY_ALIAS,
O
>;
return outer;
@juanmrad juanmrad merged commit 03b0415 into main May 22, 2026
16 checks passed
@juanmrad juanmrad deleted the fix-eslint-server branch May 22, 2026 00:37
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.

Address eslint warnings after removing betterer

3 participants