Skip to content
31 changes: 31 additions & 0 deletions ApiDocs/HelloFutsal/Booking/BulkBookSlots.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
meta {
name: BulkBookSlots
type: http
seq: 15
}

post {
url: {{development}}/bookings/bulk/time-range
body: json
auth: bearer
}

headers {
Content-Type: application/json
}

auth:bearer {
token: {{token}}
}

body:json {
{
"fieldId": "{{fieldId}}",
"startDate": "2026-05-10",
"endDate": "2026-05-12",
"startTime": "6:00",
"endTime": "11:00",
Comment on lines +26 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use zero-padded HH:mm in example payloads.

On Line 26, startTime is "6:00" while most validators/examples expect "06:00" format. Keep both times zero-padded to avoid validation failures when running this request directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ApiDocs/HelloFutsal/Booking/BulkBookSlots.bru` around lines 26 - 27, The
example payload uses non-zero-padded times; update the example values for the
startTime and endTime fields in the BulkBookSlots example so they use
zero-padded "HH:mm" format (e.g., change "6:00" to "06:00" and "11:00" to
"11:00" if not already zero-padded) to match validators that expect two-digit
hours; locate and edit the startTime and endTime entries in the BulkBookSlots
example JSON to enforce the "HH:mm" format.

"userName": "John Doe",
"phoneNumber": "+9779800000000"
}
}
28 changes: 28 additions & 0 deletions ApiDocs/HelloFutsal/Booking/BulkConfirmBookings.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
meta {
name: BulkConfirmBookings
type: http
seq: 16
}

patch {
url: {{development}}/bookings/bulk/confirm
body: json
auth: bearer
}

headers {
Content-Type: application/json
}

auth:bearer {
token: {{token}}
}

body:json {
{
"totalAmount": 5000,
"bookings": [
{ "slotId": "{{slotId}}" }
]
}
}
19 changes: 19 additions & 0 deletions ApiDocs/HelloFutsal/Booking/CancelBooking.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
meta {
name: CancelBooking
type: http
seq: 15
}

patch {
url: {{development}}/bookings/{{slotId}}/cancel
body: none
auth: bearer
}

auth:bearer {
token: {{token}}
}

headers {
Content-Type: application/json
}
25 changes: 25 additions & 0 deletions ApiDocs/HelloFutsal/Booking/CancelMembership.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
meta {
name: CancelMembership
type: http
seq: 20
}

patch {
url: {{development}}/membership-plans/{{membershipId}}/cancel
body: json
auth: bearer
}

auth:bearer {
token: {{token}}
}

headers {
Content-Type: application/json
}

body:json {
{
"endDate": "2026-05-20"
}
}
39 changes: 39 additions & 0 deletions ApiDocs/HelloFutsal/MembershipSlots/UpdateMembership.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
meta {
name: UpdateMembership
type: http
seq: 7
}

patch {
url: {{development}}/membership-plans/{{membershipId}}
body: json
auth: none
}

headers {
Authorization: Bearer {{token}}
Content-Type: application/json
Comment on lines +10 to +15
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Auth mode is inconsistent with the actual request headers.

Line 10 sets auth: none, while Line 14 still sends a bearer token. Prefer auth: bearer + auth:bearer block for consistency with other booking docs and to avoid accidental unauthenticated copies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ApiDocs/HelloFutsal/MembershipSlots/UpdateMembership.bru` around lines 10 -
15, Update the auth declaration and headers to match other booking docs: replace
"auth: none" with "auth: bearer", remove the inline "Authorization: Bearer
{{token}}" header, and add an "auth:bearer" block (with the bearer token
variable) consistent with how other endpoints (e.g., UpdateMembership) declare
authentication so the file uses explicit bearer auth instead of sending
Authorization in headers while stating none.

}

body:json {
{
"userName": "Ayush Morning Slot 1",
"phoneNumber": "9867654567",
"fieldId": "{{fieldId}}",
"perSlotPrice": 2000,
"effectiveFromDate": "2026-05-20",
"startDate": "2026-05-02",
"timeRange": [
{
"day": "tuesday",
"slots": [
{
"startTime": "06:00",
"endTime": "07:00"
}
]
}
],
"active": true
}
}
4 changes: 2 additions & 2 deletions ApiDocs/HelloFutsal/VerifyOTP/Admin OTP Verify.bru
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ auth:bearer {

body:json {
{
"requestId": "a9c46cc5-a4fa-462b-b6c0-cce177c422c7",
"otp": "817418"
"requestId": "dcec5e4b-303c-4fd2-ac10-204f6e872c04",
"otp": "160433"
Comment on lines +23 to +24
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for potential hardcoded credentials in .bru files

# Search for OTP patterns and UUIDs in body sections
rg -n -C2 '"otp":\s*"[0-9]+"' --glob '*.bru'
rg -n -C2 '"requestId":\s*"[a-f0-9-]+"' --glob '*.bru'

Repository: hellofutsal/HelloFutsal

Length of output: 1511


Replace hardcoded OTP and requestId values with environment variable placeholders across all API documentation.

Hardcoded credentials appear in at least two .bru files (Admin OTP Verify.bru and User OTP Verify.bru). While these may be test values, committing credential patterns to version control is a security risk. Use environment variables instead:

 body:json {
   {
-    "requestId": "dcec5e4b-303c-4fd2-ac10-204f6e872c04",
-    "otp": "160433"
+    "requestId": "{{requestId}}",
+    "otp": "{{otp}}"
   }
 }

Define these variables in Bruno environment configuration files rather than in API request definitions.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"requestId": "dcec5e4b-303c-4fd2-ac10-204f6e872c04",
"otp": "160433"
"requestId": "{{requestId}}",
"otp": "{{otp}}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ApiDocs/HelloFutsal/VerifyOTP/Admin` OTP Verify.bru around lines 23 - 24,
Replace the hardcoded "requestId" and "otp" JSON values in the Admin OTP
Verify.bru (and similarly in User OTP Verify.bru) with environment variable
placeholders (e.g., use Bruno variable syntax for requestId and otp) and remove
literal credentials from the request body; instead add those variables to the
Bruno environment configuration so requests reference env vars (look for the
"requestId" and "otp" fields in the .bru files and update them to use the
environment placeholders rather than fixed strings).

}
}
8 changes: 4 additions & 4 deletions ApiDocs/HelloFutsal/environments/Dev.bru
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
vars {
development: http://localhost:3000
fieldId: 3066550b-b4b3-4098-ad5c-8dd25a703fe0
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4MTNlNzNhYi1iYzE1LTQ0ZWUtODgxZC1kMTZiNzQzOWQ5NDQiLCJlbWFpbCI6bnVsbCwibW9iaWxlTnVtYmVyIjoiOTg2Nzc1NDczOCIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc3Nzg4MDc1NCwiZXhwIjoxNzc3OTY3MTU0fQ.r-zjgdL-KOFvqFl7_bM3jH7qMOSxJU-cGzqYl2VHDB4
fieldId: 1bdfdb6b-41d8-4e39-a38c-398bdca0ba39
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzMDIyMWFkOS0zZjgyLTQzZDgtYjQ1OS1kZGYyMGY2YzgzOTAiLCJlbWFpbCI6bnVsbCwibW9iaWxlTnVtYmVyIjoiOTg2Nzc1NDczOCIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc3ODMwMDMyOSwiZXhwIjoxNzc4Mzg2NzI5fQ.GHeUq7DIOmimuj6eBVFtFq6HiFXf9oSQP8RS0pW1sCU
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove committed JWT and rotate it immediately

A live token is checked into source. This is a credential exposure and should be replaced with a local placeholder plus secret rotation.

Suggested fix
-  token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
+  token: <SET_LOCALLY_DO_NOT_COMMIT>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzMDIyMWFkOS0zZjgyLTQzZDgtYjQ1OS1kZGYyMGY2YzgzOTAiLCJlbWFpbCI6bnVsbCwibW9iaWxlTnVtYmVyIjoiOTg2Nzc1NDczOCIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc3ODMwMDMyOSwiZXhwIjoxNzc4Mzg2NzI5fQ.GHeUq7DIOmimuj6eBVFtFq6HiFXf9oSQP8RS0pW1sCU
token: <SET_LOCALLY_DO_NOT_COMMIT>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ApiDocs/HelloFutsal/environments/Dev.bru` at line 4, The committed JWT value
under the token key in Dev.bru is a live credential; remove the literal token
and replace it with a placeholder (e.g., token: <YOUR_JWT_HERE>) and wire the
code that reads Dev.bru to load the real secret from an environment variable or
secret manager instead; after removing the token, rotate/invalidate the exposed
JWT immediately and update any docs or CI that referenced the file to use the
new secret-loading mechanism (reference the token entry in Dev.bru to locate the
change).

ruleBookSpecificSlotId: 2e78fc78-08e4-423e-a8ef-5ff10c59f1a7
ruleBookAllSlotId: 81e212b2-dd86-47db-bb96-8a163b615d61
ruleBookTimeSlotId: 4aebf2ac-9651-4450-8968-812cd487261e
slotId: 9ab23a63-d756-4708-a984-9d3b7f58e76c
slotId: c7b13c7d-6d73-4e24-941e-d74a8eb18d5f
bookingId: c04ce07f-f1af-4ac2-a854-2f4394b2c565
scheduleSettingId: c06a9396-8f7f-4158-94d9-59ebd9d0adfd
membershipId: 6d0203b7-fab7-4382-a26c-7402ff217245
membershipId: 528852ea-9aa7-499f-bb9d-77301c0f8eae
}
29 changes: 29 additions & 0 deletions src/booking/booking.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { JwtAuthGuard } from "../auth/guards/jwt-auth.guard";
import { AuthenticatedAccount } from "../auth/types/authenticated-account.type";
import { ConfirmBookingDto } from "./dto/confirm-booking.dto";
import { CreateBookingDto } from "./dto/create-booking.dto";
import { BulkBookSlotsDto } from "./dto/bulk-book-slots.dto";
import { BulkConfirmBookingsDto } from "./dto/bulk-confirm-bookings.dto";
import { BookingService } from "./booking.service";

@Controller("bookings")
Expand All @@ -28,6 +30,15 @@ export class BookingController {
return this.bookingService.createBooking(account, createBookingDto);
}

@UseGuards(JwtAuthGuard)
@Patch("bulk/confirm")
bulkConfirmBookings(
@CurrentAccount() account: AuthenticatedAccount,
@Body() bulkConfirmDto: BulkConfirmBookingsDto,
) {
return this.bookingService.bulkConfirmBookings(account, bulkConfirmDto);
}

@UseGuards(JwtAuthGuard)
@Patch(":slotId/confirm")
confirmBooking(
Expand All @@ -42,6 +53,24 @@ export class BookingController {
);
}

@UseGuards(JwtAuthGuard)
@Patch(":slotId/cancel")
cancelBooking(
@CurrentAccount() account: AuthenticatedAccount,
@Param("slotId", new ParseUUIDPipe()) slotId: string,
) {
return this.bookingService.cancelBooking(account, slotId);
}

@UseGuards(JwtAuthGuard)
@Post("bulk/time-range")
bulkBookSlots(
@CurrentAccount() account: AuthenticatedAccount,
@Body() bulkBookDto: BulkBookSlotsDto,
) {
return this.bookingService.bulkBookSlots(account, bulkBookDto);
}

@UseGuards(JwtAuthGuard)
@Get("field/:fieldId")
listBookingsByField(
Expand Down
2 changes: 2 additions & 0 deletions src/booking/booking.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MembershipPlanController } from "./membership-plan.controller";
import { BookingRevenueModule } from "./revenue/booking-revenue.module";
import { Field } from "../fields/entities/field.entity";
import { FieldsModule } from "../fields/fields.module";
import { MembershipPricingHistory } from "./entities/membership-pricing-history.entity";

@Module({
imports: [
Expand All @@ -21,6 +22,7 @@ import { FieldsModule } from "../fields/fields.module";
UserAccount,
MembershipPlan,
Field,
MembershipPricingHistory,
// membership payments
require("./entities/membership-payment.entity").MembershipPayment,
]),
Expand Down
Loading
Loading