Skip to content

Commit

Permalink
Create product function
Browse files Browse the repository at this point in the history
The frontend is not hooked into this yet.
  • Loading branch information
FyreByrd committed Sep 17, 2024
1 parent d41ad08 commit 683dc47
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
154 changes: 154 additions & 0 deletions source/SIL.AppBuilder.Portal/common/databaseProxy/Products.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,70 @@
import type { Prisma } from '@prisma/client';
import prisma from '../prisma.js';
import { RequirePrimitive } from './utility.js';

export async function create(
productData: RequirePrimitive<Prisma.ProductsUncheckedCreateInput>
): Promise<boolean | string> {
if (
!validateProductBase(
productData.ProjectId,
productData.ProductDefinitionId,
productData.StoreId,
productData.StoreLanguageId
)
)
return false;

// No additional verification steps

try {
const res = await prisma.products.create({
data: productData
});
return res.Id;
} catch (e) {
return false;
}
}

export async function update(
id: string,
productData: RequirePrimitive<Prisma.ProductsUncheckedUpdateInput>
): Promise<boolean> {
// There are cases where a db lookup is not necessary to verify that it will
// be a legal relation after the update, such as if none of the relevant
// columns are changed, but for simplicity we just lookup once anyway
const existing = await prisma.products.findUnique({
where: {
Id: id
}
});
const projectId = productData.ProjectId ?? existing!.ProjectId;
const productDefinitionId = productData.ProductDefinitionId ?? existing!.ProductDefinitionId;
const storeId = productData.StoreId ?? existing!.StoreId;
const storeLanguageId = productData.StoreLanguageId ?? existing!.StoreLanguageId;
if (!validateProductBase(
projectId,
productDefinitionId,
storeId,
storeLanguageId
)) return false;

// No additional verification steps

try {
await prisma.products.update({
where: {
Id: id
},
data: productData
});
// later: Are there any other updates that need to be done?
} catch (e) {
return false;
}
return true;
}

function deleteProduct(productId: string) {
// Delete all userTasks for this product, and delete the product
Expand All @@ -16,3 +82,91 @@ function deleteProduct(productId: string) {
]);
}
export { deleteProduct as delete };

/** A product is valid if:
* 1. The store's type matches the Workflow's store type
* 2. The project has a WorkflowProjectUrl
* 3. The store is allowed by the organization
* 4. The language is allowed by the store
* 5. The product type is allowed by the organization
*/
async function validateProductBase(
projectId: number,
productDefinitionId: number,
storeId: number,
storeLanguageId: number
) {
const productDefinition = await prisma.productDefinitions.findUnique({
where: {
Id: productDefinitionId
},
select: {
Id: true,
// Store type must match Workflow store type
Workflow: {
select: {
StoreTypeId: true
}
}
}
});
const project = await prisma.projects.findUnique({
where: {
Id: projectId,
// Project must have a WorkflowProjectUrl
WorkflowProjectUrl: {
not: null
}
},
select: {
Organization: {
select: {
// Store must be allowed by Organization
OrganizationStores: {
where: {
StoreId: storeId
},
select: {
Store: {
select: {
StoreType: {
select: {
// Store type must match Workflow store type
Id: true,
// StoreLanguage must be allowed by Store
StoreLanguages: {
where: {
Id: storeLanguageId
}
}
}
}
}
}
}
},
// Product type must be allowed by Organization
OrganizationProductDefinitions: {
where: {
ProductDefinitionId: productDefinition?.Id
}
}
}
}
}
});

// 3. The store is allowed by the organization
return (
project?.Organization.OrganizationStores.length > 0 &&
// 1. The store's type matches the Workflow's store type
productDefinition?.Workflow.StoreTypeId ===
project.Organization.OrganizationStores[0].Store.StoreType.Id &&
// 2. The project has a WorkflowProjectUrl
// handled by query
// 4. The language is allowed by the store
project.Organization.OrganizationStores[0].Store.StoreType.StoreLanguages.length > 0 &&
// 5. The product type is allowed by the organization
project.Organization.OrganizationProductDefinitions.length > 0
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { valibot } from 'sveltekit-superforms/adapters';
import * as v from 'valibot';
import type { Actions, PageServerLoad } from './$types';
import { verifyCanView } from './common';
import { NoAdminS3 } from 'sil.appbuilder.portal.common/workflow';
import { createActor } from 'xstate';

const deleteReviewerSchema = v.object({
id: idSchema
Expand All @@ -22,6 +24,14 @@ const addReviewerSchema = v.object({
email: v.pipe(v.string(), v.email()),
language: v.string()
});
const addProductSchema = v.object({
productDefinitionId: idSchema,
storeId: idSchema,
storeLanguageId: idSchema,
workflowJobId: idSchema,
workflowBuildId: idSchema,
workflowPublishId: idSchema
});

// Are we sending too much data?
export const load = (async ({ locals, params }) => {
Expand Down Expand Up @@ -141,6 +151,29 @@ export const actions = {
async addProduct(event) {
if (!verifyCanView((await event.locals.auth())!, parseInt(event.params.id))) return fail(403);
// TODO: api and bulltask
const form = await superValidate(event.request, valibot(addProductSchema));
if (!form.valid) return fail(400, { form, ok: false });
// Appears that CanUpdate is not used TODO
const res = await DatabaseWrites.products.create({
ProjectId: parseInt(event.params.id),
ProductDefinitionId: form.data.productDefinitionId,
StoreId: form.data.storeId,
StoreLanguageId: form.data.storeLanguageId,
WorkflowJobId: form.data.workflowJobId,
WorkflowBuildId: form.data.workflowBuildId,
WorkflowPublishId: form.data.workflowPublishId
});

if (typeof res === 'string') {
const tmpActor = createActor(NoAdminS3, {
input: {
productId: res
}
});
tmpActor.start();
}

return { form, ok: true };
},
async addAuthor(event) {
if (!verifyCanView((await event.locals.auth())!, parseInt(event.params.id))) return fail(403);
Expand Down

0 comments on commit 683dc47

Please sign in to comment.