DATA MODELS =========== This document describes the key top-level entities this application will be working with and the attributes of each. This is a work-in-progress. Other top-level entities will be introduced to the application as necessary. Representations in this document are in application context; for database structure, see SCHEMA.md in this directory. # Person A Person represents a person! Specifically, a Person is a person who is using/has used the web application. Many applications call this entity a "User". We call them a Person. ``` rust struct PersonId { id: String, } struct Person { id: PersonId, remote_id: String, name: String, handle: Option, email: Option>, is_active: bool, is_blocked: bool, created_at: chrono::DateTime, modified_at: chrono::DateTime, modified_by: PersonId, deleted_at: Option, deleted_by: Option, last_seen: chrono::DateTime, } ``` # PersonCredential A PersonCredential is an authentication method associated with a specific Person. ``` rust struct PersonCredentialId { id: String, } enum PersonCredentialProviderType { OAuth2, Local, } struct PersonCredentialProviderId { id: String, } enum PersonCredentialProvider { id: PersonCredentialProviderId, name: String, config: String, } struct PersonCredential { id: PersonCredentialId, person_id: PersonId, provider_id: PersonCredentialProviderId, provider_user_id: String, is_enabled: bool, } ``` # Tag A Tag is a classification label that a Person wants to associate to a Label, an Artist, an Album, a Track, or a Playlist, used as a way of grouping entities together via some commonality the context of which is not programmatically relevant. ``` rust struct Tag { host: String, name: String, } impl Tag { pub fn new(host: String, name: String) -> Self { TagId { host, name, } } } impl fmt::Display for Tag { fn format(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}::tag::{}", self.host.as_ref(), self.name.as_ref()) } } ``` # Label A Label represents a record label (a group of people who handle promotion and/or distribution for one or more Artists). ``` rust struct LabelId { id: String, } struct Label { id: LabelId, name: String, description: String, website: String, artists: HashMap, tags: Option>, comments: Option>, } ``` # Artist An Artist represents a musical artist. ``` rust struct ArtistId { id: String, } struct Artist { id: ArtistId, name: String, bio: String, website: String, tags: Option>, comments: Option>, } ``` # Track A Track represents a single piece of work by an Artist that is contained in an audio file. ``` rust struct TrackId { id: String, } struct Track { id: TrackId, title: String, description: String, duration: chrono::Duration, artists: HashMap, is_public: bool, is_available: bool, preview_source: Option, source: String, price: Option, created_by: PersonId, created_at: chrono::DateTime, modified_by: PersonId, modified_at: chrono::DateTime, deleted_by: Option, deleted_at: Option, tags: Option>, comments: Option>, lyrics: Option, cover: Option, images: Option>, } ``` # Album An Album represents a work by an Artist that contains one or more Tracks. ``` rust struct AlbumId { id: String, } struct Album { id: AlbumId, title: String, description: String, artists: HashMap, tracks: HashMap, is_public: bool, is_available: bool, preview_source: Option, source: String, price: Option, created_by: PersonId, created_at: chrono::DateTime, modified_by: PersonId, modified_at: chrono::DateTime, deleted_by: Option, deleted_at: Option, tags: Option>, comments: Option>, cover: Option, images: Option>, } ``` # Playlist A Playlist represents an ordered collection of Tracks assembled by a Person. ``` rust struct PlaylistId { id: String, } struct Playlist { id: PlaylistId, title: String, description: String, created_by: String, created_at: chrono::DateTime, modified_at: chrono::DateTime, deleted_at: Option is_public: bool, cover: Option, tracks: Vec, tags: Option>, comments: Option>, } ``` # Article An Article represents a "blog post" style article written by a Person. ``` rust struct ArticleId { id: String, } struct Article { id: ArticleId, title: String, body: String, description: Option, created_by: PersonId, created_at: chrono::DateTime, modified_at: chrono::DateTime, deleted_at: Option is_public: bool, is_draft: bool, cover: Option, images: Option>, tracks: Option>, tags: Option>, comments: Option>, } ``` # Comment A Comment represents a textual comment that a Person wants to attach contextually to an Artist, an Album, a Track, or a Playlist. ``` rust enum CommentTargetType { Label, Artist, Album, Track, Playlist, Article, Comment, } struct CommentTargetId { label_id: Option, artist_id: Option, album_id: Option, track_id: Option, playlist_id: Option, article_id: Option, comment_id: Option, } struct CommentId { id: String, } struct Comment { id: CommentId, body: String, target_type: CommentTargetType, target_id: CommentTargetId, created_by: PersonId, created_at: chrono::DateTime, modified_at: chrono::DateTime, deleted_at: Option is_public: bool, is_approved: bool, in_reply_to: Option, } ``` # Collection A Collection represents one or more Albums and/or Tracks that are offered together as a package for Purchase ``` rust struct CollectionId { id: String, } struct Collection { id: CollectionId, name: String, description: String, created_by: Person, created_at: chrono::DateTime, modified_by: Person, modified_at: chrono::DateTime, is_public: bool, is_available: bool, deleted_by: Option, deleted_at: Option, albums: Option>, tracks: Option>, price: Oprion, } ``` # OtherProduct An OtherProduct represents a product that is not a Track, Album, or Collection that is nonetheless for sale as a Purchase. ``` rust struct OtherProductId { id: String, } struct OtherProduct { id: OtherProductId, name: String, description: String, } ``` # Purchase A Purchase represents one or more Tracks or Albums that a Person purchases from an Artist or Label through the server. ``` rust enum PurchaseItemType { Album, Track, Collection, OtherProduct, } struct PurchaseItemId { id: String, } struct SkuId { id: String, } struct Sku { id: SkuId, album_id: Option, track_id: Option, collection_id: Option, other_product_id: Option, } struct PurchaseItem { id: PurchaseItemId, type: PurchaseItemType, sku: SkuId, quantity: usize, discount_percentage: usize, } enum PurchaseState { InCart, Processing, PaymentRejected, PaymentCompleted, Fulfilled, Cancelled, Refunded, } struct Purchase { id: String, items: Vec, state: PurchaseState, purchased_by: Person, purchased_at: Option, } ```