Artist

A creative entity that releases music — a person, a group, an orchestra or an AI project. Artists are credited on Albums and Tracks, and carry identity, origin, lifespan, verification, aliases, group memberships and social links.

apps/api/src/Features/Artists/Models/Artist.cs

1 Full schema

Artist inherits from BaseModel (Id, CreatedAtUtc, UpdatedAtUtc) and is mapped to the artists table.

public class Artist : BaseModel
{
    public required string Name { get; set; }
    public required string Biography { get; set; }
    public ArtistStatus Status { get; set; } = ArtistStatus.Draft;

    public Guid? OwnerUserId { get; set; }
    public User? Owner { get; set; }

    // Type and origin
    public ArtistType Type { get; set; } = ArtistType.Person;
    public string? CountryCode { get; set; }
    public long? OriginStateId { get; set; }
    public PlaceState? OriginState { get; set; }
    public long? OriginCityId { get; set; }
    public PlaceCity? OriginCity { get; set; }
    public string? OriginCustomLocation { get; set; }

    // Lifespan
    public int? StartYear { get; set; }
    public int? EndYear { get; set; }
    public ArtistEndReason? EndReason { get; set; }

    // Verification
    public VerificationLevel VerificationLevel { get; set; } = VerificationLevel.None;
    public DateTime? VerifiedAtUtc { get; set; }
    public Guid? VerifiedByUserId { get; set; }

    // AI-specific
    public bool IsAiGenerated { get; set; }
    public string? AiModelTag { get; set; }
    public string? AiModelTagCustom { get; set; }

    // Navigations
    public ICollection<ArtistAlias>      Aliases     { get; set; } = [];
    public ICollection<ArtistMembership> Memberships { get; set; } = [];
    public ICollection<ArtistMembership> MemberOf    { get; set; } = [];
    public ICollection<ArtistSocialLink> SocialLinks { get; set; } = [];
    public ICollection<ArtistImage>      Images      { get; set; } = [];
    public ICollection<Genre>            Genres      { get; set; } = [];
    public ICollection<Album>            Albums      { get; set; } = [];
    public ICollection<Track>            Tracks      { get; set; } = [];
}

2 Identity & status

FieldTypeDescription
Id Guid Primary key. Inherited from BaseModel.
Name string · required · ≤255 The artist's canonical display name. Indexed via aliases for search.
Biography string · required · ≤4000 Long-form artist biography.
Status ArtistStatus enum Lifecycle state. Default Draft. See §6.
OwnerUserId / Owner Guid? + User? The user who owns/manages this artist profile. Optional FK, OnDelete = SetNull.

3 Type & origin

FieldTypeDescription
Type ArtistType enum What kind of artist this is — Person, Group, AiProject, … Default Person. Indexed.
CountryCode string? · ≤2 ISO 3166-1 alpha-2 country code of origin. Indexed.
OriginStateId / OriginState long? + PlaceState? Origin state/province. FK into the GeoNames-backed places dataset. OnDelete = SetNull.
OriginCityId / OriginCity long? + PlaceCity? Origin city. FK into the places dataset. OnDelete = SetNull.
OriginCustomLocation string? · ≤200 Free-text origin when no GeoNames place fits (e.g. a fictional or virtual place).

4 Lifespan

FieldTypeDescription
StartYear int? Year the artist/group started or was born. Indexed.
EndYear int? Year the artist/group ended, if applicable.
EndReason ArtistEndReason? enum Why the artist's activity ended — Disbanded, Deceased, Hiatus, … See §6.

5 Verification

FieldTypeDescription
VerificationLevel VerificationLevel enum How strongly the profile is verified. Default None. See §6.
VerifiedAtUtc DateTime? When verification was granted.
VerifiedByUserId Guid? The moderator/admin user who verified the profile.

6 AI-specific

FieldTypeDescription
IsAiGenerated bool Whether the artist itself is an AI persona/project.
AiModelTag string? · ≤80 Identifier of the AI model/tool behind the artist (a known tag).
AiModelTagCustom string? · ≤200 Free-text model description when no known tag applies.

7 Enums

ArtistStatus

ValueIntMeaning
Draft0Being created; not public. Default.
Published1Visible in the public catalog.
Archived2Removed from the catalog but preserved.

ArtistType

ValueIntMeaning
Person0A single individual. The default.
Group1A band or group of members.
Orchestra2An orchestra.
Choir3A choir.
Character4A fictional character/persona.
AiProject5An AI music project.
Collective6A loose collective of creators.

ArtistEndReason

ValueIntMeaning
Unknown0End reason not known.
Disbanded1A group that disbanded.
Deceased2The person passed away.
Retired3The artist retired.
Hiatus4On an indefinite hiatus.
Discontinued5The project was discontinued.
ModelDeprecated6The underlying AI model was deprecated.
Active7Still active (explicit "not ended").

VerificationLevel

ValueIntMeaning
None0Unverified. The default.
EmailConfirmed1The owner confirmed an email address.
DomainVerified2A domain/website was verified.
ManualReview3Verified by manual moderator review.
OfficialPartner4An official partner of Beatix.

8 ArtistAlias

Alternative names for an artist — stage names, birth names, translations, romanisations. Used to broaden search and to render the right name per locale.

apps/api/src/Features/Artists/Models/ArtistAlias.cs
FieldTypeDescription
ArtistId / Artist Guid + nav Parent artist. OnDelete = Cascade.
Name string · required · ≤255 The alias text. Indexed; unique per (ArtistId, Name, Locale).
Locale string? · ≤16 The locale this alias applies to, when locale-specific.
Type ArtistAliasType enum The kind of alias (see below).
IsPrimary bool Marks the preferred alias.

ArtistAliasType

ValueIntMeaning
StageName0A stage/performance name.
BirthName1The person's birth name.
Nickname2An informal nickname.
Translated3A translated form of the name.
RomanizedName4A romanised form of a non-Latin name.
LegalName5The legal name.
FormerName6A name previously used.

9 ArtistMembership

Links a member artist to a group artist — both sides are Artist rows. This models band line-ups, AI collectives, and so on.

apps/api/src/Features/Artists/Models/ArtistMembership.cs
The two navigation collections

An Artist exposes the relation from both sides: Artist.Memberships are the rows where this artist is the member (the groups it belongs to), while Artist.MemberOf are the rows where this artist is the group (its own line-up).

FieldTypeDescription
GroupArtistId / GroupArtist Guid + nav The group artist. OnDelete = Cascade.
MemberArtistId / MemberArtist Guid + nav The member artist. OnDelete = Restrict.
Role MembershipRole enum The member's role in the group (see below).
JoinedYear / LeftYear int? Years the member joined and left the group.
IsCurrent bool Whether the member is currently in the group.
OrderIndex int Display order within the line-up.

A unique index on (GroupArtistId, MemberArtistId, Role) prevents duplicate membership rows.

MembershipRole

ValueIntValueInt
Vocalist0Composer8
LeadVocalist1Lyricist9
BackingVocalist2Conductor10
Guitarist3Instrumentalist11
Bassist4Creator12
Drummer5Founder13
Keyboardist6FormerMember14
Producer7GuestMember15

10 ArtistSocialLink

External links for an artist — streaming profiles, social media, and AI-platform pages.

apps/api/src/Features/Artists/Models/ArtistSocialLink.cs
FieldTypeDescription
ArtistId / Artist Guid + nav Parent artist. OnDelete = Cascade.
Platform SocialPlatform enum Which platform the link points to (see below).
Url string · required · ≤500 The link URL.
Handle string? · ≤120 The account handle/username on the platform.
IsVerified bool Whether the link/account is verified.
OrderIndex int Display order. Unique per (ArtistId, Platform, Url).

SocialPlatform

Streaming & music: Spotify (0), AppleMusic (1), Bandcamp (2), SoundCloud (3), YouTube (4). Social: Instagram (5), TikTok (6), X (7), Facebook (8), Threads (9), Website (10), Discord (11), Twitch (12). AI & creator platforms: Suno (13), Udio (14), HuggingFace (15), GitHub (16), Patreon (17), KoFi (18), Substack (19).

11 ArtistImage

A resized variant of an artist's imagery. Identical in shape to AlbumImage — it implements the same IImageVariantRecord interface — with ArtistId in place of AlbumId.

apps/api/src/Features/Artists/Models/ArtistImage.cs
FieldTypeDescription
ArtistId / Artist Guid + nav Parent artist. OnDelete = Cascade.
Variant / Size ImageVariant / ImageSize Crop/shape and resolution tier. See Image variants & sizes.
ObjectKey string · required · ≤500 S3 object key of the stored file.
Width / Height / SizeBytes int / int / long Pixel dimensions and file size.
ContentHash string · required · ≤64 Content hash for dedup/cache-busting.
IsPrimary bool Marks the primary image for its (Variant, Size). One primary per group (unique filtered index).

12 Relationships

Property Cardinality Join / FK OnDelete
Aliases One-to-Many artist_aliases.ArtistId Cascade
SocialLinks One-to-Many artist_social_links.ArtistId Cascade
Images One-to-Many artist_images.ArtistId Cascade
MemberOf (as group) One-to-Many artist_memberships.GroupArtistId Cascade
Memberships (as member) One-to-Many artist_memberships.MemberArtistId Restrict
Genres Many-to-Many artist_genres Cascade (join table)
Albums Many-to-Many album_artists Cascade (join table)
Tracks Many-to-Many track_artists Cascade (join table)
Owner Many-to-One (optional) artists.OwnerUserId SetNull
OriginState / OriginCity Many-to-One (optional) artists.OriginStateId / OriginCityId SetNull
Restrict as a member

An artist cannot be deleted while it is listed as a member of some group — the fk_artist_memberships_member FK uses Restrict. Deleting a group artist, however, cascades and removes its line-up rows.