Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Module

App store module (app_store)

Module page for app_store, which holds the app catalogue, the licence, role seat assignments, app requests, and the deployment's install state.

The app_store module in src/cluster_erp/modules/app_store/ is a platform module. It keeps the catalogue of sellable apps, the uploaded licence, which roles may use which app, users' requests for apps, and which apps the deployment has installed. Administrators manage it through the store and app manager apps; every user's launcher is rendered from its registry. The enforcement on other modules' APIs is in server/entitlements.py and is explained in app store licensing and entitlements.

At a glance

Item Value Source
Package src/cluster_erp/modules/app_store/ folder
Module class Module src/cluster_erp/modules/app_store/module.py:18
name / version app_store / 0.1.0 src/cluster_erp/modules/app_store/module.py:26-32
API prefix /api/v1/app_store (ModuleBase.api_prefix) src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/app_store/module.py:54-57
Sub-modules 0; a flat module with license.py, models.py, routes.py, services.py, and catalog.json folder listing
Tables 5: app_store_apps, app_store_licenses, app_store_assignments, app_store_requests, app_store_installs src/cluster_erp/modules/app_store/models.py:32-138
Entities in metadata 0; no sidebar content src/cluster_erp/modules/app_store/module.py:65-79
Web app presence System apps store, app-library, and app-manager in the catalogue; gallery folders in webapp/store/ src/cluster_erp/modules/app_store/catalog.json
Desktop presence none; no folder in src/cluster_erp/desktop/modules/ folder

What the module does

  • Converges the catalogue table to the shipped catalog.json at every start-up and installs new apps on first boot (src/cluster_erp/modules/app_store/module.py:38-52, src/cluster_erp/modules/app_store/services.py:91-135).
  • Serves each user's registry: every enabled app with its entitled, installed, seat, and reconsent state (src/cluster_erp/modules/app_store/routes.py:18-39).
  • Stores and re-verifies the licence (src/cluster_erp/modules/app_store/services.py:191-265).
  • Keeps role seat rules and app requests (src/cluster_erp/modules/app_store/services.py:267-361).
  • Installs, reconsents, and uninstalls apps (src/cluster_erp/modules/app_store/services.py:169-189).
  • Serves per-app JavaScript bundles from gated_apps/ after a layer check (src/cluster_erp/modules/app_store/routes.py:95-155).

Sub-modules

Sub-module Purpose Main entities Router Source
none (flat module) Catalogue, licence, seats, requests, installs StoreApp, AppLicense, AppAssignment, AppRequest, AppInstall /api/v1/app_store src/cluster_erp/modules/app_store/routes.py (router)

Data model

Entity Table Key fields Notes Source
StoreApp app_store_apps app_key, enabled, sort, manifest manifest is JSONB with labels, screen wiring, and covered modules src/cluster_erp/modules/app_store/models.py:14-52
AppLicense app_store_licenses raw_text, licensee, status_cache, last_seen_at newest live row wins src/cluster_erp/modules/app_store/models.py:55-75
AppAssignment app_store_assignments app_key, role_id, intent unique (app_key, role_id) among live rows src/cluster_erp/modules/app_store/models.py:77-104
AppRequest app_store_requests app_key, requested_by, status, decided_by, decision_reason src/cluster_erp/modules/app_store/models.py:107-120
AppInstall app_store_installs app_key, status, app_version, consented_modules unique app_key among live rows src/cluster_erp/modules/app_store/models.py:123-162

The catalogue holds 28 apps, 6 of them system apps, counted from the entries of catalog.json.

Screens and metadata

The module declares no metadata entities; its surfaces are dedicated apps, not metadata screens (src/cluster_erp/modules/app_store/module.py:65-79). The licence card shows License Status (webapp/i18n/en.json key license.status_title) and the store shows License required for an unlicensed app (webapp/i18n/en.json key store.license_needed). The client code is documented in gated app bundles.

Status and actions

Record Values Source
Licence state none, invalid, active, grace, read_only src/cluster_erp/modules/app_store/license.py:9-14
AppInstall.status installed, uninstalled src/cluster_erp/modules/app_store/services.py:169-189
AppRequest.status pending, approved, denied src/cluster_erp/modules/app_store/models.py:114-116, src/cluster_erp/modules/app_store/services.py:352
AppAssignment.intent required, available, blocked src/cluster_erp/modules/app_store/services.py:282
Action Label Condition Endpoint Permission Source
upload licence Upload and Verify (license.upload) licensing armed; document verifies POST /api/v1/app_store/license license.manage src/cluster_erp/modules/app_store/routes.py:71-82
remove licence none in metadata a licence exists DELETE /api/v1/app_store/license license.manage src/cluster_erp/modules/app_store/routes.py:85-92
request app none in metadata authenticated POST /api/v1/app_store/apps/{app_key}/request authentication only src/cluster_erp/modules/app_store/routes.py:184-191
decide request none in metadata request pending POST /api/v1/app_store/requests/{request_id}/decide store_app.assign src/cluster_erp/modules/app_store/routes.py:228-264
install, reconsent none in metadata known app; reconsent needs installed POST /api/v1/app_store/apps/{app_key}/install, /reconsent store_app.install src/cluster_erp/modules/app_store/routes.py:267-285
uninstall none in metadata not a system app POST /api/v1/app_store/apps/{app_key}/uninstall store_app.uninstall src/cluster_erp/modules/app_store/routes.py:288-295

Business rules

  • A seat rule blocked on any of the user's roles wins; once any required or available rule exists, only those roles get the app; an app without rules is open (src/cluster_erp/modules/app_store/services.py:23-47).
  • Approving an app request makes the app available for every live role of the requester (src/cluster_erp/modules/app_store/services.py:357-361, src/cluster_erp/modules/app_store/routes.py:243-252).
  • Re-seeding never re-enables an app that an operator withdrew from sale (src/cluster_erp/modules/app_store/services.py:91-99).
  • A replaced or removed licence stays as a deactivated row (src/cluster_erp/modules/app_store/services.py:246-265).

Events and queries

The module registers no EventBus handlers (src/cluster_erp/modules/app_store/module.py:59-60). It reads role ids through role_ids_for in modules/auth/guards.py (src/cluster_erp/modules/app_store/routes.py:250-252).

Direction Contract class Handler or emitter Source
none none none src/cluster_erp/modules/app_store/module.py:59-60

Permissions

Permission key Used by Source
license.manage licence upload and removal src/cluster_erp/modules/app_store/routes.py:71-92
store_app.assign assignments, request list, request decision src/cluster_erp/modules/app_store/routes.py:158-264
store_app.install install and reconsent src/cluster_erp/modules/app_store/routes.py:267-285
store_app.uninstall uninstall src/cluster_erp/modules/app_store/routes.py:288-295

The four codes are seeded as extra codes (src/cluster_erp/server/app.py:801-807). The registry, the licence read, the asset route, and app requests need authentication only (src/cluster_erp/modules/app_store/routes.py:18-66, src/cluster_erp/modules/app_store/routes.py:103-110).

Privacy, retention, and history

The module holds no personal data beyond user and role ids on requests and assignments; it has no privacy_handlers.py. All tables derive from BaseModel, so their changes are in change history; see change history.

Analytics facts

This module has no analytics_facts.py.

Settings and reference data

license_public_key arms licensing; when empty, every catalogue app is entitled (src/cluster_erp/config/settings.py:566-569). The catalogue itself is vendor data in catalog.json (src/cluster_erp/modules/app_store/services.py:50-63).

Tests

Found by file name in tests/ and web-client/.

Kind File Covers
pytest tests/test_entitlement_stamp.py entitlement cache version stamp (2 tests)
pytest tests/test_store_catalog_assets.py catalogue screenshots and captions (4 tests)
e2e web-client/_e2e_app_store.mjs, web-client/_e2e_store.mjs, web-client/_e2e_store_uibook.mjs store and app manager
e2e web-client/_e2e_license.mjs licence upload and states

Terms introduced

Term Code identifier Definition Turkish term Source
app request AppRequest A user's request to be granted a seat on an app. uygulama isteği src/cluster_erp/modules/app_store/models.py:107
system app manifest.system A catalogue app that is always entitled and cannot be uninstalled. sistem uygulaması src/cluster_erp/modules/app_store/services.py:182-189

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

Verified against commit 92f8051 · 2026-11-13