feat: Add cross-band entity relationship models
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
Schema additions for fediversion multi-band architecture: - SongCanon: Canonical master songs for cross-band linking (e.g., 'Dark Star' links GD, D&C, Billy Strings versions) - UserVerticalPreference: User band display preferences - display_mode: primary/secondary/attribution_only/hidden - priority: Sort order for UI - notify_on_show: Per-band notification settings - Vertical additions: - primary_artist_id: Link to main Artist entity - color: Hex branding color - emoji: Display emoji - Song additions: - canon_id: Link to SongCanon for cross-band tracking
This commit is contained in:
parent
42ede48a70
commit
56f52de7fc
1 changed files with 41 additions and 5 deletions
|
|
@ -61,6 +61,13 @@ class Vertical(SQLModel, table=True):
|
|||
slug: str = Field(unique=True, index=True)
|
||||
description: Optional[str] = Field(default=None)
|
||||
|
||||
# Link to primary artist/band for this vertical
|
||||
primary_artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
|
||||
|
||||
# Theming
|
||||
color: Optional[str] = Field(default=None, description="Hex color for branding")
|
||||
emoji: Optional[str] = Field(default=None, description="Display emoji")
|
||||
|
||||
shows: List["Show"] = Relationship(back_populates="vertical")
|
||||
songs: List["Song"] = Relationship(back_populates="vertical")
|
||||
|
||||
|
|
@ -155,6 +162,18 @@ class Show(SQLModel, table=True):
|
|||
attendances: List["Attendance"] = Relationship(back_populates="show")
|
||||
performances: List["Performance"] = Relationship(back_populates="show")
|
||||
|
||||
class SongCanon(SQLModel, table=True):
|
||||
"""Canonical 'master' song independent of band - enables cross-band song linking"""
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
title: str = Field(index=True)
|
||||
slug: str = Field(unique=True, index=True)
|
||||
original_artist: Optional[str] = Field(default=None, description="Original songwriter/band")
|
||||
original_artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
|
||||
notes: Optional[str] = Field(default=None)
|
||||
|
||||
# All vertical-specific versions of this song
|
||||
versions: List["Song"] = Relationship(back_populates="canon")
|
||||
|
||||
class Song(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
title: str = Field(index=True)
|
||||
|
|
@ -164,11 +183,15 @@ class Song(SQLModel, table=True):
|
|||
notes: Optional[str] = Field(default=None)
|
||||
youtube_link: Optional[str] = Field(default=None)
|
||||
|
||||
# New Relation
|
||||
artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
|
||||
artist: Optional[Artist] = Relationship(back_populates="songs")
|
||||
# Link to canonical song for cross-band tracking
|
||||
canon_id: Optional[int] = Field(default=None, foreign_key="songcanon.id")
|
||||
canon: Optional[SongCanon] = Relationship(back_populates="versions")
|
||||
|
||||
vertical: Vertical = Relationship(back_populates="songs")
|
||||
# Artist who wrote/performs this version
|
||||
artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
|
||||
artist: Optional["Artist"] = Relationship(back_populates="songs")
|
||||
|
||||
vertical: "Vertical" = Relationship(back_populates="songs")
|
||||
|
||||
class Sequence(SQLModel, table=True):
|
||||
"""Named groupings of consecutive songs, e.g. 'Autumn Crossing' = Travelers > Elmeg the Wise"""
|
||||
|
|
@ -346,7 +369,20 @@ class UserPreferences(SQLModel, table=True):
|
|||
email_on_chase: bool = Field(default=True, description="Email when your chase song is played")
|
||||
email_digest: bool = Field(default=False, description="Weekly digest email")
|
||||
|
||||
user: User = Relationship(back_populates="preferences")
|
||||
user: "User" = Relationship(back_populates="preferences")
|
||||
|
||||
class UserVerticalPreference(SQLModel, table=True):
|
||||
"""User preferences for which bands to display prominently vs. attribution-only"""
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
user_id: int = Field(foreign_key="user.id", index=True)
|
||||
vertical_id: int = Field(foreign_key="vertical.id", index=True)
|
||||
display_mode: str = Field(default="primary", description="primary, secondary, attribution_only, hidden")
|
||||
priority: int = Field(default=0, description="Sort order - lower = higher priority")
|
||||
notify_on_show: bool = Field(default=True, description="Notify when this band plays a show")
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||
|
||||
user: "User" = Relationship()
|
||||
vertical: "Vertical" = Relationship()
|
||||
|
||||
class Profile(SQLModel, table=True):
|
||||
"""A user's identity within a specific context or global"""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue