Skip to content

feat(artifacts): shareable purchase artifact page (flag: artifact_share)#735

Draft
dhamariT wants to merge 1 commit into
mainfrom
feat/purchase-artifact
Draft

feat(artifacts): shareable purchase artifact page (flag: artifact_share)#735
dhamariT wants to merge 1 commit into
mainfrom
feat/purchase-artifact

Conversation

@dhamariT

Copy link
Copy Markdown
Collaborator

What

A shop purchase gets a public, shareable "I earned this" page, designed for posting on LinkedIn / Slack: "earned by shipping [project] on Stardance, then redeemed [X] stardust for [item]." Behind a new artifact_share Flipper flag (off by default).

Why

Payouts are going out and people are spending stardust. Turning a purchase into a shareable artifact gives builders social proof to post off-platform, which is free, organic marketing for Stardance.

How (least code, reuse-heavy)

No new model, no migration, no bespoke image generator.

  • Public page ArtifactsController#show + ArtifactPolicy#show? => true, modeled on the public project page.
  • Security (fail-closed): the URL is keyed by ShopOrder#signed_id(purpose: :artifact), not the sequential order id, so purchases cannot be enumerated (no IDOR). noindex, nofollow by default. Tampered/invalid ids 404.
  • Social preview: reuses the existing content_for :og_* system and the featured project's existing OG image via project_og_image_url — no new OG-image service/controller.
  • Provenance: stardust is a pooled balance, so a purchase is not tied to a specific ship. We feature the buyer's most recent ship-event payout's project; generic copy when they have no ships. Item + stardust-spent are exact off the order.
  • UI: reuses .idv-setup-card styling + copy_controller.js for the share button. No new SCSS or components.
  • Entry point: a "Share your win →" button on the buyer's own orders page, gated behind :artifact_share. The public page itself is not flag-gated (it is open-by-signed-link), so logged-out recipients can always view a shared link once the owner has the flag and mints it.

Diff: 3 small new files (controller, policy, view) + ~19 lines across routes, the flag list, and the orders page.

Test

bin/rails runner 'Flipper.enable_actor(:artifact_share, User.find_by(email: "you@example.com"))'

Place a shop order as that user, open the orders page, click "Share your win →", paste the link in a logged-out browser. Confirm: the page renders, OG meta + image are present (view-source or the OG preview tooling), noindex is set, and a bare sequential id at /artifacts/123 does NOT resolve (signed id only).

Note: rubocop/erb_lint were not run locally (the sandbox only had Ruby 2.6, not the project's 3.4.3); ERB + controller syntax were validated and CI will run the full lint.

Follow-ups

  • Bespoke OgImage::Artifact branded share image ("bought [item] for [X] stardust").
  • Let the buyer pick which ship to feature.
  • Optionally show the item image on the page (kept text-only here to avoid new SCSS).

…hare)

A shop purchase gets a public, shareable "I earned this" page for posting on
LinkedIn/Slack: earned by shipping <project>, redeemed <X> stardust for <item>.

- Public page keyed by ShopOrder#signed_id(purpose: :artifact), not the
  sequential id, so purchases can't be enumerated; noindex by default
- ArtifactsController#show + public ArtifactPolicy; reuses the existing OG-meta
  system and the featured project's OG image (project_og_image_url) for the
  social preview, no bespoke image generator
- Provenance from the buyer's most recent ship-event payout ledger entry
  (stardust is pooled, not per-order); generic fallback when no ships
- Reuses .idv-setup-card styling + copy_controller; no new SCSS/components
- Share button on the orders page gated behind :artifact_share (off by default);
  the public page stays open-by-signed-link so logged-out recipients can view it

No model, no migration.
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