My Solution for Design a File Sharing Platform with Score: 9/10

by nectar4678

Requirements

  1. File Upload and Download:
    • Users can upload files of various types (e.g., documents, images, videos).
    • System must support uploading large files (with possible chunked upload support).
    • Users can download files that they have access to.
  2. File Sharing:
    • Users can share files by generating shareable links.
    • File owners can specify access levels for these links (e.g., view-only, edit).
    • Option to set expiration dates on the sharing links.
  3. User Permissions:
    • Granular control of file permissions (Owner, Editor, Viewer).
    • Ability to modify permissions after sharing.
    • Permissions are enforced on both file access and file actions (upload, download, delete, edit).
  4. Cloud Storage Integration:
    • Files are stored in the cloud, leveraging services like AWS S3 or Google Cloud Storage.
    • Storage should support scaling based on the number of files and storage size.
  5. Notifications:
    • Users receive notifications when:
      • A file is shared with them.
      • Permissions on a shared file are changed.
      • A shared file is downloaded or modified.





Define Core Objects

User: Represents the users interacting with the platform.

  • Attributes: user ID, username, email, permissions (per file).

File: Represents the files being uploaded, shared, and stored.

  • Attributes: file ID, name, size, type, storage location (cloud URL), owner, version history.

Permission: Defines the level of access users have to specific files.

  • Attributes: permission ID, user ID, file ID, access level (Owner, Editor, Viewer).

ShareableLink: Represents links generated for file sharing.

  • Attributes: link ID, file ID, generated URL, expiration date, permissions.

Notification: Represents notifications triggered by file events.

  • Attributes: notification ID, user ID, file ID, event type (shared, modified, downloaded).






Analyze Relationships

Now, we will analyze how the core objects interact with each other to fulfill the file-sharing platform's use cases. Here's a breakdown of the relationships:

  1. User ↔ File:
    • A User can upload and own multiple Files. The relationship is one-to-many, as one user can own multiple files, but a file can only have one owner.
    • Users can download files they own or have permission to access.
  2. User ↔ Permission ↔ File:
    • Users have different access levels to Files through Permissions. This relationship is many-to-many via the Permission object.
    • One file can have multiple users with different access levels (e.g., owner, editor, viewer).
    • A user can have different permissions for different files.
  3. File ↔ ShareableLink:
    • A File can have multiple ShareableLinks. A user generates these links to share files with others, specifying access permissions and link expiration.
    • Each link contains an association with the file and the defined access level.
  4. User ↔ Notification:
    • Users receive Notifications when actions are taken on shared files (e.g., a file was shared, permissions were updated, a file was downloaded).
    • Notifications are triggered by events related to files the user has access to or owns.
  5. File ↔ Cloud Storage:
    • Each File is stored in a cloud storage system, and its storage location is saved as an attribute (e.g., a cloud URL) of the File object.
    • Files will be referenced by their storage URLs when users download or share them.






Establish Hierarchy

Here we will define any inheritance or abstraction to promote code reuse and polymorphism where appropriate. The system includes several distinct types of objects, but certain aspects can be abstracted into common classes:


BaseEntity (abstract class):

  • Common attributes like ID, createdAt, updatedAt can be abstracted into a parent class called BaseEntity.
  • This base class can be inherited by User, File, Permission, ShareableLink, and Notification.


FilePermission (abstract class):

  • Different permissions (owner, editor, viewer) can be treated as subclasses of a FilePermission base class, where each permission has different behaviors when interacting with files (e.g., editing, viewing).






Design Patterns

Based on the system's requirements and core objects, several design patterns can be applied to promote scalability, maintainability, and flexibility. Here's how some relevant design patterns could be utilized:

  1. Factory Pattern:
    • To create different types of Permissions (Owner, Editor, Viewer), the Factory Pattern can be used. This allows for dynamically creating permission objects based on the user's access level without hard-coding the logic.
    • Example: A PermissionFactory class would generate the appropriate permission object (OwnerPermission, EditorPermission, ViewerPermission) when the system assigns or modifies user permissions.
  2. Observer Pattern:
    • The Observer Pattern is useful for the Notification system. When a file is modified, shared, or downloaded, all users who are "watching" the file (i.e., who have access to it) are notified automatically.
    • Example: The File class will act as the "subject" and User objects as "observers". When a file event occurs (e.g., shared, modified), the file will notify all users subscribed to that file via their observer (notification) system.
  3. Singleton Pattern:
    • The Singleton Pattern can be applied to the CloudStorageService. Since only one instance of the cloud storage service is needed to upload or download files, the singleton ensures that only one instance is used globally throughout the application.
    • Example: A CloudStorageService.getInstance() method will return the same instance for all file storage interactions.
  4. Strategy Pattern:
    • For File Sharing, the Strategy Pattern can be employed to manage different sharing strategies. For example, some files may be shared via a direct link with limited access, while others might require a password or a login. The strategy pattern enables selecting the appropriate sharing mechanism dynamically.
    • Example: A SharingStrategy interface might have different implementations such as LinkSharingStrategy, PasswordProtectedSharingStrategy, etc.





Define Class Members (write code)

We will now define the core attributes and methods for the key classes in the system. Below are the key class definitions:


User Class:

class User(BaseEntity): def __init__(self, user_id, username, email): self.user_id = user_id self.username = username self.email = email self.files = [] # Files owned by the user self.permissions = [] # Permissions the user has for different files def upload_file(self, file): # Upload a file and add it to the user's owned files pass def download_file(self, file): # Download a file the user has permission to access pass def receive_notification(self, notification): # Handle notification logic pass


File Class:

class File(BaseEntity): def __init__(self, file_id, name, size, type, storage_url, owner): self.file_id = file_id self.name = name self.size = size self.type = type self.storage_url = storage_url self.owner = owner self.version_history = [] # Store previous versions self.permissions = [] # List of permission objects def share(self, user, permission): # Share the file with another user pass def add_permission(self, permission): # Add permission to the file pass


Permission Class:

class Permission(BaseEntity): def __init__(self, permission_id, user, file, access_level): self.permission_id = permission_id self.user = user self.file = file self.access_level = access_level # "owner", "editor", "viewer" def grant_access(self): # Logic to grant the user access based on access level pass


ShareableLink Class:

class ShareableLink(BaseEntity): def __init__(self, link_id, file, expiration_date, access_level): self.link_id = link_id self.file = file self.expiration_date = expiration_date self.access_level = access_level # Access level for the link def is_valid(self): # Check if the link is still valid based on expiration date pass


Notification Class:

class Notification(BaseEntity): def __init__(self, notification_id, user, file, event_type): self.notification_id = notification_id self.user = user self.file = file self.event_type = event_type # e.g., "shared", "modified", "downloaded" def send(self): # Logic to send the notification to the user pass



Adhere to SOLID Guidelines

Single Responsibility Principle (SRP):

  • Each class handles a single responsibility (e.g., User manages user actions, File handles file-related operations).

Open/Closed Principle (OCP):

  • Classes can be extended without modifying existing code, like adding new permission levels or sharing strategies.

Liskov Substitution Principle (LSP):

  • Subtypes (like different permission types) can replace their parent class without breaking functionality.

Interface Segregation Principle (ISP):

  • Classes are only given the methods they need to implement, avoiding large, bloated interfaces.

Dependency Inversion Principle (DIP):

  • High-level classes depend on abstractions (like sharing strategies), not concrete implementations.






Consider Scalability and Flexibility


Scalability:

  1. Cloud Storage Integration:
    • Using scalable cloud services like AWS S3 or Google Cloud ensures the platform can handle large numbers of files and users efficiently.
  2. Observer Pattern for Notifications:
    • This pattern ensures that multiple users can be notified about file events without performance degradation, allowing the system to scale with the user base.
  3. Singleton for Cloud Storage Service:
    • Ensures that file storage operations are handled by a single, centralized service instance, reducing overhead and improving performance.


Flexibility:

  1. Factory Pattern for Permissions:
    • Easily extend the system to support new permission levels (e.g., commenter) without modifying existing code.
  2. Strategy Pattern for File Sharing:
    • Allows for adding new sharing mechanisms (e.g., password-protected sharing) with minimal changes to the core logic.
  3. Modular Class Structure:
    • The use of clear object relationships (e.g., User, File, Permission) supports future extensions, such as integrating with third-party services or adding real-time collaboration.






Create/Explain your diagram(s)


Class Diagram


Summary of Relationships:

  • A User can own multiple Files.
  • A User can have different Permissions to access multiple Files.
  • A File can be shared using ShareableLinks, each link having an expiration date and access level.
  • Users are notified of changes or events via Notifications.


State Diagram


Explanation of the States:

  1. Uploading:
    • This is the initial state where the user is uploading a file to the platform.
    • The file is being transferred to cloud storage (e.g., AWS S3 or Google Cloud Storage).
  2. Uploaded:
    • The file has been successfully uploaded and stored.
    • At this point, the user can manage the file (view, download, or move to the sharing phase).
  3. Sharing:
    • The user generates a shareable link or assigns specific permissions (owner, editor, viewer) to other users.
    • This can involve specifying access expiration dates and access levels.
  4. Shared:
    • The file has been shared, either via a shareable link or by directly granting access to other users.
    • The file can now be accessed by users based on the permissions assigned.
  5. Accessed:
    • A user with permission has accessed or downloaded the shared file.
    • If the file is accessed or downloaded frequently, the system may track usage.
  6. Updated:
    • The file is updated (a new version is uploaded), and the updated version is now available.
    • The system will allow users with access to the old version to see the updated one.
  7. Expired:
    • The shareable link has expired or the owner has revoked access.
    • This ends the sharing phase, and users no longer have access to the file.
  8. Archived:
    • The file is no longer being shared, and the owner has chosen to archive it for storage rather than sharing.
  9. Deleted:
    • The file has been permanently deleted by the owner and is no longer available in the system.



Future improvements


Real-time Collaboration: Introduce real-time editing and collaboration features where multiple users can work on the same file simultaneously, with live updates.

Offline Access: Enable users to access and modify files offline, with automatic synchronization once they reconnect to the internet.

Enhanced Search: Implement advanced search capabilities, allowing users to filter files by tags, metadata, and content within the files.

Integrations with Third-party Tools: Integrate with productivity suites like Google Docs or Microsoft Office for seamless file management and editing within the platform.