* feat(web): move Hire Us pricing to $400/hour metered billing (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 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> * fix(mcp): advance prd_next_id expectation to 0003 for PRD 0002 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> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
7.7 KiB
| openprd | id | title | status | authors | created | updated | repo | implementation | tags | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.2 | 0002 | Move Hire Us pricing from a weekly retainer to an hourly rate | Accepted |
|
2026-07-28 | 2026-07-28 | https://github.com/profullstack/logicsrc | apps/logicsrc-web |
|
Problem
The Hire Us surface on logicsrc.com prices standards work at $250/week, paid through a recurring CoinPay invoice after project acceptance. That number reads as a token retainer rather than a rate for senior open-spec implementation work — schemas, CLIs, SDKs, MCP resources, and provider-neutral plugin surfaces. It anchors every inbound conversation at a price that cannot cover the work, and it selects for clients who are shopping on price rather than on the standard.
The replacement is $400/hour. This is not a bump to an existing hourly number; it is a change of pricing model, which touches page copy, the payment configuration, and the invoicing mechanics that currently assume a fixed weekly amount.
Goals
- Every public price on logicsrc.com states one rate, in one unit, with no stale $250/week copy left behind on any surface.
- Inbound Hire Us inquiries arrive already anchored to a senior rate, so the pricing conversation is about scope rather than about the number.
- Billing can actually execute the new model: an accepted project produces a correct invoice without manual repair.
- The change is reversible and auditable — the reasoning survives in the repo, not in a Slack thread.
Non-Goals
- Repricing the standard itself. LogicSRC schemas, specs, and reference implementations stay open and free; this covers implementation services only.
- Building time tracking. Hourly billing needs hours captured, but that is an operational process for now, not a product to build.
- Replacing CoinPay or adding a second payment provider.
- Publishing a rate card with tiers, discounts, or role-based pricing. One rate, one line.
- Migrating anyone currently engaged at $250/week. Handled case by case, not by this PRD.
Users
- Prospective clients evaluating whether to hire Profullstack for LogicSRC work — mostly founders and engineering leads arriving from the spec pages, who read the price before they read anything else.
- Profullstack, as the party quoting, invoicing, and collecting.
- Existing clients on the weekly plan, who must not be silently repriced.
Decisions
Two questions blocked this PRD at drafting time. Both were resolved before implementation:
- The rate is $400/hour, confirmed deliberately. Against $250/week this is roughly a 64x change at a 40-hour week. The magnitude is the point: the weekly figure was a token retainer, not a rate, and the new number is intended to filter out engagements too small to scope.
- Billing is metered against actual hours, not a committed weekly block. This matches how
the code already works —
/api/payments/createcreates a single one-shot payment, never a recurring subscription, so the previous "recurring invoice" copy documented a mechanic that did not exist. Metered billing also avoids the committed-block failure mode, which is a weekly rate wearing an hourly label. A 10-hour minimum engagement replaces the week as the unit of commitment.
Requirements
- R1 [P0] The Hire Us section heading states the new rate and unit, replacing "$250/week for accepted LogicSRC work".
- R2 [P0] The price display block shows $400 with the unit "per hour".
- R3 [P0] The
/hire-usentry in the Top-Level Pages list is updated; it repeated the weekly figure independently of the section above it. - R4 [P0] The
/hire-uspage body and its meta description are updated. - R5 [P0] The CoinPay configuration block reflects the new model.
COINPAY_AMOUNT_USD=250andCOINPAY_INTERVAL=weekare both wrong under hourly pricing and are replaced by a rate, a billing mode, and a minimum rather than renumbered. - R6 [P0] A repo-wide search for
250,per week, and/weekreturns no remaining pricing references before the change is considered done. - R7 [P1] The site states what an hour is billed against — metered actual hours, invoiced after the client approves them — so the invoice mechanic is legible before a client asks.
- R8 [P1] Minimum engagement and cancellation terms are stated, since removing the weekly cadence also removes the implicit unit of commitment.
- R9 [P2] Terms of engagement are documented at
/termsrather than only in marketing copy.
Surfaces the original draft did not list, but which carried the weekly price and were therefore
in scope for R6: /pricing (metadata, two FAQ answers, and the rate bullet), /about,
llms.txt, skill.md, the Hire Us form's success message, and both the contract and e2e tests.
UX Notes
The price appears in several places across the front page, /pricing, /about, and the
machine-readable surfaces; they are separate strings and will drift if edited one at a time.
Treat the set as one change.
The CoinPay block is rendered as example configuration, so it reads as documentation of how billing actually works. A weekly interval next to an hourly rate is worse than a stale price — it looks like the system does not do what the copy says.
The stated rate sits next to what it buys. The existing four capability cards (workflow specs, reference implementations, integration hardening, open infrastructure) already do that work and are unchanged.
Implementation Notes
src/lib/page-markup.ts— section heading, price row, a new.price-termsline carrying the minimum and cancellation summary, the CoinPay config block, and the Top-Level Pages entries for both Hire Us and Terms.src/app/api/hire-us/coinpay-checkout/route.ts— the amount is now derived ashours × $400rather than hardcoded. Hours are validated as quarter-hour increments at or above the 10-hour minimum, defaulting to the minimum when omitted; invalid hours return 422 before any call to CoinPay. Payment metadata carriesbilling,hours, andrate_usd_per_hourin place ofinterval.src/app/api/hire-us/project-request/route.ts— returns a rate, billing mode, and minimum instead of a fixedamount_usd/intervalpair, since no amount exists until hours are approved.src/app/terms/page.tsx— new real route, replacing the/termsstub that rendered the homepage SPA. The stub's entry was removed from the catch-all'sROUTE_META.
Success Metrics
- Zero occurrences of the weekly price across the site and repo after the change, verified by grep rather than by reading.
- First accepted project under the new model invoices correctly on the first attempt, with no manual adjustment to the CoinPay invoice.
- Inbound inquiries that reach a scoping conversation do not open by disputing the rate.
- No existing engagement is repriced without explicit agreement.
Risks & Open Questions
- Hours are not currently tracked. Metered billing won, and there is no capture mechanism.
/termsnow defines what is billable (project work, meetings, and written communication in quarter-hour increments; not scoping calls, invoicing, or warranty fixes), so the definition is settled even though the tooling is not. Capturing hours is an operational process until it is worth building. - Client mix will change. An hourly rate at this level filters out the small experimental engagements the weekly price attracted. This is the intent, recorded here as a decision rather than left to be discovered.
- Existing weekly clients keep their terms until both sides agree in writing to move, per
/terms. Whether any active weekly engagements exist is still unknown. - Author attribution is assumed from the CoinPay org configuration and should be corrected if wrong.