Spaces:
Running
Running
Download apps/api/src/network/network.controller.ts from Benaah/MicProtocol: direct link, hf CLI and curl.
- Browser
- Download file 11.9 kB
-
https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/api/src/network/network.controller.ts
- Command line
-
hf download hf://spaces/Benaah/MicProtocol/apps/api/src/network/network.controller.ts
-
curl -L -o network.controller.ts https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/api/src/network/network.controller.ts
11.9 kB
| import { | |
| Controller, | |
| Get, | |
| Post, | |
| Put, | |
| Delete, | |
| Param, | |
| Body, | |
| Query, | |
| UseGuards, | |
| Req, | |
| ForbiddenException, | |
| } from "@nestjs/common"; | |
| import { | |
| ApiTags, | |
| ApiOperation, | |
| ApiParam, | |
| ApiQuery, | |
| ApiResponse, | |
| ApiBearerAuth, | |
| } from "@nestjs/swagger"; | |
| import { Throttle } from "@nestjs/throttler"; | |
| import { BetterAuthGuard } from "../auth/better-auth.guard"; | |
| import { PodcastAccessGuard } from "../common/guards/podcast-access.guard"; | |
| import { NetworkService } from "./network.service"; | |
| import { | |
| CreateGuestPublicProfileDto, | |
| UpdateGuestPublicProfileDto, | |
| GuestNetworkSearchDto, | |
| CreateNetworkBookingRequestDto, | |
| RespondToBookingRequestDto, | |
| CreateNetworkBookmarkDto, | |
| UpdateNetworkBookmarkDto, | |
| CreateHostReviewDto, | |
| TrackProfileViewDto, | |
| } from "./network.dto"; | |
| ("Network") | |
| ("network") | |
| export class NetworkController { | |
| constructor(private readonly networkService: NetworkService) {} | |
| // βββ Public Endpoints ββββββββββββββββββββββββββββββββ | |
| ("guests/search") | |
| ({ default: { limit: 30, ttl: 60000 } }) | |
| ({ summary: "Search the guest network" }) | |
| ({ status: 200, description: "Search results" }) | |
| async searchGuests(() query: GuestNetworkSearchDto) { | |
| return this.networkService.searchProfiles(query as any); | |
| } | |
| ("guests/trending") | |
| ({ summary: "Get trending guest voices" }) | |
| ({ name: "region", required: false, example: "east-africa" }) | |
| ({ name: "limit", required: false, example: 10 }) | |
| async getTrending( | |
| ("region") region?: string, | |
| ("limit") limit?: number, | |
| ) { | |
| return this.networkService.getTrending(region, limit || 10); | |
| } | |
| ("guests/:vanityUrl") | |
| ({ summary: "Get public guest profile by vanity URL" }) | |
| ({ name: "vanityUrl", example: "john-nduati" }) | |
| async getProfile(("vanityUrl") vanityUrl: string) { | |
| return this.networkService.getProfileByVanityUrl(vanityUrl); | |
| } | |
| ("views") | |
| ({ summary: "Track a profile view" }) | |
| async trackView(() body: TrackProfileViewDto) { | |
| return this.networkService.trackView(body as any); | |
| } | |
| // βββ Protected Endpoints βββββββββββββββββββββββββββββ | |
| ("profiles") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Create your public guest profile" }) | |
| ({ status: 201, description: "Profile created" }) | |
| ({ status: 409, description: "Profile already exists" }) | |
| async createProfile( | |
| () req: any, | |
| () body: CreateGuestPublicProfileDto, | |
| ) { | |
| return this.networkService.createProfile(req.userId, body as any); | |
| } | |
| ("profiles/me") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Update your public guest profile" }) | |
| async updateMyProfile( | |
| () req: any, | |
| () body: UpdateGuestPublicProfileDto, | |
| ) { | |
| return this.networkService.updateProfile(req.userId, body as any); | |
| } | |
| ("profiles/me") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Get your public profile with analytics" }) | |
| async getMyProfile(() req: any) { | |
| return this.networkService.getMyProfile(req.userId); | |
| } | |
| ("profiles/:id/views") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Get profile view statistics" }) | |
| ({ name: "id" }) | |
| ({ name: "days", required: false, example: 30 }) | |
| async getViewStats( | |
| () req: any, | |
| ("id") id: string, | |
| ("days") days?: number, | |
| ) { | |
| // SECURITY: `req.userId` is set by BetterAuthGuard from the verified session. | |
| // Never trust client-supplied identity headers (e.g. `x-user-id`) for | |
| // authorization decisions. getProfileViewStats enforces ownership | |
| // server-side. | |
| return this.networkService.getProfileViewStats(req.userId, id, days || 30); | |
| } | |
| // βββ Bookmarks βββββββββββββββββββββββββββββββββββββββ | |
| ("bookmarks") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Bookmark a guest profile" }) | |
| async createBookmark( | |
| () body: CreateNetworkBookmarkDto, | |
| () req: any, | |
| ) { | |
| return this.networkService.createBookmark(body as any, req.userId); | |
| } | |
| ("bookmarks/:id") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Update a bookmark" }) | |
| async updateBookmark( | |
| () req: any, | |
| ("id") id: string, | |
| () body: UpdateNetworkBookmarkDto, | |
| ) { | |
| return this.networkService.updateBookmark(req.userId, id, body as any); | |
| } | |
| ("bookmarks/:id") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Remove a bookmark" }) | |
| async removeBookmark( | |
| () req: any, | |
| ("id") id: string, | |
| ) { | |
| return this.networkService.removeBookmark(req.userId, id); | |
| } | |
| ("bookmarks") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "List bookmarked guest profiles" }) | |
| ({ name: "podcastId", required: true }) | |
| ({ name: "status", required: false }) | |
| async listBookmarks( | |
| () req: any, | |
| ("podcastId") podcastId: string, | |
| ("status") status?: string, | |
| ) { | |
| return this.networkService.listBookmarks(podcastId, req.userId, status); | |
| } | |
| // βββ Booking Requests ββββββββββββββββββββββββββββββββ | |
| ("booking-requests") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Send a booking request to a guest" }) | |
| ({ status: 201, description: "Booking request created" }) | |
| async createBookingRequest( | |
| () body: CreateNetworkBookingRequestDto, | |
| () req: any, | |
| ) { | |
| return this.networkService.createBookingRequest(body as any, req.userId); | |
| } | |
| ("booking-requests/:id/respond") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Accept or decline a booking request" }) | |
| ({ name: "id" }) | |
| async respondToBookingRequest( | |
| () req: any, | |
| ("id") id: string, | |
| () body: RespondToBookingRequestDto, | |
| ) { | |
| return this.networkService.respondToBookingRequest( | |
| id, | |
| req.userId, | |
| body.status, | |
| ); | |
| } | |
| ("booking-requests/received") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "List received booking requests" }) | |
| ({ name: "profileId", required: true }) | |
| ({ name: "status", required: false }) | |
| async listBookingRequests( | |
| () req: any, | |
| ("profileId") profileId: string, | |
| ("status") status?: string, | |
| ) { | |
| return this.networkService.listBookingRequests(req.userId, profileId, status); | |
| } | |
| ("booking-requests/sent") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "List sent booking requests" }) | |
| ({ name: "podcastId", required: true }) | |
| ({ name: "status", required: false }) | |
| async listSentBookingRequests( | |
| () req: any, | |
| ("podcastId") podcastId: string, | |
| ("status") status?: string, | |
| ) { | |
| return this.networkService.listSentBookingRequests(req.userId, podcastId, status); | |
| } | |
| // βββ Reviews βββββββββββββββββββββββββββββββββββββββββ | |
| ("reviews") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Submit a host review for a guest" }) | |
| async submitReview( | |
| () req: any, | |
| () body: CreateHostReviewDto, | |
| ) { | |
| return this.networkService.submitReview(req.userId, body as any); | |
| } | |
| // βββ Reputation ββββββββββββββββββββββββββββββββββββββ | |
| ("profiles/:id/reputation") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Get reputation insights for a profile" }) | |
| ({ name: "id" }) | |
| async getReputationInsights( | |
| () req: any, | |
| ("id") id: string, | |
| ) { | |
| return this.networkService.getReputationInsights(req.userId, id); | |
| } | |
| ("profiles/:id/reputation/recalculate") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Recalculate reputation score for a profile" }) | |
| ({ name: "id" }) | |
| async recalculateReputation( | |
| () req: any, | |
| ("id") id: string, | |
| ) { | |
| return this.networkService.recalculateReputation(req.userId, id); | |
| } | |
| // βββ Recommendations βββββββββββββββββββββββββββββββββ | |
| ("profiles/:id/recommendations") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Get guest recommendations based on network graph" }) | |
| ({ name: "id" }) | |
| ({ name: "limit", required: false, example: 5 }) | |
| async getRecommendations( | |
| () req: any, | |
| ("id") id: string, | |
| ("limit") limit?: number, | |
| ) { | |
| return this.networkService.getRecommendations(req.userId, id, limit || 5); | |
| } | |
| ("profiles/:id/network-stats") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Get social network statistics for a profile" }) | |
| ({ name: "id" }) | |
| async getProfileNetworkStats( | |
| () req: any, | |
| ("id") id: string, | |
| ) { | |
| return this.networkService.getProfileNetworkStats(req.userId, id); | |
| } | |
| // βββ Podcast Network Stats βββββββββββββββββββββββββββ | |
| ("stats/:podcastId") | |
| (BetterAuthGuard, PodcastAccessGuard) | |
| () | |
| ({ summary: "Get network usage statistics for a podcast" }) | |
| ({ name: "podcastId" }) | |
| async getPodcastNetworkStats( | |
| ("podcastId") podcastId: string, | |
| () req: any, | |
| ) { | |
| return this.networkService.getPodcastNetworkStats(podcastId, req.userId); | |
| } | |
| // βββ Admin βββββββββββββββββββββββββββββββββββββββββββ | |
| ("admin/verify/:profileId") | |
| (BetterAuthGuard) | |
| () | |
| ({ summary: "Verify a guest profile (admin)" }) | |
| ({ name: "profileId" }) | |
| async verifyProfile( | |
| () req: any, | |
| ("profileId") profileId: string, | |
| () body: { status: "basic" | "verified" | "featured" }, | |
| ) { | |
| // SECURITY: `req.userId` is set by BetterAuthGuard from the verified session. | |
| // Using the client-controlled `x-user-id` header here would let any | |
| // authenticated user impersonate an admin for this endpoint. | |
| return this.networkService.verifyProfile(req.userId, profileId, body.status); | |
| } | |
| } | |