Files
jobtrackingapp/docs/verification/product-001-honest-plans.md
T
cesnimda 191de69c48
CI and Deploy / test (pull_request) Successful in 5m27s
CI and Deploy / deploy (pull_request) Has been skipped
test(billing): prove downgrade lifecycle
2026-08-15 20:28:23 +02:00

3.6 KiB

PRODUCT-001 honest Free/Pro surfaces

Updated: 2026-08-15

Status: IMPLEMENTED — NOT VERIFIED. Repository and local Chromium scope passes. Configured Stripe checkout, expiry/downgrade browser behavior, native assistive technology and production remain external.

Confirmed problem

The public homepage contradicted the server policy. It advertised three tiers, fixed prices and billing intervals, a Free AI allowance, a bring-your-own-key tier and unlimited AI. The authoritative AccountPlans model exposes only Free and Pro, gives Free no AI admission, and applies finite Pro ceilings. Commercial terms are owned by configured Stripe Checkout, not application copy.

Implemented contract

  • planCatalog.ts is the single frontend source for public plan names and capability copy. It contains exactly free and pro; the server remains authoritative for enforcement and numeric entitlements.
  • Free describes core non-AI tracking, correspondence/documents, manual Career Profile/CV editing, deterministic matching and data export/retention.
  • Pro describes the existing AI-assisted application/CV/Career capabilities and Pro themes. It does not claim an invented price, interval, trial or unlimited usage.
  • The homepage uses two semantic plan sections, sends the Free action to registration and the Pro action through sign-in to Settings. Branding is consistently Jobjakt.
  • Settings shows Checkout/portal actions only when the authenticated billing status permits them. A Free user sees an honest deployment-unavailable explanation when Stripe is not configured.
  • Active AI surfaces reuse a dismissible ProFeatureNotice. Copy is benefit-specific, preserves access to manual/existing content and never implies that work was generated.
  • Product/business-model and implementation-roadmap claims now match POL-001. Historical competitor pricing remains research, not current product copy.

No backend behavior, database, dependency, billing configuration or production state changed.

Verification

  • Public catalogue, landing, reusable notice, usage card and active AI surfaces: 7 suites, 30/30 tests.
  • Current server entitlement/billing-policy slice: 30/30 tests, including Free, Pro, Admin, stale-role downgrade and subscription-status behavior.
  • Expanded local entitlement/billing slice: 33/33, including configured checkout metadata, active → expired → canceled/replayed webhook behavior and fail-closed Product-ID rejection.
  • Full frontend: 57/57 suites, 232/232 tests.
  • Optimized production frontend build/TypeScript: pass.
  • Full Playwright: 8/8. The public plan page shows exactly Free/Pro, contains none of the retired claims, persists explicit Light/Dark, has no horizontal overflow at 375/768/1440, and both plan actions work from the keyboard.
  • git diff --check: pass; line-ending notices only.

Remaining gates

  • Production Stripe price/interval/trial text must continue to come from hosted Checkout. No commercial term is claimed until the configured product is inspected in the authorized production account.
  • Exercise a configured Free checkout, successful webhook/role transition, portal, cancellation/expiry/downgrade and existing-data access in an authorized synthetic production account.
  • Native screen-reader and switch-control spot checks remain external.
  • Cross-feature user-generation accounting is complete locally (V-184); the public site still avoids commercial or unlimited claims because production Stripe terms and model capacity remain external.

Rollback

Revert the PRODUCT-001 frontend/documentation commit. No migration or data rollback is required; server-side Free/Pro enforcement is unchanged and must not be reverted with presentation copy.