Skip to content

fix: restore log and device table search/sort behavior#1823

Merged
riderx merged 9 commits into
mainfrom
codex/fix-log-device-search-sort
Mar 19, 2026
Merged

fix: restore log and device table search/sort behavior#1823
riderx merged 9 commits into
mainfrom
codex/fix-log-device-search-sort

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented Mar 17, 2026

Summary (AI generated)

  • fix TableLog so search, sort, and range changes emit reloads in manual mode
  • only send active sort directives from the log and deployment tables so backend validation accepts the request
  • align Supabase log/device search with substring matching and allow device updated-at sorting to flow through the private devices endpoint

Motivation (AI generated)

Search and sort interactions in the logs view were updating URL state without triggering fresh backend reads, and the Supabase search path did not match the same fields and semantics as the Cloudflare path. That made the logs page feel broken and created inconsistent behavior on the devices page.

Business Impact (AI generated)

This restores a core debugging workflow in the console. Users can filter and reorder logs again, and device searches behave consistently across local and Supabase-backed environments, which reduces friction when investigating rollout issues.

Test Plan (AI generated)

  • Run bun lint
  • Run bun typecheck
  • Verify in the browser that log search reloads and filters results
  • Verify in the browser that log sort changes update the query and reorder results

Generated with AI

Summary by CodeRabbit

  • Bug Fixes

    • Sorting now resets non-active sortable columns when the active sort changes.
    • Changes to columns, date range, or search consistently trigger reloads.
    • Reload now resets pagination to the first page.
    • Cursor pagination only applies when a compatible sort is active, preventing incorrect page cursors.
  • Improvements

    • Per-column sort controls and a standardized order are applied across tables and exports.
    • Backend pagination and ordering now respect selected sort direction.
    • Search matching broadened to substring matches and includes action-based filters.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Frontend now derives an explicit active order from columns, normalizes sortable flags, and unconditionally triggers reloads (respecting an autoReload guard); backend query builders and cursor pagination now honor dynamic updated_at sort direction and use substring ilike matching.

Changes

Cohort / File(s) Summary
Table sorting & watchers
src/components/TableLog.vue
Added autoReload computed and requestReload(); watchers now call requestReload() unconditionally; sortClick normalizes other non-active string-sortable columns to true.
Table components: active-order extraction
src/components/tables/DeploymentTable.vue, src/components/tables/DeviceTable.vue, src/components/tables/LogTable.vue
Introduced getActiveOrder(columns) helper (filters columns with string sortable and maps to { key, sortable }); API requests use order: getActiveOrder(...); reload() now resets currentPage to 1; DeviceTable adds per-column sortable flags.
Backend: Cloudflare analytics pagination
supabase/functions/_backend/utils/cloudflare.ts
readDevicesCF now detects updated_at order and applies cursor comparison (timestamp >/< cursorTime) and ORDER BY updated_at ASC/DESC with device_id ASC tie-breaker; cursor predicate gated on active order; added doc comment.
Backend: Supabase query builders & search
supabase/functions/_backend/utils/supabase.ts
Switched PostgREST ilike from prefix to contains (%value%); added getDevicesOrder(order?) to apply updated_at direction to cursor comparisons and ordering; readStatsSB may add action-based or filters and restricts ilike targets when deviceIds present.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Table Component
    participant Order as getActiveOrder()
    participant API as Backend Function
    participant DB as Database

    User->>UI: Click column / change search or date
    UI->>UI: update column.sortable, call requestReload()
    UI->>Order: derive active order (string-sortable cols)
    Order-->>UI: [{key, sortable}, ...]
    UI->>API: Fetch/export with order + cursor/search params
    API->>DB: Query with cursor comparison (gt/lt) and ORDER BY updated_at (ASC/DESC), device_id ASC
    DB-->>API: Return ordered, paginated rows
    API-->>UI: Respond with data
    UI-->>User: Render table
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

codex

Poem

🐰 I hop through headers, nudging sort to and fro,
Strings tell me which way the wild orders go.
Reloads now tumble when search or dates play,
Cursors chase timestamps, in ASC or DESC they sway.
A little rabbit cheers — data streams all day! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: restoring search/sort behavior for log and device tables.
Description check ✅ Passed The description provides a comprehensive summary, motivation, business impact, and test plan covering all required sections.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-log-device-search-sort
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c163aea615

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/TableLog.vue Outdated
Comment thread src/components/TableLog.vue Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01272fad40

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/TableLog.vue Outdated
@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

Merged origin/main and resolved the conflict in the deployment/log tables. I kept the branch’s helper (instead of the inline ) so the stats request keeps sending the same computed sort payload after the merge.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

Merged origin/main and resolved the conflict in the deployment/log tables. I kept the branch’s getActiveOrder helper (instead of the inline .filter/.map) so the stats request still sends the same sort payload after the merge.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3ec4461bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/TableLog.vue Outdated
Comment on lines +155 to +157
newColumns.forEach((col, index) => {
if (index !== key && col.sortable && typeof col.sortable === 'string')
newColumns[index] = { ...col, sortable: true }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear the default sort when restoring URL sort state

This new single-sort reset logic only runs on click. loadFromUrlParams() still starts from props.columns, so a bookmarked/shared URL like ?sort_action=asc leaves the default created_at: 'desc' column active and adds action: 'asc' on top. Because /private/stats applies orders in column order, logs/deployments opened from a sort URL will still be primarily sorted by created_at, making the restored sort state incorrect.

Useful? React with 👍 / 👎.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

CI is failing on an auth regression unrelated to the search/sort changes in this PR. Failing job: https://github.com/Cap-go/capgo/actions/runs/23280657065/job/67693315697. The only failing suite is tests/app.test.ts, case [GET] /app subkey ownership enforcement, where the test expects 200 and gets 401 at tests/app.test.ts:241. This PR mainly changes table sorting/search wiring plus backend ordering/search helpers, so the failure looks like fallout from the main merge or another auth-path change rather than from the intended feature work here.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

@riderx We just need you. Thank you for the pull request. We just need you to reply or fix your pull request according to the AI comments. When the AI reviewer is done and the build passes in the CI, we will merge your pull request.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f64a11077a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/utils/supabase.ts
@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

CI is still red on this run. The current failure is in : the hook times out at / after 60s. The branch diff is limited to table UI/helpers and backend ordering/search utilities, so this does not look like a simple branch-local fix. The current failure appears to be a shared test setup / seeding timeout rather than behavior introduced by this PR.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

CI is still red on https://github.com/Cap-go/capgo/actions/runs/23290936479/job/67726094876. The current failure is in tests/events.test.ts: the beforeAll hook times out at resetAndSeedAppData(APPNAME_EVENT) and resetAndSeedAppDataStats(APPNAME_EVENT) after 60s. The branch diff is limited to table UI/helpers and backend ordering/search utilities, so this does not look like a simple branch-local fix. The current failure appears to be a shared test setup / seeding timeout rather than behavior introduced by this PR.

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Mar 19, 2026

CI is still red on https://github.com/Cap-go/capgo/actions/runs/23290936479/job/67726094876. The failing Run tests job is timing out in tests/events.test.ts beforeAll while seeding APPNAME_EVENT (resetAndSeedAppData(APPNAME_EVENT) / resetAndSeedAppDataStats(APPNAME_EVENT)), so this looks like a shared test bootstrap/seeding timeout rather than a small branch-local fix.

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: 1

🧹 Nitpick comments (1)
src/components/tables/LogTable.vue (1)

28-32: Consider extracting getActiveOrder to a shared utility.

This helper is duplicated in DeploymentTable.vue. For DRY, consider moving it to a shared location (e.g., ~/services/table.ts or ~/components/comp_def.ts).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/tables/LogTable.vue` around lines 28 - 32, Extract the
duplicated helper getActiveOrder (signature getActiveOrder(columns:
TableColumn[])) into a shared utility module (e.g., services/table.ts or
components/comp_def.ts): create an exported function that returns
columns.filter(col => typeof col.sortable === 'string').map(col => ({ key:
col.key, sortable: col.sortable })), then replace the local implementations in
LogTable.vue and DeploymentTable.vue with an import of that shared
getActiveOrder to remove duplication and keep behavior identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/TableLog.vue`:
- Around line 385-389: The ESLint failure is caused by unnecessary parentheses
around single arrow parameters in the expressions that compute hasSortParam and
newColumns; update the arrow functions used in hasSortParam (currently using
(col) => ...) and the map callback for newColumns (currently using (col) => ...)
to use the single-parameter shorthand (col => ...) so the hasSortParam and
newColumns computations conform to the style/arrow-parens rule while preserving
the same logic for setting sortable.

---

Nitpick comments:
In `@src/components/tables/LogTable.vue`:
- Around line 28-32: Extract the duplicated helper getActiveOrder (signature
getActiveOrder(columns: TableColumn[])) into a shared utility module (e.g.,
services/table.ts or components/comp_def.ts): create an exported function that
returns columns.filter(col => typeof col.sortable === 'string').map(col => ({
key: col.key, sortable: col.sortable })), then replace the local implementations
in LogTable.vue and DeploymentTable.vue with an import of that shared
getActiveOrder to remove duplication and keep behavior identical.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 75820722-d467-4790-995f-baa6b013575f

📥 Commits

Reviewing files that changed from the base of the PR and between a3ec446 and a5728cc.

📒 Files selected for processing (3)
  • src/components/TableLog.vue
  • src/components/tables/DeploymentTable.vue
  • src/components/tables/LogTable.vue

Comment thread src/components/TableLog.vue Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5728cc7e3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/tables/LogTable.vue
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30b4cca302

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1265 to +1268
const devicesOrder = getDevicesOrder(params.order)

// Cursor-based pagination only works when an updated_at order is active
if (params.cursor && devicesOrder) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore cursor support without an explicit device sort

This change makes pagination depend on order containing updated_at, but the public device list endpoint still calls readDevices() with only app_id, cursor, and limit (supabase/functions/_backend/public/device/get.ts:101-105) while readDevices() continues to mint nextCursor as updated_at|device_id (supabase/functions/_backend/utils/stats.ts:324-329). As a result, any caller that follows nextCursor on /device now gets page 1 again because both readDevicesSB and readDevicesCF ignore the cursor when order is omitted, and the default ordering also changes from newest-first to device_id ASC.

Useful? React with 👍 / 👎.

@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit d66f338 into main Mar 19, 2026
15 checks passed
@riderx riderx deleted the codex/fix-log-device-search-sort branch March 19, 2026 19:57
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.

1 participant