diff --git a/bible-local/03-database.md b/bible-local/03-database.md index 2164612..e28ed79 100644 --- a/bible-local/03-database.md +++ b/bible-local/03-database.md @@ -360,6 +360,39 @@ Retained for historical data only. Not queried by QuoteForge. **machine**: machine_name (PK, char 255), machine_description **machine_log**: machine_log_id AUTO_INCREMENT, date, supplier (FK→supplier), country, opty, type, machine (FK→machine), customer_requirement, variant, price_gpl, price_estimate, qty, quality, carepack, lead_time_weeks, prepayment_percent, price_got, Comment +## MariaDB User Permissions + +The application user needs read-only access to reference tables and read/write access to runtime tables. + +```sql +-- Read-only: reference and pricing data +GRANT SELECT ON RFQ_LOG.qt_categories TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.qt_lot_metadata TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.qt_pricelists TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.qt_pricelist_items TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.stock_log TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.stock_ignore_rules TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.qt_partnumber_books TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.qt_partnumber_book_items TO 'qfs_user'@'%'; +GRANT SELECT ON RFQ_LOG.lot TO 'qfs_user'@'%'; + +-- Read/write: runtime sync and user data +GRANT SELECT, INSERT, UPDATE, DELETE ON RFQ_LOG.qt_projects TO 'qfs_user'@'%'; +GRANT SELECT, INSERT, UPDATE, DELETE ON RFQ_LOG.qt_configurations TO 'qfs_user'@'%'; +GRANT SELECT, INSERT, UPDATE ON RFQ_LOG.qt_client_schema_state TO 'qfs_user'@'%'; +GRANT SELECT, INSERT, UPDATE ON RFQ_LOG.qt_pricelist_sync_status TO 'qfs_user'@'%'; +GRANT SELECT, INSERT, UPDATE ON RFQ_LOG.qt_vendor_partnumber_seen TO 'qfs_user'@'%'; + +FLUSH PRIVILEGES; +``` + +Rules: +- `qt_client_schema_state` requires INSERT + UPDATE for sync status tracking (uses `ON DUPLICATE KEY UPDATE`); +- `qt_vendor_partnumber_seen` requires INSERT + UPDATE (vendor PN discovery during sync); +- no DELETE is needed on sync/tracking tables — rows are never removed by the client; +- `lot` SELECT is required for the connection validation probe in `/setup`; +- the setup page shows `can_write: true` only when `qt_client_schema_state` INSERT succeeds. + ## Migrations SQLite: