Skip to content

Add moderator UI for delisting a published extension - #321

Merged
admdly merged 5 commits into
mainfrom
claude/paygate-extension-removal-58a9fa
Sep 4, 2026
Merged

Add moderator UI for delisting a published extension#321
admdly merged 5 commits into
mainfrom
claude/paygate-extension-removal-58a9fa

Conversation

@admdly

@admdly admdly commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Why

Companion to FOSSBilling/api#215, which adds POST /extensions/{id}/delist so moderators can pull a published extension out of the catalogue. This PR wires that endpoint up on the site side.

Depends on api#215 — the regenerated openapi/extensions-v2.json and typed client here were generated against a local api dev server running that PR's branch, not against production, since production doesn't have the endpoint yet. This should merge/deploy after (or alongside) api#215, not before.

What

  • Regenerated openapi/extensions-v2.json and src/lib/api/generated/extensions-v2/*.
  • Added ApiClient.delistExtension().
  • Added a "Delist a published extension" form to /account/moderate, posting to a new /account/moderate/delist route. Unlike approve/reject, which act on a queue entry already in view, this targets an arbitrary extension id typed into the form, so the id travels in the form body rather than the URL path.

Paygate's source repo is gone and paygate.love is down, so its catalogue
page links to a dead download with no way to reach the developer. The api
repo now has POST /extensions/{id}/delist for this (moderator-only); this
wires it up here:

- Regenerated openapi/extensions-v2.json and the typed client against a
  local api dev server running the new endpoint.
- Added ApiClient.delistExtension().
- Added a "Delist a published extension" form to /account/moderate,
  posting to a new /account/moderate/delist route. Unlike approve/reject,
  which act on a queue entry already in view, this targets an arbitrary
  extension id typed into the form, so id travels in the body rather than
  the URL path.

Does not yet email the developer - the delist reason is visible to them via
GET /extensions/mine once that's surfaced in the owner-facing UI, but actual
notification needs picking an email provider, which is out of scope here.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 4, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
extensions cfbc2bd Commit Preview URL

Branch Preview URL
Sep 04 2026, 09:23 AM

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/pages/account/moderate/index.astro
… carry

Every other method on the ApiClient object, and both sibling
moderate/[id]/*.ts action routes, are comment-free by convention here (this
repo's house style is terser than the api repo's) - the two comments I'd
added on delistExtension() and delist.ts were the only ones in either file.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

0 issues found across 2 files (changes from recent commits).

Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

@admdly admdly self-assigned this Sep 4, 2026
Delisting is destructive and immediate - the extension leaves the public
catalogue as soon as the form posts - but it had no confirmation step,
unlike the reject flow it otherwise mirrors (which uses RejectDialog, a
modal the moderator must explicitly confirm in).

The id/reason form no longer posts directly. Submitting it (native required
validation still applies first) populates and opens a confirmation dialog -
same structure as RejectDialog: title naming the extension, Cancel/Delist
buttons, a close icon - whose own form does the actual POST to
/account/moderate/delist.

The populate-then-open logic needed more than the single-expression inline
onclick handlers this file otherwise uses (see RejectDialog's trigger
button), so it's a <script> block instead, matching the existing precedent
for non-trivial client interactivity in src/pages/account/index.astro.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: Adds moderator UI to delist published extensions, wiring a new API endpoint and regenerating client code. Depends on the unmerged API PR #215, so this cannot be safely deployed independently.

Re-trigger cubic

Regenerated the client against api's delist-published-extensions branch
(now has the new endpoint). Adds:

- ApiClient.getModerationExtension()
- A new detail page, /account/moderate/extensions/[id], showing the full
  record - developer, published content, pending edit, last review, and
  the delist reason/timestamp front and center when present. Mirrors
  developers/[id]/history.astro's layout and error handling.
- A "View an extension" lookup on the moderation index page, and the
  revision queue's extension id is now a link to the same page - so a
  moderator can get from 'reviewing a revision' or 'typing paygate' to
  the full record in one step, not just after delisting something.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread src/pages/account/moderate/extensions/[id].astro Outdated
repositoryURL() returns repository.repo verbatim for type: 'custom', so a
developer-supplied javascript:/data: URI would execute in a moderator's
session on click. DetailsCard.astro (the public extension page) already
guards this with isSafeHttpUrl() before rendering it as a link - this page
missed it, matching the Website field on the same page which already had
the guard.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: Adds moderator UI to delist published extensions, wiring a new API endpoint and regenerating client code. Still depends on the unmerged API PR #215, so merging this client change first would break the site.

Re-trigger cubic

@admdly
admdly merged commit e65310e into main Sep 4, 2026
9 checks passed
@admdly
admdly deleted the claude/paygate-extension-removal-58a9fa branch September 4, 2026 10:08
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