Give your agent a wallet you control.
Let your agents pay online using one-time-use cards or with machine payment protocols. You approve every request.
Replace spreadsheets with integrated bookkeeping. Built for UK service firms and neurodiverse founders — with display and focus controls. Free 30-day trial.
FinanceGitHub @wrightlOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Alfa is accounting software for UK limited companies and sole traders, built by Dot and Dash Consulting Ltd (stylised Dot + Dash Consulting). Replaces spreadsheets and shared folders with one app for quotes, orders, invoicing, expenses, reimbursements, bank reconciliation, and reporting.
Production: alfa.dotanddashconsulting.com
Each organisation is a tenant (one legal entity). Founders belong to one company; accountants can be invited to many and switch between them. New users sign up with Google, then complete onboarding (limited company or sole trader) before they can open the books.
Status: Day-to-day accounting is in the app — including quote PDF/email with client accept links, orders with payment milestones, recurring invoices, inbound expense email, and receipt OCR. Bank import supports major UK banks via CSV (no live feed). Books are GBP only. VAT rates and accountant export are available when registered; there is no HMRC/MTD submit. See What’s next.
| Concern | Choice |
|---|---|
| Framework | Next.js 16 (App Router, RSC, Server Actions), React 19, TypeScript |
| Styling | Tailwind CSS v4, brand-themed design tokens |
| Auth & roles | Clerk (identity + Google SSO); roles in Postgres, not Clerk metadata |
| Database | Neon Postgres + Drizzle ORM (PGlite for tests) |
| File storage | Vercel Blob (private, streamed via authorised routes) |
Pluggable provider (Resend); console in dev (rejected in production) | |
| AI / OCR | Local Tesseract, or Vercel AI Gateway (optional) |
| Testing | Vitest (unit + integration), Playwright (e2e) |
| Hosting/CI | Vercel (merge to main + PR previews) + GitHub Actions |
Sales
{prefix}-{year}-{seq} (configurable per company).Expenses
alfa.expenses+{companySlug}.{userSlug}@inbound.dotanddashconsulting.com.
Forward a receipt; the app creates a pending expense for that person and company.Banking & money out
Reporting & admin
⌘K / Ctrl+K) for navigation.Clerk is identity only. Role and company come from Postgres
(users + company_memberships). First sign-in creates a local user as
pending unless the email is in the bootstrap lists.
| Role | Access |
|---|---|
| admin | Full access, including users and settings. |
| user | Co-founder: day-to-day accounting, reports, and export. |
| accountant | Filing pages + export only. May belong to multiple companies. |
| pending | Signed in, no books access. Assigned from Dashboard → Users. |
Self-serve onboarding creates a company and makes that user admin. Invited
users skip onboarding and attach to the inviting company. Platform operators
are provisioned by install-time data migrations (src/db/data-migrations/) on
npm run db:migrate / Vercel build, then invited from Platform → Users
(not a company role).
npm install
cp .env.example .env.local # fill in when integrations are ready
npm run dev # http://localhost:3001
The app runs without credentials: public pages work, and auth/DB activate once their env vars are present (see Configuration).
When DATABASE_URL is set, apply schema and install-time data migrations:
npm run db:migrate # schema + data migrations (e.g. bootstrap platform admin)
The first platform operator is created by data migration 0001_platform_admin
([email protected], role platform_admin, no company) and
invited via Clerk when CLERK_SECRET_KEY is set. Operators use /platform only —
they never join a tenant. Later operators are invited from the portal UI.
| Command | Description |
|---|---|
npm run dev | Next.js dev server on port 3001 |
npm run build | Migrate (schema + data, if a database URL is set) then production build |
npm run start | Next.js production server |
npm run lint | ESLint |
npm run typecheck | TypeScript, no emit |
npm test | Vitest unit + integration (PGlite) |
npm run test:watch | Vitest watch mode |
npm run test:e2e | Playwright e2e (own server on port 3100) |
npm run db:generate | Generate a Drizzle migration from the schema |
npm run db:migrate | Apply schema migrations then install-time data migrations over a direct Postgres connection (pg) |
npm run auth:agent | Mint a one-time Clerk sign-in URL for a local tenant founder (Cursor agent browser). Development keys only. |
npm run db:push | Unsafe while Drizzle meta snapshots lag behind hand migrations (after 0010). Prefer db:generate + db:migrate. Do not point at Neon production. |
npm run db:studio | Drizzle Studio |
npm run tunnel | ngrok to port 3001 (inbound webhooks in local dev) |
npm run promo:all | Seed demo data, record UI, assemble the promo video |
Promo video notes: docs/promo-video.md.
Environment variables are documented in .env.example and
validated lazily in src/env.ts so public pages and tests can
run before every secret is set.
Feature flags derive from presence:
BLOB_READ_WRITE_TOKEN — Vercel Blob in production (required). Dev/test
fall back to in-memory storage.EMAIL_PROVIDER — console (default) or resend.AI_GATEWAY_API_KEY — required only when Settings uses the ai_gateway
receipt OCR provider.CRON_SECRET — required; /api/cron/* returns 503 until it matches.Clerk paths in .env.example: sign-in /sign-in, sign-up /sign-up, after
sign-in /dashboard, after sign-up /onboarding.
On Vercel, Neon, Clerk, and Blob integrations inject the core secrets. Full
provisioning (SSO, Resend inbound MX, custom domain, DNS):
docs/SETUP.md.
Vercel Hobby only allows cron jobs once per day, so scheduling is split:
Vercel Cron (vercel.json) — daily at 07:00 UTC, Authorization: Bearer $CRON_SECRET:
| Path | Schedule | Purpose |
|---|---|---|
/api/cron/daily | 07:00 daily | Recurring invoice generation + overdue reminders |
Manual triggers (same auth) still available: /api/cron/reminders,
/api/cron/recurring, /api/cron/inbound-email.
GitHub Actions (.github/workflows/cron-inbound-email.yml) — every 15 minutes:
| Path | Purpose |
|---|---|
/api/cron/inbound-email | Retry stuck/failed inbound expense jobs |
Requires GitHub Actions secrets CRON_SECRET and APP_URL (production base URL,
no trailing slash).
Inbound receipt email is primarily handled by the Resend webhook
(/api/webhooks/resend), which also opportunistically drains a few pending jobs;
the scheduled Action is the drain/retry when no new mail arrives.
src/lib/money.ts). Books are GBP.Europe/London (src/lib/dates.ts), not UTC, so overdue and
financial-year windows do not flip a day early.requirePermission in src/lib/auth.ts). The client is never
trusted. Queries take companyId from the session tenant.src/db/schema.ts. Schema + install-time
data migrations run on Vercel build via scripts/migrate-on-build.mjs when a
database URL is set (src/db/data-migrations/).src/proxy.ts (Next.js 16
proxy = former middleware). Auth is enforced in pages, layouts, route
handlers, and server actions (requirePermission in src/lib/auth.ts).
Fine-grained RBAC: src/lib/roles.ts.tests/integration/tenant-isolation.test.ts).next.config.ts.npm test # unit + integration (in-memory PGlite)
npm run test:e2e # Playwright against a production build
GitHub Actions (.github/workflows/ci.yml) runs lint, typecheck, Vitest,
next build, and Playwright on every push to main and on pull requests.
| Area | State |
|---|---|
| Live bank feed | CSV import for major UK banks; Open Banking / live feed later |
| VAT / Making Tax Digital | Rates + period summary/export when registered; no HMRC submission |
| Multi-currency books | GBP only; foreign receipt currency is informational |
Public /pricing | Live — Trial / Essentials (£19) / Premium (£29); Checkout from Settings → Billing |
| Subscriptions / billing | Live — Stripe Checkout + Portal, entitlements, platform complimentary / tiers / metrics, lifecycle emails |
The original phased plan (invoicing → expenses → reimbursements → bank →
reports → quotes/cron) is in docs/plan.md. Treat unfinished
items there as follow-ups, not unstarted work.
Competitor landscape (Sep 2026): docs/competitor-research.md.
Roadmap for gaps, billing, and public pricing: docs/plans/gaps-subscriptions-pricing.md.