This page describes the content sub-module in src/cluster_erp/modules/intranet/content/ and the feed sub-module in src/cluster_erp/modules/intranet/feed/. Content holds spaces, posts with their publication history and acknowledgements, comments, reactions, translations, and the intranet settings. The feed merges posts, events, and recognition into one timeline. Access grants and audience segments are on access, audience, and retention.
Scope and source¶
- Defined in:
src/cluster_erp/modules/intranet/models.py(IntranetSettings,IntranetSpace,IntranetContent,IntranetContentVariant,IntranetContentRevision,IntranetReaction,IntranetComment,IntranetPublication,IntranetPublicationRecipient,IntranetAcknowledgment,IntranetAnalyticsEvent),content/services.py,content/routes.py,content/metadata.py,feed/services.py, andfeed/routes.py. - Count: 38 routes in
content/routes.pyand 1 infeed/routes.py; 8ActionMetaentries incontent/metadata.py.
Content fields¶
| Name | Meaning | Source |
|---|---|---|
code, space_id, kind |
Business key, space, and kind: page, news, policy, or alert |
src/cluster_erp/modules/intranet/models.py:68, src/cluster_erp/modules/intranet/models.py:263-267 |
title, slug, summary, body |
Text; body is a list of blocks |
src/cluster_erp/modules/intranet/models.py:268-271 |
owner_party_id, deputy_party_id |
Owner and deputy | src/cluster_erp/modules/intranet/models.py:273-278 |
status, primary_language |
Lifecycle state and language | src/cluster_erp/modules/intranet/models.py:279-284 |
publish_at, feature_from, feature_to, review_at, expire_at |
The date pairs of publication, featuring, review, and expiry | src/cluster_erp/modules/intranet/models.py:285-295 |
is_pinned, priority |
Pin and order | src/cluster_erp/modules/intranet/models.py:296-297 |
mandatory_read, ack_statement |
Whether readers must acknowledge, and the statement they confirm | src/cluster_erp/modules/intranet/models.py:299-303 |
audience_segment_id |
Target segment; empty means every active employee | src/cluster_erp/modules/intranet/models.py:304-307, src/cluster_erp/modules/intranet/content/services.py:1022-1042 |
allow_comments, allow_reactions, version_no, view_count |
Switches and counters | src/cluster_erp/modules/intranet/models.py:311-318 |
Statuses and actions¶
A post is draft, in_review, approved, published, or archived (src/cluster_erp/modules/intranet/models.py:69-75). The service allows these transitions (src/cluster_erp/modules/intranet/content/services.py:103-114):
stateDiagram-v2 [*] --> draft draft --> in_review: submit_review in_review --> approved: approve draft --> approved: approve in_review --> draft: return_to_draft approved --> draft: return_to_draft draft --> published: publish in_review --> published: publish approved --> published: publish published --> published: publish again published --> draft: unpublish published --> archived: archive archived --> draft: restore
In prose: a post starts as a draft, can be sent to review, approved, and published. Publishing again from published creates a new version. Unpublish returns it to draft and keeps the publication rows as history. Archive is possible from every state except archived, and Restore to Draft brings it back.
| Action key | Label | Condition | Source |
|---|---|---|---|
submit_review |
Submit for Review | status is draft |
src/cluster_erp/modules/intranet/content/metadata.py:134-142 |
approve |
Approve | status is in_review |
src/cluster_erp/modules/intranet/content/metadata.py:143-151 |
publish |
Publish | status is approved |
src/cluster_erp/modules/intranet/content/metadata.py:152-160 |
publish_draft |
Publish Now | status is draft |
src/cluster_erp/modules/intranet/content/metadata.py:161-169 |
republish |
Re-publish | status is published |
src/cluster_erp/modules/intranet/content/metadata.py:170-178 |
archive |
Archive | status is published |
src/cluster_erp/modules/intranet/content/metadata.py:179-187 |
restore |
Restore to Draft | status is archived |
src/cluster_erp/modules/intranet/content/metadata.py:188-196 |
All run on POST /content/{id}/actions/{action}. The editorial actions approve, publish, unpublish, archive, and restore need intranet_content.publish in addition to intranet_content.update. When the space or the post carries publish grants, the actor must match one (src/cluster_erp/modules/intranet/content/routes.py:243-264, src/cluster_erp/modules/intranet/content/services.py:808-855). The eighth ActionMeta is rebuild on segments (src/cluster_erp/modules/intranet/content/metadata.py:416-420).
Publication and acknowledgement¶
Publishing does five things (src/cluster_erp/modules/intranet/content/services.py:953-1020):
- It raises
version_no, setspublishedandpublish_at, and stores an immutable revision (IntranetContentRevision). - It writes an
IntranetPublicationrow with the acknowledgement terms and the SHA-256 hash of the acknowledgement statement. - It freezes the recipient set. A post with a segment rebuilds the segment against the current employees first; a post without a segment targets every active employee (
src/cluster_erp/modules/intranet/content/services.py:1022-1042). - For a mandatory read, it inserts one notification per recipient with kind
mandatory_read. - The route then emits
IntranetPostPublishedwith the recipient count (src/cluster_erp/modules/intranet/content/routes.py:266-283).
Acknowledging is idempotent: one row per publication, party, and version. The row records the time, the client address, the User-Agent header, the signature kind, and the statement hash (src/cluster_erp/modules/intranet/content/services.py:1087-1131). GET /content/{id}/compliance returns the recipient count, the acknowledgement count, and up to 500 pending party ids (src/cluster_erp/modules/intranet/content/services.py:1044-1081). GET /content/pending-acks lists the caller's open mandatory reads (src/cluster_erp/modules/intranet/content/routes.py:181-202, src/cluster_erp/modules/intranet/content/services.py:1147).
Comments, reactions, views, and translations¶
- Comments are created as
published. Moderation setspublished,hidden, orpending; the code comment states that hidden is a quarantine state, not a deletion (src/cluster_erp/modules/intranet/models.py:141,src/cluster_erp/modules/intranet/content/services.py:1266-1302). Moderation needsintranet_content.publish(src/cluster_erp/modules/intranet/content/routes.py:500-504). - A reaction is set or removed per party and post (
src/cluster_erp/modules/intranet/content/services.py:1195-1245). POST /content/{id}/viewcounts a view, marks the first view on the publication recipient, and records an analytics event (src/cluster_erp/modules/intranet/content/services.py:857-887).- A translation (
IntranetContentVariant) is one row per language with the source version it was made from (src/cluster_erp/modules/intranet/content/services.py:903-932). - Editing never changes the status and does not reset the review date unless a new one is sent (
src/cluster_erp/modules/intranet/content/services.py:794-806).
Feed¶
GET /feed/ returns one timeline of the types post, event, and kudos, newest first, with a before cursor and a limit from 1 to 50 (src/cluster_erp/modules/intranet/feed/routes.py:26-37). The route drops event and kudos when the caller lacks intranet_event.read or intranet_kudos.read, and applies the content access filter unless the caller holds intranet_content.read_all (src/cluster_erp/modules/intranet/feed/routes.py:38-55). Pinned posts lead the first page only (src/cluster_erp/modules/intranet/feed/services.py:91-99). Each item carries its media and, for posts, reaction and comment counts (src/cluster_erp/modules/intranet/feed/services.py:1-5).
Settings and spaces¶
GETandPUT /settings/read and write the single settings row (src/cluster_erp/modules/intranet/content/routes.py:659-685).- The home layout is a list of sections. The shipped default enables alerts, greeting, for-you, celebrations, feed, events, and quick links, and disables kudos. Unknown keys are dropped and missing sections are appended disabled (
src/cluster_erp/modules/intranet/content/services.py:55-100). - A space (
IntranetSpace) has a code, name, slug, parent, owner, icon, colour, and order (src/cluster_erp/modules/intranet/models.py:202-237).
Constraints and validation¶
- An unknown action or a disallowed source status is refused with
INTRANET_INVALID_STATUS(src/cluster_erp/modules/intranet/content/services.py:819-831). - Acknowledging an unpublished post is refused (
src/cluster_erp/modules/intranet/content/services.py:1096-1101). - Deleting a post sets
deleted_at(src/cluster_erp/modules/intranet/content/routes.py:287-301).
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| publication | IntranetPublication |
One published version of a post with its frozen recipient set and acknowledgement terms. | Yayın | src/cluster_erp/modules/intranet/models.py:511 |
| acknowledgement | IntranetAcknowledgment |
The audit record that one person confirmed one version of a mandatory read. | Okundu onayı | src/cluster_erp/modules/intranet/models.py:570 |
| mandatory read | mandatory_read |
A post that recipients must acknowledge. | Zorunlu okuma | src/cluster_erp/modules/intranet/models.py:299 |
Related pages¶
Verified against commit 92f8051 on 2026-11-13.