Skip to main content
Lens Music uses PostgreSQL with TypeORM to manage a relational database schema. This page documents all entities, their fields, and relationships in the database.

Entity overview

The database consists of the following core entities:

User

User accounts and authentication

Artist

Artist profiles and metadata

Label

Record label information

Release

Albums, singles, and EPs

Track

Individual songs

Lyrics

Song lyrics with timestamps

Role

User roles

Permission

System permissions

RolePermission

Role-permission mappings

Base entity

All entities extend the AbstractEntity class, which provides common fields:

AbstractEntity

id
UUID
required
Unique identifier for the entity. Auto-generated using PostgreSQL’s UUID generation.
createdAt
timestamp
required
Timestamp when the entity was created. Automatically set to CURRENT_TIMESTAMP on creation.
updatedAt
timestamp
required
Timestamp when the entity was last updated. Automatically updated to CURRENT_TIMESTAMP on any modification.
id: UUID
createdAt: Date
updatedAt: Date
All entities inherit these fields automatically. They don’t need to be explicitly defined in child entities.

Core entities

User

Represents user accounts in the system. Users can create labels, artists, and releases. Table name: user
email
string
required
User’s email address. Must be unique and valid.
  • Max length: 255 characters
  • Validation: Email format validation
  • Unique constraint: Yes
name
string
required
User’s full name.
  • Max length: 255 characters
phone
string
User’s phone number (optional).
  • Max length: 255 characters
  • Unique constraint: Yes (composite with email)
status
enum
required
Account status.
  • Values: ACTIVE, INACTIVE, SUSPENDED
  • Default: ACTIVE
password
string
required
Hashed password. Not included in query results by default.
  • Max length: 255 characters
  • Select: false (excluded from queries)
Relationships:
  • Has many labels (one-to-many with Label)
  • Has many artists (one-to-many with Artist)
  • Has many releases (one-to-many with Release)
  • Has many createdRoles (one-to-many with Role)
  • Has many createdRolePermissions (one-to-many with RolePermission)
Source: api/src/entities/user.entity.ts:14

Artist

Represents artists who create music. Artists belong to users and can be associated with multiple releases. Table name: artists
name
string
required
Artist’s name or stage name.
status
enum
required
Artist’s status in the system.
  • Values: ACTIVE, INACTIVE
  • Default: ACTIVE
userId
UUID
required
Foreign key to the user who owns this artist profile.
Relationships:
  • Belongs to user (many-to-one with User)
    • onDelete: CASCADE - Artist is deleted when user is deleted
    • onUpdate: CASCADE - Artist’s userId updates when user id changes
  • Has many releases through ReleaseArtist (one-to-many)
Source: api/src/entities/artist.entity.ts:13

Label

Represents record labels that publish music releases. Table name: labels
name
string
required
Label’s name.
  • Max length: 255 characters
email
string
Label’s contact email address (optional).
  • Max length: 255 characters
description
string
Description of the label (optional).
  • Max length: 255 characters
userId
UUID
required
Foreign key to the user who owns this label.
country
enum
required
Country where the label is based.
  • Values: ISO country codes (e.g., RW, US, GB)
  • Default: RW (Rwanda)
Relationships:
  • Belongs to user (many-to-one with User)
  • Has many releases (one-to-many with Release)
Source: api/src/entities/label.entity.ts:15

Release

Represents music releases (albums, singles, EPs) distributed through the platform. Table name: releases
title
string
required
Release title.
coverArt
string
URL or path to the release cover art image (optional).
upc
string
Universal Product Code for the release (optional).
releaseDate
string
required
Date when the release is published.
version
string
Release version (e.g., “Deluxe Edition”, “Remastered”) - optional.
productionYear
integer
required
Year the release was produced.
catalogNumber
string
Label’s catalog number for the release (optional).
labelId
UUID
Foreign key to the associated label (optional).
userId
UUID
required
Foreign key to the user who created this release.
Unique constraint: Combination of title, releaseDate, productionYear, userId, labelId, and version must be unique. Relationships:
  • Belongs to label (many-to-one with Label)
    • onDelete: CASCADE - Release is deleted when label is deleted
    • onUpdate: CASCADE
  • Belongs to user (many-to-one with User)
    • onDelete: CASCADE - Release is deleted when user is deleted
    • onUpdate: CASCADE
  • Has many artists through ReleaseArtist (one-to-many)
  • Has many tracks (one-to-many with Track)
Source: api/src/entities/release.entity.ts:15

Track

Represents individual tracks (songs) within a release. Table name: tracks
title
string
required
Track title.
duration
integer
required
Track duration in seconds.
explicit
boolean
required
Whether the track contains explicit content.
  • Default: false
releaseId
UUID
required
Foreign key to the release this track belongs to.
isrc
string
International Standard Recording Code - unique identifier for the recording (optional).
  • Unique constraint: Yes
Relationships:
  • Belongs to release (many-to-one with Release)
  • Has many lyrics (one-to-many with Lyrics)
Source: api/src/entities/track.entity.ts:7

Lyrics

Stores synchronized lyrics for tracks with optional timestamps. Table name: lyrics
content
jsonb
required
Lyrics content stored as JSON array of line objects.Format:
[
  { time: "00:00:12", text: "First line of lyrics" },
  { text: "Line without timestamp" }
]
Each line can optionally include a timestamp.
trackId
UUID
required
Foreign key to the associated track.
language
string
required
Language code for the lyrics (e.g., en, fr, rw).
  • Default: en
Relationships:
  • Belongs to track (many-to-one with Track)
Source: api/src/entities/lyrics.entity.ts:7

ReleaseArtist

Junction table linking releases to artists (many-to-many relationship). Table name: release_artists
releaseId
UUID
required
Foreign key to the release.
artistId
UUID
required
Foreign key to the artist.
Relationships:
  • Belongs to release (many-to-one with Release)
  • Belongs to artist (many-to-one with Artist)
Source: api/src/entities/releaseArtist.entity.ts:10

Authorization entities

These entities manage user roles and permissions for access control.

Role

Defines roles that can be assigned to users. Table name: roles
name
string
required
Role name.
  • Unique constraint: Yes
description
string
Description of the role’s purpose (optional).
createdById
UUID
required
Foreign key to the user who created this role.
Relationships:
  • Belongs to createdBy user (many-to-one with User)
  • Has many permissions through RolePermission (one-to-many)
Source: api/src/entities/role.entity.ts:7

Permission

Defines system permissions that can be granted to roles. Table name: permissions
name
string
required
Permission name.
  • Unique constraint: Yes
description
string
Description of what the permission grants (optional).
Relationships:
  • Has many roles through RolePermission (one-to-many)
Source: api/src/entities/permission.entity.ts:5

RolePermission

Junction table linking roles to permissions (many-to-many relationship). Table name: role_permissions
roleId
UUID
required
Foreign key to the role.
permissionId
UUID
required
Foreign key to the permission.
createdById
UUID
Foreign key to the user who created this assignment (optional).
Unique constraint: Combination of roleId and permissionId must be unique. Relationships:
  • Belongs to role (many-to-one with Role)
  • Belongs to permission (many-to-one with Permission)
  • Belongs to createdBy user (many-to-one with User)
Source: api/src/entities/rolePermission.entity.ts:8

Entity relationship diagram

Database management

Migrations

In development mode, TypeORM automatically synchronizes the schema. For production, use proper migrations to manage schema changes safely.

Seeding

Populate the database with initial data using the seed script:
cd api
npm run seed
Seed scripts are located in api/src/seeds/.

Cascading deletes

Several relationships have CASCADE delete configured:
  • Deleting a User cascades to their Artists, Releases, Labels
  • Deleting a Label cascades to its Releases
  • Deleting a Release cascades to its Tracks
Be cautious when deleting entities with cascade relationships, as it will permanently remove related data.

Development setup

Set up your local database

Environment variables

Configure database connection

Monorepo structure

Explore entity files in the codebase

API reference

API endpoints that use these entities

Build docs developers (and LLMs) love