Skip to content

halfguru/castor-payroll

Repository files navigation

🍁 Castor — Canadian Federal Payroll System

Castor logo

Tests License: MIT Next.js TypeScript PostgreSQL Tailwind CSS Made with AI Cost

Canada's Phoenix pay system launched in 2016. It burned. By 2018, it had produced 1.2 million pay errors. Public servants went unpaid, were overpaid, or received no pay at all. The total cost to fix it? $2.4 billion and counting.

The solution? The government hired Dayforce (Ceridian) for another $4.2 billion to replace it. The phoenix rises again — at taxpayer expense.

Castor is named after the beaver (Castor canadensis) — Canada's national symbol, and nature's engineer. Beavers don't rise from ashes. They just build things that work.

This is a proof-of-concept federal payroll system, built entirely by agentic AI, demonstrating that you don't need a mythical bird or a $4.2 billion contract to pay people correctly.

Phoenix burned. Dayforce is expensive. The beaver just builds.


The Pitch

Castor is a working demo of the core Canadian federal payroll system — employee self-service, compensation advisor tools, HR actions, manager approvals, collective agreements, retroactive pay, acting appointments, statutory deductions — the whole deal.

It was vibe-coded by AI. Yes, really. Every line. The domain logic, the UI, the database schema, the bilingual translations, the 251 tests — all generated by LLMs following architecture patterns and domain rules.

The point isn't that AI writes perfect code. The point is that the distance between "we need a payroll system" and "here's a working demo" should not be measured in billions of dollars.*


What It Does

Four roles, one system

Role What they see
Employee Pay stubs, tax slips, leave balances, overtime requests, transactions, direct deposit
Compensation Advisor Case management, employee search, audit trail, pay corrections, retroactive pay simulation, acting appointment management
HR Officer Employee management, onboarding, employment changes, leave entry, department transfers
Manager Approval queue, team view, acting appointments

Real payroll math

  • 4 collective agreements (PA, EC, IT, SV) with actual TBS pay scales
  • CRA 2025 statutory deductions: CPP, CPP2, EI, federal/provincial income tax, pension
  • Retroactive pay engine — the hard problem. Simulate a 2.5% increase across 50,000 PA employees, see the cost, then execute with full audit trail
  • Acting pay differentials, overtime (including IT's 1.5x/2.0x two-tier), bilingual bonus, LIA agreements
  • Money value object — bigint cents, zero floating-point. Because this is payroll, not a tip calculator.

Bilingual

Every string, English and French. Language toggle on every page. Because Gouvernement du Canada.


Tech Stack

Layer Choice Why
Framework Next.js 16 + App Router Server components, server actions, file-based routing
Database PostgreSQL + Drizzle ORM Type-safe queries, migrations, zero magic
UI shadcn/ui + Tailwind v4 GC-inspired design system, accessible out of the box
Testing Vitest 251 tests. They pass.
i18n next-intl Proper bilingual, not bolted on
Auth Better Auth (mock) Role picker for demo purposes
Money Custom Money class (bigint cents) Never use number for currency. Ever.

Architecture

src/
  domain/              <- Pure TypeScript. Zero framework deps. Fully testable.
    agreements/          Collective agreement strategies (PA, EC, IT, SV)
    pay/                 Entitlement, deduction, retroactive, acting, LIA calculators
    models/              Employee, Assignment, PayStatement, PayCorrection...
    shared/              Money value object, domain types
  infrastructure/      <- Drizzle, PostgreSQL, repositories
    db/
      schema.ts          16 tables
      seed/               500+ employees, pay periods, cases, approvals
    repositories/
  application/         <- Use-case orchestration
    pay-run-service.ts
    overtime-integration-service.ts
  app/                 <- Next.js App Router (thin server actions, client components)
    (employee)/
    (advisor)/
    (hr)/
    (manager)/

Hexagonal architecture. Domain layer has no idea Next.js exists. Swap the framework tomorrow and the pay calculation engine doesn't change.


Getting Started

# Start PostgreSQL
docker compose up -d

# Install dependencies
npm install

# Push schema to database
npm run db:push

# Seed with 500+ employees
npm run db:seed

# Start dev server
npm run dev

Open http://localhost:3000. Pick an employee. Pick a role. Go wild.


The Numbers

Metric Value
Lines of code ~15,800
Test files 19
Tests passing 251
Database tables 16
Collective agreements 4 (PA, EC, IT, SV)
App routes 30
Server actions 33
Bilingual messages 750+ lines (EN + FR)
Seed employees 500+
Cost to build ~$0 in API calls
What Canada paid for Phoenix $2,400,000,000
What Canada is paying for Dayforce $4,200,000,000

Commands

npm run dev          # Start dev server
npm run build        # Production build
npm run test         # Run tests
npm run test:watch   # Run tests in watch mode
npm run lint         # ESLint
npm run db:push      # Push schema to database
npm run db:seed      # Seed with sample data
npm run db:studio    # Drizzle Studio (browse DB)

Caveats (aka the honest fine print)

  • This is a proof of concept, not production software
  • Auth is mocked — there's a role picker, not SAML/2FA
  • Tax calculations follow CRA 2025 formulas but aren't CRA-certified
  • 500 seed employees, not 280,000
  • No, the AI didn't do this alone — a human architect directed every phase
  • Yes, a real system needs security audits, load testing, accessibility certification, change management, training...

But also: none of that costs $6.6 billion.


License

MIT


About

Proof-of-concept Canadian federal payroll system — demonstrating agentic AI can build this for ~$0 vs $4.2B Dayforce

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages