feat(orders): «عدم سفارش» blocks app orders; import starts everyone allowed (MON-05)

Legacy stored customers.sts but no code read it, so the switch never
stopped an order, and 313 active customers carry it, mostly as the
sign-up default. Owner option 2: enforce it from now on, for orders
placed from the app only (an operator can still order for the
customer), and import every customer as allowed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-10-08 11:16:29 +03:30
co-authored by Claude Opus 5.5
parent 1c850216e9
commit 4b7b2473fc
5 changed files with 58 additions and 5 deletions
+15 -2
View File
@@ -1,4 +1,4 @@
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { OrderChannel, OrderStatus, Prisma } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';
import { CatalogService } from '../catalog/catalog.service';
@@ -38,10 +38,23 @@ export class OrdersService {
* from the request body. The body's `customerId` is ignored; see the note
* on CreateOrderDto.
*/
async createOrder(dto: CreateOrderDto, customerId: string) {
async createOrder(
dto: CreateOrderDto,
customerId: string,
opts: { placedBy: 'customer' | 'operator' } = { placedBy: 'operator' },
) {
const customer = await this.prisma.customer.findUnique({ where: { id: customerId } });
if (!customer) throw new NotFoundException(`Customer ${customerId} not found`);
// MON-05 (owner ruling 2026-10-08): «معلق کردن سفارش» stops the customer
// ordering from the app. Legacy stored the switch (customers.sts) but no
// code read it, so it stopped nothing. An operator placing an order FOR
// the customer from the panel is not blocked — that is how a suspended
// account is still served.
if (opts.placedBy === 'customer' && !customer.canPlaceOrders) {
throw new ForbiddenException('ثبت سفارش برای حساب شما فعلاً غیرفعال است. لطفاً با پشتیبانی تماس بگیرید.');
}
// The apps still send customerId in the body (removed from them in Phase 2).
// It is not used for anything; a mismatch means either a stale client or an
// attempt to order on someone else's account, and both are worth seeing.