From the full multi-agent review (0 high, 7 medium, 17 low findings). Applies the mechanical, low-risk items; design/policy findings left for a decision. Docs accuracy: CLAUDE.md contract 0.10.0 -> 0.11.0 and both stale Alembic head citations -> 7d24_customfield_searchable / 31 migrations; Dockerfile bundled- plugin comment fixed (drop nonexistent "equipment", add machines + measuringtools, count eleven). Style/naming (LOCKED rules): remove a CSS-escaped pushpin emoji before location search results (no-emoji policy); rename ManifestEditor shareRoot -> shareroot (variable mirrors the API field verbatim). Dead code: remove confirmed-unused imports across ~20 modules (require_role/ require_permission scaffold residue, stray db/Vendor/Model/current_user/Optional/ error_response); drop unused build_scope import + a stale GEENFORCE_API_KEY docstring clause in geenforce. Migration files left untouched. Correctness: geenforce ingest robustness - record_enforcement_report now 400s on a non-dict counts / non-list results instead of 500; _apply_app_link ignores a non-numeric appid per its docstring instead of 500. Regression tests added. Backend query.get sweep finished: auth.py refresh -> db.session.get (last one). 910 backend tests pass; pyflakes clean; naming green; frontend build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
USB plugin - CMMC USB check-in/out database contract
The USB plugin tracks removable-media check-in/out for CMMC compliance. Device
and log state live in a separate, read-write MySQL database (cmmc_usb),
reached with parameterized pymysql via cmmc_usb_connection(). Names of people
are resolved from the HR employee directory (see the employees plugin).
The plugin's own reference tables (usbdevicetypes, usbdevices,
usbcheckouts) live in the main app database; only the live check-in/out data
is in cmmc_usb.
The schema is standardized across sites - the
cmmc_usbcheck-in/out solution is the same deployment everywhere, so the tables below match as-is and no schema adaptation is needed. The database name may differ per site, though - setcmmc_usb_db_name(defaultcmmc_usb) to match the local name. The view recipe at the end is only a fallback for a site that somehow differs. (Contrast the employee directory, which genuinely varies per site.)
Connection
Credentials resolve settings-first, then environment, except the password which is env-only (never stored in the app database).
| Field | Setting key (editable in the setup wizard) | Env var (fallback) |
|---|---|---|
| Host | cmmc_usb_db_host |
CMMC_USB_DB_HOST |
| Database | cmmc_usb_db_name |
CMMC_USB_DB_NAME |
| User | cmmc_usb_db_user |
CMMC_USB_DB_USER |
| Password | (not stored) | CMMC_USB_DB_PASSWORD |
Set the password in .env; the setup wizard's Features step shows the exact
line to paste. This database is read-write - the app account needs
SELECT, INSERT, UPDATE. Engine is MySQL/MariaDB (pymysql).
Required schema
The plugin runs raw SQL against these tables (or views - see below).
devices
| Column | Type | Notes |
|---|---|---|
device_id |
VARCHAR | Primary key; the device serial/tag |
device_desc |
VARCHAR | Description |
device_owner |
VARCHAR | Owner |
status |
VARCHAR | Check-in/out state |
locker_location |
VARCHAR | Where the device is stored |
Operations: SELECT (list + by id), INSERT (register device), UPDATE
(edit fields, change status).
checkinoutlog
| Column | Type | Notes |
|---|---|---|
log_id |
INT (PK) | Auto id |
badge_number |
VARCHAR | Person's badge |
device_id |
VARCHAR | FK to devices.device_id |
action |
VARCHAR | check-in / check-out |
timestamp |
DATETIME | When it happened |
scanned_viruses |
(text/int) | Scan result |
locker_location |
VARCHAR | Locker at time of event |
sanitized |
(bool/int) | Sanitization flag |
Operations: SELECT (history per device), INSERT (log an event).
users
| Column | Type | Notes |
|---|---|---|
badge_number |
VARCHAR | Primary key; the scanned badge |
first_name |
VARCHAR | Given name |
last_name |
VARCHAR | Surname |
Operations: SELECT by badge, INSERT (auto-add a badge on first scan).
Employee directory dependency
To turn a scanned badge into a name, the plugin also reads the HR employees
directory (via the employees plugin's connection). A badge shaped 0<digits>BZ
carries a PayNo (the digits); lookups try employees.SSO and employees.PayNo.
See plugins/employees/README.md for that schema and connection.
Adapting a different site schema (recommended: views)
Sites whose USB-tracking database uses different table/column names should
create read-only/updatable views named devices, checkinoutlog, and
users that map local columns to the names above. Example:
CREATE VIEW devices AS
SELECT
asset_tag AS device_id,
description AS device_desc,
owner AS device_owner,
state AS status,
storage_bay AS locker_location
FROM usb_assets;
Because the plugin writes to devices/checkinoutlog/users, either make the
views updatable (single-table views usually are) or expose real tables with
these column names. Grant the app account SELECT, INSERT, UPDATE.
Notes:
device_idandbadge_numberare the natural keys the plugin matches on.- If
cmmc_usbis unreachable, USB endpoints return an error and the rest of the app keeps working (the feature degrades, it does not crash the app).