Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Web app

Explanation

Web app overview

Layout of the webapp folder, how the server serves it under /app with a content stamp, and the metadata-driven rule that shapes every screen.

The web app is a single-page browser client kept in the webapp/ folder at the repository root. The API server serves it from the same origin under /app, so the browser calls /api/v1 without cross-origin requests. This page describes the folder layout, how files are served and cached, and the rule that screens come from server metadata. Start-up and the API layer are on boot, session, and API calls.

In short

  • The web app is plain ES modules with no build step: index.html loads one module script, js/main.js (webapp/index.html:406).
  • webapp/js/ holds 51 JavaScript files plus the vendor/ folder (counted with ls webapp/js: 52 entries).
  • The server mounts the folder twice: /app with revalidation on every load, and /app/v/<stamp>/ as immutable files (src/cluster_erp/server/app.py:1633-1644 at commit 92f8051).
  • Every list, form, card, action, and module tab is built from GET /api/v1/_meta (webapp/js/meta.js:16-47). The project's written engineering rules make the web app fully metadata-driven.

How it works

Folder layout

Path Content Count How counted
webapp/index.html The shell: sign-in screen, home screen, app view, overlays, and the module script 1 file, 408 lines wc -l
webapp/operator.html The operator console page 1 file ls webapp
webapp/js/ Engine and screen modules 51 .js files and vendor/ ls webapp/js
webapp/js/vendor/pdfjs/ Vendored PDF renderer (pdfjs-dist 6.2.108, Apache-2.0) 4 files webapp/js/vendor/pdfjs/README.txt
webapp/css/ tokens.css, app.css, gen.css, tiles.css, mail.css 5 files ls webapp/css
webapp/i18n/ en.json, tr.json, and the manifest languages.json 3 files ls webapp/i18n
webapp/fonts/ Self-hosted Manrope font files, manrope.css, and OFL.txt 8 files ls webapp/fonts
webapp/assets/ Chat wallpaper images for the assistant screen 2 files ls webapp/assets
webapp/store/ Screenshot galleries for app store entries, one folder per app 26 folders ls webapp/store

The operator console is documented on operator console. The comment in webapp/index.html:8-12 states that the typeface is served from the node so that no visitor request leaves the deployment for a font.

Module groups in the js folder

Group Files
Boot and transport main.js, api.js, app-session.js, gen-api.js, meta.js, data-bus.js, ui-state.js
Generic engines gen-list.js, gen-form.js, gen-detail.js, gen-tree.js, gen-settings.js, entity.js, action-sheet.js, customselect.js, form-drafts.js, table-align.js, avatar.js
Shell home.js, module-app.js, app-scope.js, nav.js, app-wheel.js, tiles.js, touch-gate.js, device-class.js, search-index.js, custom-widgets.js
Widgets widget-ai.js, widget-approvals.js, widget-scope.js
Language and appearance i18n.js, prefs.js, a11y.js, a11y-ui.js, icons.js, ui.js
Screens general.js, retention.js, changed.js, logs.js, profile.js, mail.js, mail-settings.js, signup.js, record-docs.js, viewer.js, share.js, assistant.js, chat-task.js
Operator page operator.js

The grouping follows the header comment of each file. It is a reading aid, not a structure in code.

Serving and the asset stamp

webapp/index.html links every stylesheet, module, and font under ./v/__ASSET_STAMP__/ (webapp/index.html:13-74). When the server returns index.html, it replaces the placeholder with asset_stamp(webapp_dir), a digest over every file in the folder, and answers with Cache-Control: no-cache and an ETag (src/cluster_erp/server/app.py:1616-1625 at commit 92f8051). A file requested under the current stamp is sent with public, max-age=31536000, immutable. A file under an older stamp is sent with no-cache (src/cluster_erp/server/app.py:1599-1614). A deploy therefore produces a new set of URLs. The stamp function is documented on cache and asset stamp.

The modulepreload list in index.html is generated by web-client/_gen_modulepreload.mjs and is marked as not for hand editing (webapp/index.html:24).

Security headers that shape the client

The server sends a content security policy with every response. Scripts may load only from the same origin and from blob: URLs. The comment states that blob: is required for the gated-app module import and for object-URL previews (src/cluster_erp/server/app.py:1325-1352 at commit 92f8051). Framing is limited to the same origin, which the duplicated home tiles need (src/cluster_erp/server/app.py:1348-1351). See gated app bundles and home screen, dock, and launcher.

Why it is built this way

  • Same-origin serving: the comment in src/cluster_erp/server/app.py:1574-1576 (at commit 92f8051) states that serving the front end from the API server lets the browser reach the API with no CORS.
  • Two mounts: the comment in src/cluster_erp/server/app.py:1578-1588 states that a reload previously cost 62 revalidation round trips, and that versioned URLs remove them while index.html still picks up a deploy at once.
  • Metadata-driven screens: the project's written engineering rules require that screen, form, list, and action behaviour comes from metadata and forbid UI-specific embedded rules. See metadata-driven UI.

Rules and boundaries

  • The generic engines gen-list.js, gen-detail.js, gen-form.js, entity.js, and gen-settings.js must not compare against business module names. tests/test_architecture_boundaries.py:75 (test_generic_web_engines_do_not_branch_on_business_module_names) enforces this.
  • Generic web files must not name module paths, module permissions, or per-language columns, and must not branch on a language code. tests/test_metadata_driven_rules.py:85 enforces this for eleven files.
  • The web app is mounted only when the webapp folder exists next to the package (src/cluster_erp/server/app.py:1633-1634).

Interaction with other parts

Limits and open points

  • The folder web-client/ holds the browser test battery and a separate Vite project. Whether that project is in use is not determined from code; see repository map.
  • index.html declares lang="tr" and a Turkish sign-in label in markup (webapp/index.html:2, webapp/index.html:161). Both are replaced at boot by the selected language (webapp/js/i18n.js:81, webapp/js/main.js:221).

Terms introduced

Term Code identifier Definition Turkish term Source
web app webapp/ The browser client in webapp/ that the server serves at /app. web uygulaması src/cluster_erp/server/app.py:1633
asset stamp placeholder __ASSET_STAMP__ The token in index.html that the server replaces with the current asset stamp. varlık damgası yer tutucusu webapp/index.html:18
versioned mount /app/v The static mount that serves files under a stamp as immutable. sürümlü bağlama src/cluster_erp/server/app.py:1635-1639

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13