Skip to content

SEP-1625: Server-side sort/search for proxied inventory list endpoints + SchemaListView manual sort/filter - #1331

Open
peter-o-addo wants to merge 17 commits into
mainfrom
SEP-1625
Open

SEP-1625: Server-side sort/search for proxied inventory list endpoints + SchemaListView manual sort/filter#1331
peter-o-addo wants to merge 17 commits into
mainfrom
SEP-1625

Conversation

@peter-o-addo

@peter-o-addo peter-o-addo commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Add server-side sort/search for proxied inventory list endpoints and gate SchemaListView manual sorting/filtering on an opt-in capability.

  • app/inventory/crud.py : allow service_id / schema_id on schema and table sort allowlists
  • app/sep/apps/framework/list_query.py, app/sep/apps/inventory/list_query.py : public in-memory list-query builder, per-entity specs, request dep, and upstream sort/search adapter
  • app/sep/apps/inventory/api_routes.py : wire validated list-query params into the inventory proxy and keep filtered totals from upstream
  • app/sep/apps/framework/schema.py, app/sep/apps/inventory/schema.py, frontend/packages/api/src/types/app-schema.ts : add server_side_query and enable it on the four inventory list views
  • frontend/packages/api/src/hooks/useAppTasks.ts : thread sort / search through list fetch options and query keys
  • frontend/packages/framework/.../SchemaListView.tsx, AppListPage.tsx : drive manual sort/search from server params when pagination + capability are on; reset offset on change
  • OpenAPI/schema snapshots, generated TS client, and changelog.d/SEP-1625.added.md : refresh specs and document the user-facing change
  • Tests : cover allowlists, proxy forwarding/totals, capability gate, and no-regression for other SchemaListView consumers

Tested

  • App schema exposes server_side_query=true and the expected default_sort for nodes, services, schemas, and tables
  • Each inventory list returns a paginated envelope where total can exceed the page size (limit=1)
  • Unknown sort keys are rejected with 422 (e.g. sort=bogus)
  • Cross-entity sort keys are rejected with 422 (e.g. nodes/?sort=service_id)
  • Schemas can be sorted by service_id ascending and descending
  • Tables can be sorted by schema_id ascending and descending
  • Search returns a filtered total that stays correct across pages (limit=1, offset 0 then 1)

Checklist

  • New/modified functions have type hints and rST docstrings
  • New tests added for new features or bug fixes
  • All tests pass locally (make test)
  • Pre-commit hooks pass (make run-pre-commit)
  • Database migrations generated if models changed (make makemigrations)
  • User-facing changes documented (README, inline help, UI text)
  • Configuration changes documented with examples
  • Changelog fragment added under changelog.d/ if the change is user-facing (make changelog-add), or confirmed N/A (internal-only change, or a same-release-cycle fix for an unreleased sibling ticket)

@github-actions github-actions Bot added python frontend app:inventory PR touches the inventory app slice app:tasks PR touches the tasks app slice svc:inventory PR touches the inventory service (app/inventory/) labels Aug 11, 2026
@peter-o-addo

Copy link
Copy Markdown
Contributor Author

Schema capability flags

GET /api/apps/inventory/schema
{
  "name": "inventory",
  "entities": [
    { "name": "nodes", "server_side_query": true, "default_sort": "-created_at" },
    { "name": "services", "server_side_query": true, "default_sort": "-name" },
    { "name": "schemas", "server_side_query": true, "default_sort": "-created_at" },
    { "name": "tables", "server_side_query": true, "default_sort": "-created_at" }
  ]
}

Page totals (limit=1)

GET /api/apps/inventory/nodes/?limit=1
{ "total": 8, "offset": 0, "limit": 1, "items_len": 1 }
GET /api/apps/inventory/services/?limit=1
{ "total": 7, "offset": 0, "limit": 1, "items_len": 1 }
GET /api/apps/inventory/schemas/?limit=1
{ "total": 8, "offset": 0, "limit": 1, "items_len": 1 }
GET /api/apps/inventory/tables/?limit=1
{ "total": 9, "offset": 0, "limit": 1, "items_len": 1 }

Unknown sort rejected

GET /api/apps/inventory/nodes/?sort=bogus
→ 422
{ "detail": "Invalid sort key: 'bogus'" }

(same 422 for services, schemas, tables)


Cross-entity sort rejected

GET /api/apps/inventory/nodes/?sort=service_id
→ 422
{ "detail": "Invalid sort key: 'service_id'" }

Schemas sort by service_id

GET /api/apps/inventory/schemas/?sort=service_id&limit=10
→ 200
{
  "total": 8,
  "offset": 0,
  "limit": 10,
  "items": [
    { "id": 1, "name": "testdb", "service_id": 4 },
    { "id": 2, "name": "analytics", "service_id": 4 },
    { "id": 3, "name": "AlphaSearchSchema_1785745159", "service_id": 5 },
    { "id": 4, "name": "OtherSchema_1785745159", "service_id": 5 },
    { "id": 5, "name": "LQ1638Sch_1785745159_a", "service_id": 5 },
    { "id": 6, "name": "LQ1638Sch_1785745159_b", "service_id": 5 },
    { "id": 7, "name": "aaa_lq_schema_1785745159", "service_id": 5 },
    { "id": 8, "name": "bbb_lq_schema_1785745159", "service_id": 5 }
  ]
}
GET /api/apps/inventory/schemas/?sort=-service_id&limit=10
→ 200
{ "service_ids": [5, 5, 5, 5, 5, 5, 4, 4] }

Tables sort by schema_id

GET /api/apps/inventory/tables/?sort=schema_id&limit=10
→ 200
{
  "total": 9,
  "offset": 0,
  "limit": 10,
  "items": [
    { "id": 1, "name": "employees", "schema_id": 1 },
    { "id": 2, "name": "orders", "schema_id": 1 },
    { "id": 3, "name": "daily_metrics", "schema_id": 2 },
    { "id": 4, "name": "AlphaSearchTable_1785745159", "schema_id": 3 },
    { "id": 5, "name": "OtherTable_1785745159", "schema_id": 3 },
    { "id": 6, "name": "LQ1638Tbl_1785745159_a", "schema_id": 3 },
    { "id": 7, "name": "LQ1638Tbl_1785745159_b", "schema_id": 3 },
    { "id": 8, "name": "aaa_lq_table_1785745159", "schema_id": 3 },
    { "id": 9, "name": "bbb_lq_table_1785745159", "schema_id": 3 }
  ]
}
GET /api/apps/inventory/tables/?sort=-schema_id&limit=10
→ 200
{ "schema_ids": [3, 3, 3, 3, 3, 3, 2, 1, 1] }

Search filtered total (not page length)

GET /api/apps/inventory/schemas/?search=LQ1&limit=1&sort=name
→ 200
{
  "total": 2,
  "offset": 0,
  "limit": 1,
  "items": [
    { "id": 5, "name": "LQ1638Sch_1785745159_a", "service_id": 5 }
  ]
}
GET /api/apps/inventory/schemas/?search=LQ1&limit=1&offset=1&sort=name
→ 200
{
  "total": 2,
  "offset": 1,
  "limit": 1,
  "items": [
    { "id": 6, "name": "LQ1638Sch_1785745159_b", "service_id": 5 }
  ]
}

@peter-o-addo
peter-o-addo marked this pull request as ready for review August 11, 2026 14:41
@peter-o-addo
peter-o-addo requested a review from nachodd as a code owner August 11, 2026 14:41
Copilot AI lite review requested due to automatic review settings August 11, 2026 14:41
@peter-o-addo peter-o-addo added the qa in progress Someone is currently testing this PR - do not merge it label Aug 11, 2026
@peter-o-addo peter-o-addo added qa passed Tests for this PR are completed and successful. and removed qa in progress Someone is currently testing this PR - do not merge it labels Aug 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 extends SEP’s Inventory app experience to support whole-result-set sorting and searching on list pages by proxying validated sort/search parameters through SEP to the Inventory sub-app, and adds a schema capability flag (server_side_query) so the React SchemaListView only enables manual (server-driven) sort/filter when an endpoint opts in.

Changes:

  • Add per-entity list-query specs + request-boundary validation for the SEP Inventory proxy, and forward validated sort/search upstream while preserving filtered totals.
  • Introduce ListView.server_side_query (schema + OpenAPI + TS types) and gate FE manual sort/search on this capability (and server pagination).
  • Expand Inventory sub-app sortable allowlists for schemas/tables to include parent FK sort keys, with tests + snapshot refreshes.

Reviewed changes

Copilot reviewed 44 out of 46 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/app/sep/snapshots/schema/inventory.json Snapshot updates for server_side_query on inventory list views.
tests/app/sep/snapshots/openapi/tasks.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/snippets.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/mysql_backups.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/mysql_backups__restore.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/inventory.json OpenAPI snapshot updated for proxy sort/search params + server_side_query.
tests/app/sep/snapshots/openapi/dipper.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/checksums.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/backup_pg.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/backup_mongo.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/backup_mongo__restore.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/atw.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/archives.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/alters.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/snapshots/openapi/alert_troubleshooting.json OpenAPI snapshot updated for framework__ListView.server_side_query.
tests/app/sep/apps/inventory/test_schema.py Assert inventory list views opt into server_side_query.
tests/app/sep/apps/inventory/test_list_query.py Unit tests for inventory proxy list-query dependency + upstream param mapping.
tests/app/sep/apps/inventory/test_api_routes.py Proxy route tests for forwarding sort/search + preserving upstream filtered totals.
tests/app/sep/apps/framework/test_schema.py Tests for ListView.server_side_query default/serialization behavior.
tests/app/sep/apps/framework/test_list_query.py Tests for the new public list-query builder helper.
tests/app/inventory/test_crud.py Assert Inventory sub-app allowlists include service_id/schema_id sorting.
tests/app/inventory/routes/test_tables.py Inventory /tables/ route test for sorting by schema_id.
tests/app/inventory/routes/test_schemas.py Inventory /schemas/ route test for sorting by service_id.
frontend/packages/framework/src/index.ts Re-export new SchemaListServerQuery type.
frontend/packages/framework/src/components/SchemaListView/SchemaListView.tsx Add server-driven sort/search plumbing gated by server_side_query + pagination.
frontend/packages/framework/src/components/SchemaListView/SchemaListView.test.tsx Tests for capability gating + callbacks for server sort/search.
frontend/packages/framework/src/components/SchemaListView/index.ts Re-export new SchemaListServerQuery type.
frontend/packages/framework/src/components/SchemaDrivenApp/AppListPage.tsx Thread server-side sort/search state into list fetch + reset offset on changes.
frontend/packages/framework/src/components/SchemaDrivenApp/AppListPage.test.tsx Tests for default sort seeding + offset reset + capability-off behavior.
frontend/packages/apps/tasks/src/TasksListPage.test.tsx Regression test: tasks list remains client-side (no serverQuery).
frontend/packages/apps/inventory/src/TargetHostsPage.test.tsx Regression test: no server search box without pagination/capability.
frontend/packages/apps/inventory/src/InventoryApp.test.tsx Regression test: nested lists remain client-side even if list view opts in.
frontend/packages/api/tests/useAppTasks.test.ts Tests for forwarding/omitting sort/search params.
frontend/packages/api/src/types/app-schema.ts Add server_side_query to ListView type.
frontend/packages/api/src/hooks/useAppTasks.ts Add sort/search options, include in query keys, and emit request params safely.
frontend/packages/api/src/generated/sep.ts Regenerated types for SEP OpenAPI changes (server_side_query + sort/search params).
frontend/packages/api/src/generated/inventory.ts Regenerated types for Inventory OpenAPI allowlist expansion.
frontend/packages/api/specs/sep.json Updated stored SEP spec snapshot.
frontend/packages/api/specs/inventory.json Updated stored Inventory spec snapshot.
changelog.d/SEP-1625.added.md Changelog entry for server-side sort/search on inventory list pages.
app/sep/apps/inventory/schema.py Enable server_side_query on inventory list views.
app/sep/apps/inventory/list_query.py New per-entity list-query specs + validation + upstream param adapter.
app/sep/apps/inventory/api_routes.py Wire validated list-query into upstream proxy call and preserve totals.
app/sep/apps/framework/schema.py Add server_side_query field to ListView schema model + docs.
app/sep/apps/framework/list_query.py Export a public build_in_memory_list_query helper for non-dep call sites.
app/inventory/crud.py Extend schema/table sortable allowlists to include parent FK IDs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

return build_in_memory_list_query(spec, sort or spec.default_sort, search)


InventoryListQueryDep = Annotated[InMemoryListQuery, Depends(inventory_list_query)]
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  app/sep/apps/framework
  list_query.py 198
  schema.py
  app/sep/apps/inventory
  api_routes.py
  list_query.py
  app/sep/sync/syncers
  pmm.py
Project Total  

This report was generated by python-coverage-comment-action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:inventory PR touches the inventory app slice app:tasks PR touches the tasks app slice frontend python qa passed Tests for this PR are completed and successful. svc:inventory PR touches the inventory service (app/inventory/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants