Skip to content

Add DateTime attribute range filtering (__after / __before / between)#9074

Open
FragmentedPacket wants to merge 9 commits intostablefrom
feature/attr-datetime-filter
Open

Add DateTime attribute range filtering (__after / __before / between)#9074
FragmentedPacket wants to merge 9 commits intostablefrom
feature/attr-datetime-filter

Conversation

@FragmentedPacket
Copy link
Copy Markdown
Contributor

Closes #9073.

Summary

Adds before / after / between filtering on node attributes of kind DateTime, mirroring the picker UX 1.9 already provides for node_metadata__created_at / node_metadata__updated_at. Six commits, three layers — none large.

Commit Layer Change
291f14b backend tests Failing TDD tests for time__after / time__before / range / __isnull regression baseline (4 tests)
efa6cf9 backend GraphQL Override get_graphql_filters on DateTime data type to expose <name>__after / <name>__before
0cda9e6 backend Cypher default_attribute_query_filter accepts datetime and routes before/after to > / < against av.value; filter values normalized to canonical UTC via Timestamp(value.isoformat()).to_string() (mirrors _build_metadata_filter_requirement)
83d9d8b frontend conds Extend DATETIME_FILTER_CONDITION_OPTIONS with BEFORE / AFTER / BETWEEN
3c080f9 frontend refactor Extract DateMetadataFilterForm's picker block into shared DateRangePickerFields component
8eb6c8d frontend form AttributeFilterForm routes DateTime kind + range condition to the new picker; default condition for DateTime flips from IS_EMPTY to AFTER

Test plan

  • TDD red phase — 3 new tests fail with Unknown argument 'time__after' GraphQL errors before efa6cf9.
  • TDD green phase — All 4 TestDateTimeAttributeFilter tests pass after 0cda9e6.
  • backend/tests/component/graphql/test_graphql_query_metadata.py — 37/37 pass.
  • backend/tests/component/core/test_node_get_list_query.py — 57/57 pass.
  • Backend unit suite (uv run invoke backend.test-unit) — 608/608 pass.
  • Backend component (full graphql/ + core/) — 1446 passed, 13 skipped, 3 xfailed; pytest exit 0. Local run hit --session-timeout=1800 at ~53% of files; CI has a longer budget.
  • Frontend vitest — 653/653 pass across 88 files.
  • Biome — clean.
  • Manual UI smoke test pending. Built-in CoreAccountToken.expiration is the easiest path (generate a few API tokens with varied expirations, filter by expiration__after / __before / between). Other built-in DateTime fields exist on CoreValidator and CoreCheck. None of the default-loaded demo nodes (models/base/, models/infrastructure_edge.py) currently have a custom DateTime attribute — separate optional follow-up could add e.g. InfraDevice.last_seen for richer demo coverage.

Implementation notes

  • No regression on existing UX. __isnull / __value filters on DateTime attributes still work identically. The __isnull regression test confirms it.
  • No frontend type regeneration in this PR. frontend/app/src/shared/api/graphql/generated/types.ts is regenerated by pnpm codegen from schema/schema.graphql, which itself is exported from a live backend via infrahub dev export-graphql-schema. Codegen against the current schema.graphql is a no-op — the file pre-dates the new filter args. Since the frontend builds list-page queries dynamically via jsonToGraphQLQuery (no gql-tagged static queries reference these new args), runtime behavior works regardless. Schema/types regeneration should happen as part of the normal release workflow.
  • Two existing helpers already handle the new keys — no change needed:
    • getCurrentFilterCondition already maps <attr>__afterAFTER / <attr>__beforeBEFORE.
    • active-filter-tags.tsx already renders chips for before / after suffixes on non-relationship definitions.

Caveat: stored value timezone canonicalization

DateTime attribute values are stored as user-supplied strings (BaseAttribute.serialize_value is identity). Lexicographic Cypher < / > is correct only when stored values are also in canonical form. In practice values written via the standard graphene DateTime ingestion path are canonical, but values inserted via direct DB writes or non-standard paths could produce off-by-tz results. Same limitation applies to the existing metadata path; flagged in #9073 for a separate hardening effort (either write-time normalization or datetime() casts in Cypher).

🤖 Generated with Claude Code

FragmentedPacket and others added 6 commits April 27, 2026 17:11
Relax default_attribute_query_filter to accept datetime values and
route before/after filter names to a `>` / `<` comparison against
av.value. Filter values are normalized to canonical UTC strings via
Timestamp(...).to_string(), mirroring what _build_metadata_filter_requirement
already does for node_metadata__*__before/after.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ttributes

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@FragmentedPacket FragmentedPacket requested review from a team as code owners April 28, 2026 01:45
@github-actions github-actions Bot added group/backend Issue related to the backend (API Server, Git Agent) group/frontend Issue related to the frontend (React) labels Apr 28, 2026
…ity under C901

The new before/after branch in default_attribute_query_filter pushed the
function's cyclomatic complexity to 21, tripping the project's ruff C901
threshold of 20. Move the branch body into a small _datetime_range_filter_clause
helper so the inline elif drops back to a flat extend/update/extend.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 28, 2026

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing feature/attr-datetime-filter (260a744) with stable (6cd0418)

Open in CodSpeed

FragmentedPacket and others added 2 commits April 27, 2026 20:01
…e filters

Wires every DateTime attribute (CoreCheck.created_at, CoreValidator.completed_at /
started_at, CoreAccountToken.expiration, etc.) to the new range filter inputs
exposed by DateTime.get_graphql_filters. Generated by:

    uv run invoke schema.generate-graphqlschema

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Picks up `<attr>__after` / `<attr>__before` inputs on every node kind
that has a DateTime attribute (CoreCheck, CoreValidator, CoreAccountToken,
etc.). Generated by:

    pnpm codegen

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/backend Issue related to the backend (API Server, Git Agent) group/frontend Issue related to the frontend (React)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: DateTime attribute range filtering (__after / __before) doesn't reach GraphQL — UI was removed in 1.9 but underlying gap predates it

1 participant