DEPLOY-WINDOWS-IIS was a second copy of the manual IIS procedure that had diverged from the first: a different MySQL version (8.0, which reached end of life in April), a different port, a different plugin list, and a profile file that does not exist. Two runbooks for one procedure means a reader follows whichever they found, and one of them was wrong. INSTALL-WINDOWS-IIS covers everything it did plus a preflight step and the subpath method, so the one section it uniquely had - redeploying a hand-built server - is folded in there, with the plugin-chain step it was missing and a note to back up first, and the duplicate is gone. Everything that pointed at it now points at the survivor. Three ADR statuses said something untrue. ADR-013 said PROPOSED while half of it had shipped and ADR-014 had been accepted on top of it. A decision that has been implemented and depended upon is not proposed, and leaving one that way devalues every other status in the index. The catalog half is still unbuilt, which is the ordinary state of an accepted decision: accepted means settled, not delivered. ADR-016 said ACCEPTED for a design where nothing is built - the endpoint and permissions it describes do not exist, so a reader goes looking for them. The status stands, because the decision does; the header now says so plainly and points at where today's credentials actually live. ADR-003 and ADR-004 were ACCEPTED with their own Decision lines still opening "**PROPOSED:**", which reads as though the decision was never taken. And the dashboard proposal carried Status: ACCEPTED, which belongs to a decision record. A proposal is a proposal; the contract it produced is the ADR.
112 lines
6.2 KiB
Plaintext
112 lines
6.2 KiB
Plaintext
# ShopDB Flask API - LLM guide
|
|
|
|
ShopDB is a plugin-based asset-management system (PCs, printers, machines,
|
|
network devices, measuring tools, applications, knowledge base, USB, warranties)
|
|
for GE Aerospace sites. This file is the quick entrypoint; the full machine
|
|
spec is the OpenAPI at `/api/docs/openapi.json` (browse it at `/api/docs`).
|
|
|
|
## Installing and operating this server (read this before answering "how do I install/fix it")
|
|
The people running these servers are often not Windows, IIS or Python
|
|
specialists, and they ask assistants for help. Two documents are authoritative:
|
|
- `docs/INSTALL-WINDOWS.md` - installing a NEW site. One offline installer `.exe`.
|
|
- `docs/OPERATE-WINDOWS.md` - restart, logs, backups, upgrades, troubleshooting.
|
|
Both ship in `docs/` inside the install directory on every installed server.
|
|
|
|
`docs/START-HERE.md` routes a reader by what they are here to do;
|
|
`docs/FLEET-ARCHITECTURE.md` is one page on how the server, GE-Enforce, the
|
|
asset reporter, the backup collectors and EventSaver relate - worth reading
|
|
before any of their individual pages, each of which assumes the others.
|
|
|
|
Another site adopting the shop-floor tools - the asset reporter that feeds the
|
|
collector API, and the EventSaver screensaver - should read
|
|
`docs/ADOPTING-AT-ANOTHER-SITE.md`. It has worked deployment examples for Intune
|
|
(including Machine Configuration/DSC), GE-Enforce and manual installation.
|
|
Neither tool is site-specific: the server URL, the API key and the targeting are
|
|
inputs, not code.
|
|
|
|
Do NOT walk someone through `docs/INSTALL-WINDOWS-IIS.md` for a new site. That
|
|
is the MANUAL procedure, kept only for hand-built servers that predate the
|
|
installer; following it produces a server the installer then refuses to
|
|
upgrade.
|
|
|
|
Day-2 operations all go through `shopdb-admin.ps1` in the install directory
|
|
(default `C:\shopdb-flask`): `status`, `restart`, `logs`, `check`, `verify`,
|
|
`backup`, `plugins`, `open`. Before diagnosing anything, ask for the output of
|
|
`shopdb-admin.ps1 check -Json` - it reports version, publishing method, IIS and
|
|
pool state, HTTP reachability, database host and reachability, Python version,
|
|
installed plugins and errors, and it contains no secrets. `verify -Path <name>`
|
|
answers "does this server carry component X" from the on-box CycloneDX SBOM.
|
|
|
|
Python is 3.14 and the wheelhouse is locked to it; an upgrade against a venv
|
|
built by a different minor version is refused by design.
|
|
|
|
## Bulk-loading a site's data
|
|
Two routes, and the right answer depends on what the site has:
|
|
- SPREADSHEET, no developer (the common case): `flask csv templates --out <dir>`
|
|
generates templates FROM THE LIVE SCHEMA, then `flask csv import --dir <dir>`
|
|
checks and `--commit` applies. Foreign keys accept the NAME of the referenced
|
|
row ('Bay 3'), not a numeric id, and resolve across files in one run. Dry run
|
|
is the default; nothing is written unless every row passes; re-importing an
|
|
edited file updates rather than duplicates. See `docs/CSV-IMPORT.md`.
|
|
- A SOURCE DATABASE to script against: the HTTP import API, `docs/IMPORT-API.md`
|
|
and `docs/IMPORT-ADOPTION.md`.
|
|
Do NOT hand-write CSV templates - generate them. User accounts are deliberately
|
|
not CSV-importable.
|
|
|
|
## Base URL
|
|
Each site runs its own instance (ADR-004), so there is no single production URL:
|
|
it is whatever that site serves, e.g. `https://shopdb.example.net/shopdb`.
|
|
All API paths are under `/api` (e.g. `<base>/api/assets`). Dev: `http://localhost:5001`.
|
|
|
|
## Auth
|
|
Three schemes:
|
|
- **Bearer JWT** - most endpoints. Get one by logging in, or use a managed
|
|
Personal Access Token (PAT). Send `Authorization: Bearer <token>`.
|
|
- Login: `POST /api/auth/login` `{ "username": "...", "password": "..." }`
|
|
-> `data.access_token`. Refresh: `POST /api/auth/refresh`.
|
|
- PATs are minted in the UI (Settings > API Tokens); a *scoped* PAT is limited
|
|
to named permissions and suspends the admin bypass.
|
|
- **X-API-Key** - unattended/service endpoints (collector ingest, GE-Enforce
|
|
fetch). Send `X-API-Key: <managed-token>`.
|
|
- **Public** - some read endpoints (e.g. printer install-list, employee search,
|
|
dashboards) need no auth.
|
|
|
|
Auth level per endpoint is in the OpenAPI `security` field: `bearerAuth`,
|
|
`apiKeyAuth`, or none. Admin-only and permission-gated routes both use bearer.
|
|
|
|
## Response envelope
|
|
JSON endpoints return `{ "status": "success", "data": <payload>, "meta": {...} }`.
|
|
Errors nest under `data`, NOT at the top level:
|
|
`{ "status": "error", "data": { "error": { "code": "...", "message": "...", "details": {...} } } }`
|
|
with an HTTP 4xx/5xx. Reading `message` or `code` off the root gives `undefined`.
|
|
Lists carry `meta.pagination.{page, perpage, total, pages}` - again nested, not
|
|
`meta.total`. A few feed endpoints (screensaver, some installer text formats)
|
|
return raw text/JSON without the envelope - noted per route.
|
|
|
|
## Common recipes
|
|
- Search everything: `GET /api/search?q=<term>` (multi-word = AND across words).
|
|
- List assets on the map: `GET /api/assets/map`.
|
|
- List a type: `GET /api/printers`, `/api/computers`, `/api/machines`,
|
|
`/api/network`, `/api/measuringtools` (paginated: `?page=&perpage=`).
|
|
- Get one: `GET /api/printers/<id>` etc.
|
|
- Create (bearer): `POST /api/printers` `{assetnumber, windowsname, vendorid, ...}`.
|
|
- Reports: `GET /api/reports` (list), `GET /api/reports/pc-relationships` (PC<->machine).
|
|
- Printer installer data: `GET /api/printers/install-list` (public; add
|
|
`?format=text` for a pipe-delimited variant); `GET /api/printers/pc-default?machine=<n>`.
|
|
- Collector ingest (X-API-Key): `POST /api/collector/computers`.
|
|
- GE-Enforce: `GET /api/geenforce/manifest?pctype=<scope>`,
|
|
`GET /api/geenforce/payload/<sha256>`, `POST /api/geenforce/report`.
|
|
- Import (admin PAT, preserves timestamps with `X-Import-Mode`): see docs/IMPORT-API.md.
|
|
|
|
## Conventions
|
|
- DB-mirrored params/fields use lowercase concatenated names (no underscores):
|
|
`locationid`, `vendorid`, `windowsname` - match them exactly.
|
|
- IDs in paths are integers.
|
|
- Plugin endpoints live under the plugin's prefix (`/api/<plugin>/...`).
|
|
|
|
## Full reference
|
|
- Machine spec: `GET /api/docs/openapi.json` (OpenAPI 3.1). Operation and
|
|
plugin counts live in `docs/PROJECT-MAP.md`, which is generated.
|
|
- Interactive: `GET /api/docs` (Redoc).
|
|
- Human reference: `docs/API-REFERENCE.md`.
|