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

Module

Documents module (documents)

Module page for documents, with typed documents linked to any record, numbered versions, activation through an approval chain, and document types.

The documents module in src/cluster_erp/modules/documents/ keeps controlled documents. A document has a type, may be linked to any record by entity type and id, and carries numbered versions. One version at a time is active; a new version becomes active either at once or through an approval chain. The module also provides the "documents attached to this record" capability that the web app finds by metadata.

At a glance

Item Value Source
Package src/cluster_erp/modules/documents/ folder
Module class Module src/cluster_erp/modules/documents/module.py:18
name / version documents / 0.1.0 src/cluster_erp/modules/documents/module.py:19-25
API prefix /api/v1/documents (ModuleBase.api_prefix), with the app gate require_app("documents") src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/documents/module.py:48-63
Sub-modules 2: documents, settings; plus privacy_handlers.py folder listing
Tables 3: documents_documents, documents_versions, documents_types __tablename__ in the two models.py files
Entities in metadata 3 keys in entities src/cluster_erp/modules/documents/module.py:267-271
Routes 23 route decorators in the package grep for @...router.get/post/put/patch/delete
Actions 5 ActionMeta entries grep "ActionMeta(" in the package
Migrations 7 files files in migrations/versions/ whose text contains one of the three table names
Contracts consumes 5, produces 6 see the section "Events and queries"
Web app presence Catalogue app documents; the capability record_documents used by the record documents panel src/cluster_erp/modules/app_store/catalog.json (entry documents), src/cluster_erp/modules/documents/module.py:228-230
Desktop presence generic widgets only src/cluster_erp/desktop/modules/ has no documents folder

What the module does

  • Keeps documents with a business code, a type, a title, translations, a description, and an optional link to any record through entity_type and entity_id (src/cluster_erp/modules/documents/documents/models.py:26-49).
  • Keeps numbered versions per document; each version points to a file in the core attachments store (src/cluster_erp/modules/documents/documents/models.py:52-87). Storage is described on attachments, notes, and storage.
  • Activates a version directly or after an approval chain decides, and marks the previous active version as superseded (src/cluster_erp/modules/documents/documents/services.py:255-337).
  • Keeps document types with allowed file extensions and seeds a default set (src/cluster_erp/modules/documents/settings/models.py:11-28, src/cluster_erp/modules/documents/module.py:37-46).
  • Answers other modules: the documents of a record, and the file behind a version (src/cluster_erp/modules/documents/module.py:98-149).

Sub-modules

Sub-module Purpose Main entities Router Source
documents Documents and their versions Document, DocumentVersion /documents, /versions src/cluster_erp/modules/documents/documents/routes.py:38-383
settings Document types DocumentType /settings/document-types src/cluster_erp/modules/documents/settings/routes.py:20-107

Data model

Entity Table Key fields Notes Source
Document documents_documents code, document_type_id, entity_type, entity_id, title, translations, description, is_active, extra code unique; extra holds tenant field values src/cluster_erp/modules/documents/documents/models.py:26-49
DocumentVersion documents_versions code, document_id, version_no, status, valid_from, valid_to, attachment_id, change_notes, approved_by, approved_at version_no unique per document among live rows src/cluster_erp/modules/documents/documents/models.py:52-87
DocumentType documents_types code, name, translations, description, allowed_extensions, is_active code unique among live rows src/cluster_erp/modules/documents/settings/models.py:11-28

Document codes come from the sequence document and version codes from document_version (src/cluster_erp/modules/documents/documents/services.py:110-111, src/cluster_erp/modules/documents/documents/services.py:208). A new version takes the next number after the highest live version (src/cluster_erp/modules/documents/documents/services.py:200-221).

Screens and metadata

get_metadata declares a sidebar group Documents (Turkish Belgeler) with a list section Documents and a settings section with the tab document_type (src/cluster_erp/modules/documents/module.py:232-265). The module publishes provides={"record_documents": {...}}, so the web client finds the record documents feature by capability, not by module name (src/cluster_erp/modules/documents/module.py:228-230). The record documents panel and the viewer are described on records, documents, viewer, and share.

Status and actions

A version is draft, active, superseded, or withdrawn (src/cluster_erp/modules/documents/documents/services.py:200-337). The diagram shows the version and approval chain.

flowchart TD
 V["DocumentVersion draft"] --> S["POST /versions/id/submit-approval"]
 S --> Q{"GetApprovalChainForAction: document_version, activate"}
 Q -->|no chain| ACT["DocumentVersionService.activate"]
 Q -->|chain| SUB["SubmitForApproval"]
 SUB --> AC["ApprovalCompleted event"]
 AC -->|final_status approved| ACT
 AC -->|other status| STAY["version stays draft"]
 V --> D["POST /versions/id/activate"]
 D --> ACT
 ACT --> SUP["previous active version: superseded"]
 ACT --> NEW["this version: active, approved_by, approved_at"]
 NEW --> W["POST /versions/id/withdraw: withdrawn"]

In prose:

  1. A version starts as a draft. Only a draft can be edited or deleted (src/cluster_erp/modules/documents/documents/services.py:223-253).
  2. Submit for Approval asks GetApprovalChainForAction for the resource document_version and the action activate. Without a chain, it activates the version at once. With a chain, it calls SubmitForApproval and the version stays a draft (src/cluster_erp/modules/documents/documents/routes.py:302-351).
  3. When the auth module publishes ApprovalCompleted for a document_version with final_status approved, the handler reads the decider through GetApprovalRequestById and activates the version. Any other final status leaves it as a draft (src/cluster_erp/modules/documents/module.py:151-204).
  4. Activate needs a draft with an attachment. It marks the current active version superseded, sets the new one active with the approver and time, and emits DocumentVersionSuperseded and DocumentVersionActivated (src/cluster_erp/modules/documents/documents/services.py:255-295, src/cluster_erp/modules/documents/documents/services.py:316-337).
  5. Withdraw moves an active version to withdrawn (src/cluster_erp/modules/documents/documents/services.py:297-314).
Action Label Condition Endpoint Permission Source
view_version View none GET /versions/{id}/file document_version.read src/cluster_erp/modules/documents/documents/metadata.py:266-272, src/cluster_erp/modules/documents/documents/routes.py:240-268
submit_approval Submit for Approval status is draft POST /versions/{id}/submit-approval document_version.submit_approval src/cluster_erp/modules/documents/documents/metadata.py:273-280
activate Activate status is draft POST /versions/{id}/activate document_version.activate src/cluster_erp/modules/documents/documents/metadata.py:281-288, src/cluster_erp/modules/documents/documents/routes.py:354-369
withdraw Withdraw status is active POST /versions/{id}/withdraw document_version.withdraw src/cluster_erp/modules/documents/documents/metadata.py:289-296, src/cluster_erp/modules/documents/documents/routes.py:371-383
seed_defaults Seed Defaults none POST /settings/document-types/seed-defaults document_type.seed src/cluster_erp/modules/documents/settings/metadata.py:30-36, src/cluster_erp/modules/documents/settings/routes.py:52-58

Approval chains are described on approvals and approval chains.

Business rules

  • A version without an attachment cannot be activated (src/cluster_erp/modules/documents/documents/services.py:269-274).
  • At most one version per document is active; activation supersedes the previous one (src/cluster_erp/modules/documents/documents/services.py:316-337).
  • Tenant field values in extra are validated on create (src/cluster_erp/modules/documents/documents/services.py:110-115). See tenant fields.
  • GET /versions/{id}/file streams the file of the version from storage and answers not found when the file is missing (src/cluster_erp/modules/documents/documents/routes.py:240-268).
  • Deleting a document or a draft version sets deleted_at; bulk delete uses the core soft-delete helper (src/cluster_erp/modules/documents/documents/services.py:150-162, src/cluster_erp/modules/documents/documents/services.py:241-253).

Events and queries

The module consumes 5 contracts and produces 6, counted as on the fleet module page. The full list is on the contracts reference.

Direction Contract class Handler or emitter Source
subscribes ApprovalCompleted _handle_approval_completed src/cluster_erp/modules/documents/module.py:74-77, src/cluster_erp/modules/documents/module.py:151-204
answers query ResolveDocumentVersionFile _handle_resolve_version_file src/cluster_erp/modules/documents/module.py:78, src/cluster_erp/modules/documents/module.py:127-149
answers query GetDocumentsForEntity _handle_get_documents_for_entity src/cluster_erp/modules/documents/module.py:79, src/cluster_erp/modules/documents/module.py:98-125
subscribes CollectSubjectData, AnonymiseSubject privacy_handlers.py src/cluster_erp/modules/documents/module.py:81-96
emits DocumentCreated DocumentService.create src/cluster_erp/modules/documents/documents/services.py:119-126
emits DocumentVersionActivated, DocumentVersionSuperseded activate, _supersede_active src/cluster_erp/modules/documents/documents/services.py:284-293, src/cluster_erp/modules/documents/documents/services.py:328-337
queries GetApprovalChainForAction, SubmitForApproval, GetApprovalRequestById submit route, approval handler src/cluster_erp/modules/documents/documents/routes.py:325-350, src/cluster_erp/modules/documents/module.py:178-183

ResolveDocumentVersionFile serves the intranet delivery download, and GetDocumentsForEntity serves the intranet "my documents" list (src/cluster_erp/modules/intranet/delivery/routes.py:143-150, src/cluster_erp/modules/intranet/my_documents/services.py:17-28).

Permissions

Permission key Used by Source
document.read, .create, .update, .delete, .bulk_delete documents src/cluster_erp/modules/documents/documents/routes.py:59-180
document_version.read, .create, .update, .delete, .submit_approval, .activate, .withdraw versions src/cluster_erp/modules/documents/documents/routes.py:194-377
document_type.read, .create, .update, .delete, .bulk_delete, .seed document types src/cluster_erp/modules/documents/settings/routes.py:23-102

Privacy, retention, and history

privacy_handlers.py lists the documents filed against a person (entity type party). Anonymisation is an operator decision (include_documents); when included, the documents are retired, their title and description replaced, and the version files reported for removal (src/cluster_erp/modules/documents/privacy_handlers.py:1-9). See privacy and data-subject requests. The module has no retention_handlers.py. Changes are captured by change history.

Analytics facts

This module has no analytics_facts.py.

Settings and reference data

Document types are reference data. On start the module seeds the default set through DocumentTypeService.seed_defaults, and Seed Defaults runs it on demand (src/cluster_erp/modules/documents/module.py:37-46, src/cluster_erp/modules/documents/settings/routes.py:52-58). seed_data.py holds 15 default types, for example form, instruction, procedure, and technical_drawing, each with an English name and a Turkish translation (src/cluster_erp/modules/documents/settings/seed_data.py:1-113).

Tests

Found by name (web-client/_e2e_doc*.mjs, web-client/_e2e_record_docs.mjs) and by a grep for documents in tests/*.py.

Kind File Covers
e2e web-client/_e2e_doc_version.mjs versions and activation
e2e web-client/_e2e_doc_viewer.mjs the document viewer
e2e web-client/_e2e_record_docs.mjs documents attached to records
e2e web-client/_e2e_intranet_mydocs.mjs the intranet lens over documents
pytest tests/test_erasure_ledger.py, tests/test_metadata_driven_rules.py, tests/test_secure_defaults.py, tests/test_order_shipment_chain.py files that mention documents

Discrepancies

Terms introduced

Term Code identifier Definition Turkish term Source
document Document A controlled document with a type, optionally linked to a record. Belge src/cluster_erp/modules/documents/documents/models.py:26
document version DocumentVersion One numbered revision of a document with its file and status. Belge sürümü src/cluster_erp/modules/documents/documents/models.py:52
document type DocumentType Reference row that classifies documents and lists allowed file extensions. Belge türü src/cluster_erp/modules/documents/settings/models.py:11

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

Verified against commit 92f8051 · 2026-11-13