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 pagepage: 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 OKwith announcement collection and pagination metadata - Error: Appropriate error message
- Success:
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 OKwith announcement resource - Error: Appropriate error message if announcement not found
- Success:
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 Createdwith announcement data - Error: Appropriate error message
- Success:
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 OKwith updated announcement data - Error: Appropriate error message
- Success:
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 OKwith success message - Error: Appropriate error message if deletion fails
- Success:
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 OKwith image URL and filename - Error: Appropriate error message
- Success:
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