File Attachment System
Relevant source files
The following files were used as context for generating this wiki page:
The File Attachment System is a core module within the Dashboard Task Management application designed to handle the lifecycle of files uploaded by users. It provides capabilities for uploading, storing, linking files to specific entities (Tasks or Comments), downloading, and deleting attachments. The system is integrated with the project's security layer to ensure that file access and management are restricted based on user roles and project assignments.
The system follows a two-step process: an initial upload to a temporary directory followed by a binding step where the file is moved to a permanent directory associated with a Task or a Comment. This ensures that orphans (files uploaded but not linked) can be managed separately and that files are organized logically within the server's file system.
Sources: README.md:144-150, src/main/java/com/example/demo/services/AttachmentService.java:54-105
System Architecture and Logic
The system is built using a Spring Boot backend and a Vue.js/JavaScript frontend. It utilizes a relational database (PostgreSQL) to store file metadata and the server's local file system for physical storage.
Data Model
The Attachment entity stores metadata about the file, its location on the disk, and its association with other entities.
| Field | Type | Description |
|---|---|---|
id | Long | Primary key |
entityType | Enum | The type of entity the file is attached to (TASK or COMMENT) |
entityId | Long | ID of the linked Task or Comment |
uploader | User | Reference to the user who uploaded the file |
fileName | String | Original name of the file |
filePath | String | Physical path on the server |
fileSize | Long | Size in bytes |
mimeType | String | Content type (e.g., application/pdf) |
uploadedAt | LocalDateTime | Timestamp of upload |
Sources: src/main/java/com/example/demo/entity/Attachment.java:12-44
File Storage Lifecycle
The following diagram illustrates the lifecycle of a file from upload to entity binding.
The system first places files in a temp directory within the configured upload directory. When a user binds the file to a Task or Comment, the AttachmentService moves the file to a structured path: ${upload-dir}/${entityType}/${entityId}/${uniqueName}.
Sources: src/main/java/com/example/demo/services/AttachmentService.java:54-105
API Endpoints and Security
The system enforces strict Role-Based Access Control (RBAC) and scope-based checks. Users can only interact with files belonging to tasks they have access to.
Endpoint Summary
| Method | Endpoint | Description | Role Requirement |
|---|---|---|---|
| POST | /api/attachments/upload | Initial file upload to temp storage | ADMIN, MANAGER, PM, TEAM |
| POST | /api/tasks/{taskId}/attachments | Bind an uploaded file to a Task | ADMIN, MANAGER, PM |
| POST | /api/comments/{id}/attachments | Bind an uploaded file to a Comment | ALL ROLES |
| GET | /api/attachments | List files for an entity | ALL ROLES (with Task access) |
| GET | /api/attachments/{id}/download | Download a specific file | ALL ROLES (with Task access) |
| DELETE | /api/attachments/{id} | Delete an attachment | ADMIN or Uploader |
Sources: src/main/java/com/example/demo/controllers/AttachmentController.java:27-101
Security Restrictions
The AttachmentService includes a checkTaskAccess method that validates access rights:
- ADMIN: Full access to all files.
- MANAGER: Access only to tasks within their department.
- PM: Access only to tasks within their assigned projects.
- TEAM: Access only to tasks where they are an assignee. Additionally, TEAM members can only attach files to Comments, not directly to Tasks.
Sources: src/main/java/com/example/demo/services/AttachmentService.java:185-225
File Constraints and Formats
The system implements server-side validation for file size and type to ensure security and resource management.
- Max File Size: 10 MB.
- Allowed MIME Types:
- Images:
jpeg,png,gif,webp - Documents:
pdf,msword,docx,excel,xlsx,txt - Archives:
zip,rar
- Images:
Sources: src/main/java/com/example/demo/services/AttachmentService.java:43-52
Frontend Integration
The frontend uses standard FormData for uploads and provides visual feedback like icons based on MIME types.
Upload Sequence
The following sequence shows how the frontend interacts with the API during a file upload on the Task Detail page.
Utility Functions
The frontend includes helper functions to format file sizes and determine icons for display:
formatBytes(bytes): Converts raw bytes to KB or MB.fileIcon(mime): Maps MIME types to emojis (e.g.,image/-> 🖼️,pdf-> 📕).
Sources: src/main/resources/static/js/task-detail.js:120-176
Implementation Details
File Deletion
Deleting an attachment removes both the database record and the physical file from the disk. The service checks if the user is an admin or the original uploader before proceeding.
// src/main/java/com/example/demo/services/AttachmentService.java:147-152
public void delete(Long attachmentId, String userEmail) throws IOException {
Attachment attachment = attachmentRepository.findById(attachmentId)
.orElseThrow(() -> new ResourceNotFoundException("Файл не найден"));
// ... access checks ...
Files.deleteIfExists(Paths.get(attachment.getFilePath()));
attachmentRepository.delete(attachment);
}
File Download
The download endpoint uses Content-Disposition: attachment to force browser downloads. File names are UTF-8 encoded to handle special characters.
Sources: src/main/java/com/example/demo/controllers/AttachmentController.java:82-95, src/main/java/com/example/demo/services/AttachmentService.java:125-141
Conclusion
The File Attachment System provides a robust and secure way to manage documents and media within the project management workflow. By separating the upload and binding phases, the system maintains a clean file structure and ensures that every file on the server is accounted for and governed by the project's access control policies.