Operations Guide

Development & Operations Runbook

Step-by-step procedures for operating the Pinehaven Ventures platform. Covers adding ventures, running generators, seeding Stripe, deploying to Vercel, and troubleshooting common issues.

Last updated: March 3, 2026. Procedures verified against current production configuration.

Procedure: Add a new venture

The standard operating procedure for adding a new product to the portfolio. This can be executed end-to-end by an AI agent or a human operator.

1

Edit ventures.json

Add a new entry to the ventures array with all required fields: id, name, tagline, description, color, icon, status, target_market, features, and plans.

Color options: green, blue, purple, orange, red, cyan, amber. For free tiers, set price: 0 and omit stripe_env_key.

2

Run the generator

Reads ventures.json and regenerates stripe-products.ts, seed-stripe.ts, .env.example, and scaffolds a new product page if one does not already exist.

npm run generate

Use npm run generate:dry to preview changes without writing files.

3

Customize the generated page

The generator creates a functional but basic product page. Enhance the hero copy, add "How It Works" sections, flesh out features, and adjust pricing card layout.

Existing pages are never overwritten — only new pages are scaffolded.

4

Seed Stripe (if live keys available)

Creates Stripe products and prices, configures the billing portal, and outputs environment variable assignments.

STRIPE_SECRET_KEY=sk_live_... npm run seed-stripe

Use npm run seed-stripe:dry to preview. Copy output env vars into .env.local.

5

Verify the build

Run TypeScript type checking and a full production build to catch errors before deploying.

npx tsc --noEmit && npm run build
6

Push to GitHub

Commit all changes and push. Vercel will automatically build and deploy to pinehavenventures.io.

git add . && git commit -m "Add <venture-name> to portfolio" && git push

ventures.json field reference

Venture fields

FieldTypeRequiredDescription
idstringRequiredURL-safe slug (e.g., "my-new-app"). Used in routes and Stripe config.
namestringRequiredDisplay name for the product.
taglinestringRequiredShort value proposition (one line).
descriptionstringRequiredLonger description for the hero section.
colorstringRequiredTheme color: green, blue, purple, orange, red, cyan, or amber.
iconstringRequiredIcon identifier for the product.
statusstringRequiredProduct lifecycle: live, in-development, or coming-soon.
target_marketstring[]RequiredArray of audience segments.
featuresstring[]RequiredTop-level product features.
plansPlan[]RequiredArray of pricing plans (see plan fields below).
has_free_tierbooleanOptionalSet to true if the product has a $0 plan.
has_demobooleanOptionalSet to true if a demo page exists.

Plan fields (nested in plans array)

FieldTypeDescription
idstringUnique plan identifier (e.g., "my-app-starter").
namestringDisplay name (e.g., "Starter", "Pro").
pricenumberPrice in dollars. Use 0 for free tiers.
currencystringAlways "usd".
intervalstring"month" or "year".
stripe_env_keystringEnvironment variable name for the Stripe price ID. Omit for free tiers.
descriptionstringShort description of who the plan is for.
featuresstring[]Features included in this plan.
popularbooleanMark as the recommended/highlighted plan.

Available commands

CommandDescriptionSafe to run?
npm run generateRead ventures.json and regenerate all derived files. Scaffold new product pages.Safe
npm run generate:dryPreview what generate would do without writing any files.Safe
npm run seed-stripeCreate products/prices in Stripe and configure billing portal. Requires STRIPE_SECRET_KEY.Caution
npm run seed-stripe:dryPreview what Stripe objects would be created without making API calls.Safe
npm run devStart the development server with Turbopack at localhost:3000.Safe
npm run buildRun a full production build. Catches SSR errors, missing imports, and type issues.Safe
npm run lintRun ESLint with Next.js recommended rules.Safe
npx tsc --noEmitType-check all TypeScript files without emitting output. Fast validation.Safe

Vercel deployment checklist

Connect GitHub repository

Setup

Vercel watches the repo for pushes. Every push to main triggers a build.

Configure environment variables

Setup

Add all variables from .env.example to the Vercel project settings. Include Stripe keys, price IDs, and Airtable credentials.

Verify build framework

Setup

Vercel auto-detects Next.js. No vercel.json or custom config is needed.

Set production domain

Setup

Point pinehavenventures.io to the Vercel project via DNS.

Configure Stripe webhook endpoint

Stripe

In Stripe Dashboard, set the webhook URL to https://pinehavenventures.io/api/stripe/webhooks and select the five handled events.

Test checkout flow

Verification

Use Stripe test mode keys to verify checkout, success, and cancel pages work end to end.

Verify webhook delivery

Verification

In Stripe Dashboard, check webhook logs to confirm events are received and returning 200.

Stripe webhook events to configure

These five events must be selected in the Stripe Dashboard webhook endpoint configuration. The endpoint URL is https://pinehavenventures.io/api/stripe/webhooks.

EventAction
checkout.session.completedProvision access, record customer and subscription IDs
customer.subscription.updatedHandle plan upgrades/downgrades, update access level
customer.subscription.deletedRevoke access, trigger retention flow
invoice.payment_succeededLog successful recurring payment
invoice.payment_failedFlag for follow-up, notify customer

Troubleshooting

Build fails after adding a new venture

Cause: Generated files are stale — ventures.json was edited but generator was not run.

Fix: Run npm run generate, then npm run build again.

Stripe checkout redirects to error page

Cause: Price ID environment variable is missing or incorrect.

Fix: Check .env.local against .env.example. Run npm run seed-stripe if price IDs have not been created.

Webhook returns 400 in Stripe Dashboard

Cause: STRIPE_WEBHOOK_SECRET is missing or does not match the endpoint.

Fix: Verify the webhook secret in Vercel environment variables matches the one in Stripe Dashboard.

Product page shows $0 for all plans

Cause: NEXT_PUBLIC_STRIPE_PRICE_* env vars are not set in Vercel.

Fix: Add price ID environment variables to Vercel project settings and redeploy.

Generator does not create a page for existing venture

Cause: Product page already exists — generator only scaffolds new pages, never overwrites.

Fix: This is expected behavior. Edit the existing page manually.

TypeScript errors after generator run

Cause: ventures.json has a schema issue (missing field, wrong type).

Fix: Validate ventures.json fields against the schema documented above.

Related references

See the Architecture reference for the full tech stack and file map, or the Site Map for a complete route inventory.