Skip to content

Feature proposal: Compare apps across keywords (rank matrix view) #2

@onlyilkr

Description

@onlyilkr

Problem

The dashboard currently shows keyword rank for one selected app at a time. When several apps compete in the same category, there is no way to see how they stack up side by side on a shared keyword set without manually switching between apps and mentally diffing the numbers.

Typical questions that are hard to answer today:

  • On which keywords does my app lead vs. trail competitors?
  • If I track keywords on App A and my teammate tracks a different set on App B, what does the unified picture look like?
  • Where are the biggest rank gaps worth closing?

Proposal

Add a Compare Apps view reachable from the dashboard. The user picks N apps (2–10) and M keywords (1–100), and a matrix renders with rows = keywords, columns = apps, cells = current rank + change delta.

Key design point: ranks are already derivable from the existing aso_keywords.ordered_app_ids top-200 list, so an app's rank can be computed for any keyword it appears in even if that app has not explicitly tracked the keyword in app_keywords. This means the matrix is meaningful even when apps have different keyword lists.

No schema changes required. Two new read-only endpoints:

  • GET /api/aso/compare/keywords — union of keywords tracked by the selected apps, with coverage metadata.
  • POST /api/aso/compare/matrix — per-(app, keyword) rank/change data.

Why it fits this project

  • Local-first, read-only — no new external API calls, no auth surface changes.
  • Reuses existing primitives (Button, Input, Badge, Card), existing route factory pattern, and the same SQL idiom already used by keyword-handlers.ts (json_each(ordered_app_ids)).
  • Respects current boundary ownership: no changes to keywordPipelineService or keywordWriteRepository.
  • Adds 12 unit tests in cli/db/app-compare.test.ts (full suite still passes: 393 tests).

Scope (what would ship)

  • Compare entry point next to the sidebar Apps heading.
  • Live-updating matrix (debounced refetch on selection changes).
  • Custom keyword picker with "tracked by all / any" filter and search.
  • Per-column sort (keyword, popularity, any app's rank).
  • Inline removal of apps/keywords from the matrix.
  • Fullscreen toggle on the matrix (+ ESC to exit).
  • localStorage persistence of last comparison.
  • Three distinct empty-cell states: not tracked, outside top 200, not yet researched — each with tooltip + aria-label.

Explicitly out of scope for v1 (could come later based on feedback):

  • Shareable URL state / named saved comparisons
  • CSV or Markdown export
  • Sparkline / historical trend per cell

Status

Implementation PR: #1

Everything passes locally (typecheck + 393/393 tests + build). I have opened the PR alongside this issue so the code is visible for review, but fully happy to adjust scope, API shape, or integration approach — or hold off entirely — based on your feedback.

Thanks for building this tool.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions