Every site's HR directory and USB check-in/out databases may use a different schema, so document exactly what each plugin queries and how to adapt. - plugins/employees/README.md: required employees table columns (SSO, First_Name, Last_Name, Team, Role, Picture), the queries run, photo handling, and a CREATE VIEW recipe to map a different site schema without code changes. - plugins/usb/README.md: cmmc_usb devices / checkinoutlog / users columns, read-write ops, the employee-directory dependency, and a view recipe. - USB plugin gains get_config_schema() (cmmc_usb_db_host/name/user + password); cmmc_usb_connection reads host/name/user settings-first (env fallback), the password stays env-only - matching the employees plugin. - Config-field help points at the READMEs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
95 lines
4.0 KiB
Markdown
95 lines
4.0 KiB
Markdown
# Employees plugin - directory database contract
|
|
|
|
Read-only lookups against a **separate** employee/HR directory database. Powers:
|
|
|
|
- Employee search (add people to a notification, browse the directory)
|
|
- Single + batch SSO lookup
|
|
- Recognition notifications (name + photo on the shopfloor / lobby displays)
|
|
|
|
The plugin never writes to this database. Use a read-only account.
|
|
|
|
## 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 | `employee_db_host` | `EMPLOYEE_DB_HOST` |
|
|
| Database | `employee_db_name` | `EMPLOYEE_DB_NAME` |
|
|
| User | `employee_db_user` | `EMPLOYEE_DB_USER` |
|
|
| Password | (not stored) | `EMPLOYEE_DB_PASSWORD` |
|
|
|
|
Set the password in `.env`; the setup wizard's Features step shows the exact
|
|
line to paste. Engine is MySQL/MariaDB (pymysql).
|
|
|
|
## Required schema
|
|
|
|
The plugin runs these queries verbatim, so a site's database must expose a
|
|
table (or **view** - see below) named `employees` with these columns:
|
|
|
|
| Column | Type | Notes |
|
|
| ------------ | ------------------- | ------------------------------------------------- |
|
|
| `SSO` | INT | Unique person id. Lookups require it to be numeric |
|
|
| `First_Name` | VARCHAR | Displayed as the given name |
|
|
| `Last_Name` | VARCHAR | Displayed as the surname; sort key |
|
|
| `Team` | VARCHAR | Team / group label |
|
|
| `Role` | VARCHAR | Job title / role |
|
|
| `Picture` | VARCHAR | **Image filename** (see Photos) |
|
|
|
|
Queries actually executed:
|
|
|
|
```sql
|
|
-- search
|
|
SELECT SSO, First_Name, Last_Name, Team, Role, Picture
|
|
FROM employees
|
|
WHERE First_Name LIKE %s OR Last_Name LIKE %s OR CAST(SSO AS CHAR) LIKE %s
|
|
ORDER BY Last_Name, First_Name LIMIT %s;
|
|
|
|
-- single / batch
|
|
SELECT SSO, First_Name, Last_Name, Team, Role, Picture FROM employees WHERE SSO = %s;
|
|
SELECT SSO, First_Name, Last_Name, Team, Role, Picture FROM employees WHERE SSO IN (...);
|
|
```
|
|
|
|
Rows are returned to the API **with these exact column names**. The frontend
|
|
(EmployeeSearch, NotificationForm, EmployeeDetail, ShopfloorDashboard) reads
|
|
`SSO`, `First_Name`, `Last_Name`, `Team`, `Role`, `Picture` as-is - do not
|
|
rename them in the response.
|
|
|
|
## Photos
|
|
|
|
`Picture` holds an **image filename** (e.g. `123456.jpg`), not a path or blob.
|
|
The app renders it as `/static/employees/<Picture>`, so the image files must
|
|
live in the app's `static/employees/` directory. Leave `Picture` empty/NULL for
|
|
people with no photo; the UI falls back to initials.
|
|
|
|
## Adapting a different site schema (recommended: a view)
|
|
|
|
Sites whose HR/directory database uses different table or column names should
|
|
**not** be forced to rename anything. Instead, create a read-only **view**
|
|
named `employees` that maps local columns to the names above:
|
|
|
|
```sql
|
|
CREATE VIEW employees AS
|
|
SELECT
|
|
person_id AS SSO,
|
|
given_name AS First_Name,
|
|
surname AS Last_Name,
|
|
department AS Team,
|
|
job_title AS Role,
|
|
photo_filename AS Picture
|
|
FROM hr_people
|
|
WHERE active = 1;
|
|
```
|
|
|
|
Grant the app's read-only user `SELECT` on the view. No app code changes -
|
|
point `employee_db_*` at that database and the plugin works.
|
|
|
|
Notes:
|
|
- `SSO` must be numeric (single/batch lookup validate `isdigit()`).
|
|
- Column-name case follows your database's identifier casing; match the names
|
|
above exactly on case-sensitive platforms.
|
|
- If the directory is unreachable or the `employees` object is missing, lookups
|
|
return a 500 and the rest of the app keeps working (the feature degrades, it
|
|
does not crash the app).
|