LiveSaaS · Payroll & HR · Accounting offices
ZEUS Finance
Payroll and HR software for small, medium and large businesses and groups in Cyprus and Greece, and for the accounting offices and accountants who run their payroll. Built from an empty repository and running in production.
- Who uses it
- Small businesses (up to 50 employees), medium businesses (up to 800), large businesses and groups of companies (800+), and accounting offices and accountants running payroll for their clients.
- Built with
- Next.js16.3.8
- React19.2.8
- TypeScript6.0.3
- PostgreSQL16
- Prisma7.10.0
- Zod4.6.5
- Tailwind CSS4.3.3
- decimal.js10.6.0
- Argon2id2.2.1
- WebAuthn13.3.3
- pdf-lib1.17.1
- Recharts3.10.1
- Nodemailer10.0.10
- Vercel Blob2.8.0
- Vitest5.0.2
- Playwright1.63.0
- Vercel
- GitHub Actions
- lines of code
- 294,737lines of code
- automated tests
- 1,579automated tests
- database models
- 130database models
- scheduled jobs
- 22scheduled jobs
Screens
One Next.js application and one PostgreSQL database. Hours and days go in once; contributions, tax, payslips, the SEPA file for the bank, leave balances and the official files for each country come out of the same system.
01The problem
Employers in Cyprus and Greece need payroll that is right to the cent and produces the official files each authority asks for, not just a payslip. Accounting offices need every client's month in one place. Both handle the most sensitive data a company has, so the system has to be correct and safe by default.
02What I built
I designed and built ZEUS Finance from an empty repository. It is a Next.js 16 and TypeScript application on PostgreSQL 16 with Prisma 7, deployed on Vercel in Frankfurt.
Payroll follows each country's own rules and official rates. In Cyprus: Social Insurance, GESY, the Social Cohesion, Redundancy and holiday funds, HRDA, the 13th and 14th salary, and the files for SISnet, the monthly PAYE return (TF7) and the annual IR7 for Tax For All. In Greece: e-EFKA contributions, income tax, the Christmas and Easter bonuses and holiday allowance, the monthly ΑΠΔ file and the staff list for ERGANI.
Around payroll sits the HR side: employees and personnel files, documents that expire, leave in days or hours, overtime with gross and net per kind, advances, departments and managers, attendance, announcements, employee accounts, and a team with roles and approvals. Payslips carry the company's logo and go out by email; a SEPA file pays everyone at once.
Packages scale from one company with a few employees to groups of up to 50 companies and 2,000 employees, with custom terms above that. Accounting offices get their own workspace: every client's month on one page, checks before approval and all the files in one ZIP. Accountants are verified against the AADE and ΓΕΜΗ registries in Greece and the ICPAC registers in Cyprus.
Payments run through Worldline (wallee): the checkout, renewal and payment links, refunds, payments on hold and chargebacks, with invoices, credit notes and EU VAT numbers checked live against VIES. The interface is in English and Greek.
03Approach
Every figure comes from what the company entered or imported, or is calculated from it. Nothing is guessed: if the data cannot answer something an official file needs, the file stops and says why. Security is enforced in three places: identity comes only from the session, every service checks roles, permissions and package limits, and the database itself refuses to link one company's data to another's.
04Everything it does
Small businesses
Up to 50 employees
Medium businesses
Up to 800 employees
Large businesses and groups
800+ employees, up to 50 companies
Accounting offices and accountants
Every client's payroll in one place
Payroll for Cyprus and Greece
- Contributions, tax and net pay with each country's official rates, checked every day against the government sources.
- Cyprus: Social Insurance, GESY, Social Cohesion and Redundancy funds, HRDA, provident and holiday funds, the 13th salary.
- Greece: e-EFKA contributions with the year's ceiling, income tax with children and the under-30 rules, Christmas and Easter bonuses, leave allowance.
- Monthly and daily-paid staff, overtime per kind with gross and net, advances repaid in instalments, final settlement for leavers.
- Checks before approval: missing IBAN or tax number, pay below the minimum wage, a big change from last month, expired documents.
- Payslips with the company's logo in Greek or English, sent by e-mail, and one SEPA file to pay everyone at once.
Shift rota and attendance
- A weekly rota for salaried, daily-paid and temporary staff, with shift types, colours and quick fill.
- Working-time rules checked on every shift: 11 hours of rest, 48 hours a week, six days in a row, holidays and contract ends.
- Leave over shifts: before approving, the manager picks which free colleague covers each shift.
- The payroll pays the rota: daily-paid days and Sunday or holiday premiums come straight from the shifts.
- Employees see only the published rota, on their page and by e-mail; attendance by clock or entry.
People and HR
- Personnel files with every document, its issue and expiry date, and reminders before ID, residence or work permits expire.
- Leave in days or hours with balances, a team calendar and one-click approval.
- Departments and managers, announcements to the company or chosen departments with read receipts.
- Employee expenses repaid through payroll, equipment, joining and leaving checklists, training and certificates.
- People-only companies: keep HR, shifts and leave in ZEUS Finance while payroll stays in another program.
Employee self-service and requests
- Each company chooses what employees can do: view only, or ask for leave, changes, forms and expenses with approval.
- Employment certificates, income confirmations and earnings statements issued with a QR code anyone can verify.
- Every request reaches the right manager by e-mail, and in the app for whoever switches it on.
Official files for the accountant
- Cyprus: the monthly SISnet file, the Tax For All PAYE return and the annual IR7, as XML checked against each portal's schema.
- Greece: the monthly ΑΠΔ for e-EFKA's portal, the supplementary ΑΠΔ and the ERGANI staff list.
- Year-end earnings certificates, the month's accounting entry and a yearly report, with Excel downloads in Greek and English.
- Deadlines for contributions, tax and bonuses with the official source and a reminder a week before.
- The files are prepared for the accountant to check and submit; nothing is sent to the authorities automatically.
Accounting offices
- An accountant's desk with every client company in one list, the month's checks and all the files in one ZIP.
- Month-end close per client, and clients who send their changes from their own page.
- Packages for accounting offices, with accountants verified against the AADE and ΓΕΜΗ registries in Greece and the ICPAC registers in Cyprus.
Team, roles and approvals
- Roles for accountant, HR Manager, HR and department managers, each seeing only what concerns them.
- Second-person approval for salary changes, payslip edits and deletions, with a full change history.
- Several companies per account, from one company up to groups of 50 companies and 2,000 employees.
Getting started
- A public demo with two complete sample companies, no sign-up needed.
- Moving from another payroll program with CSV or JSON, checked first without saving anything.
- A free employer cost calculator and the full payroll calculation rules, published with their sources.
- A written proposal for each business with a page of its own: accepted online, the date, time and name kept on record, then paid by card.
- A new customer's account and package opened in four steps, kept as a draft while it is typed, with the VAT number checked in VIES (without VAT, by reverse charge, for businesses elsewhere in the EU), paid by card link or by bank transfer, with the invoice issued once the payment is in.
- Signing up asks who is signing up, a business or an accounting office, and starts each in the right place; a short welcome then asks the size and offers a call to set up the payroll, which reaches the team at once as a request.
- Renewals by payment link, without VAT by reverse charge for businesses elsewhere in the EU whose VAT number VIES confirms when the link is sent.
Security and reliability
- Passkeys, authenticator apps and e-mailed codes; companies can require a second step before payroll opens.
- A security control centre: lockout, session limits, admin work only with a passkey or an authenticator app, the networks and countries it may come from, new-device e-mails and emergency sign-outs, all changed without a release.
- Ranked administration: no administrator deletes accounts or changes another person's sign-in, no super administrator acts on another, and the founder's account is guarded by the database itself.
- New passwords checked against known data breaches, sending only five characters of their hash.
- IBANs, tax and social insurance numbers and personnel files encrypted at rest with AES-256-GCM.
- The database itself refuses to link one company's data to another's, and the audit log cannot be edited.
- Servers in the EU (Frankfurt), no ads and no selling of data.
- A continuous check every 10 minutes while the platform is in use, and a full check after every release.
- An “I'm not a robot” check (Google reCAPTCHA) on every public form, from sign-up and sign-in to contact and the newsletter, verified again on the server.
- Card payments through Worldline (wallee) for the checkout, renewal links, Custom offers, accepted proposals and new customers' links: a payment counts only when Worldline's own API confirms it for exactly what was sold, and signed webhooks are verified.
- Refunds, payments on hold and chargebacks from the admin: all of a payment or part of it back to the card through Worldline with a credit note, a customer's packages frozen at once for suspected fraud or a chargeback Worldline reports, then released, ended or refunded by the administrator.
- Another Worldline account, or a new key, from the admin without a release: keys tried on Worldline before they are saved and stored encrypted, while every earlier payment keeps being read and refunded through the account it was made in.
- A customer who has not confirmed their e-mail can do nothing until they do, on the web and in the phone app; two automatic reminders with a new link follow, on the 2nd and the 7th day, then none, and the administrator can send one from the customer's card.
- Every e-mail to a customer opens from their history as they received it, with one-time codes and sign-in links hidden and the copy kept encrypted; all of them are listed on one admin page, next to every e-mail template as it looks.
- A wrong invoice is cancelled the lawful way: a credit note for its whole amount, no money moving, its number kept for good and a corrected invoice under the next one.
- A weekly backup restore test: the database's own backup is restored into a separate copy, compared table by table with the live database and deleted, with the result in the admin's diagnostics.
05Recently shipped
- Companies of thousands of employees: a payroll of 4,000 people in seconds and complete rotas, tested with millions of rows
- Sent e-mails as customers saw them, automatic confirmation reminders, invoice cancellation by credit note and a weekly backup restore test
- Worldline accounts changeable from the admin, e-mail previews in the customer history and confirmed e-mails before anything else
- Refunds through Worldline, payments on hold and chargebacks, all from the admin
- Every payment and payment link through Worldline (wallee), with signed webhooks read back from Worldline
- Signing up as a business or an accounting office, with a welcome that can book a set-up call
- An “I'm not a robot” check on every public form
- Renewal links without VAT for EU businesses confirmed in VIES
06Architecture
- →Modular monolith: Next.js App Router with Server Components and Server Actions, and a single PostgreSQL 16 database.
- →Strict layers, enforced by ESLint and server-only imports: pure domain logic (contributions, tax, leave, overtime), platform services, application services, then thin pages, actions and REST handlers.
- →The /api/v1 REST API and the web interface call the same services, so validation and permissions cannot drift apart.
- →Amounts are stored as integer cents with a currency; rates use decimal arithmetic. Floating point is banned for money by a lint rule.
- →Official files are built against the authorities' own XML schemas, and CI validates them on every push.
- →Scheduled jobs on Vercel Cron, among them payslip emails, notifications, maintenance and a daily check of the official payroll sources for rate changes.
- →One Prisma schema with versioned migrations. CI fails on any drift between the two.
07The codebase
294,737 lines of code in 1,617 files. A big number says little on its own, so here is how it is counted, how much of it is the product, how it stays maintainable and what the tests check. Every number on this page comes live from zeusfinance.com.cy, counted at its last release on 21 Oct 2026, 07:36.
How are the lines counted?
A script inside ZEUS Finance counts them at every release, from the same files that go live. Only lines that do something count: blank lines and comments do not. Only the website counts: the iPhone app, the libraries it uses, generated code, images and other public files are left out.
- TypeScript200,201 · 67.9%
- TSX (React)69,922 · 23.7%
- JavaScript17,882 · 6.1%
- SQL3,510 · 1.2%
- Prisma schema2,974 · 1.0%
- CSS248 · 0.1%
How much of it is the product itself?
179,438 lines (60.9%) run the product: the server, the screens and the calculations. The rest is the texts in two languages, the tests and the tooling, and the last two never reach the browser.
- Server, data and security85,375 · 29.0%
Services, permissions, the database schema and its migrations, e-mails and files.
- Interface76,812 · 26.1%
Every screen of the app and of the website.
- Calculations and payroll rules17,251 · 5.9%
Contributions, tax, leave, overtime and money, kept apart from the database and the screens.
- Tests47,267 · 16.0%
Never sent to the browser.
- Texts in Greek and English46,874 · 15.9%
Every word of the interface, the in-app guide and the website, in both languages.
- Tooling21,158 · 7.2%
Scripts that make the manuals, presentations and checks. Never sent to the browser.
How easy is it to maintain?
- Small files: half of them are 81 lines or fewer, and 86.3% are 300 lines or fewer.
- Strict TypeScript everywhere, including checked access to arrays and objects.
- Lint with zero warnings allowed, and every file's formatting checked.
- Lint rules keep server code out of anything that runs in the browser, and floating-point numbers away from money.
- 25 production dependencies, each one a deliberate choice.
- About one line of tests for every 5 lines of application code.
- 141 versioned database migrations, checked against the schema for drift.
Are the tests automated, and what do they check?
Yes, all of them. 1,579 test cases in 328 files. The secret scan, the type check and the unit tests run on every push; everything else runs every night when something changed, and by hand before a release with a database change. I run them locally before every commit, too.
Unit tests
600
cases in 113 files
The calculations and rules on their own: contributions, tax, net pay, leave, overtime, dates, money and formats.
Integration tests
930
cases in 181 files
The services on a real PostgreSQL database: permissions, each company's data kept apart, the official XML files against the authorities' schemas, billing and imports.
Browser tests
49
cases in 34 files
Real journeys on the built site: signing up and running a Cypriot payroll to the SEPA file, the public demo, a passkey sign-in, requests, inviting a team member, Greek forms and phone layouts.
What they cover
- Payroll, calculations and official files441 cases · 89 files
- Packages and billing211 cases · 43 files
- Website, demo and both languages193 cases · 50 files
- People, leave, shifts and requests133 cases · 27 files
- Administration and monitoring117 cases · 27 files
- Sign-in, security and permissions112 cases · 20 files
- Companies, accounts and settings97 cases · 19 files
- Connection with the iPhone app91 cases · 12 files
- Accounting offices61 cases · 9 files
- Imports, exports and spreadsheets26 cases · 9 files
- Everything else97 cases · 23 files
- Files
- 1,617
- Database models
- 130
- Migrations
- 141
- Scheduled jobs
- 22
08Stack and versions
| Technology | Used for |
|---|---|
| Next.js16.3.8 | App Router, Server Components and Server Actions |
| React19.2.8 | Interface |
| TypeScript6.0.3 | Strict mode, end to end |
| PostgreSQL16 | Database, with triggers and constraints for isolation |
| Prisma7.10.0 | Schema, migrations and queries |
| Zod4.6.5 | Validation of every input |
| Tailwind CSS4.3.3 | Styling |
| decimal.js10.6.0 | Exact rates; money is kept in integer cents |
| Argon2id2.2.1 | Password hashing |
| WebAuthn13.3.3 | Passkeys |
| pdf-lib1.17.1 | Payslips, certificates and reports as PDF |
| Recharts3.10.1 | Charts |
| Nodemailer10.0.10 | E-mail delivery |
| Vercel Blob2.8.0 | Document storage |
| Vitest5.0.2 | Unit and integration tests on a real PostgreSQL |
| Playwright1.63.0 | End-to-end tests in a browser |
| Vercel | Hosting in Frankfurt, scheduled jobs and deployments |
| GitHub Actions | CI: audit, secret scan, schema and XML checks, every test |
09Integrations
- →Worldline (wallee) for card payments. Webhooks must carry a valid signature, and every payment is read back from Worldline before anything is granted.
- →EU VIES for VAT numbers and intra-EU reverse charge.
- →AADE and ΓΕΜΗ (Greece) and ICPAC registers (Cyprus) to verify accountants.
- →Upload-ready files for SISnet, Tax For All, e-EFKA and ERGANI. ZEUS Finance prepares them; the employer or accountant submits.
- →Cloudflare Turnstile or reCAPTCHA on sign-up, Vercel Blob for files.
10Sign-in and security
- →Argon2id password hashing with transparent re-hashing and a common-password blocklist.
- →Passkeys (Face ID, Touch ID, Windows Hello, security keys), authenticator apps, emailed codes and recovery codes. Companies can require a second step before payroll opens.
- →Session tokens are random and only their SHA-256 is stored. Sessions expire, idle out and are revoked on password change.
- →IBANs, tax and social insurance numbers and personnel files encrypted at rest with AES-256-GCM, each bound to the account that owns it.
- →Composite foreign keys on every owned table: a bug in application code still cannot link one company's data to another's.
- →Strict Content Security Policy with per-request nonces, HSTS preload and origin checks on every mutation.
- →Rate limits stored in PostgreSQL so they hold across all serverless instances.
- →Append-only audit log. Updates and deletes are rejected by database triggers.
11Administration
- →Roles mapped to permissions, checked inside every admin service. Denied attempts are audited.
- →Packages for small, medium and large businesses and for accounting offices, each listing exactly what the app enforces.
- →Offers, refunds, invoices, credit notes and accountant verification from one admin panel.
12Notes
- →Screens on this page come from the public demo at zeusfinance.com.cy/demo, which uses two sample companies with invented data. They are refreshed whenever the product changes and load from zeusfinance.com.cy, so they always show the current version.
- →CI runs a dependency audit, a secret scan, the migration drift check, typecheck, lint, the XML schema checks, and the unit, integration and end-to-end tests against a real PostgreSQL.