mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
chore: Новый черновик DRAFT, удалить старые docs-v
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Headers,
|
||||
Param,
|
||||
Patch,
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from "@nestjs/common";
|
||||
import {
|
||||
ApiCookieAuth,
|
||||
ApiCreatedResponse,
|
||||
ApiNotModifiedResponse,
|
||||
ApiOkResponse,
|
||||
ApiOperation,
|
||||
ApiSecurity,
|
||||
ApiTags,
|
||||
} from "@nestjs/swagger";
|
||||
import type { Response } from "express";
|
||||
import {
|
||||
ApiDemoScenarioHeader,
|
||||
ApiOrganizationHeader,
|
||||
ApiStandardErrors,
|
||||
} from "../../../common/api.decorators";
|
||||
import {
|
||||
ComplexCookieGuard,
|
||||
ComplexCsrfGuard,
|
||||
type ComplexDemoRequest,
|
||||
ComplexOrganizationGuard,
|
||||
ComplexRoles,
|
||||
ComplexRolesGuard,
|
||||
} from "../complex.auth";
|
||||
import { ComplexStore } from "../complex.store";
|
||||
import {
|
||||
AdjustInventoryDto,
|
||||
BrandsResponseDto,
|
||||
ComplexCategoriesResponseDto,
|
||||
ComplexProductResponseDto,
|
||||
ComplexProductsResponseDto,
|
||||
CreateComplexProductDto,
|
||||
CursorProductQueryDto,
|
||||
InventoryItemResponseDto,
|
||||
InventoryResponseDto,
|
||||
UpdateComplexProductDto,
|
||||
WarehousesResponseDto,
|
||||
} from "../dto/catalog.dto";
|
||||
import { ComplexRole } from "../dto/identity.dto";
|
||||
|
||||
@ApiTags("Products")
|
||||
@ApiCookieAuth("cookieSession")
|
||||
@ApiOrganizationHeader()
|
||||
@ApiDemoScenarioHeader()
|
||||
@UseGuards(ComplexCookieGuard, ComplexOrganizationGuard)
|
||||
@Controller("products")
|
||||
export class ComplexProductsController {
|
||||
constructor(private readonly store: ComplexStore) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: "List tenant products using cursor pagination" })
|
||||
@ApiOkResponse({ type: ComplexProductsResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
list(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Query() query: CursorProductQueryDto,
|
||||
): ComplexProductsResponseDto {
|
||||
return this.store.listProducts(request.organizationId!, query);
|
||||
}
|
||||
|
||||
@Get(":id")
|
||||
@ApiOperation({
|
||||
summary: "Get a rich product with variants and ETag support",
|
||||
})
|
||||
@ApiOkResponse({ type: ComplexProductResponseDto })
|
||||
@ApiNotModifiedResponse()
|
||||
@ApiStandardErrors({ auth: true, notFound: true })
|
||||
get(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Param("id") id: string,
|
||||
@Headers("if-none-match") ifNoneMatch: string | undefined,
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
): ComplexProductResponseDto | undefined {
|
||||
const product = this.store.getProduct(request.organizationId!, id);
|
||||
const etag = `W/\"${product.id}-v${product.version}\"`;
|
||||
response.setHeader("ETag", etag);
|
||||
response.setHeader("Cache-Control", "private, max-age=0, must-revalidate");
|
||||
if (etag === ifNoneMatch) {
|
||||
response.status(304);
|
||||
return undefined;
|
||||
}
|
||||
return { data: product };
|
||||
}
|
||||
|
||||
@Post()
|
||||
@UseGuards(ComplexRolesGuard, ComplexCsrfGuard)
|
||||
@ComplexRoles(ComplexRole.Admin, ComplexRole.Manager)
|
||||
@ApiSecurity("csrf")
|
||||
@ApiOperation({ summary: "Create a tenant product with variants" })
|
||||
@ApiCreatedResponse({ type: ComplexProductResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
create(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Body() dto: CreateComplexProductDto,
|
||||
): ComplexProductResponseDto {
|
||||
return {
|
||||
data: this.store.createProduct(
|
||||
request.organizationId!,
|
||||
request.user!.id,
|
||||
dto,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@Patch(":id")
|
||||
@UseGuards(ComplexRolesGuard, ComplexCsrfGuard)
|
||||
@ComplexRoles(ComplexRole.Admin, ComplexRole.Manager)
|
||||
@ApiSecurity("csrf")
|
||||
@ApiOperation({ summary: "Update a product using optimistic locking" })
|
||||
@ApiOkResponse({ type: ComplexProductResponseDto })
|
||||
@ApiStandardErrors({ auth: true, notFound: true, conflict: true })
|
||||
update(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Param("id") id: string,
|
||||
@Body() dto: UpdateComplexProductDto,
|
||||
): ComplexProductResponseDto {
|
||||
return {
|
||||
data: this.store.updateProduct(
|
||||
request.organizationId!,
|
||||
request.user!.id,
|
||||
id,
|
||||
dto,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ApiTags("Catalog")
|
||||
@ApiCookieAuth("cookieSession")
|
||||
@ApiOrganizationHeader()
|
||||
@ApiDemoScenarioHeader()
|
||||
@UseGuards(ComplexCookieGuard, ComplexOrganizationGuard)
|
||||
@Controller()
|
||||
export class ComplexCatalogController {
|
||||
constructor(private readonly store: ComplexStore) {}
|
||||
|
||||
@Get("categories")
|
||||
@ApiOperation({ summary: "List a recursive category tree" })
|
||||
@ApiOkResponse({ type: ComplexCategoriesResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
categories(@Req() request: ComplexDemoRequest): ComplexCategoriesResponseDto {
|
||||
return { data: this.store.listCategories(request.organizationId!) };
|
||||
}
|
||||
|
||||
@Get("brands")
|
||||
@ApiOperation({ summary: "List product brands" })
|
||||
@ApiOkResponse({ type: BrandsResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
brands(@Req() request: ComplexDemoRequest): BrandsResponseDto {
|
||||
return { data: this.store.listBrands(request.organizationId!) };
|
||||
}
|
||||
}
|
||||
|
||||
@ApiTags("Inventory")
|
||||
@ApiCookieAuth("cookieSession")
|
||||
@ApiOrganizationHeader()
|
||||
@ApiDemoScenarioHeader()
|
||||
@UseGuards(ComplexCookieGuard, ComplexOrganizationGuard)
|
||||
@Controller()
|
||||
export class ComplexInventoryController {
|
||||
constructor(private readonly store: ComplexStore) {}
|
||||
|
||||
@Get("warehouses")
|
||||
@ApiOperation({ summary: "List tenant warehouses" })
|
||||
@ApiOkResponse({ type: WarehousesResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
warehouses(@Req() request: ComplexDemoRequest): WarehousesResponseDto {
|
||||
return { data: this.store.listWarehouses(request.organizationId!) };
|
||||
}
|
||||
|
||||
@Get("inventory")
|
||||
@ApiOperation({ summary: "List inventory with optional product filter" })
|
||||
@ApiOkResponse({ type: InventoryResponseDto })
|
||||
@ApiStandardErrors({ auth: true })
|
||||
inventory(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Query("productId") productId?: string,
|
||||
): InventoryResponseDto {
|
||||
return {
|
||||
data: this.store.listInventory(request.organizationId!, productId),
|
||||
};
|
||||
}
|
||||
|
||||
@Post("inventory/:id/adjust")
|
||||
@UseGuards(ComplexRolesGuard, ComplexCsrfGuard)
|
||||
@ComplexRoles(ComplexRole.Admin, ComplexRole.Manager)
|
||||
@ApiSecurity("csrf")
|
||||
@ApiOperation({ summary: "Adjust stock using optimistic locking" })
|
||||
@ApiOkResponse({ type: InventoryItemResponseDto })
|
||||
@ApiStandardErrors({ auth: true, notFound: true, conflict: true })
|
||||
adjust(
|
||||
@Req() request: ComplexDemoRequest,
|
||||
@Param("id") id: string,
|
||||
@Body() dto: AdjustInventoryDto,
|
||||
): InventoryItemResponseDto {
|
||||
return {
|
||||
data: this.store.adjustInventory(
|
||||
request.organizationId!,
|
||||
request.user!.id,
|
||||
id,
|
||||
dto,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user