Skip to content

Latest commit

 

History

59 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Consulting realization kernel

CI License Node

Open-source realization kernel for consulting firms: utilization, WIP, contract and milestone billing, partner-level profitability, and PostgreSQL row-level security. Timesheets are an input to realization — not the product. Optional Xero and QuickBooks journal push. See docs/DESIGN-PIVOT.md.

Permit rule: Realization numbers come from approved time, WIP, and contracts — not from a model. Humans operate this kernel. Same instinct: SafetyMP.

Why not Kimai

  • Kimai is a time tracker. Hours, approvals, and timesheets are its product.
  • This repo is realization. WIP, contract/milestone billing, utilization, and partner-level profitability are the product; time entries feed those numbers.
  • Postgres RLS is the tenancy model. Organization isolation is enforced in the database, not only in application middleware.

PSA platform demo — dashboard, invoices, and profitability views

Features

  • Multi-tenant organizations with role-based access (Admin, Manager, Consultant)
  • Clients & projects — tasks, team members, budgets, billing models (T&M, fixed fee, retainer, milestone)
  • Time & expenses — approval workflows, categories, receipt uploads, bulk approval
  • Resources — profiles, allocations, utilization reporting
  • Billing — WIP and contract/progress invoicing, milestone billing, PDF export, journal CSV
  • Accounting — chart of accounts, Xero / QuickBooks OAuth, push journals from invoices
  • Reporting — profitability with contract/milestone columns, expense breakdown by category
  • Row-level security — PostgreSQL RLS enforces organization isolation

Screenshots

Dashboard Invoices Profitability Accounting
Dashboard Invoices Profitability Accounting

Stack

Prerequisites

  • Node.js 22+ (see .nvmrc)
  • Docker (for local Postgres) or an existing PostgreSQL 16 instance
  • npm

Quick start

git clone https://github.com/SafetyMP/Professional-Service-Automation.git
cd Professional-Service-Automation

cp .env.example .env
# Edit .env: set AUTH_SECRET (e.g. openssl rand -base64 32)

docker compose up -d

npm install
npm run db:migrate
npm run db:seed

npm run dev -- -p 3005
# http://localhost:3005

Demo login

Field Value
Organization demo-firm
Admin admin@demo.com / password123
Manager manager@demo.com / password123

Do not use demo credentials in production. Change passwords and rotate AUTH_SECRET before deploying.

Environment variables

See .env.example:

Variable Purpose
DATABASE_URL App database URL (RLS role psa_app)
DIRECT_URL Direct Postgres URL for migrations (postgres superuser)
AUTH_SECRET Session signing secret (required)
AUTH_URL Public app URL (e.g. http://localhost:3005)
XERO_CLIENT_ID / XERO_CLIENT_SECRET Optional — Xero OAuth
QUICKBOOKS_CLIENT_ID / QUICKBOOKS_CLIENT_SECRET Optional — QuickBooks OAuth
QUICKBOOKS_ENV sandbox (default) or production

Local Docker Postgres listens on port 5440 (mapped from container 5432).

Deploy

For production or a one-command demo stack (Postgres + app in Docker):

export AUTH_SECRET="$(openssl rand -base64 32)"
docker compose -f docker-compose.stack.yml up --build -d
# http://localhost:3000 — demo-firm / admin@demo.com / password123

See docs/deploy.md for Railway, Fly.io, manual Node deployment, and the production checklist.

Scripts

Command Description
npm run dev Prisma generate + Next.js dev server
npm run build Production build
npm run lint ESLint
npm run typecheck TypeScript check
npm run test Vitest unit tests
npm run db:migrate Apply Prisma migrations
npm run db:seed Reset and seed demo data
npm run check:boundaries Module import boundary lint
./scripts/verify.sh Full local verification gate
npm run screenshots Capture README screenshots and demo GIF (requires running server)

Project layout

lib/           Domain services (clients, projects, time, billing, …)
src/app/       Next.js App Router pages and API routes
prisma/        Schema, migrations, RLS policies
specs/         Domain rules and product scope
tests/         Unit tests
scripts/       Seed, verify, boundary checks

Domain logic lives in lib/<domain>/service.ts. Cross-domain imports must go through public service files only (enforced by scripts/check-boundaries.ts).

Contributing

Contributions are welcome. See CONTRIBUTING.md for setup, conventions, and the pull request checklist.

Roadmap

Phase 1 (MVP) is implemented. Planned Phase 2 items are listed in specs/product/mvp-scope.md, including accounting integrations, expanded expense UI, and general ledger support.

Release history: CHANGELOG.md.

CI

GitHub Actions on every push and pull request:

Workflow Purpose
CI Lint, typecheck, unit tests, boundaries, Prisma validate, production build, E2E smoke tests
CodeQL Security analysis (weekly + on PR)
Release Publish Docker image to GHCR on release
Screenshots Regenerate README images on release

Dependabot opens weekly PRs for npm, GitHub Actions, and Docker base images.

Local E2E: npm run test:e2e (requires running server + seeded DB on port 3005).

Documentation

Security

See SECURITY.md for reporting vulnerabilities.

License

Apache License 2.0

Releases

Packages

Used by

Contributors

Languages