# PROJECT_KNOWLEDGE.md Project-specific technical and domain knowledge for RollCalcPython. ## Purpose RollCalcPython is an internal roll calculator for Naue roll products. The backend is a minimal Flask application that provides authentication, routing, static file delivery, and access logs. Most domain behavior runs in the browser inside `templates/roll_calculator.html`. The tool is not intended as an unchecked source of truth. Inputs and outputs must be checked for plausibility before operational use. ## Current Architecture Backend: - `app.py` creates the Flask app. - HTTP Basic Auth is implemented with `Flask-HTTPAuth`. - Users are currently hardcoded in `BETA_USERS`. - `/` renders the active calculator template. - `/static/` is intended to serve static files behind Basic Auth. - `/api/health` returns health/version information. - `/api/user` returns the authenticated user. - Access events are appended to `access_log.json`. Frontend: - `templates/roll_calculator.html` is the active application page. - The page contains most CSS and JavaScript inline. - `window.ARTICLE_DATA` is loaded from `/static/article-data.json`. - `window.APP_CONFIG` is currently defined inline for forklift rules. - A disclaimer modal blocks use until the user checks the confirmation checkbox. ## Roll Geometry Calculations assume an ideal cylindrical winding. Assumptions: - Constant material thickness. - No compression. - No air gaps. - Roll geometry is derived mathematically, not physically measured in the app. Nominal diameter formula used by the Direct Calculation tab: ```text D = sqrt(d^2 + (4 * L * 1000 * t) / pi) ``` Variables: - `D`: roll diameter in mm. - `d`: core diameter in mm. - `L`: product length in m. - `t`: material thickness in mm. When a tolerance/stddev value is present, the UI also displays a `-2σ` and `+2σ` diameter range. ## Product Length and Extrapolation Product length from a known diameter is calculated by rearranging the diameter formula: ```text L = (pi / (4 * t)) * (D^2 - d^2) / 1000 ``` The extrapolation tab estimates a new diameter from a known roll diameter/length pair: ```text D1 = sqrt(d^2 + (L1 / L0) * (D0^2 - d^2)) ``` Variables: - `D0`: known/measured roll diameter. - `L0`: known/measured roll length. - `L1`: target length. - `D1`: extrapolated roll diameter. ## Roll Weight Roll weight is calculated client-side when width, area weight, and length are available: ```text weight_kg = area_weight_g_m2 * length_m * width_m / 1000 ``` Material thickness and area weight values are loaded from article data and are generated automatically. They are not guaranteed to be complete or reviewed. ## Article Data Active data source: ```text static/article-data.json ``` The UI expects article records with fields such as: - `nr` - `name` - `thickness` - `thickness_stddev` - `area_weight` - `area_weight_stddev` - `core_type` Observed additional fields include min/max/count values for material thickness and area weight. Important data rule: - Article data is generated from ERP-derived sources. - These values should not be manually changed unless the task is explicitly data maintenance. Known domain caveat from existing project notes: - For articles in the groups Secugrid, Combigrid, Carbofol MF/MF, Carbofol F/F, Carbofol s/F, and Carbofol BF/s, the thickness from `article-data.json` must not be used without domain validation. ## Forklift and Heavy-Roll Rules The active template currently evaluates forklift warnings through `checkForklift()` and inline `window.APP_CONFIG`. Current inline rule behavior: - Applies to category `bentofix`. - Warning threshold: `1700 kg`. - Hard limit: `2750 kg`. - Minimum core outer diameter: `170 mm`. There is also a richer JSON configuration in: ```text static/config.json ``` That file includes localized messages and additional equipment requirements. Before changing forklift behavior, verify whether the active inline config or the static JSON should be authoritative. ## Load Optimizer The Load Optimizer is implemented inline in `templates/roll_calculator.html`. Classes: - `LoadOptimizer` - `LoadOptimizerUI` It uses calculated roll data from the Direct Calculation tab: - Roll diameter. - Core diameter. - Roll width. - Roll weight. - Product length. - Square meters per roll. It supports transport presets: - 20ft Container. - 40ft Container. - 40ft High Cube. - LKW Sattelzug. - LKW Tandem. It calculates limiting scenarios by: - Weight. - Volume. - Geometry. It also draws a side-view SVG visualization. ## Disclaimer Gate The active calculator page includes a disclaimer modal shown after Basic Auth login and before calculator use. The modal: - Contains German and English disclaimer text. - Requires checkbox confirmation. - Enables the confirmation button only after the checkbox is selected. - Hides the overlay after confirmation. This is client-side only. It is not persisted, logged, or enforced server-side. ## Admin Area State RollCalc no longer contains an admin UI or admin API. The previous `/admin/logs` route and `templates/admin.html` have been removed. Login/access logging remains part of RollCalc, but log viewing and article-data administration should not be implemented inside this app. Maintenance of `article-data.json` is planned for a separate application. ## Known Technical Risks - Hardcoded plaintext credentials in `app.py`. - Basic Auth only; no sessions or role framework beyond the user dictionary. - `access_log.json` is rewritten on every logged request and is not concurrency-safe. - No log rotation or retention policy is implemented. - Flask's default static route may conflict with the intended authenticated `/static/` behavior; verify effective routing before relying on protected static files. - Most active logic is concentrated in one large HTML template. - Multiple similar static JavaScript files exist; not all are necessarily active. - No automated test suite is visible. - Some docs and filenames in `docs/` may reflect earlier package/archive versions.