# Sample project primer: the Tally repo, for a new engineer

A fictional result of the Onboard into a project recipe: what Tally is, how the repo is laid out, how to run it, and the three things to read first.

> [!info]
> **Fictional example.** Tally is an invented invoicing app made by an invented team, Fernbrook. This shows the shape of what the *Onboard into a project* recipe produces; the names and details are made up.

## What Tally is

Tally sends invoices for freelancers and small studios, chases late ones with polite reminders, and takes card and bank payments through Stripe. About 2,300 paying accounts. The team is seven people; Sam Okafor leads engineering.

## How the repo is laid out

| Path | What lives there |
| --- | --- |
| app/ | The web app (Next.js): invoices, clients, settings |
| lib/billing/ | Invoice totals, taxes and currencies; the part with the most tests |
| lib/reminders/ | Late-payment reminders, now moving onto the job queue |
| jobs/ | The background worker: reminders, exports, Stripe webhooks |
| db/migrations/ | Postgres schema, numbered; run on every deploy |

## Run it

```sh
pnpm install
pnpm db:up        # Postgres in Docker
pnpm migrate
pnpm dev          # app on :3000
pnpm worker       # background jobs, in a second terminal
```

## Read these three first

1. Decision: retry failed payments three times, then stop
   Explains the payment states you will see everywhere in `lib/billing`.
2. Postmortem: invoice reminders sent twice
   Why reminders are moving to the job queue, and what to be careful of there.
3. Handoff: moving reminders to the job queue
   Where that work stands today. It is the most likely first task.

## What onecell already knew

Twelve documents in the engineering cell, four decisions, and two facts worth knowing on day one: production deploys go out from `main` after review, and the worker must never send an email outside 8am–8pm in the client's time zone.

## Open questions for your first week

- [ ] Why do invoice numbers have their own sequence per account rather than a global one?
- [ ] Who owns the Stripe webhook secret rotation?
