11 KiB
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.
struct PersonId {
id: String,
}
struct Person {
id: PersonId,
remote_id: String,
name: String,
handle: Option<String>,
email: Option<Vec<String>>,
avatar: Option<String>,
cover: Option<String>,
bio: Option<String>,
is_active: bool,
is_blocked: bool,
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
modified_by: PersonId,
deleted_at: Option<chrono::DateTime>,
deleted_by: Option<PersonId>,
last_seen: chrono::DateTime,
shipping_address: Option<String>,
}
PersonCredential
A PersonCredential is an authentication method associated with a specific Person.
struct PersonCredentialId {
id: String,
}
enum PersonCredentialProviderType {
OAuth2,
Local,
}
struct PersonCredentialProviderId {
id: String,
}
struct PersonCredentialProvider {
id: PersonCredentialProviderId,
name: String,
type: PersonCredentialProviderType,
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.
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).
struct LabelId {
id: String,
}
struct Label {
id: LabelId,
name: String,
description: String,
website: String,
is_enabled: bool,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
artists: HashMap<Artist>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
}
LabelContact
A LabelContact represents a method for contacting a representative of a Label.
struct LabelContactId {
id: String,
}
struct LabelContact {
id: LabelContactId,
method: String,
address: String,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
sort_order: usize,
}
Artist
An Artist represents a musical artist.
struct ArtistId {
id: String,
}
struct Artist {
id: ArtistId,
name: String,
bio: String,
website: String,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
is_enabled: bool,
is_public: bool,
labels: Option<Vec<LabelId>>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
cover: Option<String>,
images: Option<Vec<String>>,
}
Track
A Track represents a single piece of work by an Artist that is contained in an audio file.
struct TrackId {
id: String,
}
struct Track {
id: TrackId,
title: String,
description: Option<String>,
duration: chrono::Duration,
artists: Vec<Artist>,
is_public: bool,
is_available: bool,
preview_source: Option<String>,
source: String,
price: Option<rusty_money::Money>,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
lyrics: Option<String>,
cover: Option<String>,
images: Option<Vec<String>>,
}
Album
An Album represents a work by an Artist that contains one or more Tracks.
struct AlbumId {
id: String,
}
struct Album {
id: AlbumId,
title: String,
description: String,
artists: Vec<Artist>,
tracks: Vec<Track>,
is_public: bool,
is_available: bool,
preview_source: Option<String>,
source: String,
price: Option<rusty_money::Money>,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
cover: Option<ImageId>,
images: Option<Vec<ImageId>>,
}
Playlist
A Playlist represents an ordered collection of Tracks assembled by a Person.
struct PlaylistId {
id: String,
}
struct Playlist {
id: PlaylistId,
title: String,
description: Option<String>,
created_by: PersonId,
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
deleted_at: Option<chrono::DateTime>,
is_public: bool,
cover: Option<ImageId>,
tracks: Vec<Track>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
}
Article
An Article represents a "blog post" style article written by a Person.
struct ArticleId {
id: String,
}
struct Article {
id: ArticleId,
title: String,
body: String,
description: Option<String>,
created_by: PersonId,
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
published_at: Option<chrono::DateTime>,
deleted_at: Option<chrono::DateTime>,
is_public: bool,
is_draft: bool,
cover: Option<ImageId>,
images: Option<Vec<ImageId>>,
tracks: Option<Vec<Track>>,
tags: Option<Vec<Tag>>,
comments: Option<Vec<Comment>>,
}
Comment
A Comment represents a textual comment that a Person wants to attach contextually to an Artist, an Album, a Track, or a Playlist.
enum CommentTargetType {
Label,
Artist,
Album,
Track,
Playlist,
Article,
Comment,
}
struct CommentTargetId {
label_id: Option<LabelId>,
artist_id: Option<ArtistId>,
album_id: Option<AlbumId>,
track_id: Option<TrackId>,
playlist_id: Option<PlaylistId>,
article_id: Option<ArticleId>,
comment_id: Option<CommentId>,
}
struct CommentId {
id: String,
}
struct Comment {
id: CommentId,
body: String,
target_type: CommentTargetType,
target_id: CommentTargetId,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: Option<PersonId>,
modified_at: Option<chrono::DateTime>,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
is_public: bool,
is_approved: bool,
in_reply_to: Option<CommentId>,
}
Image
An Image represents an image file that a Person wants to reference from a Label, an Artist, an Album, a Track, a Playlist, or an Article.
struct ImageId {
id: String,
}
struct Image {
id: ImageId,
name: Option<String>,
path: String,
url: String,
width: usize,
height: usize,
alt_text: String,
is_public: bool,
allow_hotlinking: bool,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
}
Video
A Video represents a video file that a Person wants to reference from a Label, an Artist, an Album, a Track, a Playlist, or an Article.
struct VideoId {
id: String,
}
struct Video {
id: VideoId,
name: Option<String>,
path: String,
url: String,
width: usize,
height: usize,
duration: chrono::Duration,
alt_text: String,
is_public: bool,
allow_hotlinking: bool,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
}
Collection
A Collection represents one or more Albums and/or Tracks that are offered together as a package for Purchase
struct CollectionId {
id: String,
}
struct Collection {
id: CollectionId,
name: String,
description: String,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: Person,
modified_at: chrono::DateTime,
is_public: bool,
is_available: bool,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
albums: Option<Vec<Album>>,
tracks: Option<Vec<Track>>,
other_products: Option<Vec<OtherProduct>>,
price: Option<rusty_money::Money>,
}
OtherProduct
An OtherProduct represents a product that is not a Track, Album, or Collection that is nonetheless for sale as a Purchase.
struct OtherProductId {
id: String,
}
struct OtherProduct {
id: OtherProductId,
name: String,
description: String,
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
is_public: bool,
is_available: bool,
deleted_by: Option<PersonId>,
deleted_at: Option<chrono::DateTime>,
price: Option<rusty_money::Money>
}
Purchase
A Purchase represents one or more Tracks or Albums that a Person purchases from an Artist or Label through the server.
enum PurchaseItemType {
Album,
Track,
Collection,
OtherProduct,
}
struct PurchaseItemId {
id: String,
}
struct SkuId {
id: String,
}
struct Sku {
id: SkuId,
album_id: Option<AlbumId>,
track_id: Option<TrackId>,
collection_id: Option<CollectionId>,
other_product_id: Option<OtherProductId>,
variant: Option<String>,
discount_percentage: Option<f64>,
discount_flatrate: Option<rusty_money::Money>,
}
struct PurchaseItem {
id: PurchaseItemId,
type: PurchaseItemType,
sku: Option<SkuId>,
quantity: usize,
}
enum PurchaseState {
InCart,
Processing,
PaymentRejected,
PaymentCompleted,
Fulfilled,
Cancelled,
Refunded,
}
struct Purchase {
id: String,
items: Vec<PurchaseItem>,
state: PurchaseState,
purchased_by: Person,
purchased_at: Option<chrono::DateTime>,
}