feat(web): move Hire Us pricing to $400/hour metered billing (PRD 0002) - #102
Merged
Conversation
Replaces the $250/week retainer with a $400/hour rate billed against actual hours, invoiced through CoinPay after the client approves them. A 10-hour minimum engagement replaces the week as the unit of commitment. The weekly price lived in 12 places, not the 3 the PRD listed: the front-page Hire Us section, the Top-Level Pages list, /hire-us metadata, /pricing (metadata, two FAQ answers, rate bullet), /about, llms.txt, skill.md, and the Hire Us form success message. Metered billing rather than a committed weekly block, because the old "recurring CoinPay invoice" copy documented a mechanic that never existed: /api/payments/create makes a single one-shot payment, not a subscription. - coinpay-checkout derives amount_usd from hours x 400 instead of a hardcoded 250, validates hours as quarter-hour increments at or above the minimum, and returns 422 before calling CoinPay on bad input. Payment metadata carries billing/hours/rate_usd_per_hour in place of interval. - project-request returns a rate, billing mode, and minimum; no amount exists until hours are approved. - CoinPay config block documents COINPAY_RATE_USD_PER_HOUR / COINPAY_BILLING / COINPAY_MINIMUM_HOURS instead of a weekly amount and interval. - New real /terms route replacing the SPA stub: what is billable, the approve-then-invoice flow, the minimum, cancellation on one week's notice, and an explicit clause that existing engagements keep their terms until both sides agree in writing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
The standards test asserts prd_next_id against the live prd/ directory, so adding prd/0002-hourly-hire-us-rate.md moves the next free id to 0003. This assertion advances with every PRD added to the repo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Implements PRD 0002. Replaces the $250/week retainer with a $400/hour rate billed against actual hours, invoiced through CoinPay after the client approves them. A 10-hour minimum engagement replaces the week as the unit of commitment.
The two decisions the PRD was blocked on
/api/payments/createcreates a single one-shot payment, never a subscription. A committed block would also just be a weekly rate wearing an hourly label.Scope was wider than the PRD listed
The PRD named 3 front-page spots plus
/hire-us. The weekly price actually lived in 12 places — the four it missed entirely were/pricing(metadata, two FAQ answers, rate bullet),/about,llms.txt,skill.md, and the Hire Us form's success message.Code, not just copy
coinpay-checkoutderivesamount_usdfromhours × 400instead of a hardcoded250, validates hours as quarter-hour increments at or above the minimum, and returns 422 before calling CoinPay on bad input. Metadata carriesbilling/hours/rate_usd_per_hourin place ofinterval.project-requestreturns a rate + billing mode + minimum; no amount exists until hours are approved.COINPAY_RATE_USD_PER_HOUR=400/COINPAY_BILLING=metered_hours/COINPAY_MINIMUM_HOURS=10./termsroute (R9) replacing the SPA stub: what is billable, the approve-then-invoice flow, the minimum, cancellation on one week's notice, and an explicit clause that existing engagements keep their terms until both sides agree in writing — making the "no silent repricing" success metric enforceable rather than aspirational.Verification
tsc --noEmitcleannext buildsucceeds,/termsemits as a static routeKnown gaps (recorded in the PRD, not fixed here)
/termsdefines what is billable, so the definition is settled even though the mechanism isn't.🤖 Generated with Claude Code