Skip to content

feat: template referral system#778

Open
selenaalpha77-sketch wants to merge 1 commit intoMerit-Systems:masterfrom
selenaalpha77-sketch:feat/template-referral-system
Open

feat: template referral system#778
selenaalpha77-sketch wants to merge 1 commit intoMerit-Systems:masterfrom
selenaalpha77-sketch:feat/template-referral-system

Conversation

@selenaalpha77-sketch
Copy link
Copy Markdown

Summary

Implements the template referral system requested in #612.

When a user scaffolds an app from an external GitHub template via echo-start, the template creator is automatically registered as a referrer on the new app.

What changed

echo-start CLI

  • Reads echo.config.json from the cloned template directory
  • Validates and sanitizes the referralCode field
  • Calls POST /api/v1/apps/template-referral to register the template creator as referrer
  • Removes echo.config.json from the scaffolded project (template metadata, not app code)
  • Non-blocking: referral steps fail silently

New API endpoint: POST /api/v1/apps/template-referral

  • No auth required (referral code identifies the creator)
  • Validates the code is not archived/expired
  • Registers it as templateReferrerCodeId on the app (idempotent, first-come-first-served)

Prisma schema + migration

  • Adds templateReferrerCodeId to EchoApp
  • SQL migration adding the column

Docs

  • Documents template referral setup in referrals.mdx

How it works

  1. Template creator adds echo.config.json to their repo with their referral code
  2. User scaffolds: npx echo-start --template https://github.com/creator/template --app-id <id>
  3. echo-start reads the code, calls the Echo API, registers the creator as referrer
  4. echo.config.json is deleted from the new project

/claim #612

When a user scaffolds an app from an external GitHub template via echo-start,
automatically register the template creator as a referrer on the new app.

Changes:
- echo-start: reads echo.config.json from the cloned template, sanitizes
  and validates the referralCode field, calls the Echo API to register the
  template creator as referrer, then removes echo.config.json from the project
- New API endpoint POST /api/v1/apps/template-referral: registers a referral
  code as the template referrer for an app (no auth required, idempotent,
  first-come-first-served per app)
- Prisma schema: adds templateReferrerCodeId to EchoApp and the inverse
  templateReferredApps relation on ReferralCode
- Migration: ALTER TABLE echo_apps to add templateReferrerCodeId column
- Docs: documents the template referral feature in referrals.mdx

Template creators add echo.config.json to their repo with their referral code.
echo-start handles the rest automatically, non-blocking — failures are silent.

Closes Merit-Systems#612
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 25, 2026

@selenaalpha77-sketch is attempting to deploy a commit to the Merit Systems Team on Vercel.

A member of the Team first needs to authorize it.

@vercel vercel Bot temporarily deployed to Preview – component-registry April 25, 2026 15:57 Inactive
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
component-registry Skipped Skipped Apr 25, 2026 3:57pm

Comment on lines +75 to +79
await db.echoApp.update({
where: { id: echoAppId },
data: { templateReferrerCodeId: code.id },
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
await db.echoApp.update({
where: { id: echoAppId },
data: { templateReferrerCodeId: code.id },
});
// Use updateMany with a conditional where clause to make this atomic.
// This prevents race conditions where two concurrent requests could both
// pass the check above and race to update the app.
const result = await db.echoApp.updateMany({
where: { id: echoAppId, templateReferrerCodeId: null },
data: { templateReferrerCodeId: code.id },
});
// If count is 0, another request already registered a referrer
if (result.count === 0) {
return NextResponse.json({
success: true,
message: 'Template referrer already registered',
});
}

Race condition in template referral registration allows second concurrent request to overwrite first, violating "first-come-first-served" semantics

Fix on Vercel

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