Announcement Management

Overview Description

The Announcement Management feature enables administrators to create, view, update, and delete system-wide announcements. These announcements serve as a communication channel between administrators and system users, providing important information, updates, or notices. The feature supports rich content including text and images, with dedicated functionality for image uploads to cloud storage.

Activity Diagram

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Main components
    AdminUser[Admin User]
    AdminInterface[Announcement Management Interface]
    ActionSelect{Action Selection}
    
    %% Action components
    ViewAnnouncements[List Announcements]
    AnnouncementDetails[Announcement Details]
    CreateForm[Announcement Creation Form]
    EditForm[Announcement Edit Form]
    DeleteConfirm{Confirm Deletion}
    
    %% Processing components
    EnterContent[Enter Content]
    EditContent[Edit Content]
    ImageAddCheck{Add Images?}
    ImageChangeCheck{Add/Change Images?}
    UploadImages[Upload Images]
    SaveAnnouncement[Save Announcement]
    DeleteFromDB[Delete from Database]
    
    %% Flow connections with numbered steps
    AdminUser --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>Access Interface</p>
        </div>
    ]
    Step1 --> AdminInterface
    
    AdminInterface --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>Select Action</p>
        </div>
    ]
    Step2 --> ActionSelect
    
    ActionSelect --- Step3A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3A</span>
            <p style='margin-top: 8px'>View Announcements</p>
        </div>
    ]
    Step3A --> ViewAnnouncements
    
    ActionSelect --- Step3B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3B</span>
            <p style='margin-top: 8px'>View Details</p>
        </div>
    ]
    Step3B --> AnnouncementDetails
    
    ActionSelect --- Step3C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3C</span>
            <p style='margin-top: 8px'>Create Announcement</p>
        </div>
    ]
    Step3C --> CreateForm
    
    ActionSelect --- Step3D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3D</span>
            <p style='margin-top: 8px'>Update Announcement</p>
        </div>
    ]
    Step3D --> EditForm
    
    ActionSelect --- Step3E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3E</span>
            <p style='margin-top: 8px'>Delete Announcement</p>
        </div>
    ]
    Step3E --> DeleteConfirm
    
    CreateForm --- Step4C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4C</span>
            <p style='margin-top: 8px'>Enter Content</p>
        </div>
    ]
    Step4C --> EnterContent
    
    EditForm --- Step4D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4D</span>
            <p style='margin-top: 8px'>Edit Content</p>
        </div>
    ]
    Step4D --> EditContent
    
    EnterContent --- Step5C[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5C</span>
            <p style='margin-top: 8px'>Check Images</p>
        </div>
    ]
    Step5C --> ImageAddCheck
    
    EditContent --- Step5D[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5D</span>
            <p style='margin-top: 8px'>Check Images</p>
        </div>
    ]
    Step5D --> ImageChangeCheck
    
    ImageAddCheck --- Step6C1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6C</span>
            <p style='margin-top: 8px'>Upload Images</p>
        </div>
    ]
    Step6C1 -->|Yes| UploadImages
    
    ImageChangeCheck --- Step6D1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6D</span>
            <p style='margin-top: 8px'>Upload Images</p>
        </div>
    ]
    Step6D1 -->|Yes| UploadImages
    
    ImageAddCheck --- Step6C2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6C</span>
            <p style='margin-top: 8px'>Skip Upload</p>
        </div>
    ]
    Step6C2 -->|No| SaveAnnouncement
    
    ImageChangeCheck --- Step6D2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6D</span>
            <p style='margin-top: 8px'>Skip Upload</p>
        </div>
    ]
    Step6D2 -->|No| SaveAnnouncement
    
    UploadImages --- Step7CD[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #9966cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
            <p style='margin-top: 8px'>Save</p>
        </div>
    ]
    Step7CD --> SaveAnnouncement
    
    SaveAnnouncement --- Step8CD[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #9966cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step8CD --> AdminInterface
    
    DeleteConfirm --- Step4E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4E</span>
            <p style='margin-top: 8px'>Delete Record</p>
        </div>
    ]
    Step4E -->|Confirm| DeleteFromDB
    
    DeleteFromDB --- Step5E[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5E</span>
            <p style='margin-top: 8px'>Return to Interface</p>
        </div>
    ]
    Step5E --> AdminInterface
    
    DeleteConfirm -.->|Cancel| AdminInterface
    
    %% Styling
    style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style AdminInterface fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style ActionSelect fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ViewAnnouncements fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style AnnouncementDetails fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style CreateForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style EditForm fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style EnterContent fill:#fff0f5,stroke:#cc6699,stroke-width:2px
    style EditContent fill:#fff0f5,stroke:#cc6699,stroke-width:2px
    style ImageAddCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style ImageChangeCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style UploadImages fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style SaveAnnouncement fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    style DeleteConfirm fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style DeleteFromDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3A fill:transparent,stroke:transparent,stroke-width:1px
    style Step3B fill:transparent,stroke:transparent,stroke-width:1px
    style Step3C fill:transparent,stroke:transparent,stroke-width:1px
    style Step3D fill:transparent,stroke:transparent,stroke-width:1px
    style Step3E fill:transparent,stroke:transparent,stroke-width:1px
    style Step4C fill:transparent,stroke:transparent,stroke-width:1px
    style Step4D fill:transparent,stroke:transparent,stroke-width:1px
    style Step4E fill:transparent,stroke:transparent,stroke-width:1px
    style Step5C fill:transparent,stroke:transparent,stroke-width:1px
    style Step5D fill:transparent,stroke:transparent,stroke-width:1px
    style Step5E fill:transparent,stroke:transparent,stroke-width:1px
    style Step6C1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6C2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6D1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6D2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step7CD fill:transparent,stroke:transparent,stroke-width:1px
    style Step8CD fill:transparent,stroke:transparent,stroke-width:1px

API: Announcement Management API

Case Documentation

Case 1: Listing Announcements

Description

Administrator retrieves a paginated list of all announcements in the system.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Repository as AnnouncementRepository
    participant DB as Database

    Note over Admin,DB: Step 1: Request Announcement List
    Admin->>API: GET /api/admin/announcements (with query params)
    
    Note over API,Repository: Step 2: Retrieve Announcements
    API->>Repository: getPaginated(params)
    Repository->>DB: Query Announcements
    DB-->>Repository: Return Matching Announcements
    Repository-->>API: Return Paginated Results
    
    Note over API,Admin: Step 3: Return Announcement List
    API-->>Admin: 200 OK (announcements collection)

Steps

Step 1: Request Announcement List

  • Description: Admin requests the list of announcements with optional pagination
  • Request: GET /api/admin/announcements
  • Query Parameters:
    • per_page: Number of items per page
    • page: Page number
    • Other potential filters (depending on implementation)

Step 2: Retrieve Announcements

  • Description: System fetches announcements from the database
  • Action:
    • Apply pagination and any filters
    • Retrieve announcements in order (likely newest first)

Step 3: Return Announcement List

  • Description: Return the paginated list of announcements
  • Response:
    • Success: 200 OK with announcement collection and pagination metadata
    • Error: Appropriate error message

Error Handling

  • Log
    • Announcement list retrieval failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 Generic error with exception message When unexpected errors occur

Case 2: Viewing a Specific Announcement

Description

Administrator views the details of a specific announcement.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Model as Announcement
    participant DB as Database

    Note over Admin,DB: Step 1: Request Announcement Details
    Admin->>API: GET /api/admin/announcements/{id}
    
    Note over API,Model: Step 2: Retrieve Announcement
    API->>Model: Load Announcement by ID
    Model->>DB: Query by ID
    DB-->>Model: Return Announcement Data
    
    Note over API,Admin: Step 3: Return Announcement Details
    API-->>Admin: 200 OK (announcement resource)

Steps

Step 1: Request Announcement Details

  • Description: Admin requests details for a specific announcement
  • Request: GET /api/admin/announcements/{id}

Step 2: Retrieve Announcement

  • Description: System fetches the announcement by ID
  • Action: Retrieve complete announcement record

Step 3: Return Announcement Details

  • Description: Return the announcement details
  • Response:
    • Success: 200 OK with announcement resource
    • Error: Appropriate error message if announcement not found

Error Handling

  • Log
    • If errors occur, they would be logged
  • Error Detail:
    Status Code Error Message Description
    404 "Announcement not found" When the requested announcement doesn't exist
    400 Generic error with exception message When unexpected errors occur

Case 3: Creating a New Announcement

Description

Administrator creates a new announcement in the system.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Repository as AnnouncementRepository
    participant Event as AnnouncementCreated
    participant DB as Database

    Note over Admin,DB: Step 1: Submit Announcement Creation
    Admin->>API: POST /api/admin/announcements (announcement_data)
    
    Note over API,API: Step 2: Validate Input
    API->>API: Validate Request Data
    
    Note over API,Repository: Step 3: Create Announcement
    API->>Repository: create(validated_data)
    Repository->>DB: Store New Announcement
    DB-->>Repository: Return Created Announcement
    
    Note over API,Event: Step 4: Trigger Event
    API->>Event: event(AnnouncementCreated)
    
    Note over API,Admin: Step 5: Return Response
    Repository-->>API: Return Announcement Data
    API-->>Admin: 201 Created (announcement resource)

Steps

Step 1: Submit Announcement Creation

  • Description: Admin submits form to create a new announcement
  • Request: POST /api/admin/announcements
  • Required fields:
    • title: Announcement title
    • content: Announcement content (may include HTML)
    • Other fields as required by the implementation

Step 2: Validate Input

  • Description: System validates all input data
  • Action: Runs validation rules from StoreAnnouncementRequest
  • Potential errors: Validation failures

Step 3: Create Announcement

  • Description: System creates the new announcement
  • Action: Store announcement record in database

Step 4: Trigger Event

  • Description: System triggers announcement creation event
  • Action: Fire AnnouncementCreated event for potential listeners
  • Purpose: Allow other parts of the system to react to new announcements

Step 5: Return Response

  • Description: Return the created announcement data
  • Response:
    • Success: 201 Created with announcement data
    • Error: Appropriate error message

Error Handling

  • Log
    • Announcement creation failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "error.announcement.create" When announcement creation fails

Case 4: Updating an Announcement

Description

Administrator updates an existing announcement.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Repository as AnnouncementRepository
    participant Event as AnnouncementUpdated
    participant DB as Database

    Note over Admin,DB: Step 1: Submit Announcement Update
    Admin->>API: PUT /api/admin/announcements/{id} (updated_data)
    
    Note over API,API: Step 2: Validate Input
    API->>API: Validate Request Data
    
    Note over API,Repository: Step 3: Update Announcement
    API->>Repository: update(id, validated_data)
    Repository->>DB: Update Announcement Record
    DB-->>Repository: Return Updated Announcement
    
    Note over API,Admin: Step 4: Return Response
    Repository-->>API: Return Announcement Data
    API-->>Admin: 200 OK (announcement resource)

Steps

Step 1: Submit Announcement Update

  • Description: Admin submits form to update announcement information
  • Request: PUT /api/admin/announcements/{id}
  • Updatable fields:
    • title: Announcement title
    • content: Announcement content
    • status: Announcement status
    • Other fields as allowed by the implementation

Step 2: Validate Input

  • Description: System validates all input data
  • Action: Runs validation rules from UpdateAnnouncementRequest
  • Potential errors: Validation failures

Step 3: Update Announcement

  • Description: System updates the announcement information
  • Action: Update announcement record with new data

Step 4: Return Response

  • Description: Return the updated announcement data
  • Response:
    • Success: 200 OK with updated announcement data
    • Error: Appropriate error message

Error Handling

  • Log
    • Announcement update failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "error.announcement.update" When announcement update fails

Case 5: Deleting an Announcement

Description

Administrator removes an announcement from the system.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Model as Announcement
    participant DB as Database

    Note over Admin,DB: Step 1: Request Announcement Deletion
    Admin->>API: DELETE /api/admin/announcements/{id}
    
    Note over API,Model: Step 2: Delete Announcement
    API->>Model: delete()
    Model->>DB: Delete Announcement Record
    DB-->>Model: Confirm Deletion
    
    Note over API,Admin: Step 3: Return Response
    API-->>Admin: 200 OK (success message)

Steps

Step 1: Request Announcement Deletion

  • Description: Admin requests to delete an announcement
  • Request: DELETE /api/admin/announcements/{id}

Step 2: Delete Announcement

  • Description: System removes the announcement from the database
  • Action: Delete announcement record

Step 3: Return Response

  • Description: Confirm successful deletion
  • Response:
    • Success: 200 OK with success message
    • Error: Appropriate error message if deletion fails

Error Handling

  • Log
    • Announcement deletion failures would be logged
  • Error Detail:
    Status Code Error Message Description
    400 "error.announcement.delete" When deletion fails

Case 6: Uploading an Image for Announcement Content

Description

Administrator uploads an image to be used within announcement content.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as AnnouncementController
    participant Storage as CloudStorage
    participant DB as Database

    Note over Admin,DB: Step 1: Submit Image Upload
    Admin->>API: POST /api/admin/announcements/upload-image (image file)
    
    Note over API,API: Step 2: Validate Image
    API->>API: Validate Image File
    
    Note over API,Storage: Step 3: Process and Store Image
    API->>API: Generate Unique Filename
    API->>Storage: Upload to Cloud Storage
    Storage-->>API: Return Image URL
    
    Note over API,Admin: Step 4: Return Response
    API-->>Admin: 200 OK (image URL)

Steps

Step 1: Submit Image Upload

  • Description: Admin uploads an image file for an announcement
  • Request: POST /api/admin/announcements/upload-image
  • Required fields:
    • image: The image file (multipart/form-data)

Step 2: Validate Image

  • Description: System validates the uploaded image
  • Action: Check if file exists and meets requirements
  • Potential errors: Missing file, invalid file type, file too large

Step 3: Process and Store Image

  • Description: System processes and stores the image
  • Action:
    • Generate unique filename (using UUID)
    • Determine storage path
    • Set content type and caching metadata
    • Upload to cloud storage with public visibility

Step 4: Return Response

  • Description: Return the URL to the stored image
  • Response:
    • Success: 200 OK with image URL and filename
    • Error: Appropriate error message

Error Handling

  • Log
    • Image upload failures logged to application log
  • Error Detail:
    Status Code Error Message Description
    400 "error.announcement.no_image_uploaded" When no image file is provided
    500 "error.announcement.upload_image_failed" When upload to cloud storage fails
    400 Generic error with exception message For other errors during upload

Additional Notes

  • The Announcement Management feature supports rich content through HTML in the announcement content field
  • Images are hosted on Google Cloud Storage with public access for display in announcements
  • Unique filenames are generated using UUID to prevent collisions in cloud storage
  • Proper content type and cache control headers are set for optimal performance of image assets
  • Announcements may trigger system events that can be listened for by other parts of the application
  • Error handling includes detailed logging with stack traces for troubleshooting

Database Related Tables & Fields

erDiagram
    announcements {
        bigint id PK "Primary key"
        string title "Announcement title"
        text content "Announcement content (HTML allowed)"
        bigint created_by FK "Reference to users.id"
        string status "Announcement status (e.g., draft, published)"
        timestamp created_at "Record creation timestamp"
        timestamp updated_at "Record last update timestamp"
    }
    users {
        bigint id PK "Primary key"
        string name "User's full name"
        string email "User's email address (unique)"
        timestamp created_at "Account creation timestamp"
        timestamp updated_at "Last update timestamp"
    }

    announcements }|--|| users : created_by