Skip to content

Development Setup

This guide covers installation, configuration, and getting the development environment running.

Prerequisites

Node.js Version

This project requires Node.js 24 or higher. We use mise for version management:

mise use node@24

Native Dependencies

This project uses native Node.js modules that require compilation:

  • sharp - Image processing library for @nuxt/image (IPX provider)
  • better-sqlite3 - SQLite3 bindings for Nuxt Content

Build scripts run automatically during pnpm install without requiring manual approval.

Troubleshooting Image Loading: - If images fail to load with 500 errors on /_ipx/ endpoints, ensure sharp is installed - Restart the dev server after installing sharp to load the native module - In CI environments, build tools (python3, make, g++) are automatically installed

Installation

Install all dependencies once (from root):

pnpm install

Environment Setup

API Configuration

The API requires environment variables. Create apps/api/.env based on .env.example:

# Supabase Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_supabase_key_here

# Supabase Service Role Key (REQUIRED for audit logging)
# Get this from: Supabase Dashboard → Settings → API → service_role key
# ⚠️ Keep this secret! Never expose to client-side code.
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here

# API Configuration
PORT=3001

# Web Application URL (used for email redirects in auth flows)
# Production: https://meister-bill.com
# Development: http://localhost:3000 (or your dev URL)
WEB_URL=http://localhost:3000

Important: The SUPABASE_SERVICE_ROLE_KEY is required for automatic audit logging. See Audit Logging Setup for details.

Web Application Configuration

For the web application, you can control authentication visibility and analytics:

# To disable new user signups (useful for prelaunch/maintenance)
# WEB: Hides login/register buttons and shows newsletter CTA instead
# API: Blocks the /auth/signup endpoint (returns 403)
NUXT_PUBLIC_ENABLE_SIGNUPS=false  # For web app (requires NUXT_PUBLIC_ prefix)
ENABLE_SIGNUPS=false              # For API

# Umami Analytics (Privacy-friendly tracking)
# Set to false to disable tracking (useful for development)
NUXT_PUBLIC_UMAMI_ENABLED=true
NUXT_PUBLIC_UMAMI_WEBSITE_ID=your_umami_website_id
NUXT_PUBLIC_UMAMI_SCRIPT_URL=https://your-umami-instance.com/script.js

# Newsletter Service (Sender.net)
SENDER_API_KEY=your_sender_api_key_here

# Stripe Configuration (for payment links)
# Get your keys from: https://dashboard.stripe.com/test/apikeys
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key_here
# Webhook secret for verifying webhook signatures
# Get from: https://dashboard.stripe.com/test/webhooks
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here
# Stripe Connect Client ID (for OAuth account linking)
# Get from: https://dashboard.stripe.com/settings/applications
STRIPE_CONNECT_CLIENT_ID=ca_your_client_id_here

Umami Analytics Setup

Configure Umami analytics using the environment variables shown above for privacy-friendly tracking.

See the Stripe Workflow documentation for complete setup instructions.

Development Services

Before starting development, run the required services:

docker-compose up -d  # Start mailpit (mail testing) and gotenberg (PDF generation)

Development Services: - Mailpit: Local SMTP/IMAP server for email testing - Web interface: http://localhost:8026/ - SMTP: localhost:1026 (configured in docker-compose.yml) - Use for testing invoice email sending and other email features - Gotenberg: PDF generation service - API: http://localhost:3003/ - Converts HTML templates to PDF for invoices - Required for invoice PDF generation

Running the Application

Start individual apps:

pnpm dev                              # Start both API and web in parallel
pnpm --filter @meisterbill/web dev    # Start web frontend only
pnpm --filter @meisterbill/api dev    # Start API backend only
pnpm --filter @meisterbill/app dev    # Start Ionic app
# Note: blogwriter app runs standalone via ts-node

Note: Both API and WEB have hot reloading. No need to restart after code changes.

Next Steps

See Also