Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,14 @@ model Campaign {
id String @id @default(uuid())
title String
description String
story String?
goalAmount Decimal @db.Decimal(20, 7)
raisedAmount Decimal @default(0) @db.Decimal(20, 7)
status CampaignStatus @default(DRAFT)
creatorId String
contractId String?
acceptedAssets Json?
isFeatured Boolean @default(false)
startDate DateTime?
endDate DateTime?
imageUrl String?
Expand All @@ -173,6 +177,7 @@ model Campaign {
@@index([status])
@@index([createdAt])
@@index([category])
@@index([isFeatured])
@@map("campaigns")
}

Expand All @@ -181,7 +186,9 @@ model Donation {
id String @id @default(uuid())
amount Decimal @db.Decimal(20, 7)
assetCode String @default("XLM")
txHash String? @unique
assetIssuer String?
txHash String @unique
isAnonymous Boolean @default(false)
status DonationStatus @default(PENDING)
donorId String
campaignId String
Expand All @@ -199,7 +206,6 @@ model Donation {
disputes Dispute[]
tip PlatformTip? @relation(fields: [tipId], references: [id])

@@unique([donorId, campaignId, txHash])
@@index([donorId])
@@index([campaignId])
@@index([status])
Expand Down
3 changes: 2 additions & 1 deletion src/api-keys/api-keys.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { PrismaModule } from '../prisma/prisma.module';
import { AuthModule } from '../auth/auth.module';
import { ApiKeysController } from './api-keys.controller';
import { ApiKeyGuard } from './api-key.guard';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';

@Module({
imports: [PrismaModule, AuthModule],
controllers: [ApiKeysController],
providers: [ApiKeyGuard],
providers: [ApiKeyGuard, JwtAuthGuard],
exports: [ApiKeyGuard],
})
export class ApiKeysModule {}
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RedisModule } from './redis/redis.module';
import { HealthModule } from './health/health.module';
import { AuthModule } from './auth/auth.module';
import { CampaignsModule } from './campaigns/campaigns.module';
import { StellarModule } from './stellar/stellar.module';
import { AdminModule } from './admin/admin.module';
import { NotificationsModule } from './notifications/notifications.module';
import { DonationsModule } from './donations/donations.module';
Expand All @@ -29,6 +30,7 @@ import { DonationsModule } from './donations/donations.module';
ApiKeysModule,
CampaignsModule,
DonationsModule,
StellarModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
32 changes: 31 additions & 1 deletion src/campaigns/campaigns.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
BadRequestException,
Controller,
Get,
Param,
UseGuards,
ParseUUIDPipe,
Patch,
Post,
Expand All @@ -11,23 +11,32 @@ import {
Req,
BadRequestException,
Inject,
UseGuards,
} from '@nestjs/common';
import Keyv from 'keyv';
import { AuthGuard } from '@nestjs/passport';
import { CampaignsService } from './campaigns.service';
import { CampaignStats } from './interfaces/campaign-stats.interface';
import { Roles } from '../common/decorators/roles.decorator';
import { RolesGuard } from '../common/guards/roles.guard';
import { UpdateCampaignDto } from './dto/update-campaign.dto';
import { CreateCampaignDto } from './dto/create-campaign.dto';
import { Body } from '@nestjs/common';
import { Request } from 'express';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { AdminGuard } from '../users/guards/admin.guard';
import { BrowseCampaignsQueryDto, BrowseCampaignsResponseDto } from './dto/browse-campaigns.dto';

const FORBIDDEN_FIELDS = [
'goalAmount',
'contractId',
'acceptedAssets',
'milestones',
'endDate',
];

const CACHE_MANAGER = 'CACHE_MANAGER';

@Controller('campaigns')
@UseGuards(AuthGuard('jwt'), RolesGuard)
export class CampaignsController {
Expand All @@ -44,6 +53,7 @@ export class CampaignsController {
) {}

@Post()
@UseGuards(JwtAuthGuard)
async create(
@Body() body: CreateCampaignDto,
@Req() req: Request & { user: any },
Expand All @@ -53,6 +63,7 @@ export class CampaignsController {
}

@Patch(':id')
@UseGuards(JwtAuthGuard)
async update(
@Param('id') id: string,
@Body() body: UpdateCampaignDto,
Expand Down Expand Up @@ -88,6 +99,14 @@ export class CampaignsController {
return result;
}

@Get('featured')
async featured() {
return this.campaignsService.getFeaturedCampaigns();
}

/**
* Generate a cache key based on query parameters
*/
private generateCacheKey(query: BrowseCampaignsQueryDto): string {
const parts = [
'campaigns',
Expand All @@ -103,3 +122,14 @@ export class CampaignsController {
return parts.join(':');
}
}

@Controller('admin/campaigns')
export class AdminCampaignsController {
constructor(private readonly campaignsService: CampaignsService) {}

@Post(':id/feature')
@UseGuards(JwtAuthGuard, AdminGuard)
async feature(@Param('id') id: string) {
return this.campaignsService.featureCampaign(id);
}
}
13 changes: 13 additions & 0 deletions src/campaigns/campaigns.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import { Module } from '@nestjs/common';
import { AdminCampaignsController, CampaignsController } from './campaigns.controller';
import { CampaignsService } from './campaigns.service';
import { PrismaModule } from '../prisma/prisma.module';
import { AuthModule } from '../auth/auth.module';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { AdminGuard } from '../users/guards/admin.guard';

@Module({
imports: [PrismaModule, AuthModule],
controllers: [CampaignsController, AdminCampaignsController],
providers: [CampaignsService, JwtAuthGuard, AdminGuard],
exports: [CampaignsService],

import { TypeOrmModule } from '@nestjs/typeorm';
import { Campaign } from './entities/campaign.entity';
import { Donation } from '../donations/entities/donation.entity';
Expand Down
Loading