The app_store module exposes the app catalogue registry, the licence file, app assets, seat assignments per role, app requests and decisions, and install, re-consent, and uninstall actions. All 13 endpoints sit under /api/v1/app_store. For business meaning see the App store module page.
Group facts¶
| Item | Value | Source |
|---|---|---|
| Base path | /api/v1/app_store |
src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/app_store/module.py:57 |
| Routers | 1 router objects in 1 files; listed in the section Endpoint summary | src/cluster_erp/modules/app_store/module.py:54 |
| Endpoints | 13, counted from the route decorators and add_api_route calls of the routers that register_routes mounts |
src/cluster_erp/modules/app_store/routes.py |
| Authentication | Bearer header or session cookie, resolved by get_current_user; see Authentication and headers |
src/cluster_erp/modules/auth/guards.py:85-167 |
| Permission guard | 9 of 13 routes declare require_permission; the other routes show their guard in the tables |
src/cluster_erp/modules/auth/guards.py:205-240 |
| App entitlement gate | None attached in register_routes |
src/cluster_erp/modules/app_store/module.py:57 |
| Error format | JSON body {"error": {...}}; see Errors |
src/cluster_erp/server/error_handler.py:33-46 |
Endpoint summary¶
One row per sub-module folder. The router prefix is added to the base path.
| Sub-module | Routers | Endpoints | Router source |
|---|---|---|---|
routes |
router |
13 | src/cluster_erp/modules/app_store/routes.py:15 |
App store endpoints¶
One router with no prefix of its own. Four routes resolve the signed-in user in the handler; the others carry require_permission codes.
| Method | Path | Handler | Permission | Request | Query | Response | Status | Source |
|---|---|---|---|---|---|---|---|---|
GET |
/api/v1/app_store/registry |
get_registry |
authenticated user (get_current_user) |
none | none | dict |
200 (default) | src/cluster_erp/modules/app_store/routes.py:18 |
GET |
/api/v1/app_store/license |
get_license |
authenticated user (get_current_user) |
none | none | dict |
200 (default) | src/cluster_erp/modules/app_store/routes.py:61 |
POST |
/api/v1/app_store/license |
upload_license |
license.manage |
dict[str, Any] |
none | dict |
200 (default) | src/cluster_erp/modules/app_store/routes.py:71 |
DELETE |
/api/v1/app_store/license |
delete_license |
license.manage |
none | none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:85 |
GET |
/api/v1/app_store/assets/{app_key}/{filename} |
get_app_asset |
authenticated user (get_current_user) |
none | none | Response |
200 (default) | src/cluster_erp/modules/app_store/routes.py:103 |
GET |
/api/v1/app_store/apps/{app_key}/assignments |
get_assignments |
store_app.assign |
none | none | dict |
200 (default) | src/cluster_erp/modules/app_store/routes.py:158 |
PUT |
/api/v1/app_store/apps/{app_key}/assignments/{role_id} |
put_assignment |
store_app.assign |
dict[str, Any] |
none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:168 |
POST |
/api/v1/app_store/apps/{app_key}/request |
request_app |
authenticated user (get_current_user) |
none | none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:184 |
GET |
/api/v1/app_store/requests |
get_requests |
store_app.assign |
none | none | dict |
200 (default) | src/cluster_erp/modules/app_store/routes.py:197 |
POST |
/api/v1/app_store/requests/{request_id}/decide |
decide_request |
store_app.assign |
dict[str, Any] |
none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:228 |
POST |
/api/v1/app_store/apps/{app_key}/install |
install_app |
store_app.install |
none | none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:267 |
POST |
/api/v1/app_store/apps/{app_key}/reconsent |
reconsent_app |
store_app.install |
none | none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:277 |
POST |
/api/v1/app_store/apps/{app_key}/uninstall |
uninstall_app |
store_app.uninstall |
none | none | none | 204 |
src/cluster_erp/modules/app_store/routes.py:288 |
Error codes¶
The table lists the error codes that code under src/cluster_erp/modules/app_store/ raises, found by a syntax-tree scan for AppError(...), the factories in src/cluster_erp/core/errors.py (not_found, conflict, protected, permission_denied, privilege_escalation, check_version), and HTTPException(...). A status of 400 is the AppError default (src/cluster_erp/core/errors.py:23). Guard errors (401, 403), the entitlement codes, and validation errors (422) apply to every route and are listed on Errors.
| Code | HTTP status | Raised in | First site |
|---|---|---|---|
HTTP_404 |
404 |
routes, services |
src/cluster_erp/modules/app_store/routes.py:136 |
HTTP_409 |
409 |
services |
src/cluster_erp/modules/app_store/services.py:179 |
HTTP_422 |
422 |
services |
src/cluster_erp/modules/app_store/services.py:243 |
entitlement.asset_denied |
403 |
routes |
src/cluster_erp/modules/app_store/routes.py:127 |
Events emitted¶
The table lists the contract classes that code under src/cluster_erp/modules/app_store/ passes directly to EventBus.emit, found by a syntax-tree scan. Events built in a variable first are not counted. The contracts are described in Contracts reference.
None found by the scan.
Related pages¶
Verified against commit 92f8051 on 2026-11-13.