feat(products): include ownerId in product creation and enforce its requirement
This commit is contained in:
@@ -128,8 +128,8 @@ export class ProductsController {
|
||||
|
||||
@Roles('admin')
|
||||
@Post()
|
||||
create(@Body() body: CreateProductDto) {
|
||||
return this.productsService.create(body);
|
||||
create(@Body() body: CreateProductDto, @Request() req: { user: { id: number } }) {
|
||||
return this.productsService.create(body, req.user.id);
|
||||
}
|
||||
|
||||
// Tillgänglig för alla inloggade användare — req.user.id injiceras av JWT-guard
|
||||
|
||||
@@ -116,7 +116,7 @@ export class ProductsService {
|
||||
return product;
|
||||
}
|
||||
|
||||
async create(data: CreateProductDto) {
|
||||
async create(data: CreateProductDto, ownerId?: number) {
|
||||
const name = data.name.trim();
|
||||
const normalizedName = normalizeName(name);
|
||||
|
||||
@@ -140,8 +140,13 @@ export class ProductsService {
|
||||
return existing;
|
||||
}
|
||||
|
||||
if (!ownerId) {
|
||||
throw new Error('ownerId är obligatorisk för att skapa en produkt');
|
||||
}
|
||||
|
||||
return this.prisma.product.create({
|
||||
data: {
|
||||
ownerId,
|
||||
name,
|
||||
normalizedName,
|
||||
canonicalName: name,
|
||||
|
||||
@@ -120,11 +120,11 @@ export class ReceiptImportService {
|
||||
const [aliases, products] = await Promise.all([
|
||||
this.prisma.receiptAlias.findMany({
|
||||
where: aliasFilter,
|
||||
select: { receiptName: true, productId: true, product: { select: { id: true, name: true, canonicalName: true, categoryId: true, categoryRef: { select: { id: true, name: true, path: true } } } } },
|
||||
select: { receiptName: true, productId: true, product: { select: { id: true, name: true, canonicalName: true, categoryId: true, categoryRef: { select: { id: true, name: true } } } } },
|
||||
}),
|
||||
this.prisma.product.findMany({
|
||||
where: productFilter,
|
||||
select: { id: true, name: true, canonicalName: true, categoryId: true, categoryRef: { select: { id: true, name: true, path: true } } },
|
||||
select: { id: true, name: true, canonicalName: true, categoryId: true, categoryRef: { select: { id: true, name: true } } },
|
||||
}),
|
||||
]);
|
||||
|
||||
@@ -140,7 +140,7 @@ export class ReceiptImportService {
|
||||
...item,
|
||||
matchedProductId: alias.product.id,
|
||||
matchedProductName: alias.product.canonicalName ?? alias.product.name,
|
||||
...(cat ? { categorySuggestion: { categoryId: cat.id, categoryName: cat.name, path: cat.path, confidence: 'high' as const, usedFallback: false } } : {}),
|
||||
...(cat ? { categorySuggestion: { categoryId: cat.id, categoryName: cat.name, path: cat.name, confidence: 'high' as const, usedFallback: false } } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -154,15 +154,15 @@ export class ReceiptImportService {
|
||||
...item,
|
||||
suggestedProductId: suggestion.id,
|
||||
suggestedProductName: suggestion.canonicalName ?? suggestion.name,
|
||||
...(cat ? { categorySuggestion: { categoryId: cat.id, categoryName: cat.name, path: cat.path, confidence: 'medium' as const, usedFallback: false } } : {}),
|
||||
...(cat ? { categorySuggestion: { categoryId: cat.id, categoryName: cat.name, path: cat.name, confidence: 'medium' as const, usedFallback: false } } : {}),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private findWordMatch(
|
||||
raw: string,
|
||||
products: { id: number; name: string; canonicalName: string | null; categoryId: number | null; categoryRef: { id: number; name: string; path: string } | null }[],
|
||||
): { id: number; name: string; canonicalName: string | null; categoryId: number | null; categoryRef: { id: number; name: string; path: string } | null } | undefined {
|
||||
products: { id: number; name: string; canonicalName: string | null; categoryId: number | null; categoryRef: { id: number; name: string } | null }[],
|
||||
): { id: number; name: string; canonicalName: string | null; categoryId: number | null; categoryRef: { id: number; name: string } | null } | undefined {
|
||||
// Dela upp kvittonamnet i ord (min 3 tecken)
|
||||
const rawWords = tokenize(raw);
|
||||
if (rawWords.length === 0) return undefined;
|
||||
@@ -173,7 +173,7 @@ export class ReceiptImportService {
|
||||
const rawWordSetNorm = new Set(rawWordsNorm);
|
||||
|
||||
let best:
|
||||
| { product: { id: number; name: string; canonicalName: string | null }; score: number }
|
||||
| { product: { id: number; name: string; canonicalName: string | null; categoryId: number | null; categoryRef: { id: number; name: string } | null }; score: number }
|
||||
| undefined;
|
||||
|
||||
for (const product of products) {
|
||||
|
||||
Reference in New Issue
Block a user