Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ProyectoFerretek/FerreMarket/llms.txt
Use this file to discover all available pages before exploring further.
All data flowing through FerreMarket is strictly typed via TypeScript interfaces defined in src/types/index.ts. This page is the canonical reference for every entity shape used across pages, components, and Supabase data-access functions — if a field exists in the database, it is represented here.
Producto
Represents a single hardware product in the FerreMarket catalog. Every product has a unique SKU, belongs to one category string, and carries a boolean flag that marks it as featured.
| Field | Type | Required | Description |
|---|
id | string | ✅ | Unique product identifier (database primary key) |
sku | string | ✅ | Stock-keeping unit code; used as the Cloudflare R2 image filename |
nombre | string | ✅ | Display name of the product |
descripcion | string | ✅ | Full text description |
precio | number | ✅ | Unit price (CLP) |
categoria | string | ✅ | Category identifier string (references a Categoria.id) |
stock | number | ✅ | Current units available in inventory |
imagen | string | ✅ | URL to the product image (hosted on Cloudflare CDN) |
destacado | boolean | ✅ | Whether the product is marked as featured |
export interface Producto {
id: string;
sku: string;
nombre: string;
descripcion: string;
precio: number;
categoria: string;
stock: number;
imagen: string;
destacado: boolean;
}
UpdateProducto
A trimmed payload used when updating an existing product. It omits id, sku, and imagen because those fields are not editable through the standard update flow — the image is managed separately via the Cloudflare Workers upload pipeline.
| Field | Type | Required | Description |
|---|
nombre | string | ✅ | Updated display name |
descripcion | string | ✅ | Updated description |
precio | number | ✅ | Updated unit price (CLP) |
categoria | string | ✅ | Updated category identifier |
stock | number | ✅ | Updated stock count |
destacado | boolean | ✅ | Updated featured flag |
export interface UpdateProducto {
nombre: string;
descripcion: string;
precio: number;
categoria: string;
stock: number;
destacado: boolean;
}
Cliente
Represents a customer record. FerreMarket supports two customer subtypes — individual (natural person, identified by RUN) and empresa (business entity, identified by RUT) — within a single interface. Fields relevant only to one subtype are optional; tipoCliente discriminates between them.
| Field | Type | Required | Description |
|---|
id | string | ❌ | Database primary key (absent before first save) |
estado | 'activo' | 'inactivo' | ✅ | Whether the customer account is active |
fechaCreacion | string | ❌ | ISO 8601 creation timestamp |
ultimaModificacion | string | ❌ | ISO 8601 last-modified timestamp |
notas | string | ❌ | Free-text internal notes |
compras | number | ❌ | Total number of purchases made |
totalCompras | number | ❌ | Cumulative spend across all purchases (CLP) |
ultimaCompra | string | ❌ | ISO 8601 date of the most recent purchase |
tipoCliente | string | ✅ | Subtype discriminator: 'individual' or 'empresa' |
nombre | string | ❌ | First name (individual) or commercial name (empresa) |
apellidos | string | ❌ | Last name(s) — individual clients only |
email | string | ❌ | Contact email address |
telefono | string | ❌ | Contact phone number |
direccion | string | ❌ | Postal address |
run | string | ❌ | Chilean national ID number — individual clients only |
rut | string | ❌ | Chilean tax ID number — business clients only |
giro | string | ❌ | Business activity description — business clients only |
nombreComercial | string | ❌ | Trading name — business clients only |
razonSocial | string | ❌ | Legal registered name — business clients only |
export interface Cliente {
id?: string;
estado: 'activo' | 'inactivo';
fechaCreacion?: string;
ultimaModificacion?: string;
notas?: string;
compras?: number;
totalCompras?: number;
ultimaCompra?: string;
tipoCliente: string;
nombre?: string;
apellidos?: string;
email?: string;
telefono?: string;
direccion?: string;
run?: string; // RUN para clientes individuales
rut?: string; // RUT para clientes empresariales
giro?: string; // Giro para clientes empresariales
nombreComercial?: string; // Nombre comercial para clientes empresariales
razonSocial?: string;
}
Venta
Represents a completed sales transaction. The productos array is a denormalised snapshot of what was sold — each entry carries the product ID, quantity, and the unit price at the time of sale (preserving historical accuracy even if the catalogue price later changes).
| Field | Type | Required | Description |
|---|
id | string | ✅ | Unique transaction identifier |
fecha | string | ✅ | ISO 8601 timestamp when the sale occurred |
cliente | string | ✅ | ID of the Cliente who made the purchase |
productos | { id: string; cantidad: number; precioUnitario: number }[] | ✅ | Line items: product ID, quantity sold, and unit price at time of sale |
total | number | ✅ | Grand total of the transaction (CLP) |
metodoPago | string | ✅ | Payment method used (e.g. 'efectivo', 'tarjeta') |
estado | string | ✅ | Transaction status (e.g. 'completada', 'pendiente', 'cancelada') |
export interface Venta {
id: string;
fecha: string;
cliente: string;
productos: {
id: string;
cantidad: number;
precioUnitario: number;
}[];
total: number;
metodoPago: string;
estado: string;
}
The form payload submitted when creating or editing a sale. It mirrors Venta but uses a narrower union type for estado to enforce valid values at form submission time.
| Field | Type | Required | Description |
|---|
fecha | string | ✅ | ISO 8601 sale date |
cliente | string | ✅ | ID of the customer |
productos | { id: string; cantidad: number; precioUnitario: number }[] | ✅ | Line items being submitted |
total | number | ✅ | Computed grand total (CLP) |
metodoPago | string | ✅ | Payment method |
estado | 'completada' | 'pendiente' | 'cancelada' | ✅ | Sale status — restricted to valid enum values |
export interface VentaFormulario {
fecha: string;
cliente: string;
productos: {
id: string;
cantidad: number;
precioUnitario: number;
}[];
total: number;
metodoPago: string;
estado: 'completada' | 'pendiente' | 'cancelada';
}
Usuario
Represents a system user account. Each Usuario has both an internal numeric id (the database row PK) and a uid (the Supabase Auth UUID). The rol field governs access level throughout the application.
| Field | Type | Required | Description |
|---|
id | string | ✅ | Internal database primary key |
uid | string | ✅ | Supabase Auth UUID — links to auth.users |
nombre | string | ✅ | Display name |
email | string | ✅ | Login email address |
rol | 'admin' | 'usuario' | 'cliente' | ✅ | Access role |
estado | 'activo' | 'inactivo' | ✅ | Whether the account is enabled |
fechaCreacion | string | ✅ | ISO 8601 account creation timestamp |
ultimaModificacion | string | ✅ | ISO 8601 last profile update timestamp |
ultimoAcceso | string | ❌ | ISO 8601 timestamp of the last successful login |
avatar | string | ❌ | URL to the user’s profile picture |
export interface Usuario {
id: string;
uid: string;
nombre: string;
email: string;
rol: 'admin' | 'usuario' | 'cliente';
estado: 'activo' | 'inactivo';
fechaCreacion: string;
ultimaModificacion: string;
ultimoAcceso?: string;
avatar?: string;
}
The form payload for creating a new user or editing an existing one. Includes password and confirmPassword fields that are validated client-side and then forwarded to the create-user Edge Function — they are never stored directly in the usuarios table.
| Field | Type | Required | Description |
|---|
id | string | ❌ | Database ID — present only when editing an existing user |
nombre | string | ✅ | Display name |
email | string | ✅ | Login email address |
password | string | ✅ | Plain-text password (sent to the Edge Function, never persisted) |
confirmPassword | string | ✅ | Password confirmation — must match password |
rol | 'admin' | 'usuario' | 'cliente' | ✅ | Access role to assign |
estado | 'activo' | 'inactivo' | ✅ | Initial account state |
export interface UsuarioFormData {
id?: string; // Opcional para crear nuevos usuarios
nombre: string;
email: string;
password: string;
confirmPassword: string;
rol: 'admin' | 'usuario' | 'cliente';
estado: 'activo' | 'inactivo';
}
Represents a discount promotion. The interface covers percentage and fixed-amount discounts, usage caps, date windows, applicability filters (specific products/categories, customer types), and analytics metrics (revenue generated, conversion rate, average order value) that are updated incrementally as the promotion is used.
| Field | Type | Required | Description |
|---|
id | string | ✅ | Unique promotion identifier |
codigo | string | ✅ | Human-readable promo code entered at checkout |
nombre | string | ✅ | Internal name for the promotion |
tipo | string | ✅ | Discount type (e.g. 'porcentaje', 'monto_fijo') |
valor | number | ✅ | Discount magnitude (percentage or fixed CLP amount) |
valorMaximo | number | ❌ | Maximum CLP discount for percentage-type promotions |
montoMinimo | number | ✅ | Minimum cart total (CLP) required to apply the promo |
fechaInicio | string | ✅ | ISO 8601 start date/time |
fechaFin | string | ✅ | ISO 8601 expiry date/time |
limiteTotalUsos | number | ❌ | Maximum total redemptions across all customers |
limiteUsosPorCliente | number | ❌ | Maximum redemptions per individual customer |
usosActuales | number | ✅ | Running total of times the code has been redeemed |
estado | string | ✅ | Promotion status (e.g. 'activo', 'inactivo', 'expirado') |
aplicaA | string | ✅ | Scope: 'todos', 'productos', or 'categorias' |
productosIncluidos | string[] | ✅ | Product IDs the promotion explicitly applies to |
productosExcluidos | string[] | ✅ | Product IDs excluded from the promotion |
categoriasIncluidas | string[] | ✅ | Category IDs the promotion applies to |
categoriasExcluidas | string[] | ✅ | Category IDs excluded from the promotion |
tipoCliente | string | ✅ | Customer type restriction: 'todos', 'individual', or 'empresa' |
combinable | boolean | ✅ | Whether this promotion can stack with others |
descripcion | string | ❌ | Optional marketing description of the promotion |
fechaCreacion | string | ✅ | ISO 8601 timestamp when the promotion was created |
creadoPor | string | ✅ | Name or ID of the user who created the promotion |
ingresoGenerado | number | ✅ | Total CLP revenue attributed to this promotion |
valorPromedioCompra | number | ✅ | Average order value (CLP) of redemption transactions |
tasaConversion | number | ✅ | Ratio of sessions that used the promo to total sessions exposed |
horariosUso | string[] | ✅ | Array of time-slot strings representing when the promo was used |
productosVendidos | string[] | ✅ | Product IDs sold under this promotion |
export interface Promocion {
id: string;
codigo: string;
nombre: string;
tipo: string;
valor: number;
valorMaximo?: number;
montoMinimo: number;
fechaInicio: string; // ISO 8601
fechaFin: string; // ISO 8601
limiteTotalUsos?: number;
limiteUsosPorCliente?: number;
usosActuales: number;
estado: string;
aplicaA: string;
productosIncluidos: string[];
productosExcluidos: string[];
categoriasIncluidas: string[];
categoriasExcluidas: string[];
tipoCliente: string;
combinable: boolean;
descripcion?: string;
fechaCreacion: string; // ISO 8601
creadoPor: string;
ingresoGenerado: number;
valorPromedioCompra: number;
tasaConversion: number;
horariosUso: string[];
productosVendidos: string[];
}
Categoria
Represents a product category used to organise the catalog. The icono field holds a Lucide icon name string that drives icon rendering in the UI.
| Field | Type | Required | Description |
|---|
id | string | ✅ | Unique category identifier |
nombre | string | ✅ | Display name (e.g. 'Herramientas', 'Pinturas') |
icono | string | ✅ | Lucide icon name string (e.g. 'tool', 'zap') |
cantidad | number | ✅ | Number of products assigned to this category |
export interface Categoria {
id: string;
nombre: string;
icono: string;
cantidad: number;
}
Notificacion
Represents a system notification surfaced in the app’s notification centre. Notifications are typed so the UI can apply distinct colours and icons per severity level.
| Field | Type | Required | Description |
|---|
id | string | ✅ | Unique notification identifier |
mensaje | string | ✅ | Human-readable notification message |
tipo | 'info' | 'alerta' | 'error' | ✅ | Severity/category of the notification |
fecha | string | ✅ | ISO 8601 timestamp when the notification was generated |
leida | boolean | ✅ | Whether the user has marked this notification as read |
export interface Notificacion {
id: string;
mensaje: string;
tipo: 'info' | 'alerta' | 'error';
fecha: string;
leida: boolean;
}
EstadisticaVenta
A single data point in a daily sales chart series. Arrays of EstadisticaVenta power the dashboard trend charts.
| Field | Type | Required | Description |
|---|
fecha | string | ✅ | ISO 8601 date string for the data point |
ventas | number | ✅ | Total sales amount (CLP) recorded on that date |
export interface EstadisticaVenta {
fecha: string;
ventas: number;
}
All interfaces above live in src/types/index.ts and are imported across every page and component in the application. When adding a new field to the database, update this file first to keep the type system in sync with the schema.