My App
Features

Campaign Approval

Workflow for creating and approving investor marketing campaigns

Feature Specification: Campaign Approval

Feature Owner / Responsible Team: Growth & Marketing Engineering

Feature Version: v1.2

Last Updated: 2024-03-13


Feature Purpose

The Campaign Approval feature ensures that all marketing and investor relations (IR) campaigns go through a structured review process before being published to retail investors. It guarantees compliance with regulatory standards and internal quality guidelines.

Modules Involved:

  • Campaign Management Module
  • Compliance & Review Module
  • Notification System Module

Feature Description

This feature allows marketing teams to draft investor campaigns (emails, landing page announcements, community posts) and submit them for review. Compliance officers and designated approvers receive notifications, review the content, and either approve, reject, or request changes. Approved campaigns can be scheduled for distribution.


User Workflow

  1. Drafting: A Marketing User creates a new campaign draft in the Campaign Builder.
  2. Submission: The user clicks "Submit for Approval". The system prompts for a target publish date and optional reviewers.
  3. Notification: Approvers receive an email and in-app notification about the pending review.
  4. Review: An Approver opens the campaign, reviews the content, and selects an action (Approve, Request Changes, or Reject) along with mandatory comments for rejections/changes.
  5. Resolution:
    • If Approved, the campaign status changes to Ready for Scheduling.
    • If Request Changes, the state goes back to Draft with the reviewer's comments added to the history.
    • If Rejected, the campaign is archived.

System Workflow

  1. Client sends a POST /api/campaigns/{id}/submit request.
  2. The Backend validates that the campaign has all required fields (content, audience, dates).
  3. The state machine transitions the status from DRAFT to PENDING_REVIEW.
  4. The system creates an ApprovalRequest record linked to the campaign.
  5. An async job is dispatched to the Notification Service to alert users with the CAMPAIGN_APPROVER role.
  6. When an approver submits their decision (POST /api/campaigns/approvals/{id}), the state machine processes the transition and triggers the corresponding notification and audit log events.

UI Components

  • Screens involved:
    • Campaign Draft View
    • Approval Dashboard (List of pending reviews)
    • Campaign Review Detail View
  • Buttons:
    • Submit for Approval (Primary action in Draft view)
    • Approve (Success color, in Review view)
    • Request Changes (Warning color, in Review view)
    • Reject (Danger color, in Review view)
  • Inputs:
    • Reviewer Comments (Textarea, required for Rejections/Changes)
  • Validations:
    • Cannot submit if content length < 100 chars.
    • Cannot submit if target date is in the past.
  • User feedback behavior:
    • Toast notifications for successful transitions.
    • Loading states on buttons during API calls.

Business Logic

  • Rule 1: Only users with the CAMPAIGN_APPROVER role can approve campaigns.
  • Rule 2: The creator of a campaign cannot approve their own campaign, even if they have the approver role.
  • Rule 3: Once a campaign is approved, its content becomes locked and immutable. Any further edits require reverting the status to Draft and restarting the approval process.

Database / Data Structure

  • Campaign Table:
    • id (UUID, PK)
    • title (String)
    • content (Text)
    • status (Enum: DRAFT, PENDING_REVIEW, APPROVED, REJECTED, SCHEDULED)
    • author_id (UUID, FK to User)
  • ApprovalRequest Table:
    • id (UUID, PK)
    • campaign_id (UUID, FK to Campaign)
    • reviewer_id (UUID, FK to User, nullable)
    • decision (Enum: PENDING, APPROVED, REJECTED, CHANGES_REQUESTED)
    • comments (Text)
    • created_at (Timestamp)
    • resolved_at (Timestamp, nullable)
  • AuditLog Table:
    • Records all state changes for compliance tracking.

API Endpoints

  • GET /api/campaigns/pending-approvals
    • Provides a list of campaigns waiting for the current user's review.
  • POST /api/campaigns/{id}/submit
    • Submits a draft campaign into the approval workflow.
  • POST /api/campaigns/approvals/{approval_id}
    • Submits a decision for a pending approval (body: { decision, comments }).

Error Handling

  • 403 Forbidden: If a non-approver tries to approve, or an author tries to approve their own campaign. System responds with "Action not permitted."
  • 400 Bad Request: If required comments are missing when rejecting. System responds with "Comments are required for this action."
  • 409 Conflict: If trying to submit a campaign that is already in PENDING_REVIEW.

Feature Dependencies

  • Notification Module: Required to alert approvers and authors. If this fails, the approval request should still be created, but a warning should be logged.
  • Auth Module: Required to resolve user roles (CAMPAIGN_APPROVER) and permissions.

Testing Considerations

  • Core functionality: Verify the happy path (Draft -> Submit -> Approve -> Ready).
  • Edge cases: Verify that an author cannot approve their own campaign. Verify behavior when two approvers try to approve the same campaign simultaneously.
  • Validation rules: Test that rejecting a campaign without comments is blocked by the UI and the Backend.

Feature Lifecycle

Feature History

  • v1.0 – Initial feature release with simple Approve/Reject functions.
  • v1.1 – Added "Request Changes" workflow and immutability rules.
  • v1.2 – Integrated explicit audit logging for regulatory compliance.