Welcome to the new site. If you have any issues accessing models, use store.hemrock.com.
Sign in

Portfolio Reporting Deployment

Step-by-step guide to deploy the Portfolio Reporting Stack on your own infrastructure.

Overview

The Portfolio Reporting Stack is designed as a single-tenant deployment per fund. You control your own data, your own API keys, your own domain, and your own infrastructure. Contact Taylor for managed setup, onboarding, and ongoing support.

Required services

Service What it does Free tier
Hosting (Netlify or Vercel) Runs the Next.js app Yes
Supabase Database, authentication, file storage 500 MB database, 1 GB storage
Inbound email (Postmark or Mailgun) Receives portfolio company emails Postmark: 100/mo, Mailgun: 1,000/mo
AI provider (at least one) Email processing, metric extraction, summaries See below

AI providers

Provider Default Model Notes
Anthropic claude-sonnet-4-5 Best overall quality
OpenAI gpt-4o Strong alternative
Google Gemini gemini-2.0-flash Free tier available
Ollama llama3.2 Free, runs locally

Optional services

Service When you need it
Outbound email (Resend, Postmark, Mailgun, or Gmail) To email portfolio companies from the app
Google Cloud OAuth Google Drive archiving + Gmail sending
Dropbox Alternative file archiving

Step-by-step setup

Step 1: Clone the repository

git clone https://github.com/tdavidson/reporting.git  
cd reporting  
npm install  

Step 2: Create the Supabase project

  1. Create a new project at supabase.com
  2. Go to Project Settings > API and copy:
    • Project URL (NEXT_PUBLIC_SUPABASE_URL)
    • Anon public key (NEXT_PUBLIC_SUPABASE_ANON_KEY)
    • Service role key (SUPABASE_SERVICE_ROLE_KEY)
  3. Run SQL migrations: use supabase db push or paste each file in supabase/migrations/ into the SQL Editor in order
  4. In Authentication > Providers, confirm Email is enabled

Step 3: Generate an encryption key

All secrets are encrypted at rest using AES-256-GCM:

openssl rand -hex 32  

Save this as ENCRYPTION_KEY. If you lose it, encrypted credentials become unrecoverable.

Step 4: Deploy the app

Netlify:

Deploy to Netlify

Vercel:

Deploy with Vercel

Add these environment variables in your hosting platform:

NEXT_PUBLIC_SUPABASE_URL=         # From Step 2  
NEXT_PUBLIC_SUPABASE_ANON_KEY=    # From Step 2  
SUPABASE_SERVICE_ROLE_KEY=        # From Step 2  
ENCRYPTION_KEY=                   # From Step 3  
NEXT_PUBLIC_APP_URL=              # Your deployed URL  

Trigger a redeploy after adding variables, NEXT_PUBLIC_* variables require a rebuild.

Step 5: Configure authentication

  1. Authentication > URL Configuration: set Site URL to your deployed URL, add https://your-app.com/** to Redirect URLs
  2. Authentication > Hooks: enable the Before User Created hook, select hook_before_user_created

Step 6: Allow your first user

  1. In Supabase, go to Table Editor > allowed_signups
  2. Insert a row with your email address (or *@yourfund.com for a domain)
  3. Go to /auth/signup on your deployed app and create your account
  4. Confirm via email, the first signup is the admin

Step 7: Complete the onboarding wizard

After signing in, the wizard walks you through:

  1. Fund name
  2. AI API key, at least one provider. Keys are encrypted and stored in your database.
  3. Inbound email address, see next step

Step 8: Set up inbound email

Postmark:

  1. Create a Postmark account
  2. Set the inbound webhook to: https://your-app.com/api/inbound-email?token=YOUR_TOKEN
  3. Enter the Postmark inbound address in Settings

Mailgun:

  1. Create a Mailgun account
  2. Set up an inbound route forwarding to: https://your-app.com/api/inbound-email/mailgun
  3. Enter your Mailgun API key and signing key in Settings

Step 9: Add authorized senders

In Settings > Authorized Senders, add email addresses your portfolio companies send reports from. Only emails from authorized senders are processed.

Step 10: Add companies and metrics

  1. Go to Portfolio and add your companies
  2. Configure the metrics you want to track per company
  3. Optionally use Import to bulk-create companies and metrics from a spreadsheet

Step 11: Test it

Forward a portfolio company report to your inbound address. Within a minute:

  • The email appears in Inbound
  • Metrics are extracted and visible on the company profile
  • Low-confidence extractions are flagged in Review

Step 12: Invite your team

Team members can sign up if their email matches the whitelist or your fund's email domain. Admins approve requests in Settings.

Verify your setup

Add ENABLE_SETUP_PAGE=true as an environment variable, then visit /setup to run a built-in checklist. It checks infrastructure, authentication, fund configuration, AI providers, email setup, file storage, and authorized senders. Disable it when done by removing the variable.

Optional: Google Drive / Dropbox

Google Drive:

  1. Create a Google Cloud project, enable Google Drive API and Gmail API
  2. Create OAuth 2.0 credentials (Web application)
  3. Add https://your-app.com/api/auth/google/callback as a redirect URI
  4. In Settings, enter your Client ID and Secret and connect

Dropbox:

  1. Create an app at dropbox.com/developers
  2. Add https://your-app.com/api/auth/dropbox/callback as a redirect URI
  3. Connect in Settings

Optional: Two-factor authentication

Enable TOTP-based MFA from the Settings page. Works with any authenticator app.

Feature visibility

Admins can control which features appear in the sidebar:

Level Behavior
Everyone Visible to all team members
Admin only Only visible to admins
Hidden Removed from sidebar, accessible via URL
Off Completely disabled

Configurable features: Interactions, Investments, Funds, Notes, Letters, LPs, Compliance, Imports, and Asks.

Local development

npm install  
cp .env.example .env.local
# Fill in Supabase URL, keys, and encryption key
npx supabase db push  
npm run dev  

For webhook testing locally, use a tunnel:

ngrok http 3000
# or
cloudflared tunnel --url http://localhost:3000  

Updates

The app checks for new versions against GitHub Releases. Admins see an Updates link in the sidebar when a newer version is available.

Contact

For setup assistance, managed deployments, or questions: contact Taylor.

For bug reports and feature requests: GitHub Issues.