Files
CRM_Montzar/apps/api/src/loyalty/loyalty.controller.ts
T

184 lines
4.6 KiB
TypeScript

import {
Body,
Controller,
Delete,
Get,
Param,
Patch,
Post,
Query,
Res,
StreamableFile,
UseGuards,
} from '@nestjs/common';
import type { Response } from 'express';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { CurrentUser } from '../auth/current-user.decorator';
import { Roles } from '../auth/roles.decorator';
import { RolesGuard } from '../auth/roles.guard';
import type { Actor } from '../common/record-scope';
import {
AdjustLoyaltyPointsDto,
BulkAdjustLoyaltyDto,
CreateLoyaltyRewardDto,
CreateLoyaltyTierDto,
LoyaltyMessageDto,
RedeemLoyaltyRewardDto,
UpdateLoyaltyRewardDto,
UpdateLoyaltySettingsDto,
UpdateLoyaltyTierDto,
} from './dto';
import { LoyaltyService } from './loyalty.service';
import { brand } from '@mento/shared';
@Controller('loyalty')
@UseGuards(JwtAuthGuard, RolesGuard)
export class LoyaltyController {
constructor(private readonly loyalty: LoyaltyService) {}
@Get('stats')
stats(@CurrentUser() user: Actor) {
return this.loyalty.getStats(user);
}
@Get('settings')
settings(@CurrentUser() user: Actor) {
return this.loyalty.getSettings(user.organizationId);
}
@Patch('settings')
@Roles('owner', 'admin')
updateSettings(
@CurrentUser() user: Actor,
@Body() dto: UpdateLoyaltySettingsDto,
) {
return this.loyalty.updateSettings(user.organizationId, dto);
}
@Get('tiers')
listTiers(@CurrentUser() user: Actor) {
return this.loyalty.listTiers(user.organizationId);
}
@Post('tiers')
@Roles('owner', 'admin')
createTier(
@CurrentUser() user: Actor,
@Body() dto: CreateLoyaltyTierDto,
) {
return this.loyalty.createTier(user.organizationId, dto);
}
@Patch('tiers/:id')
@Roles('owner', 'admin')
updateTier(
@CurrentUser() user: Actor,
@Param('id') id: string,
@Body() dto: UpdateLoyaltyTierDto,
) {
return this.loyalty.updateTier(user.organizationId, id, dto);
}
@Delete('tiers/:id')
@Roles('owner', 'admin')
async deleteTier(@CurrentUser() user: Actor, @Param('id') id: string) {
await this.loyalty.deleteTier(user.organizationId, id);
return { ok: true };
}
@Get('members/export')
async exportMembers(
@CurrentUser() user: Actor,
@Query('q') q: string | undefined,
@Query('tierId') tierId: string | undefined,
@Res({ passthrough: true }) res: Response,
) {
const buffer = await this.loyalty.exportMembers(user, q, tierId);
res.set({
'Content-Type':
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Content-Disposition': `attachment; filename="${brand.filePrefix}-loyalty-members.xlsx"`,
});
return new StreamableFile(buffer);
}
@Get('members')
listMembers(
@CurrentUser() user: Actor,
@Query('q') q?: string,
@Query('tierId') tierId?: string,
) {
return this.loyalty.listMembers(user, q, tierId);
}
@Get('members/:personId/ledger')
listLedger(
@CurrentUser() user: Actor,
@Param('personId') personId: string,
) {
return this.loyalty.listLedger(user, personId);
}
@Post('members/bulk-adjust')
bulkAdjust(
@CurrentUser() user: Actor,
@Body() dto: BulkAdjustLoyaltyDto,
) {
return this.loyalty.bulkAdjust(user, dto.personIds, dto.delta, dto.reason);
}
@Post('members/message')
sendMessage(@CurrentUser() user: Actor, @Body() dto: LoyaltyMessageDto) {
return this.loyalty.sendMessage(user, dto.personIds, dto.text);
}
@Post('members/:personId/adjust')
adjust(
@CurrentUser() user: Actor,
@Param('personId') personId: string,
@Body() dto: AdjustLoyaltyPointsDto,
) {
return this.loyalty.adjustPoints(user, personId, dto.delta, dto.reason);
}
@Get('rewards')
listRewards(@CurrentUser() user: Actor) {
return this.loyalty.listRewards(user.organizationId);
}
@Post('rewards')
@Roles('owner', 'admin')
createReward(
@CurrentUser() user: Actor,
@Body() dto: CreateLoyaltyRewardDto,
) {
return this.loyalty.createReward(user.organizationId, dto);
}
@Patch('rewards/:id')
@Roles('owner', 'admin')
updateReward(
@CurrentUser() user: Actor,
@Param('id') id: string,
@Body() dto: UpdateLoyaltyRewardDto,
) {
return this.loyalty.updateReward(user.organizationId, id, dto);
}
@Delete('rewards/:id')
@Roles('owner', 'admin')
async deleteReward(@CurrentUser() user: Actor, @Param('id') id: string) {
await this.loyalty.deleteReward(user.organizationId, id);
return { ok: true };
}
@Post('rewards/:id/redeem')
redeem(
@CurrentUser() user: Actor,
@Param('id') id: string,
@Body() dto: RedeemLoyaltyRewardDto,
) {
return this.loyalty.redeemReward(user, id, dto.personId);
}
}