A modern Point of Sale (POS) system built with Next.js, Supabase, and PostgreSQL.
- Frontend/Backend: Next.js 16 with App Router
- Database: PostgreSQL (via Supabase)
- ORM: Prisma
- Authentication & Storage: Supabase
- Styling: Tailwind CSS
- Language: TypeScript
├── app/ # Next.js app router pages and layouts
├── lib/ # Utility libraries and configurations
│ ├── prisma.ts # Prisma client singleton
│ └── supabase.ts # Supabase client configuration
├── prisma/
│ └── schema.prisma # Database schema and models
└── public/ # Static assets
- Node.js 18+ installed
- A Supabase account and project
- npm or yarn package manager
-
Clone the repository (if not already done)
-
Install dependencies:
npm install
-
Set up environment variables:
Create a
.envfile in the root directory with the following variables:# Supabase Configuration NEXT_PUBLIC_SUPABASE_URL=your-supabase-project-url NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key # Database URL (Connection Pooling - for queries) DATABASE_URL="postgresql://postgres:[PASSWORD]@[HOST]:6543/postgres?pgbouncer=true" # Direct Database URL (for migrations) DIRECT_URL="postgresql://postgres:[PASSWORD]@[HOST]:5432/postgres"
How to get these values from Supabase:
- Go to your Supabase project dashboard
- Navigate to Settings → API
- Copy the Project URL to
NEXT_PUBLIC_SUPABASE_URL - Copy the anon/public key to
NEXT_PUBLIC_SUPABASE_ANON_KEY - Navigate to Settings → Database
- Find the Connection Pooling section for
DATABASE_URL(port 6543) - Find the Connection String section for
DIRECT_URL(port 5432)
-
Generate Prisma Client:
npx prisma generate
Run the development server:
npm run devOpen http://localhost:3000 in your browser.
When you define your database schema in prisma/schema.prisma, create a migration:
npx prisma migrate dev --name your_migration_nameThis will:
- Create SQL migration files
- Apply the migration to your database
- Regenerate Prisma Client
To view and edit your database data visually:
npx prisma studioTo reset your database (
npx prisma migrate resetImport the Prisma client in your files:
import prisma from '@/lib/prisma'
// Example: Query data
const users = await prisma.user.findMany()
// Example: Create data
const newUser = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john@example.com'
}
})Import the Supabase client:
import { supabase } from '@/lib/supabase'
// Example: Query data
const { data, error } = await supabase
.from('your_table')
.select('*')
// Example: Upload file
const { data, error } = await supabase.storage
.from('bucket-name')
.upload('file-path', file)- Define your database schema in
prisma/schema.prisma - Create your first migration:
npx prisma migrate dev --name init - Build your POS features (products, sales, inventory, etc.)
- Set up authentication with Supabase Auth
- The
DATABASE_URLuses connection pooling (port 6543) for optimal performance with serverless functions - The
DIRECT_URLuses a direct connection (port 5432) required for running migrations - Prisma client is configured as a singleton to prevent connection pool exhaustion
- All environment variables are validated on application start
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLint