Skip to content

Terms of Use Module

Manages versioned legal agreements (Terms of Use, Privacy Policy, Community Code of Conduct) with semantic versioning, publishing control, acceptance tracking, and GDPR compliance.

Key Concepts

Versioning

Uses semantic versioning (e.g., 1.0.0, 1.1.0). Multiple published versions can coexist. Drafts (published_at = null) can be edited freely.

Structure

Each version has three sections with RTE content and auto-generated ToC:

  1. General Terms of Use - Platform terms and user conduct
  2. Privacy Policy - legal compliance (GDPR, etc.), data handling
  3. Community Code of Conduct - Community standards

Publishing

Versions are drafts until published. Publishing sets published_at = now() and validates all three sections have content. Published state is determined by published_at !== null.

Acceptance Tracking

Records member acceptances with GDPR Article 7 compliance:

  • Core: member_id, version, accepted_at
  • GDPR: ip_address, user_agent, acceptance_method, language, context (JSON)
  • Unique constraint: (member_id, version) - updates timestamp on re-acceptance

Data Model

TermsOfUse

Table: terms_of_use__versions

Fields:

  • version - Semantic version string
  • {section}_content - RTE content (text)
  • {section}_toc - Auto-generated ToC (JSON array)
  • published_at - Publication timestamp (null = draft)
  • Sections: general_terms, privacy_policy, community_code_of_conduct

Relations: acceptances() HasMany

Scopes: published(), unpublished(), latestPublished(), byVersion(string)

Methods: isPublished(), publish()

TermsOfUseAcceptance

Table: terms_of_use__acceptances

Fields: member_id, version, accepted_at, ip_address, user_agent, acceptance_method, language, context (JSON)

Indexes: Unique on (member_id, version), indexed on ip_address

Relations: member() BelongsTo, termsOfUse() BelongsTo (via version)

Methods:

  • recordAcceptance(int $memberId, string $version, ?string $ipAddress, ?string $userAgent, ?string $acceptanceMethod, ?string $language, ?array $context) - Create/update acceptance
  • memberHasAcceptedVersion(int $memberId, string $version) - Check acceptance

Nova Usage

Create: Nova → Terms of Use → Create → Enter version → Fill all sections → Save (draft)

Publish: Open draft → "Publish Version" action → Validates all sections → Sets published_at

Acceptances: Nova → Acceptances (or view per-version via relationship)

Structure

text
app/Modules/TermsOfUse/
├── Models/{TermsOfUse, TermsOfUseEloquentBuilder, TermsOfUseAcceptance}
├── Nova/{TermsOfUse, TermsOfUseAcceptance, Actions/PublishVersionAction}
└── Database/Migrations/

Tests: 19 tests across models and query builder (factories, no mocks)

Related: Member, Membership modules