# 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 configured in `BETA_USERS` with Werkzeug password hashes. - `/` renders the active calculator template. - `/help` renders the authenticated Help landing page. - `/help/user-manual` renders `docs/de/user_manual.md` server-side inside the RollCalc Help layout. - `/help/recent-changes` renders `docs/de/recent_changes.md` server-side inside the RollCalc Help layout. - `/help/user-manual/screenshots/` serves German manual screenshots from `docs/de/screenshots/`. - `/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`. - `build_info.json` is loaded at startup and exposed to all templates as `build_info`. 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. - The footer displays build metadata: version, branch, commit, and timestamp. ## Build Info Build/deployment metadata is read from: ```text build_info.json ``` Expected fields: - `version` - `branch` - `commit` - `timestamp` If `build_info.json` is missing, malformed, or does not contain a usable value, RollCalc falls back to `unknown` for that value and continues serving the site. The data is loaded centrally in `app.py` and made available to every template as `build_info`. ## Help and User Manual The in-app Help area keeps `docs/de/user_manual.md` as the leading German documentation source. RollCalc reads the Markdown file on each `/help/user-manual` request and renders it server-side with `markdown-it-py`. The documentation structure is prepared for language-specific manuals: ```text docs/ de/ user_manual.md screenshots/ ``` Additional languages can follow the same structure later. The current public route still opens the German manual and no language switcher is implemented. Rendering rules: - Raw HTML from the Markdown source is disabled. - Heading ids and the table of contents are generated from the Markdown content. - Relative image references such as `screenshots/disclaimer.png` are rewritten to the authenticated manual screenshot route. - Screenshots belong in the active language's `screenshots/` directory, currently `docs/de/screenshots/`; the screenshot route must remain limited to that directory. The Help pages use the same HTTP Basic Auth protection as the calculator. ### Recent Changes and What's New Full user-facing release notes are maintained in: ```text docs/de/recent_changes.md ``` The calculator header links directly to `/help/user-manual`. The Help landing page lists only existing documents, currently User Manual and Recent Changes. The startup What's New dialog uses `build_info.version` and is suppressed when the version is empty or `unknown`. The last acknowledged version is stored only in browser `localStorage` under: ```text rollcalc_last_seen_version ``` The short dialog item list is maintained separately in: ```text static/recent_changes.json ``` This JSON is a compact summary for the dialog, not the complete release history. Keep it aligned with the most relevant current entries from `docs/de/recent_changes.md`. ## Authentication RollCalc uses HTTP Basic Auth. User entries in `BETA_USERS` have this shape: ```python "username": { "password_hash": "..." } ``` Password verification uses `werkzeug.security.check_password_hash`. New hashes or config snippets can be generated with: ```bash python scripts/manage_users.py username ``` Passwords and hashes must not be logged. ## 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 - Password hashes are currently configured in `app.py`; this should eventually move to a protected external configuration or secrets mechanism. - 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.