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"
}