# Updating to a new version

This is the "how do I get the newer version" procedure. If you're setting
the app up for the first time, see [GETTING-STARTED.md](GETTING-STARTED.md)
instead — this document assumes you already have a working install.

**The single most important fact on this page, up front, because it's the
first thing anyone worries about:** your actual books — every account,
transaction, and balance — live in the Postgres database, in
`%LOCALAPPDATA%\BalancedSum\data\`, **not** inside this application folder.
That location was chosen precisely so that this page could say what it says:
unzipping a new version over the top of the old one physically cannot reach
your books, because they aren't in that folder and never were. Deleting,
replacing, or even completely destroying the application folder does **not**
touch your data. Updating the app is *never* the risky operation your books
are exposed to; the steps below are about not losing a couple of much
smaller, easy-to-overlook files that happen to sit next to the code.

**Be honest with yourself about what's where before you start.** The
application folder (wherever you cloned or unzipped this repo) contains
things that are yours and must survive an update: your `imports/` folder
(QuickBooks/ADP files you've uploaded), your `reports/` folder (generated
report output), and a `.env` file **if** you have one — most people don't,
because nothing needs configuring. It's tempting to assume those live
somewhere safely "outside" the app, the way your backups do — they don't.
They're inside the same folder as the application code, so a careless update
can delete them right along with the old code if you're not deliberate about
it.

What genuinely IS outside the application folder, and therefore safe no
matter how you update:

- **Your books themselves** — they live in the Postgres database, in
  `%LOCALAPPDATA%\BalancedSum\data\` (on a normal Windows account,
  `C:\Users\<your name>\AppData\Local\BalancedSum\data\`), completely
  untouched by anything you do to the application folder. The copy of
  PostgreSQL itself sits beside them in the same place, so a new version
  doesn't re-download it either. This is true whether you update
  side-by-side, update in place, or even delete the application folder
  entirely and re-clone it from scratch — the database, and therefore your
  books, survives every one of those.
- **Backups** — written to `Documents\Accounting Backups` by default (or
  wherever `BACKUP_DIR` points), never inside the app folder.

Updating never touches either of those. What it changes is the application
*code* — and the things living alongside that code that aren't code:
`imports/`, `reports/`, and `.env` if you have one.

---

## Read this first if you are coming from version 1.0.0

**Only version 1.0.0 is affected. If you are already on 2.0.0 or later, skip
this section entirely.**

Version 1.0.0 kept your books in a PostgreSQL that ran inside Docker Desktop.
Version 2.0.0 installs and runs its own PostgreSQL and does not use Docker at
all. Which of the two you end up talking to depends on one file:

**If your application folder has a `.env` file** — you made one during setup,
and it names a database — nothing changes. That setting still wins over
everything else, so 2.0.0 keeps using the exact database you have been using,
Docker and all. Update normally; the rest of this page applies unchanged.
Nothing here is urgent. Move your books across whenever you feel like it, using
the steps below, and only then stop Docker.

**If you do NOT have a `.env` file** — and most people setting up 1.0.0 never
made one, because nothing required it — then 2.0.0 has no way to know your old
database exists. It will create a new, empty one and open on an empty set of
books.

**Your books are not gone.** They are exactly where they were: in Docker's
volume, untouched, and the old version still opens them. Nothing about
installing 2.0.0 modifies, moves, or deletes them. What follows moves them
across.

### Moving your books from the Docker database into the new one

Do this with the app closed. Docker Desktop needs to be running for the first
command and can be uninstalled after the last one.

1. **Copy the old database out**, into your backups folder so it is a file you
   keep rather than a temporary thing:

   ```powershell
   mkdir "$env:USERPROFILE\Documents\Accounting Backups" -Force
   docker exec accounting-db pg_dump -U postgres -d accounting --clean --if-exists |
     Set-Content "$env:USERPROFILE\Documents\Accounting Backups\from-docker.sql" -Encoding utf8
   ```

2. **Run `npm run app` once and close it again.** This is what creates the new
   PostgreSQL, the new empty `accounting` database, and the `app` role that the
   file from step 1 expects to exist. Skipping this makes step 4 fail with
   errors about a missing role.

3. **Point PowerShell at the new database.** These three lines just save you
   typing; they last until you close the window.

   ```powershell
   $bs   = "$env:LOCALAPPDATA\BalancedSum"
   $pgbin = (Get-ChildItem "$bs\runtime" -Directory | Select-Object -First 1).FullName + "\bin"
   $env:PGPASSWORD = (Get-Content "$bs\secret" -Raw).Trim()
   ```

4. **Load it in.** `-v ON_ERROR_STOP=1` matters: without it psql shrugs off
   errors and leaves you with a half-loaded set of books that looks fine.

   ```powershell
   & "$pgbin\psql.exe" -h 127.0.0.1 -p 54329 -U postgres -d accounting -v ON_ERROR_STOP=1 -f "$env:USERPROFILE\Documents\Accounting Backups\from-docker.sql"
   ```

5. **Check it before you trust it.** This prints your companies and asks the
   ledger whether it still balances. Every company must show `0.0000`.

   ```powershell
   & "$pgbin\psql.exe" -h 127.0.0.1 -p 54329 -U postgres -d accounting -c "select c.name, ledger_out_of_balance(c.id) from companies c order by c.name;"
   ```

6. Start the app normally and confirm your companies and totals look right.
   **Only then** uninstall Docker Desktop. There is no hurry, and keeping it
   for a week costs nothing.

If step 4 or step 5 goes wrong, nothing is lost: the Docker database is still
untouched, and [RESTORE.md](RESTORE.md) covers restoring from a backup file in
more detail.

---

## Before you start

1. **Close the app.** Click into the PowerShell window running `npm run app`
   and press **Ctrl+C**. Updating while the server is running risks a
   half-copied set of files being served mid-update.

2. **Back up now, even though one already runs automatically.** The app
   takes a backup once a day on its own, but "once a day" might mean "12
   hours ago" relative to right now — updating is exactly the moment to want
   a backup from *this second*, not this morning. If the app is still open,
   go to **Settings → Back up now** before closing it (step 1). If you've
   already closed it, reopen it, back up, then close it again.

---

## Updating (recommended: side-by-side folders)

This is the safer of the two methods below because your old, working
install stays completely untouched until you've confirmed the new one
actually works.

1. **Download and unzip the new version *next to* the old folder** — not
   inside it, not on top of it. For example, if your current install is at:

   ```
   C:\Users\you\balanced-sum\
   ```

   unzip the new version to a sibling folder named for its version, e.g.:

   ```
   C:\Users\you\balanced-sum-1.1.0\
   ```

2. **Copy your data files from the old folder into the new one:**

   ```powershell
   Copy-Item "C:\Users\you\balanced-sum\.env" "C:\Users\you\balanced-sum-1.1.0\.env"
   Copy-Item "C:\Users\you\balanced-sum\imports" "C:\Users\you\balanced-sum-1.1.0\imports" -Recurse
   Copy-Item "C:\Users\you\balanced-sum\reports" "C:\Users\you\balanced-sum-1.1.0\reports" -Recurse
   ```

   (Adjust the paths to match your actual folder names. Skip the `reports`
   line if you've never generated any — it's fine if that folder doesn't
   exist yet. Skip the `.env` line if you never made one; most installs
   don't have one, and its absence is normal, not a problem. If you believe
   you have one but can't see it, make sure Windows Explorer isn't hiding it
   — it's a real file, just one that starts with a dot.)

3. **From inside the new folder**, install dependencies and start the app:

   ```powershell
   cd C:\Users\you\balanced-sum-1.1.0
   npm install
   npm run app
   ```

   `npm install` pulls in whatever changed between versions. `npm run app`
   applies any new database migrations automatically (migrations are
   forward-only and non-destructive — see `CLAUDE.md` — so this step is
   safe to let run without supervision) and starts the server as usual.

4. **Confirm it looks right.** Open the dashboard, check that your
   companies, balances, and recent activity all look the way you left them.
   Both folders read the same database — the one in
   `%LOCALAPPDATA%\BalancedSum\`, which neither of them contains — so you're
   looking at your real, current books, not a fresh empty one.

5. **Keep the old folder around** until you're confident the new one is
   working well — a few days of normal use is reasonable. Once you trust the
   new version, you can delete the old folder. There's no rush; disk space
   for a second copy of the application code is trivial compared to the
   safety of being able to fall back to a known-working folder.

---

## Alternative: unzip over the top of the existing folder

If you'd rather not manage two folders, you can update in place instead.
This is faster but riskier — there's no old, working copy to fall back to
if something goes wrong, so only use this once you're comfortable with the
process.

1. Complete the **Before you start** steps above (close the app, back up).
2. **Delete `node_modules\` from the existing folder first.** This is the
   one step that's easy to forget and causes real problems if skipped — a
   zip extracted on top of an existing `node_modules\` can leave stale
   compiled dependencies mixed with new ones, producing confusing errors
   that have nothing to do with your actual data.

   ```powershell
   Remove-Item -Recurse -Force "C:\Users\you\balanced-sum\node_modules"
   ```

3. Unzip the new version's contents directly into the existing folder,
   overwriting the application code. Your `.env`, `imports\`, and `reports\`
   are *already there* (they're not part of the release zip — see the
   honesty note below), so there's nothing to copy this time.
4. From that folder:

   ```powershell
   npm install
   npm run app
   ```

5. Confirm it looks right, same as step 4 above.

---

## Why the release zip doesn't include `.env`, `imports/`, or `reports/`

The downloadable release zip is application code only — it never contains
your settings, the files you've personally uploaded, or anything you've
generated, on purpose (those are specific to your install, not the product).
That's exactly why the side-by-side method above has you copy them across
explicitly: the new zip genuinely does not have them.

None of it is high-stakes, which is worth saying plainly. Nothing in
`imports/` or `reports/` is needed for the app to run — losing them costs you
old uploaded files or generated output, never anything from your books. And
`.env` holds optional settings only: it does not contain your database
password (that lives in `%LOCALAPPDATA%\BalancedSum\secret`, generated for
your machine and never copied into the application folder), and the app finds
its database perfectly well without one. A missing `.env` means any options
you'd chosen revert to their defaults, not that anything is lost.

---

## One future update will need an extra step: a new PostgreSQL

Not yet, and not for any update you can download today — but it is worth
knowing now rather than discovering it on the day.

Balanced Sum keeps your books in PostgreSQL 16, and it wrote down which
version it created your database with. Ordinary updates, including ones that
bring a newer PostgreSQL 16.x, carry straight on using the same database.

Eventually a release will move to a new **major** version (17, say). A
PostgreSQL 17 program cannot read a PostgreSQL 16 database directly; the
files have to be converted first. So that release will not simply start up
and hope. It will **refuse to start** and tell you so in plain English,
rather than touch a database it can't safely open — which is the behaviour
you want from an accounting program, even though it's inconvenient for an
afternoon.

That release will come with its own instructions for the conversion, and
this page will point at them. Two things will be true of it: your existing
database is kept intact and untouched while the new one is built alongside
it, and — as always — you take a backup first.

## If something goes wrong

- **The new version won't start / a migration fails**: your data is still
  safe in the database and in your backup from the "Before you start" step.
  Go back to the old folder (side-by-side method) or restore from that
  backup per [RESTORE.md](RESTORE.md) (in-place method), and try the update
  again once you understand what failed.
- **You forgot to copy `.env`** (if you had one): copy it over from the old
  folder and restart `npm run app`. Nothing is lost — the app still found
  your books; it just went back to default settings until the file was
  there.
- **Anything else**: the terminal window prints what actually failed, in
  plain English, same as every other error in this app.
