content capa

content-calendar

Calendar events, as a 1:1 extension of encounters with public submission workflow

Calendar events, as a 1:1 extension of encounters with public submission workflow

Tiercontent
Roleunclassified (baselined)
Pathcrates/content/calendar
Edition2021
Targetscontent_calendar, integration
Public items14 across 1 module
Tests37

What it is for

# content-calendar

Architecture

Library crateWhat It Provides
domain/encountersCore event data (title, description, location, scheduled_start/end)
operations/workflowModeration pattern (ApprovalStatus: pending → approved/rejected)
`content/calendar`Composition layer + calendar-specific concerns

Key Design Decisions

1. 1:1 Extension Pattern: calendar_events uses encounter_id as its PK/FK. The table doesn't duplicate encounter fields - it only adds calendar-specific data.

2. Real FK Enforcement: submitted_by_party_id and reviewed_by_party_id are real foreign keys to the parties table (not fake "references consuming app" comments).

3. PartyId-First: Uses PartyId newtype everywhere for type safety.

4. Minimal States: Only pending, approved, rejected, cancelled. No draft state to avoid scope creep.

5. Trust Logic in Repo: Auto-approval happens in repository code, not database triggers. This keeps business logic testable and debuggable.

6. Scoped Trust: Trust is calendar-specific, not global.

Example

use content_calendar::{CalendarEvent, CalendarEventRepo, ModerationStatus};
use identity_parties::PartyId;
use uuid::Uuid;

// Submit an event (auto-approves if submitter is trusted)
let encounter_id = Uuid::new_v4();
let submitter = PartyId::new_v4();

let event = repo.submit(&pool, encounter_id, submitter).await?;

// Check status
if event.moderation_status == ModerationStatus::Pending {
// Needs review
repo.approve(&pool, encounter_id, reviewer_id, Some("Looks good!".into())).await?;
}

Capabilities

verb:approve

PostgreSQL repository functions for calendar events.

Item
async fn approve_event(pool : & PgPool, encounter_id : EncounterId, reviewer : PartyId, notes : Option <String>,) -> Result <(), CalendarError>

verb:create

PostgreSQL repository functions for calendar events.

Item
async fn create_calendar_scope(pool : & PgPool, name : & str, slug : & str, scope_type : ScopeType, owner_party_id : Option <PartyId>, default_visibility : Visibility, submission_policy : SubmissionPolicy, moderation_policy : ModerationPolicy, require_approval : bool,) -> Result <CalendarScope, CalendarError>

verb:get

PostgreSQL repository functions for calendar events.

Item
async fn get_calendar_event(pool : & PgPool, encounter_id : EncounterId,) -> Result <Option <CalendarEvent>, CalendarError>
async fn get_submitter_trust(pool : & PgPool, party_id : PartyId,) -> Result <Option <CalendarSubmitterTrust>, CalendarError>
async fn get_scope_by_slug(pool : & PgPool, slug : & str,) -> Result <Option <CalendarScope>, CalendarError>

verb:is

PostgreSQL repository functions for calendar events.

Item
async fn is_submitter_trusted(pool : & PgPool, party_id : PartyId) -> Result <bool, CalendarError>

verb:list

PostgreSQL repository functions for calendar events.

Item
async fn list_public_events(pool : & PgPool, from : DateTime <Utc>, to : DateTime <Utc>,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>
async fn list_pending_events(pool : & PgPool,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>
async fn list_scopes(pool : & PgPool) -> Result <Vec <CalendarScope>, CalendarError>
async fn list_events_by_scope(pool : & PgPool, scope_id : ScopeId, from : DateTime <Utc>, to : DateTime <Utc>,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>

verb:reject

PostgreSQL repository functions for calendar events.

Item
async fn reject_event(pool : & PgPool, encounter_id : EncounterId, reviewer : PartyId, notes : Option <String>,) -> Result <(), CalendarError>

verb:set

PostgreSQL repository functions for calendar events.

Item
async fn set_submitter_trust(pool : & PgPool, party_id : PartyId, is_trusted : bool, granted_by : PartyId, notes : Option <String>,) -> Result <(), CalendarError>

verb:submit

PostgreSQL repository functions for calendar events.

Item
async fn submit_calendar_event(pool : & PgPool, encounter_id : EncounterId, submitted_by : PartyId,) -> Result <CalendarEvent, CalendarError>
async fn submit_event_to_scope(pool : & PgPool, encounter_id : EncounterId, submitted_by : PartyId, scope_id : ScopeId, visibility : Option <Visibility>,) -> Result <CalendarEvent, CalendarError>

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

content_calendar

Public surface

`postgres`

ItemWhat it is
async fn submit_calendar_event(pool : & PgPool, encounter_id : EncounterId, submitted_by : PartyId,) -> Result <CalendarEvent, CalendarError>Submit a new calendar event for an existing encounter
async fn get_calendar_event(pool : & PgPool, encounter_id : EncounterId,) -> Result <Option <CalendarEvent>, CalendarError>Get a calendar event by its encounter ID.
async fn list_public_events(pool : & PgPool, from : DateTime <Utc>, to : DateTime <Utc>,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>List public approved events within a time range
async fn list_pending_events(pool : & PgPool,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>List all pending events awaiting moderation.
async fn approve_event(pool : & PgPool, encounter_id : EncounterId, reviewer : PartyId, notes : Option <String>,) -> Result <(), CalendarError>Approve a pending calendar event.
async fn reject_event(pool : & PgPool, encounter_id : EncounterId, reviewer : PartyId, notes : Option <String>,) -> Result <(), CalendarError>Reject a pending calendar event.
async fn is_submitter_trusted(pool : & PgPool, party_id : PartyId) -> Result <bool, CalendarError>Check if a party is trusted for auto-approval.
async fn set_submitter_trust(pool : & PgPool, party_id : PartyId, is_trusted : bool, granted_by : PartyId, notes : Option <String>,) -> Result <(), CalendarError>Grant or revoke trust for a party.
async fn get_submitter_trust(pool : & PgPool, party_id : PartyId,) -> Result <Option <CalendarSubmitterTrust>, CalendarError>Get the trust record for a party (if exists).
async fn create_calendar_scope(pool : & PgPool, name : & str, slug : & str, scope_type : ScopeType, owner_party_id : Option <PartyId>, default_visibility : Visibility, submission_policy : SubmissionPolicy, moderation_policy : ModerationPolicy, require_approval : bool,) -> Result <CalendarScope, CalendarError>Create a new calendar scope
async fn get_scope_by_slug(pool : & PgPool, slug : & str,) -> Result <Option <CalendarScope>, CalendarError>Get a calendar scope by its unique slug.
async fn list_scopes(pool : & PgPool) -> Result <Vec <CalendarScope>, CalendarError>List all calendar scopes.
async fn submit_event_to_scope(pool : & PgPool, encounter_id : EncounterId, submitted_by : PartyId, scope_id : ScopeId, visibility : Option <Visibility>,) -> Result <CalendarEvent, CalendarError>Submit a calendar event to a specific scope
async fn list_events_by_scope(pool : & PgPool, scope_id : ScopeId, from : DateTime <Utc>, to : DateTime <Utc>,) -> Result <Vec <CalendarEventWithEncounter>, CalendarError>List approved events within a scope for a time range.

Re-exports. Exported here, defined elsewhere.

ExportDefined in
CalendarErrorerror::CalendarError
PartyIdidentity_parties::PartyId
{CalendarEvent,CalendarEventWithEncounter,CalendarScope,CalendarSubmitterTrust,EncounterId,ModerationPolicy,ModerationStatus,ScopeId,ScopeType,SubmissionPolicy,Visibility,}models::{CalendarEvent,CalendarEventWithEncounter,CalendarScope,CalendarSubmitterTrust,EncounterId,ModerationPolicy,ModerationStatus,ScopeId,ScopeType,SubmissionPolicy,Visibility,}
{CalendarEventRepo,SubmitEventInput}repo::{CalendarEventRepo,SubmitEventInput}
{approve_event,create_calendar_scope,get_calendar_event,get_scope_by_slug,get_submitter_trust,is_submitter_trusted,list_events_by_scope,list_pending_events,list_public_events,list_scopes,reject_event,set_submitter_trust,submit_calendar_event,submit_event_to_scope,}postgres::{approve_event,create_calendar_scope,get_calendar_event,get_scope_by_slug,get_submitter_trust,is_submitter_trusted,list_events_by_scope,list_pending_events,list_public_events,list_scopes,reject_event,set_submitter_trust,submit_calendar_event,submit_event_to_scope,}

Boundary

Reaches into foundation, identity.

Shares tier content with 5 other crates: content-assets, content-calendar-recurrence, content-cms, content-directory-listing, content-notes.

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)content
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/content/calendar
Vocabulary in force (lexicon)current

Tier flow. Which tiers this crate's own edges cross.

flowchart LR
  n_content["content"] --> n_foundation["foundation"]
  n_content["content"] --> n_identity["identity"]

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`foundation-basemodels`foundationnoalways
`identity-parties`identitynoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
async-trait^0.1noalways
chrono^0.4serdenoalways
serde^1derivenoalways
serde_json^1noalways
sqlx^0.8runtime-tokio, postgres, chrono, uuid, jsonyesalways
thiserror^2noalways
uuid^1v4, serdenoalways

Development, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
dotenvy^0.15noalways
tokio^1fullnoalways
tokio-test^0.4noalways

Build. None.

Depended on by. 2 workspace crates.

Signal flow — what reaches this crate, and what it reaches.

flowchart LR
  n_application_calendar["application-calendar"] -->|uses| SELF
  n_foundation_test_support["foundation-test-support"] -->|uses| SELF
  SELF["content-calendar"]
  SELF -->|runtime| n_foundation_basemodels["foundation-basemodels"]
  SELF -->|runtime| n_identity_parties["identity-parties"]
  classDef self fill:#1f883d,stroke:#1f883d,color:#fff;
  class SELF self;

Feature flags

FeatureEnablesOn by default
defaultyes
postgresdep:sqlxno
flowchart LR
  n_default["default"]
  n_postgres["postgres"] --> n_dep_sqlx["dep:sqlx"]

Targets

KindNameSource
libcontent_calendar`src/lib.rs`
testintegration`tests/integration.rs`

Error model

No public error type was detected: no public item declares a type named *Error, and no public signature returns one.

Operational characteristics

PropertyEvidence
async public surfaceyes
async runtimenone detected
database accessyes
network I/Onone detected
unsafe codenone detected
environment variablesnone detected

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.

2 workspace crates depend on this one: application-calendar, foundation-test-support.

Verification

KindCount
Unit tests10
Integration tests27
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
postgres1406

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc1414
Public modules with a //! block11
pie showData
    title Public items with rustdoc
    "Documented" : 14
    "No rustdoc detected" : 0

Metrics

MetricValue
Rust source files5
Source lines1763
Code lines1265
Public API items14
Public modules1
Tests37
Examples0
Cargo features2
Direct runtime dependencies9
Workspace reverse dependencies2
pie showData
    title Public API by kind
    "function" : 14
pie showData
    title Rust source composition
    "Code" : 1265
    "Blank or comment" : 498

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

Todas las content · Manual