Skip to content

pathorsAI/internal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pathors Internal

License: Apache 2.0 Next.js 16 Postgres better-auth PRs welcome

Pathors Internal

Self-hosted internal accounting (內外帳) & client-finance management for small companies.
One deployment serves many organizations, with data isolated per organization_id.

What it is — an internal accounting system for small companies that keep both internal and external books (內外帳), with built-in management of client income & expenses (projects, subscriptions, contracts, receivables). It is not a generic accounting/ERP package — it's the in-house ledger + client-finance tool we run ourselves.

Note — the application UI is in Traditional Chinese (zh-TW); the codebase, docs, and configuration are in English. Built for small Taiwanese companies, but the data model is plain enough for any small team.


Screenshots

Placeholders for now — swap the .svg files in docs/images/ for real (anonymized) screenshots / a GIF later.

Demo flow

Dashboard Transactions (內外帳)
Dashboard Transactions
Reports Members & Organizations
Reports Members

Features

  • Multi-tenancy — powered by the better-auth organization plugin. A single deployment hosts many orgs; every row is scoped by organization_id, with a built-in org switcher and owner/admin roles.
  • Dual books (內外帳) — each transaction carries a book field separating internal vs. external ledgers.
  • Accounting core — transactions, categories, bank accounts, counterparties, reconciliation, and advances/reimbursements.
  • Client finance — track client income & expenses across projects, subscriptions, contracts, and accounts receivable.
  • Payroll — employees, payroll item types, and pay runs.
  • Reports — aggregated income/expense and receivables views.
  • Documents — file uploads to object storage (e.g. receipts attached to transactions).
  • Auth — Google OAuth via better-auth; invite-based member management; org settings (rename / delete).

Tech stack

Layer Choice
Frontend Next.js 16 (App Router), React 19, Tailwind CSS v4, shadcn/ui + Base UI
Backend Next.js Route Handlers / Server Actions, better-auth
Database Postgres + Drizzle ORM (introspect-only schema, plain-SQL migrations)
Tooling Bun

Nothing here is tied to a specific host or cloud — it's a standard Next.js + Postgres app. Where we happen to run it is just one option; see Deployment.


Quick start

Prerequisites: Bun, a Postgres database, and Google OAuth credentials.

# 1. Install
bun install

# 2. Configure
cp .env.example .env.local      # fill in DATABASE_URL, BETTER_AUTH_SECRET, Google OAuth…

# 3. Run
bun dev                          # http://localhost:3000

Generate BETTER_AUTH_SECRET with openssl rand -base64 32. For Google OAuth, create a "Web application" OAuth client and add http://localhost:3000/api/auth/callback/google as an authorized redirect URI (add your production URL before deploying).

The first user to sign in lands on /onboarding. To make someone the owner of an existing organization, edit v_email in scripts/bootstrap-owner.sql and run it against your database.

Configuration

Variable Purpose
DATABASE_URL Postgres connection string (pooled)
BETTER_AUTH_SECRET Session signing secret (openssl rand -base64 32)
BETTER_AUTH_URL App base URL, no trailing slash
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET Google OAuth credentials

See .env.example for the full template.


Database

This app uses Postgres through Drizzle ORM. Everything under migrations/ is plain forward-only SQL, and src/db/schema.ts is introspected from the database (bun run db:pull) — the app never pushes schema. There is no vendor-specific SQL, so any Postgres works.

The Drizzle client lives in src/db/index.ts — point DATABASE_URL at your database and you're set. Which Postgres driver to use is the only runtime-dependent choice (a TCP driver like node-postgres on a normal server; an HTTP driver if you run somewhere that can't open TCP). That single swap is covered in the deployment guide.

How you evolve schema, branch your database, or roll out migrations is up to your own workflow — this project does not prescribe one.

Deployment

Build it (bun run build) and run it like any other Next.js app, anywhere that can serve Next.js and reach a Postgres database. The repo prescribes no host.

The deployment guide walks through two concrete setups as examples — a Docker self-host (vendor-neutral Node + Postgres, with a Dockerfile and docker-compose.yml), and the serverless setup we happen to run — but neither is a requirement.


Project structure

src/
  app/            # Next.js App Router (dashboard pages, auth routes, onboarding)
  components/     # UI components (shadcn/ui + Base UI) and shared widgets
  db/             # Drizzle client, introspected schema, queries & mutations
  lib/            # auth (better-auth), session helpers, object storage, utils
migrations/       # plain forward-only SQL migrations
scripts/          # one-off operational SQL (e.g. bootstrap-owner)
docs/             # deployment guide + README assets
Dockerfile        # vendor-neutral self-host image
docker-compose.yml

Contributing

Issues and pull requests are welcome — please use GitHub Issues for bugs and feature requests. Note that user-facing strings are Traditional Chinese (zh-TW); please keep new UI copy consistent.

License

Licensed under the Apache License 2.0. You're free to use, modify, and redistribute it, including commercially — just retain the license and copyright notices.

About

Self-hosted internal accounting & client-finance management for small companies. Multi-tenant, Next.js 16 + Drizzle + Postgres.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages