← Back to Summit Finance

How to Deploy & Use Summit Finance

Summit Deployment & Usage Guide

Prerequisites

  • Node.js: v18.17.0 or higher (required for Next.js App Router)
  • PostgreSQL: v14+ (primary database)
  • Git: For cloning the repository
  • Package Manager: npm, yarn, or pnpm
  • Optional Accounts:
    • Resend - For transactional emails
    • Xendit - For payment processing
    • MinIO or AWS S3 - For file storage (receipts, logos)
    • Railway account - For one-click deployment

Installation

1. Clone the Repository

git clone https://github.com/kugie-app/summit.git
cd summit

2. Install Dependencies

npm install
# or
yarn install
# or
pnpm install

3. Initialize Database Schema

Summit uses Drizzle ORM with PostgreSQL. Run migrations to create the required tables (companies, users, invoices, quotes, expenses, transactions, etc.):

# Generate migration files (if needed)
npm run db:generate

# Apply migrations
npm run db:migrate

# Optional: Open Drizzle Studio to verify tables
npm run db:studio

Configuration

Create a .env.local file in the project root with the following variables:

Required Core Configuration

# Database
DATABASE_URL="postgresql://username:password@localhost:5432/summit_db"

# NextAuth.js
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-random-secret-key-min-32-characters-long"

# Application
NEXT_PUBLIC_APP_URL="http://localhost:3000"

Email Configuration (Resend)

RESEND_API_KEY="re_xxxxxxxx"
EMAIL_FROM="invoices@yourdomain.com"

Payment Processing (Xendit)

XENDIT_SECRET_KEY="xnd_development_..."
XENDIT_PUBLIC_KEY="xnd_public_development_..."
XENDIT_WEBHOOK_SECRET="your-webhook-secret"

File Storage (MinIO/S3)

STORAGE_ENDPOINT="s3.amazonaws.com"
STORAGE_PORT="443"
STORAGE_USE_SSL="true"
STORAGE_ACCESS_KEY="your-access-key"
STORAGE_SECRET_KEY="your-secret-key"
STORAGE_BUCKET_NAME="summit-storage"
STORAGE_REGION="us-east-1"

Database Schema Details

Based on src/lib/db/schema.ts, the application uses these key enums:

  • Roles: admin, staff, accountant
  • Invoice Status: draft, sent, paid, overdue, cancelled
  • Quote Status: draft, sent, accepted, rejected, expired

All tables implement soft deletes via softDelete boolean fields.

Build & Run

Development Mode

npm run dev

The application will start on http://localhost:3000. First-time setup requires creating an initial company and admin user through the UI.

Production Build (Local)

# Build the application
npm run build

# Start production server
npm start

Database Management Commands

# Push schema changes (development only)
npm run db:push

# Generate migration files after schema changes
npm run db:generate

# Run pending migrations
npm run db:migrate

# Seed database (if seed script available)
npm run db:seed

Deployment

Option 1: Railway (Recommended)

The Kugie team maintains an official Railway template that provisions:

  • Next.js application
  • PostgreSQL database
  • MinIO object storage

Deploy on Railway

Post-Deployment Steps:

  1. Set environment variables in Railway dashboard
  2. Configure Xendit webhook URL: https://your-app.up.railway.app/api/webhooks/xendit
  3. For high-volume webhook processing, deploy the xendit-webhook.js function separately using Railway Functions with Hono

Option 2: Docker Deployment

# Build Docker image
docker build -t summit-finance .

# Run with environment variables
docker run -p 3000:3000 \
  -e DATABASE_URL="postgresql://..." \
  -e NEXTAUTH_SECRET="..." \
  summit-finance

Official image available: kugieapp/summit

Option 3: Self-Hosted (VPS/Cloud)

  1. Setup PostgreSQL and create database
  2. Setup MinIO or configure S3 bucket
  3. Deploy application:
    git clone https://github.com/kugie-app/summit.git
    cd summit
    npm install
    npm run build
    
  4. Run with PM2 (recommended for production):
    npm install -g pm2
    pm2 start npm --name "summit" -- start
    

Webhook Configuration

For Xendit payment processing, configure these webhook endpoints in your Xendit dashboard:

  • Invoice Paid: https://your-domain.com/api/webhooks/xendit
  • Payment Method: POST requests with proper XENDIT_WEBHOOK_SECRET validation

The webhook handler automatically updates invoice statuses from sent to paid and creates corresponding income records.

Troubleshooting

Database Connection Issues

Error: connection refused or database does not exist

  • Verify DATABASE_URL format: postgresql://user:password@host:port/database
  • Ensure PostgreSQL is running and accessible
  • Check firewall rules for port 5432

Migration Failures

Error: relation already exists or column does not exist

  • Reset database (development only): npm run db:drop && npm run db:migrate
  • For production, create specific migration files: npm run db:generate

Authentication Errors

Error: JWT must be provided or session errors

  • Verify NEXTAUTH_SECRET is set and at least 32 characters
  • Ensure NEXTAUTH_URL matches your actual domain (including protocol)
  • Check that cookies are being set properly (no restrictive SameSite issues)

File Upload Failures

Error: Failed to upload receipt or 403 errors

  • Verify MinIO/S3 credentials have s3:PutObject and s3:GetObject permissions
  • Check STORAGE_BUCKET_NAME exists and is accessible
  • Ensure STORAGE_ENDPOINT does not include protocol (e.g., use s3.amazonaws.com not https://s3.amazonaws.com)

Email Not Sending

  • Verify Resend API key has proper domain verification
  • Check EMAIL_FROM matches verified domain in Resend
  • Review spam folders; configure SPF/DKIM records for production domains

Recurring Transactions Not Processing

Recurring invoices/expenses require a cron job to hit the processing endpoint:

# Add to crontab (runs daily at midnight)
0 0 * * * curl -X POST https://your-domain.com/api/cron/process-recurring \
  -H "Authorization: Bearer ${CRON_SECRET_KEY}"

Set CRON_SECRET_KEY environment variable to secure this endpoint.

Client Portal Access Issues

  • Client portal uses magic links sent via email; ensure Resend is configured
  • Links expire after 24 hours; check NEXT_PUBLIC_APP_URL is correctly set for magic link generation