- ride-types: per-tenant catalog (economy/comfort/electric/family_van/women/scooter), seeded
- matching now class-scoped (geo:drivers:{tenant}:{class}); trips match by requested type
- trips: is_round_trip (doubles distance for fare) + payment_method + wallet settlement on paid
- dispatch: operator creates trip for phone customer (role-guarded)
- wallet: balance + credit/debit + txns + self topup; wallet-paid trips settle rider→driver
- notifications: FCM device tokens + best-effort push (assign event)
- realtime: trip:join, live driver:location broadcast, WebRTC call signaling (offer/answer/ice/end)
- migration InitP2 (ride_types, wallets, wallet_txns, device_tokens, trips.is_round_trip)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
|
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
import { WalletService } from './wallet.service';
|
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
|
import { CurrentUser, AuthUser } from '../auth/decorators/current-user.decorator';
|
|
|
|
@ApiTags('wallet')
|
|
@ApiBearerAuth()
|
|
@UseGuards(JwtAuthGuard)
|
|
@Controller('wallet')
|
|
export class WalletController {
|
|
constructor(private readonly wallet: WalletService) {}
|
|
|
|
@Get()
|
|
async me(@CurrentUser() user: AuthUser) {
|
|
return this.wallet.getOrCreate(user.tenantId, user.userId);
|
|
}
|
|
|
|
@Get('transactions')
|
|
async history(@CurrentUser() user: AuthUser) {
|
|
const w = await this.wallet.getOrCreate(user.tenantId, user.userId);
|
|
return this.wallet.history(user.tenantId, w.id);
|
|
}
|
|
|
|
// شحن ذاتي تجريبي (كاش-إن). للإنتاج يُربط بمزوّد دفع أو يُقيَّد للأدمن.
|
|
@Post('topup')
|
|
topup(@CurrentUser() user: AuthUser, @Body('amount') amount: number) {
|
|
return this.wallet.credit(user.tenantId, user.userId, Number(amount), 'topup');
|
|
}
|
|
}
|