# Running ShopDB-Flask on Windows Server

Day-to-day operation of a site installed with the Windows installer. If you are
installing for the first time, start with [INSTALL-WINDOWS.md](INSTALL-WINDOWS.md).

Everything here goes through one tool, installed alongside the application:

```
C:\shopdb-flask\shopdb-admin.ps1
```

The Start Menu folder **ShopDB-Flask** has shortcuts for the common tasks. Run it
with no arguments for a menu, or pass a command directly. It needs
Administrator - it will ask, except for `open`.

---

## The commands

| Command | What it does | Safe at any time |
|---|---|---|
| `status` | Is it published, running, responding; database and table count | yes |
| `restart` | Recycles the application pool. **Use this after any config change.** | yes - drains requests rather than cutting them off |
| `stop` / `start` | Takes the site down / brings it back | yes, but `stop` makes it unavailable |
| `logs` | Last lines of the application and install logs | yes |
| `check` | Full health check | yes |
| `check -Json` | The same, machine-readable - see [Getting help](#getting-help) | yes |
| `verify` | Which build this is, and whether what is installed still matches it | yes |
| `sessions` | IIS worker processes and memory | yes |
| `plugins` | Which features are installed, which are available | yes |
| `add-plugin -Path <name>` | Turns on a feature this build ships | changes the site; restarts it |
| `backup [-Path <dir>]` | Writes a verified `.sql` dump | yes, but see below |
| `open` | Opens the site in a browser | yes |

Examples:

```powershell
.\shopdb-admin.ps1 status
.\shopdb-admin.ps1 restart
.\shopdb-admin.ps1 backup D:\backups
.\shopdb-admin.ps1 verify -Path leaflet
```

---

## Backups

```powershell
.\shopdb-admin.ps1 backup
```

Writes to `C:\ProgramData\ShopDB-Flask\backups` unless you pass a directory. The
dump is **verified complete** before it is reported as good - a truncated backup
is deleted rather than left to be discovered later.

Two things to know:

- **The dump contains everything, including user password hashes.** The directory
  is locked to Administrators and SYSTEM. Keep it that way, and treat copies as
  sensitive.
- **Store it off this server.** A backup on the server does not survive the
  server.

An upgrade takes its own backup automatically, before it touches the schema.

Restore, and the Linux/Docker equivalents, are in
[BACKUP-RESTORE.md](BACKUP-RESTORE.md).

---

## Upgrading

Run a newer installer over the top. Nothing else. It backs up first, refuses to
go backwards, and restores if a migration fails. See
[UPGRADE.md](UPGRADE.md).

---

## Adding a feature

```powershell
.\shopdb-admin.ps1 plugins                    # what is here
.\shopdb-admin.ps1 add-plugin -Path warranty  # turn one on
```

Only features **shipped in this build** can be added. Each site's installer is
built for that site's chosen feature set, so a feature nobody asked for is not on
the server at all - adding it means a new installer built from an updated
profile. `plugins` shows you which is which.

---

## When something is wrong

Work down this list.

**1. Is it actually down?**

```powershell
.\shopdb-admin.ps1 status
```

`responding : NO` with the pool `Started` usually means the application failed to
start, not that IIS is broken.

**2. What does it say?**

```powershell
.\shopdb-admin.ps1 logs
```

Application logs are in `C:\shopdb-flask\logs`, install logs in
`C:\ProgramData\ShopDB-Flask\logs`.

**3. Try a restart.** It fixes anything that is a stuck worker, and tells you
immediately if it is not:

```powershell
.\shopdb-admin.ps1 restart
```

**4. Check the database is reachable** - `status` reports the host and whether it
could count tables. A site that starts but shows no data is usually a database
problem, not an application one.

**5. Confirm nothing has drifted:**

```powershell
.\shopdb-admin.ps1 verify
```

This flags packages that no longer match what shipped - which usually means
somebody ran a `pip install` on the server by hand.

---

## Getting help

Give an assistant real state rather than describing the symptom:

```powershell
.\shopdb-admin.ps1 check -Json
```

One structured block: version, how the site is published, IIS and pool state,
whether it responds, database host and reachability, Python version, installed
features, and any errors. **It contains no passwords** and is safe to paste into
a chat window or a ticket.

The install log is also safe to share - secrets are deliberately kept out of it.

Offline reference on the server itself:

- `/api/docs` on the site - the full API reference, self-hosted, no internet.
- `C:\shopdb-flask\docs\` - these runbooks.
- `C:\shopdb-flask\sbom.cdx.json` - every component this build contains.

---

## Answering "are we affected by this vulnerability?"

The server carries its own bill of materials, so this does not need the build box
or an internet connection:

```powershell
.\shopdb-admin.ps1 verify -Path <component-name>
```

It reports whether the component is here, at what version, and whether it
actually **ships** or is only used to build the software. Example:

```
matches for 'leaflet':
    leaflet        1.9.4     SHIPPED
```

Nothing found means this server does not carry it.

---

## Adding HTTPS

**The installer publishes over HTTP.** It has no certificate to use and no way to
get one on an air-gapped server, so it does not pretend otherwise. On an internal
network behind the site firewall that is often accepted; confirm it against your
own policy rather than assuming.

If you installed **under an existing site** (the subpath option) and that site
already has a certificate, you are already on HTTPS - nothing to do.

For a site of its own, once you have a certificate in the machine store:

```powershell
Import-Module WebAdministration

# 1. Add the binding. Get the thumbprint from the certificate you imported.
New-WebBinding -Name shopdb-flask -Protocol https -Port 443
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -like '*yourserver*' }
Get-Item "IIS:\SslBindings\0.0.0.0!443" -EA SilentlyContinue | Remove-Item -EA SilentlyContinue
New-Item "IIS:\SslBindings\0.0.0.0!443" -Value $cert

# 2. Open the port.
New-NetFirewallRule -DisplayName "shopdb-flask 443" -Direction Inbound `
    -Protocol TCP -LocalPort 443 -Action Allow
```

Then **update `CORS_ORIGINS` in `C:\shopdb-flask\.env`** to the `https://` address
and restart:

```powershell
.\shopdb-admin.ps1 restart
```

That last step is not optional. `CORS_ORIGINS` is an exact origin match, so a
site reached over `https://` while `.env` still says `http://` loads the page and
then fails every data request - which looks like the application is broken rather
than a configuration mismatch.

## Where things live

| | |
|---|---|
| Application | `C:\shopdb-flask` |
| Configuration and secrets | `C:\shopdb-flask\.env` (locked down - do not loosen) |
| Application logs | `C:\shopdb-flask\logs` |
| Install logs | `C:\ProgramData\ShopDB-Flask\logs` |
| Backups | `C:\ProgramData\ShopDB-Flask\backups` |
| Bill of materials | `C:\shopdb-flask\sbom.cdx.json` |
| Which build this is | `C:\shopdb-flask\.installed-version` |

If the bundled MySQL was installed, its generated root password was written once
to `C:\ProgramData\ShopDB-Flask\mysql-root-password.txt`. **Move it into your
password manager and delete that file.** It cannot be recovered.
