Skip to main content

Product Upload Workflow

This guide explains how to prepare and upload a product to the API step by step. It includes checking for existing materials and fittings, uploading files, and creating the product.

Step 1: Authorization

Use the /admin/login endpoint to authenticate and retrieve an access token.

1. Login

const loginResponse = await post(host, "/admin/login", {
email: "admin@example.com",
password: "password123",
});

const accessToken = loginResponse.accessToken;

Add the access token to the Authorization header for all subsequent requests

const headers = {
Authorization: `Bearer ${accessToken}`,
};

Step 2: Edge Bands

1. Check and Upload Edge Band (if needed)

Get Edge Band List

const edgeBands = await get(host, "/adminapi/edge_band", { headers });

Check if Edge Band Exists If the edge band does not exist, upload it.

if (!edgeBands.some((eb) => eb.code === pcv.code)) {
await post(host, "/adminapi/edge_band", pcv, { headers });
}

Step 3: Materials

1. Check and Upload Materials (if needed)

Materials are required for the product. Check if the materials exist in the database, and if not, upload them.

Search for materials using their SIFRA codes.

const materials = await get(
host,
`/adminapi/materials/materialsBySIFRA?SIFRAs=${m.SIFRA}`,
{ headers }
);

2. Upload Material Image

If the material does not exist, upload its image and create the material.

  • Send a POST request to /adminapi/materials/upload_image.
  • Set the request headers
    • Content-Type: multipart/form-data
    • Authorization: Bearer ${accessToken}
  • Add the image file to the request body under the field name image.

Example Request

const formData = new FormData();
formData.append("image", fileInput.files[0]); // 'image' is the field name

const response = await fetch(`${host}/adminapi/materials/upload_image`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: formData,
});

const result = await response.json();

Example Response

  • path - This is the relative path to the uploaded file. You should save this path in your database when creating or updating a material.
{
"message": "Image uploaded successfully!",
"file": {
"fieldname": "image",
"originalname": "chair.jpg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "uploads/materials/images",
"filename": "image-chair-123456789.jpg",
"path": "uploads/materials/images/image-chair-123456789.jpg",
"size": 10240
}
}

Integrating with Material Creation

When creating a material, you should upload the image first and then use the returned path in the material creation request:

// Step 1: Upload the image
const uploadResponse = await uploadMaterialImage(file);

// Step 2: Create the material
const materialData = {
name: "Wood",
price: 50,
PICFILE: uploadResponse.file.path, // Save the relative path
};

const materialResponse = await post(
host,
"/adminapi/materials",
materialData,
{ headers }
);

Error Handling

  • No File Uploaded:
    • If no file is uploaded, the API will return a 400 Bad Request with the message "No file uploaded."
  • Invalid File Type:
    • If the file type is not allowed, Multer will throw an error with the message "Invalid file type". Allowed file types are: ".jpg", ".jpeg", ".png", ".svg", ".bmp".

Step 4: Fittings

1. Check and Upload Fittings (if needed)

Get Fitting by kod (kod should be unique):

Search for a specific fitting using its kod field.

const fitting = await get(
host,
`/adminapi/fittings/getByKod/${kod}`,
{ headers }
);

2. Upload Fitting Files (if needed):

If the fitting does not exist, upload its 3D model (if available) and image, then create the fitting.

  • Send a POST request to /adminapi/fittings/upload_image.
  • Set the request headers:
    • Content-Type: multipart/form-data
    • Authorization: Bearer ${accessToken}
  • Add the files to the request body under the field name image.

Example Request

const formData = new FormData();
formData.append("image", fileInput.files[0]); // 'image' is the field name

const response = await fetch(`${host}/adminapi/fittings/upload_image`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: formData,
});

const result = await response.json();

Example Response

  • path - This is the relative path to the uploaded file. You should save this path in your database when creating or updating a fitting.
{
"message": "Image uploaded successfully!",
"file": {
"fieldname": "image",
"originalname": "screw.jpg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "uploads/fittings/images",
"filename": "image-screw-123456789.jpg",
"path": "uploads/fittings/images/image-screw-123456789.jpg",
"size": 10240
}
}

3. Integrating with Fitting Creation

When creating a fitting, you should upload the files first and then use the returned paths in the fitting creation request:

// Step 1: Upload the files
const uploadResponse = await uploadFittingFile(files);

// Step 2: Create the fitting
const fittingData = {
name: "Screw",
price: "5",
images: uploadResponse.files.map((file) => file.path), // Save the relative paths
model: uploadResponse.files.find((file) => file.originalname.endsWith(".obj"))?.path, // Save the 3D model path if available, extension can be different like .dae or .obj
};

const fittingResponse = await post(
host,
"/adminapi/fittings",
fittingData,
{ headers }
);

4. Error Handling

  • No File Uploaded:
    • If no file is uploaded, the API will return a 400 Bad Request with the message "No file uploaded."
  • Invalid File Type:
    • If the file type is not allowed, Multer will throw an error with the message "Invalid file type". Allowed file types are: ".jpg", ".jpeg", ".png", ".svg", ".bmp", ".e3d", ".obj", ".dae", ".tga", ".wrl", ".fbx",.

Step 5: Product

A product is created in two sub-steps:

  1. Upload the product file.
  2. Create the product using only the required fields.

1. Upload Product File

Before creating a product, you must upload the product’s file (for example, a 3D model or an image). The API expects the file to be sent as multipart/form-data with the field name image.

Example Request

  • Endpoint: POST /adminapi/products/upload_image
  • Headers:
    • Content-Type: multipart/form-data
    • Authorization: Bearer ${accessToken}
const formData = new FormData();
formData.append("image", fileInput.files[0]); // 'image' is the field name

const uploadResponse = await fetch(`${host}/adminapi/products/upload_image`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: formData,
});

const uploadResult = await uploadResponse.json();

Example Response

{
"message": "Files uploaded successfully!",
"files": [
{
"fieldname": "image",
"originalname": "product-model.e3d",
"encoding": "7bit",
"mimetype": "application/octet-stream",
"destination": "uploads/products",
"filename": "image-product-model-123456789.jpg",
"path": "uploads/products/image-product-model-123456789.jpg",
"size": 10240
}
]
}

Note: Save the returned path (e.g., "uploads/products/image-product-model-123456789.e3d") as you will need it when creating the product.

2. Prepare and upload the product data.

Product Model

After uploading the file, create the product using the returned file path along with the required fields. In this API, only the following fields are required:

  • status (string): Indicates the product’s current status (e.g., "1").
  • name (string): The product’s name.
  • modelPath (string): Use the file path returned from the upload step.
  • date (string): A date string representing when the product was created or is effective.
  • materialy (object): An object containing details about the product’s materials.
  • main (object): An object holding the main product details (this could include dimensions, colors, or other key attributes).

Example Request

  • Endpoint: POST /adminapi/products
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer ${accessToken}
const productData = {
status: "1", // Required
name: "Modern Chair", // Required
modelPath: uploadResult.files[0].path, // Required: use the path from the file upload response
date: "2025-02-17", // Required
materialy: {}, // Required
main: {} // Required
};

const productResponse = await post(
host,
"/adminapi/products",
productData,
{ headers }
);

Example Response

{
"_id": "product_id",
"status": "active",
"name": "Modern Chair",
"modelPath": "uploads/products/image-product-model-123456789.jpg",
"date": "2025-02-17",
"materialy": {},
"main": {},
"isPublished": false,
"createdAt": "2025-02-17T00:00:00.000Z",
"updatedAt": "2025-02-17T00:00:00.000Z"
}