feat(provider): entities-interacting section on provider detail page#38
Merged
Conversation
Add an "Entities" section below the existing sections of the provider detail page, listing every pubkey that has interacted with the provider: Date (updated_at), Public Key (truncated + copy), Status (badge per status). Loading / empty / error states match the sibling sections; UNVERIFIED uses a neutral local badge variant. Backed by GET /providers/:pp/entities. Relates to ClickUp 86ca439ah
AquiGorka
added a commit
to Moonlight-Protocol/provider-platform
that referenced
this pull request
Jun 12, 2026
…oint (#118) ## Summary A PP operator had no way to see which entities have interacted with their provider. Entities that registered via KYC self-serve get an APPROVED row in `pp_entity_approvals`; entities that interact but are NOT authorized (SEP-10 connect with no approval, or a bundle-submit 403) left zero persistent trace. This persists a record at those two unauthorized-interaction points and exposes an operator-facing list endpoint. Vertical slice with the UI side in Moonlight-Protocol/provider-console#38. ## What changed - **`recordInteraction(pp, pubkey)`** — single `ON CONFLICT … DO UPDATE … setWhere status = 'UNVERIFIED'` upsert: insert UNVERIFIED if absent, touch `updated_at` if the row is already UNVERIFIED, and **never** modify an APPROVED/PENDING/BLOCKED row. - **`listByPp(pp)`** — non-deleted rows for the PP joined to entity identity (name/jurisdictions) via account → entity, `updated_at` DESC. - **Write-points** — SEP-10 connect (`attach-entity-status.ts`) and the bundle-submit 403 gate (`add-bundle.process.ts`, both branches). Both are best-effort: a write failure never breaks the auth response and never changes the 403. - **`GET /api/v1/providers/:ppPublicKey/entities`** — operator JWT + `requirePpOwnership`, mirroring the metrics endpoint (`{ data }` envelope). - Reuses the existing table + `entity_status` enum — **no migration**. ## Testing - Unit (PGlite, real migrations): the upsert invariant across all branches (insert / touch-when-UNVERIFIED / no-op-when-APPROVED/PENDING/BLOCKED), plus `listByPp` ordering + join + soft-delete/PP scoping. - Integration: endpoint envelope + `updated_at` DESC + ownership (owner passes, non-owner denied). - Live local smoke (isolated Docker stack built from this branch): approved entity submits a real bundle; unauthorized connect records UNVERIFIED; unauthorized bundle 403s and advances `updated_at` on the existing row; operator endpoint returns all three in DESC; non-owner denied. No authorization regression. - `deno fmt --check`, `deno lint`, `deno task test` (200 passed) all green. ## Intentional deviation from the prompt text A non-owning operator receives **404** ("Provider not found"), not 403 — `requirePpOwnership` returns 404 for any PP the operator doesn't own, identical to every other `/providers/:pp` endpoint (it doesn't distinguish "exists-but-not-yours" from "absent"). The ownership property holds; only the status code differs. Tests assert the real 404. Relates to ClickUp 86ca439ah
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an "Entities" section to the provider detail page showing every pubkey that has interacted with the provider — the KYC-approved ones plus the unauthorized pubkeys now recorded by Moonlight-Protocol/provider-platform#118 (SEP-10 connect + bundle-submit 403).
UI side of the vertical slice; backend is Moonlight-Protocol/provider-platform#118.
What changed
getEntities(ppPublicKey)client call (lib/api.ts) following the existing URL-scoped pattern ({ data }envelope).views/provider.ts, below all existing sections (OpEx / Councils / Dashboard / sparklines). Columns: Date (updated_at, relative — matching the console's existing date helper), Public Key (truncated + copy affordance), Status (badge per status). Loading / empty ("No entities have interacted with this provider yet") / error states match the sibling sections..badge-unverifiedneutral grey variant inapp-styles.css(the lib ships active/pending/inactive; UNVERIFIED has no semantic colour).Testing
deno fmt --check,deno task lint,deno task test,deno task buildall green.updated_atDESC, below the existing sections. Screenshot captured.Note
The
Datecolumn uses the console's existing relative-time helper (fmtRelativeTime) — the only date format the console currently ships — to match convention. Happy to switch to an absolute timestamp if preferred.Relates to ClickUp 86ca439ah