How pupupu-core/spotify-clone works
Purpose and Workspace
Pupufy is a music-streaming system backed by the Jamendo catalog, with account auth, personal uploads, playlists, discovery, search, and audio streaming/download. It is an Nx/pnpm TypeScript monorepo: Angular SPA, NestJS API, Playwright E2E app, and shared API contracts/configuration.
Runtime Entry Points
• Web SPA bootstraps from apps/web/src/main.ts; application routing and provider setup are centered in apps/web/src/app/app.routes.ts and apps/web/src/app/app.config.ts.
• NestJS boots from apps/api/src/main.ts, composing application dependencies in apps/api/src/app/app.module.ts.
• Containers are defined per application (apps/web/dockerfile, apps/api/dockerfile) and orchestrated with docker-compose.yml; web includes Nginx configuration at apps/web/nginx.conf.
API Boundary and Application Layer
REST v1 controllers validate/transform requests, enforce authentication, and invoke use-case workflows. Authentication is guarded at the gateway boundary and API-domain failures are translated through a common filter.
• Gateway examples: apps/api/src/app/gateway/rest/v1/auth/auth.controller.ts, apps/api/src/app/gateway/rest/v1/track/track.controller.ts, apps/api/src/app/gateway/rest/guards/access-token.guard.ts.
• Workflows orchestrate domain steps for auth, tracks, playlists, search, artists, and albums: apps/api/src/app/core/workflows/auth/login-user.workflow.ts, apps/api/src/app/core/workflows/track/upload-track.workflow.ts, apps/api/src/app/core/workflows/playlist/reorder-playlist-entries.workflow.ts.
• Steps contain focused business operations and domain constraints, such as resolving playlist track references, issuing/revoking sessions, and fetching catalog data: apps/api/src/app/core/steps/resolve-playlist-track-references.step.ts, apps/api/src/app/core/steps/issue-auth-session.step.ts.
Identity, Persistence, and Uploaded Music
Local accounts, identities/sessions, uploaded tracks, playlists, visibility, genres, and playlist entries are persisted through Prisma against PostgreSQL. The schema and migrations are the durable data-model boundary.
• apps/api/prisma/schema.prisma
• apps/api/src/app/infrastructure/prisma/prisma.service.ts
• apps/api/src/app/core/steps/upload-track.step/upload-track.step.ts
Uploaded media is stored separately through an S3-compatible storage abstraction; streaming supports HTTP range behavior at the REST layer.
• apps/api/src/app/infrastructure/storage/s3-storage.service.ts
• apps/api/src/app/gateway/rest/v1/track/track-stream.service.ts
• apps/api/src/app/shared/lib/parse-http-range-header.ts
External Catalog and Token Integration
Jamendo is accessed only through its infrastructure client, DTOs, and mappers. Core fetch steps/workflows isolate the rest of the API from Jamendo-specific response shapes and availability errors.
• apps/api/src/app/infrastructure/jamendo/jamendo.client.ts
• apps/api/src/app/infrastructure/jamendo/jamendo.module.ts
• apps/api/src/app/infrastructure/jamendo/mappers/track.ts
Access/refresh token mechanics are likewise infrastructure services consumed by auth workflows and REST guards: apps/api/src/app/infrastructure/token/auth-token.service.ts, apps/api/src/app/gateway/rest/v1/auth/auth-cookie.service.ts.
Web Client Flow
Angular pages and feature components call API services, hold UI/session state in stores, and use interceptors to attach access tokens and refresh on unauthorized responses. Route guards divide guest and authenticated experiences.
• apps/web/src/app/core/interceptors/access-token/access-token.interceptor.ts
• apps/web/src/app/core/stores/auth-session.service.ts
• apps/web/src/app/core/guards/auth-guard.ts
Player services manage browser audio and queue behavior independently of catalog/UI presentation: apps/web/src/app/features/player/services/html-audio.service.ts, apps/web/src/app/features/player/services/track-player.service.ts. Feature API/store pairs serve artist, album, playlist, and search pages.
Shared Contracts and Operational Boundaries
The API and SPA share request/response models, endpoint constants, and utility functions, preventing duplicated HTTP contract definitions.
• packages/shared/model/src/index.ts
• packages/shared/config/src/lib/api/endpoints.ts
• packages/shared/utils/src/lib/build-api-path/index.ts
Swagger initialization exposes API documentation (apps/api/src/app/infrastructure/swagger/init-swagger.ts). CI/deployment workflows live under .github/workflows; E2E exercises the deployed user-facing routes from apps/e2e/src/smoke.spec.ts.
Main entry points: track.controller.ts REST v1 gateway · login-user.workflow.ts Use-case workflows · app.routes.ts Routes & providers · app.module.ts Application module
Components 19
Angular Web
- SPA bootstrap
apps/web/src/main.ts - Routes & providers
apps/web/src/app/app.routes.ts - Feature pages · Artist, album, playlist, search, and account UI.
- Session state & guards
apps/web/src/app/core/stores/auth-session.service.ts - Token interceptor · Attaches access tokens and refreshes unauthorized requests.
apps/web/src/app/core/interceptors/access-token/access-token.interceptor.ts - Browser player · Manages HTML audio playback and queue behavior.
apps/web/src/app/features/player/services/track-player.service.ts
NestJS API
- API bootstrap
apps/api/src/main.ts - Application module
apps/api/src/app/app.module.ts - REST v1 gateway · Validates requests, enforces access tokens, and serves range streaming.
apps/api/src/app/gateway/rest/v1/track/track.controller.ts - Use-case workflows · Orchestrates auth, catalog, upload, playlist, and search operations.
apps/api/src/app/core/workflows/auth/login-user.workflow.ts - Domain steps · Focused constraints, session operations, and reference resolution.
apps/api/src/app/core/steps/resolve-playlist-track-references.step.ts - Token services
apps/api/src/app/infrastructure/token/auth-token.service.ts - Prisma persistence
apps/api/src/app/infrastructure/prisma/prisma.service.ts - Jamendo client · Maps catalog responses behind an infrastructure boundary.
apps/api/src/app/infrastructure/jamendo/jamendo.client.ts - Swagger docs
apps/api/src/app/infrastructure/swagger/init-swagger.ts
Data & External Services
- PostgreSQL · Accounts, sessions, uploads, playlists, genres, and entries.
apps/api/prisma/schema.prisma - S3-compatible storage · Stores uploaded audio objects.
apps/api/src/app/infrastructure/storage/s3-storage.service.ts
Other components
- Shared API contracts · Models, endpoint constants, and API path utilities.
packages/shared/model/src/index.ts - Container deployment · Runs web and API containers; web is served by Nginx.
docker-compose.yml
Connections 22
- SPA bootstrap → Routes & providers: initializes
- Routes & providers → Feature pages: routes to
- Routes & providers → Session state & guards: protects routes
- Feature pages → Token interceptor: API requests
- Token interceptor → REST v1 gateway: REST v1
- Session state & guards → Token interceptor: access session
- Feature pages → Browser player: plays tracks
- API bootstrap → Application module: starts
- Application module → REST v1 gateway: registers
- Application module → Swagger docs: publishes
- REST v1 gateway → Use-case workflows: invokes
- REST v1 gateway → Token services: auth guard
- Use-case workflows → Domain steps: composes
- Use-case workflows → Token services: issues and revokes sessions
- Domain steps → Prisma persistence: persists domain data
- Prisma persistence → PostgreSQL: queries
- Domain steps → S3-compatible storage: uploads media
- Use-case workflows → Jamendo client: fetches catalog
- Feature pages → Shared API contracts: uses contracts
- REST v1 gateway → Shared API contracts: uses contracts
- Container deployment → SPA bootstrap: serves SPA
- Container deployment → API bootstrap: runs API