aural_isle/MODELS.md

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,
    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,
    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 CommentTarget {
    Label(LabelId),
    Artist(ArtistId),
    Album(AlbumId),
    Track(TrackId),
    Playlist(PlaylistId),
    Article(ArticleId),
    Comment(CommentId),
}
struct CommentId {
    id: String,
}
struct Comment {
    id: CommentId,
    body: String,
    target: CommentTarget,
    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, Tracks, and/or OtherProducts that are offered together as a package for Purchase

enum CollectionItem {
    Album(AlbumId),
    Track(TrackId),
    OtherProduct(OtherProductId),
}
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>,
    collection_items: Option<Vec<CollectionMember>>,
}

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>,
    requires_shipping: bool,
}

Purchase

A Purchase represents one or more Tracks, Albums, Collections, and/or OtherProducts that a Person purchases from an Artist or Label through the server.

enum PurchaseItemType {
    Album(AlbumId),
    Track(TrackId),
    Collection(CollectionId),
    OtherProduct(OtherProductId),
}
struct PurchaseItemId {
    id: String,
}
struct SkuId {
    id: String,
}
struct Sku {
    id: SkuId,
    item: PurchaseItemType,
    variant: Option<String>,
    description: Option<String>,
    price: rusty_money::Money,
    requires_shipping: bool,
    shipping_charge: Option<rusty_money::Money>,
}
struct LineItem {
    id: LineItemId,
    sku: SkuId,
    quantity: usize,
}
enum PurchaseState {
    InCart,
    Processing,
    PaymentRejected,
    PaymentCompleted,
    Fulfilled,
    Cancelled,
    Refunded,
}
struct Purchase {
    id: String,
    items: Vec<LineItem>,
    state: PurchaseState,
    purchased_by: Option<Person>,
    purchased_at: Option<chrono::DateTime>,
    fulfilled_by: Option<Person>,
    fulfilled_at: Option<chrono::DateTime>,
    coupons_applied: Option<Vec<CouponCodeId>>,
    total_charge: rusty_money::Money,
}

CouponCode

A CouponCode represents a code a Person can enter to receive a discount on a PurchateItem or on a Purchase.

struct CouponCodeId {
    id: String,
}
struct CouponCode {
    id: CouponCodeId,
    name: String,
    code: String,
    uses: usize,
    max_uses: usize,
    expiration: Option<chrono::DateTime>,
    discount_flat: Option<rusty_money::Money>,
    discount_percentage: Option<f32>,
    skus: Option<Vec<SkuId>>,
    is_active: bool,
    created_by: PersonId,
    created_at: chrono::DateTime,
    modified_by: PersonId,
    modified_at: chrono::DateTime,
    deleted_by: Option<PersonId>,
    deleted_at: Option<chrono::DateTime>,
}