- 📘 Introduction
- 💻 Getting Started
- 🔍 APIs Reference
- 🏗️🔨 Database ERD
- 🔄 Authentication Sequence Diagrams
- 📐 UML Diagram
- 👥 Author
- 🤝 Contributing
- 👀 Kanban Board
- ⭐️ Show Your Support
- 🔭 Up Next
- 💎 Lessons Learned
- 🙏 Acknowledgements
- 📜 License
🎻 Conduct your music empire! 🎧 Music Store is your one-stop API to manage artists, albums, and songs. ✨ Search, filter, integrate - it's your musical symphony. 🎶
Welcome to Music Store API, a powerful and efficient REST API built with NestJS that serves as your ultimate solution for managing your music empire. With Music Store API, you can easily organize and control your artists, albums, and songs, creating a seamless and immersive musical experience for your users.
Music Store API prioritizes the security and reliability of your music assets. The API implements robust authentication mechanisms, ensuring secure access to your music collection. With built-in security features, you can protect sensitive data and provide a safe environment for your users' musical journey.
To get a local copy up and running, follow these steps.
In order to run this project you need:
DATABASE_HOST
: the mysql host (e.g. localhost)DATABASE_PORT
: the port on which mysql are working on (e.g. 3306)DATABASE_USERNAME
: your mysql username (e.g. mysql)DATABASE_PASSWORD
: your mysql password (e.g. root)DATABASE_NAME
: the database name on which the project will use (e.g. MusicStore)JWT_SECRET
: the json web token signature to create or validate token (e.g. jwtsecret)COOKIE_SESSION_SECRET
: your cookie session secret (e.g sessionsecret)
- Clone the repository:
git clone https://github.com/ahmedeid6842/music-store
- Change to the project directory:
cd ./music-store
Install the project dependencies using NPM:
npm install
To start the application in development mode, run the following command:
npm run start:dev
The application will be accessible at http://localhost:3000.
- Alright, it's showtime! 🔥 Hit
http://localhost:3000
and BOOM! 💥 You should see the docs page and the Music Store APIs working flawlessly. ✨🧙♂️
This section provides detailed documentation and examples for the API endpoints used in the Music Store backend project. You can Hit this Link to view the documentation.
🏗️🔨 Database ERD
sequenceDiagram
participant User
participant AuthController
participant AuthService
participant UsersService
participant EmailService
participant JwtService
User->>+AuthController: register()
AuthController->>+AuthService: register(userCredentials)
AuthService->>+UsersService: createUser(userCredentials)
UsersService-->>-AuthService: user
AuthService->>+EmailService: sendRegistrationEmail(user)
EmailService-->>-AuthService: emailSent
AuthService-->>-AuthController: registrationSuccess
User->>+AuthController: login(credentials)
AuthController->>+AuthService: login(credentials)
AuthService->>+UsersService: getUserByEmail(email)
UsersService-->>-AuthService: user
AuthService->>+AuthService: comparePasswords(password, user.password)
AuthService->>+JwtService: generateToken(user)
JwtService-->>-AuthService: token
AuthService-->>-AuthController: loginSuccess(token)
User->>+AuthController: requestPasswordReset(email)
AuthController->>+AuthService: requestPasswordReset(email)
AuthService->>+UsersService: getUserByEmail(email)
UsersService-->>-AuthService: user
AuthService->>+AuthService: generatePasswordResetToken(user)
AuthService->>+EmailService: sendPasswordResetEmail(user, resetToken)
EmailService-->>-AuthService: emailSent
AuthService-->>-AuthController: passwordResetEmailSent()
User->>+AuthController: resetPassword(resetToken, newPassword)
AuthController->>+AuthService: resetPassword(resetToken, newPassword)
AuthService->>+AuthService: verifyPasswordResetToken(resetToken)
AuthService->>+UsersService: getUserById(userId)
UsersService-->>-AuthService: user
AuthService->>+AuthService: hashPassword(newPassword)
AuthService->>+UsersService: updatePassword(user, hashedPassword)
UsersService-->>-AuthService: updatedUser
AuthService-->>-AuthController: passwordResetSuccess()
User->>+AuthController: verifyEmail(email, verificationCode)
AuthController->>+AuthService: verifyEmail(email, verificationCode)
AuthService->>+UsersService: getUserByEmail(email)
UsersService-->>-AuthService: user
AuthService->>+AuthService: verifyEmail(user, verificationCode)
AuthService->>+UsersService: updateUserVerification(user)
UsersService-->>-AuthService: updatedUser
AuthService-->>-AuthController: emailVerificationSuccess()
User->>+AuthController: logout()
AuthController->>+AuthService: logout()
AuthService-->>-AuthController: logoutSuccess()
classDiagram
class UsersService {
+ create(email: string, userName: string, password: string, verificationCode: string, verificationCodeExpiresAt: Date): void
+ findOne(id: string)
+ find(email?: string, userName?: string)
+ update(userId: string, attrs: Partial<User>)
}
class User {
+ id: string
+ email: string
+ userName: string
+ password: string
+ verificationCode: string
+ verificationCodeExpiresAt: Date
}
class CreateUserDto {
+ email: string
+ password: string
+ userName: string
}
class AuthService {
+ register(userData: CreateUserDto): void
+ verifyEmail(email: string, verificationCode: string): void
+ login(userCredentials: LoginUserDto): string
+ sendResetPasswordEmail(userData: any): void
+ resetPassword(token: string, password: string): void
- generateResetPasswordToken(userId: string): string
- generateVerificationCode(): string
- generateVerificationCodeExpiration(): Date
}
class EmailService {
- email: string
- password: string
+ sendResetPasswordEmail(email: string, resetPasswordUrl: string): void
+ sendVerificationEmail(email: string, verificationCode: string): void
}
class ArtistService {
+ createArtist(artist: CreateArtistDto, user: UserDto): void
+ getArtist(query: GetArtistQueryDto): Artist[]
+ updateArtist(artist: PartialArtistDto, user: UserDto): void
}
class Artist {
+ id: string
+ name: string
+ bio: string
+ user: User
}
class AlbumService {
+ createAlbum(albumBody: CreateAlbumDto, artist: Artist): void
+ getAlbums(query: GetAlbumQueryDto): Album[]
+ updateAlbum(albumId: string, albumBody: PartialAlbumDto): void
+ deleteAlbum(albumId: string): void
}
class Album {
+ id: string
+ title: string
+ artworkUrl: string
+ artist: Artist
}
class SongService {
+ createSong(newSong: CreateSongDto, artist: Artist): void
+ getSongs(query: GetSongQueryDto): Song[]
+ updateSong(songId: string, newSong: PartialSongDto): void
+ deleteSong(songId: string): void
}
class Song {
+ id: string
+ title: string
+ duration: number
+ album: Album
+ artists: Artist[]
}
UsersService --> User: Manages
AuthService --> UsersService: Depends on
AuthService --> EmailService: Depends on
ArtistService --> Artist: Manages
ArtistService --> UsersService: Uses
AlbumService --> Album: Manages
AlbumService --> ArtistService: Uses
SongService --> ArtistService: Uses
SongService --> Song: Manages
Ahmed Eid 🙋♂️
- Github: @ahmedeid6842
- LinkedIn : Ahmed Eid
- Twitter: @ahmedeid2684
We're always looking to improve this project! 🔍 If you notice any issues or have ideas for new features, please don't hesitate to submit a pull request 🙌 or create a new issue 💡. Your contribution will help make this project even better! ❤️ 💪
You can check my kanban board from Here to see how I split this project into tasks and mange them.
If you find this project helpful, I would greatly appreciate it if you could leave a star! 🌟 💟
- Implement Search engine for different songs searches
- Enhance the DataBase queries time by using redis LRU caching
- Move from monolithic to microservices architecture.
- Apply Background jobs and task scheduling Use a job queue system like Bull or Agenda to handle time-consuming tasks.
- Support user media like image and upload songs.
- Deploy the REST API.
- Secure user access with effective authentication and authorization.
- Use a well-structured architecture, such as Nest.js, for code organization, scalability, and maintainability.
- Take advantage of different NestJS components and decorators.
- Manging the Many to Many relations
- There is always something new to learn.
I am deeply grateful to Alexapps for entrusting me with this project. The opportunity to implement this innovative concept has been an invaluable learning experience.
This project is licensed under the MIT License - you can click here to have more details MIT licensed.