Add email sending (service + 3 flows) and a general asset label generator
Email: a stdlib SMTP mailer (settings-first config, graceful no-op when unconfigured), a test-email endpoint wired to the Email settings page, forced first-login password change (users.mustchangepassword, migration 7d23, /change-password flow), new-user welcome mail, and on-demand report/alert delivery (POST /api/reports/email + Email Report buttons) with an external-cron-with-a-scoped-PAT path documented for automation. All tests patch smtplib - no network. Labels: a shared /print/asset-label/<type>/<id> view any asset detail page opens - card or plain style, QR or barcode, configurable encoding. Per-type qr_target_* templates plus label_default_style/codetype/encodes settings on the Printing page. Measuring-tool labels default to encoding their inspection-operation code (derived from the location name, e.g. 0615), so every tool in an area shares the area code - verified by decoding the rendered QR. Machine labels default to the machine number; blank-serial handled gracefully. 808 tests pass; both features verified live. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
43
CHANGELOG.md
43
CHANGELOG.md
@@ -12,6 +12,49 @@ ADR-007 and ADR-002.
|
||||
|
||||
### Added
|
||||
|
||||
- Email sending. A stdlib-only mail service (`shopdb/utils/mailer.py`;
|
||||
`smtplib`/`ssl`/`email`) reads the existing `email` SMTP settings
|
||||
settings-first with an `SMTP_*` env fallback, sends multipart HTML+text, and
|
||||
is a graceful no-op (logs a warning, returns False) when email is disabled or
|
||||
the host is unset. The SMTP password is never logged. Three flows use it:
|
||||
(1) New-user welcome + forced first-login password change. Admin-created users
|
||||
(POST `/api/users`) are flagged `mustchangepassword` (new `users` column,
|
||||
migration `7d23_user_mustchangepassword`, default false) and sent a
|
||||
best-effort welcome email with the facility name, username, temporary
|
||||
password, and sign-in link; the account is created even if mail fails
|
||||
(response carries a `warning`). Login returns `mustchangepassword`; the
|
||||
frontend forces the user through a new `/change-password` view (POST
|
||||
`/api/auth/change-password`, jwt-guarded) before the app, and changing the
|
||||
password clears the flag and resets lockout counters. A self-service "Change
|
||||
password" entry is also available from the user menu.
|
||||
(2) Test email. POST `/api/settings/test-email` (settings.edit) sends a probe
|
||||
and surfaces any SMTP error with the password scrubbed; wires up the Email /
|
||||
SMTP settings page "Send Test Email" button.
|
||||
(3) On-demand alert/report delivery. POST `/api/reports/email`
|
||||
(reports.export) mails `{subject, columns, rows}` as an HTML table to a
|
||||
supplied recipient or the site `alert_recipients`; an "Email report" button on
|
||||
the Warranty and Toner report pages posts the loaded rows. There is no
|
||||
scheduler: automation is an external cron hitting the endpoint with a scoped
|
||||
API token (PAT). Documented in `docs/CONFIG.md`.
|
||||
- Shared asset label/code generator: a single `/print/asset-label/<assettype>/<id>`
|
||||
page (public, like the other `/print/*` routes) that any asset detail page
|
||||
opens via a "Print Label" button (machines, computers, printers, network
|
||||
devices, measuring tools). A no-print controls panel toggles the layout
|
||||
(`card` badge vs `plain` code-only), the code type (QR vs CODE128 barcode),
|
||||
and what the code encodes: the asset page link, asset number, serial number,
|
||||
a per-type custom target template, or - for measuring tools by default - the
|
||||
tool's inspection location code so every tool at one operation shares one
|
||||
code (e.g. `0615`). QR codes reuse the shared logo-overlay renderer. New
|
||||
`printing` settings seed and surface on the Printing & Labels settings page:
|
||||
`qr_target_machine`, `qr_target_computer`, `qr_target_network_device`,
|
||||
`qr_target_measuring_tool`; `label_default_style` (default `card`) and
|
||||
`label_default_codetype` (default `qr`); and a per-asset-type default for what
|
||||
the code encodes, `label_default_encodes_<type>` (machines default to their
|
||||
machine number, measuring tools to their inspection location code, the rest to
|
||||
a page link), all overridable on the label page itself. When the chosen field
|
||||
has no value (e.g. serial number on an asset with none), the label states so
|
||||
instead of rendering an empty code. Asset payloads now carry a derived
|
||||
`locationcode` (leading token of the resolved own/inherited location name).
|
||||
- Support-team contact UX: the settings Support Teams page now manages each
|
||||
team's contacts in a per-team "Contacts (N)" modal (name, SSO, active, plus
|
||||
Add/Edit/Delete) instead of an inline row expander, and the application
|
||||
|
||||
Reference in New Issue
Block a user