fix(subscriptions): atomic UsageRecord metering to prevent quota bypass

- Add @@unique([subscriptionId, metric, periodStart, periodEnd]) constraint
  to UsageRecord model with corresponding migration
- Replace racy findFirst+update/create pattern with Prisma upsert using
  INSERT ON CONFLICT DO UPDATE SET count = count + delta
- Fix CheckQuotaHandler to use period-scoped findUnique instead of
  unscoped findFirst, preventing stale cross-period reads
- Update tests to reflect atomic upsert pattern

Closes GOO-4

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-22 23:22:59 +07:00
parent 65bd641e1f
commit ee6d6d4c17
16 changed files with 180 additions and 79 deletions

View File

@@ -19,17 +19,13 @@ import { formatPrice, formatPricePerM2 } from '@/lib/currency';
import { useListingsSearch } from '@/lib/hooks/use-listings';
import type { ListingDetail, PropertyType, TransactionType } from '@/lib/listings-api';
import { PROPERTY_TYPES, TRANSACTION_TYPES } from '@/lib/validations/listings';
import { HCM_DISTRICTS } from '@/lib/vietnam-geo';
// ---------------------------------------------------------------------------
// Hằng số
// ---------------------------------------------------------------------------
const DISTRICTS = [
'Quận 1', 'Quận 2', 'Quận 3', 'Quận 4', 'Quận 5', 'Quận 6', 'Quận 7',
'Quận 8', 'Quận 9', 'Quận 10', 'Quận 11', 'Quận 12',
'Bình Thạnh', 'Gò Vấp', 'Phú Nhuận', 'Tân Bình', 'Tân Phú', 'Thủ Đức',
'Bình Chánh', 'Hóc Môn', 'Củ Chi', 'Nhà Bè', 'Cần Giờ',
];
const DISTRICTS = HCM_DISTRICTS;
const PRICE_RANGES = [
{ label: 'Dưới 1 tỷ', min: '', max: '1000000000' },