2023-10-17 17:27:09 -04:00
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
2023-10-18 10:25:54 -04:00
struct PersonId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Person {
id: PersonId,
2023-10-17 17:27:09 -04:00
remote_id: String,
name: String,
2023-10-18 10:25:54 -04:00
handle: Option< String > ,
email: Option< Vec < String > >,
2023-10-19 14:57:03 -04:00
avatar: Option< String > ,
cover: Option< String > ,
bio: Option< String > ,
2023-10-18 10:25:54 -04:00
is_active: bool,
2023-10-18 12:00:47 -04:00
is_blocked: bool,
2023-10-18 10:25:54 -04:00
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
modified_by: PersonId,
deleted_at: Option< chrono::DateTime > ,
deleted_by: Option< PersonId > ,
last_seen: chrono::DateTime,
2023-10-18 14:21:42 -04:00
shipping_address: Option< String > ,
2023-10-17 17:27:09 -04:00
}
```
2023-10-18 14:05:30 -04:00
# PersonCredential
2023-10-17 17:27:09 -04:00
2023-10-18 14:05:30 -04:00
A PersonCredential is an authentication method associated with a specific Person.
2023-10-17 17:27:09 -04:00
``` rust
2023-10-18 14:05:30 -04:00
struct PersonCredentialId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
2023-10-18 14:05:30 -04:00
enum PersonCredentialProviderType {
OAuth2,
Local,
}
struct PersonCredentialProviderId {
id: String,
}
2023-10-19 13:11:52 -04:00
struct PersonCredentialProvider {
2023-10-18 14:05:30 -04:00
id: PersonCredentialProviderId,
name: String,
2023-10-19 13:11:52 -04:00
type: PersonCredentialProviderType,
2023-10-18 14:05:30 -04:00
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
2023-10-18 10:25:54 -04:00
struct Tag {
2023-10-18 14:05:30 -04:00
host: String,
2023-10-17 17:27:09 -04:00
name: String,
}
2023-10-18 14:05:30 -04:00
impl Tag {
pub fn new(host: String, name: String) -> Self {
TagId {
host,
name,
}
}
2023-10-18 14:19:34 -04:00
}
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())
2023-10-18 14:05:30 -04:00
}
}
2023-10-17 17:27:09 -04:00
```
# Label
A Label represents a record label (a group of people who handle promotion and/or distribution for one or more Artists).
``` rust
2023-10-18 10:25:54 -04:00
struct LabelId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Label {
id: LabelId,
2023-10-17 17:27:09 -04:00
name: String,
description: String,
website: String,
2023-10-19 13:11:52 -04:00
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 > ,
2023-10-17 17:27:09 -04:00
artists: HashMap< Artist > ,
2023-10-18 10:25:54 -04:00
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
2023-10-17 17:27:09 -04:00
}
```
2023-10-19 13:11:52 -04:00
# LabelContact
A LabelContact represents a method for contacting a representative of a Label.
``` rust
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,
}
```
2023-10-17 17:27:09 -04:00
# Artist
An Artist represents a musical artist.
``` rust
2023-10-18 10:25:54 -04:00
struct ArtistId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Artist {
id: ArtistId,
2023-10-17 17:27:09 -04:00
name: String,
bio: String,
website: String,
2023-10-19 13:11:52 -04:00
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 > >,
2023-10-18 10:25:54 -04:00
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
2023-10-19 13:11:52 -04:00
cover: Option< String > ,
images: Option< Vec < String > >,
2023-10-17 17:27:09 -04:00
}
```
# Track
A Track represents a single piece of work by an Artist that is contained in an audio file.
``` rust
2023-10-18 10:25:54 -04:00
struct TrackId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Track {
id: TrackId,
2023-10-17 17:27:09 -04:00
title: String,
2023-10-19 13:11:52 -04:00
description: Option< String > ,
2023-10-17 17:27:09 -04:00
duration: chrono::Duration,
2023-10-19 13:11:52 -04:00
artists: Vec< Artist > ,
2023-10-18 10:25:54 -04:00
is_public: bool,
2023-10-18 12:00:47 -04:00
is_available: bool,
2023-10-18 10:25:54 -04:00
preview_source: Option< String > ,
source: String,
created_by: PersonId,
2023-10-17 17:27:09 -04:00
created_at: chrono::DateTime,
2023-10-18 10:25:54 -04:00
modified_by: PersonId,
2023-10-17 17:27:09 -04:00
modified_at: chrono::DateTime,
2023-10-18 10:25:54 -04:00
deleted_by: Option< PersonId > ,
2023-10-17 17:27:09 -04:00
deleted_at: Option< chrono::DateTime > ,
2023-10-18 10:25:54 -04:00
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
lyrics: Option< String > ,
cover: Option< String > ,
images: Option< Vec < String > >,
2023-10-17 17:27:09 -04:00
}
```
# Album
An Album represents a work by an Artist that contains one or more Tracks.
``` rust
2023-10-18 10:25:54 -04:00
struct AlbumId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Album {
id: AlbumId,
2023-10-17 17:27:09 -04:00
title: String,
description: String,
2023-10-19 13:11:52 -04:00
artists: Vec< Artist > ,
tracks: Vec< Track > ,
2023-10-18 10:25:54 -04:00
is_public: bool,
2023-10-18 12:00:47 -04:00
is_available: bool,
2023-10-18 10:25:54 -04:00
preview_source: Option< String > ,
source: String,
created_by: PersonId,
2023-10-17 17:27:09 -04:00
created_at: chrono::DateTime,
2023-10-18 10:25:54 -04:00
modified_by: PersonId,
2023-10-17 17:27:09 -04:00
modified_at: chrono::DateTime,
2023-10-18 10:25:54 -04:00
deleted_by: Option< PersonId > ,
2023-10-17 17:27:09 -04:00
deleted_at: Option< chrono::DateTime > ,
2023-10-18 10:25:54 -04:00
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
2023-10-19 16:01:09 -04:00
cover: Option< ImageId > ,
images: Option< Vec < ImageId > >,
2023-10-17 17:27:09 -04:00
}
```
# Playlist
A Playlist represents an ordered collection of Tracks assembled by a Person.
``` rust
2023-10-18 10:25:54 -04:00
struct PlaylistId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Playlist {
id: PlaylistId,
2023-10-17 17:27:09 -04:00
title: String,
2023-10-19 14:57:03 -04:00
description: Option< String > ,
created_by: PersonId,
2023-10-17 17:27:09 -04:00
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
2023-10-19 16:01:09 -04:00
deleted_at: Option< chrono::DateTime > ,
2023-10-17 17:27:09 -04:00
is_public: bool,
2023-10-19 16:01:09 -04:00
cover: Option< ImageId > ,
2023-10-18 10:25:54 -04:00
tracks: Vec< Track > ,
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
}
```
# 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< String > ,
created_by: PersonId,
created_at: chrono::DateTime,
modified_at: chrono::DateTime,
2023-10-19 16:01:09 -04:00
published_at: Option< chrono::DateTime > ,
deleted_at: Option< chrono::DateTime > ,
2023-10-18 10:25:54 -04:00
is_public: bool,
2023-10-18 14:05:30 -04:00
is_draft: bool,
2023-10-19 16:01:09 -04:00
cover: Option< ImageId > ,
images: Option< Vec < ImageId > >,
2023-10-18 10:25:54 -04:00
tracks: Option< Vec < Track > >,
tags: Option< Vec < Tag > >,
comments: Option< Vec < Comment > >,
2023-10-17 17:27:09 -04:00
}
```
# 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
2023-10-20 09:37:57 -04:00
enum CommentTarget {
Label(LabelId),
Artist(ArtistId),
Album(AlbumId),
Track(TrackId),
Playlist(PlaylistId),
Article(ArticleId),
Comment(CommentId),
2023-10-18 10:25:54 -04:00
}
struct CommentId {
2023-10-17 17:27:09 -04:00
id: String,
2023-10-18 10:25:54 -04:00
}
struct Comment {
id: CommentId,
2023-10-17 17:27:09 -04:00
body: String,
2023-10-20 09:37:57 -04:00
target: CommentTarget,
2023-10-18 10:25:54 -04:00
created_by: PersonId,
created_at: chrono::DateTime,
2023-10-19 14:57:03 -04:00
modified_by: Option< PersonId > ,
modified_at: Option< chrono::DateTime > ,
deleted_by: Option< PersonId > ,
deleted_at: Option< chrono::DateTime > ,
2023-10-18 10:25:54 -04:00
is_public: bool,
2023-10-18 14:05:30 -04:00
is_approved: bool,
in_reply_to: Option< CommentId > ,
2023-10-17 17:27:09 -04:00
}
```
2023-10-19 14:57:03 -04:00
# 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.
``` rust
struct ImageId {
id: String,
}
struct Image {
id: ImageId,
2023-10-19 16:01:09 -04:00
name: Option< String > ,
2023-10-19 14:57:03 -04:00
path: String,
2023-10-19 16:01:09 -04:00
url: String,
2023-10-19 14:57:03 -04:00
width: usize,
height: usize,
alt_text: String,
is_public: bool,
2023-10-19 16:01:09 -04:00
allow_hotlinking: bool,
2023-10-19 14:57:03 -04:00
created_by: PersonId,
created_at: chrono::DateTime,
modified_by: PersonId,
modified_at: chrono::DateTime,
deleted_by: Option< PersonId > ,
deleted_at: Option< chrono::DateTime > ,
}
```
2023-10-19 16:17:48 -04:00
# 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.
``` rust
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 > ,
}
```
2023-10-18 12:00:47 -04:00
# Collection
2023-10-25 12:00:09 -04:00
A Collection represents one or more Albums, Tracks, and/or OtherProducts that are offered together as a package for Purchase
2023-10-18 12:00:47 -04:00
``` rust
2023-10-25 12:00:09 -04:00
enum CollectionItem {
Album(AlbumId),
Track(TrackId),
OtherProduct(OtherProductId),
}
2023-10-18 12:00:47 -04:00
struct CollectionId {
id: String,
}
struct Collection {
id: CollectionId,
name: String,
description: String,
2023-10-19 16:17:48 -04:00
created_by: PersonId,
2023-10-18 12:00:47 -04:00
created_at: chrono::DateTime,
modified_by: Person,
modified_at: chrono::DateTime,
is_public: bool,
is_available: bool,
2023-10-19 16:17:48 -04:00
deleted_by: Option< PersonId > ,
2023-10-18 12:00:47 -04:00
deleted_at: Option< chrono::DateTime > ,
2023-10-25 12:00:09 -04:00
collection_items: Option< Vec < CollectionMember > >,
2023-10-18 12:00:47 -04:00
}
```
# 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,
2023-10-19 16:17:48 -04:00
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 > ,
2023-10-20 09:32:52 -04:00
requires_shipping: bool,
2023-10-18 12:00:47 -04:00
}
```
2023-10-17 17:27:09 -04:00
# Purchase
2023-10-25 12:00:09 -04:00
A Purchase represents one or more Tracks, Albums, Collections, and/or OtherProducts that a Person purchases from an Artist or Label through the server.
2023-10-17 17:27:09 -04:00
``` rust
2023-10-18 10:25:54 -04:00
enum PurchaseItemType {
2023-10-20 09:37:57 -04:00
Album(AlbumId),
Track(TrackId),
Collection(CollectionId),
OtherProduct(OtherProductId),
2023-10-18 10:25:54 -04:00
}
struct PurchaseItemId {
id: String,
}
struct SkuId {
id: String,
}
struct Sku {
id: SkuId,
2023-10-20 09:37:57 -04:00
item: PurchaseItemType,
2023-10-19 16:17:48 -04:00
variant: Option< String > ,
2023-10-20 09:32:52 -04:00
description: Option< String > ,
2023-10-25 12:41:54 -04:00
price: rusty_money::Money,
2023-10-20 09:32:52 -04:00
requires_shipping: bool,
2023-10-25 12:00:09 -04:00
shipping_charge: Option< rusty_money::Money > ,
2023-10-18 10:25:54 -04:00
}
2023-10-25 12:41:54 -04:00
struct LineItem {
id: LineItemId,
2023-10-20 09:37:57 -04:00
sku: SkuId,
2023-10-18 10:25:54 -04:00
quantity: usize,
}
2023-10-18 12:00:47 -04:00
enum PurchaseState {
InCart,
Processing,
PaymentRejected,
PaymentCompleted,
Fulfilled,
Cancelled,
Refunded,
}
2023-10-17 17:27:09 -04:00
struct Purchase {
id: String,
2023-10-25 12:41:54 -04:00
items: Vec< LineItem > ,
2023-10-18 12:00:47 -04:00
state: PurchaseState,
2023-11-01 09:34:33 -04:00
purchased_by: Option< Person > ,
2023-10-18 12:00:47 -04:00
purchased_at: Option< chrono::DateTime > ,
2023-10-20 09:32:52 -04:00
fulfilled_by: Option< Person > ,
fulfilled_at: Option< chrono::DateTime > ,
2023-10-25 12:00:09 -04:00
coupons_applied: Option< Vec < CouponCodeId > >,
total_charge: rusty_money::Money,
2023-10-17 17:27:09 -04:00
}
```
2023-10-20 09:32:52 -04:00
# CouponCode
A CouponCode represents a code a Person can enter to receive a discount on a PurchateItem or on a Purchase.
``` rust
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 > ,
}
```