Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sergio-salcedo-dev/excel-product-manager/llms.txt

Use this file to discover all available pages before exploring further.

Preoc Product Manager follows a clean architecture pattern in which business logic, data access, and infrastructure concerns are kept strictly separated. The domain layer defines the core Product type and the ProductRepository contract; the application layer contains use cases such as SearchProducts; and the infrastructure layer provides concrete implementations like ExcelService. This page documents all public TypeScript types, interfaces, and service methods so that contributors and integrators have a single reference for the shape of data flowing through the system.

Product Interface

The Product interface is the central type in the application. Every product displayed in the catalog, imported from Excel, or returned by an AI lookup conforms to this shape.
contexts/product/domain/Product.ts
export type ProductId = string;

export interface Product {
  id: ProductId;
  code: string;
  description: string;
  unit: string;
  price: number;
  category: string;
}
id
ProductId (string)
required
Unique identifier for the product. Products created manually use the format prod-{timestamp}, while products imported via the AI search feature use preoc-{timestamp}-{index} to distinguish their origin.
code
string
required
Short reference code used to identify the product in catalogs and exports (e.g., MT-001). By convention, the prefix indicates the category:
PrefixCategory
MTMateriales
MOMano de Obra
MQMaquinaria
INInstalaciones
ACAcabados / Pinturas
description
string
required
Full technical description of the product as it appears in construction price databases and project documentation.
unit
string
required
Unit of measurement expressed in standard Spanish abbreviations:
ValueMeaning
udUnidad (unit)
m3Cubic meter
m2Square meter
kgKilogram
hHour
sacSack
palPallet
rolRoll
díaDay
price
number
required
Unit price in euros as a floating-point number. This value is used directly in cost calculations and is exported as-is to Excel.
category
string
required
Category label used to group and filter products in the catalog. Standard categories used throughout the application are: Materiales, Mano de Obra, Maquinaria, Instalaciones, Pinturas, and Acabados.

ProductRepository Interface

The ProductRepository interface is the persistence contract that the domain layer depends on. All data access goes through this interface, allowing the underlying storage mechanism (in-memory, localStorage, a remote API, etc.) to be swapped without touching business logic.
contexts/product/domain/Product.ts
export interface ProductRepository {
  search(query: string, category?: string, page?: number, limit?: number): Promise<{ products: Product[], total: number }>;
  save(product: Product): Promise<void>;
  update(product: Product): Promise<void>;
  delete(id: ProductId): Promise<void>;
  saveAll(products: Product[]): Promise<void>;
}
MethodDescription
searchReturns a paginated list of products matching the query string and optional category filter, along with the total count for pagination controls.
savePersists a single new product to the repository.
updateOverwrites an existing product record identified by its id.
deleteRemoves the product with the given ProductId from the repository.
saveAllBatch-inserts an array of products — used after parsing an Excel file or completing an AI import.

SearchProducts Use Case

SearchProducts is the application-layer use case responsible for querying the catalog. It wraps the repository’s search method and enforces sensible pagination defaults, keeping controllers and UI components free of that logic.
contexts/product/application/SearchProducts.ts
export class SearchProducts {
  constructor(private readonly repository: ProductRepository) {}

  async execute(query: string, category?: string, page: number = 1, limit: number = 10) {
    return this.repository.search(query, category, page, limit);
  }
}

execute() Parameters

query
string
required
The search string matched against a product’s description and code fields. Pass an empty string to retrieve all products in the current category or page.
category
string
Restricts results to a single category label (e.g., "Materiales" or "Mano de Obra"). When omitted, results span all categories.
page
number
default:"1"
The 1-based page number to retrieve. Used together with limit to calculate the slice of results returned by the repository.
limit
number
default:"10"
The maximum number of products to return in a single page. The repository also returns the total count so the UI can compute the number of available pages.

ExcelService

ExcelService is a static infrastructure-layer class that handles all Excel I/O using the xlsx library. Its two methods cover the full import/export lifecycle without requiring instantiation.
contexts/product/infrastructure/ExcelService.ts
export class ExcelService {
  static parseExcel(file: File): Promise<Product[]>;
  static exportToExcel(products: Product[], fileName: string = 'productos.xlsx'): void;
}

parseExcel(file: File): Promise<Product[]>

Reads a .xlsx or .xls file using the browser’s FileReader API, decodes it with XLSX.read, and maps every row in the first sheet to a Product object. Column header matching is tolerant of both English and Spanish names so that files exported from other tools can be imported without manual renaming:
FieldEnglish headerSpanish header
idid, ID
codecodeCódigo, Codigo
descriptiondescriptionDescripción, Descripcion
unitunitUnidad
pricepricePrecio
categorycategoryCategoría, Categoria
Rows with missing id values receive an auto-generated identifier in the format prod-{Date.now()}-{index}. Missing unit values default to ud, and missing category values default to General.

exportToExcel(products: Product[], fileName: string): void

Serializes an array of Product objects into a single-sheet Excel workbook and triggers a browser file download. Column headers in the exported file are always Spanish (Código, Descripción, Unidad, Precio, Categoría) for consistency with local construction industry conventions. The sheet is named Productos. The fileName parameter defaults to productos.xlsx when not provided.

CSS Theme Variables

The application’s visual theme is defined as a set of CSS custom properties in app/globals.css using Tailwind CSS v4’s @theme directive. All color tokens are declared here, making it straightforward to rebrand the application by overriding a single file.
app/globals.css
@import "tailwindcss";

@theme {
  --font-sans: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  --color-primary: #004a99;       /* Main brand blue */
  --color-accent: #f07d00;        /* Amber accent (AI search, warnings) */
  --color-app-bg: #f4f7f9;        /* App background */
  --color-surface: #ffffff;       /* Card/panel surface */
  --color-text-main: #1a1c1e;     /* Primary text */
  --color-text-muted: #64748b;    /* Secondary text */
  --color-border-subtle: #e2e8f0; /* Borders */
  --color-success: #10b981;       /* Success green */
}
All tokens — including the two font stacks (--font-sans, --font-mono) and all color variables — are defined inside Tailwind CSS v4’s @theme directive in app/globals.css, which registers them as design tokens available to every Tailwind utility class throughout the project. To rebrand the application, replace the hex values or font stacks in that file — every component that uses a token such as text-primary, bg-accent, or font-sans will update automatically without any further changes.

Build docs developers (and LLMs) love