@quadcore-lib/account
v0.1.0
Published
Direcciones del usuario final: CRUD, selector para el checkout y armado del snapshot de envío. Consume `@quadcore-lib/addresses-server`.
Downloads
34
Readme
@quadcore-lib/account
Direcciones del usuario final: CRUD, selector para el checkout y armado del snapshot de envío. Consume @quadcore-lib/addresses-server.
Instalación
npm install @quadcore-lib/accountUso
Todas las rutas de addresses-server van detrás de JwtAuthGuard. El token lo inyecta fetchWithConfig desde setAuthToken(...) de @quadcore-lib/core — llamalo al iniciar sesión, antes de montar estos componentes:
import { setAuthToken } from "@quadcore-lib/core";
setAuthToken(await getAccessTokenSilently());CRUD de direcciones
import { AddressBook } from "@quadcore-lib/account";
<AddressBook apiUrl="https://addresses.miempresa.com" />Listar, crear, editar, borrar y marcar predeterminada, todo en un componente.
Selector en el checkout
AddressSelector devuelve el addressId y el shippingAddress ya armados, que es exactamente lo que espera POST /api/orders:
import { useState } from "react";
import { AddressSelector, type AddressSelection } from "@quadcore-lib/account";
import { CheckoutForm } from "@quadcore-lib/storefront-ui";
function Checkout() {
const [selection, setSelection] = useState<AddressSelection | null>(null);
return (
<CheckoutForm
apiUrl="https://orders.miempresa.com"
addressId={selection?.addressId}
shippingAddress={selection?.shippingAddress}
requireAddress
>
<AddressSelector apiUrl="https://addresses.miempresa.com" onChange={setSelection} />
</CheckoutForm>
);
}CheckoutForm recibe la dirección por props y renderiza el selector en su slot children. No hay dependencia entre storefront-ui y este paquete: cada uno se puede usar solo.
Al montar, AddressSelector preselecciona la dirección predeterminada (o la única que haya) y emite el onChange inicial. Si hay varias y ninguna es default, no elige por el usuario.
Hook suelto
import { useAddresses } from "@quadcore-lib/account";
const { addresses, defaultAddress, loading, saving, saveError, create, update, remove, setDefault } =
useAddresses(apiUrl);Flujo de checkout
El descuento de stock no lo orquesta el cliente. orders-server lo hace server-side dentro de POST /orders, atómico y con compensación. Desde el frontend, el checkout es una sola llamada:
1. AddressSelector → { addressId, shippingAddress }
2. POST /api/orders → orders-server, en una operación:
· resuelve precios del catálogo (autoritativos)
· descuenta stock atómico (409 si no alcanza)
· valida y redime el cupón
· guarda la orden con addressId + snapshot
si algo falla, devuelve stock y cupónaddressId es la referencia viva a la dirección; shippingAddress es la copia congelada. Van los dos: si el usuario después edita o borra la dirección, el pedido histórico conserva a dónde se envió.
Limitación conocida:
POST /orderstodavía no es idempotente — un reintento de red puede duplicar la orden. Se trackea en el issue #29.
API
| Export | Tipo | Descripción |
|---|---|---|
| AddressBook | componente | CRUD completo: listar, crear, editar, borrar, marcar default |
| AddressSelector | componente | Radios de selección; emite { addressId, shippingAddress } |
| AddressList | componente | Listado presentacional con acciones (no llama a la API) |
| AddressForm | componente | Alta/edición de una dirección (no llama a la API) |
| useAddresses | hook | Listado + mutaciones + defaultAddress |
| toAddressSnapshot | función | Address → AddressSnapshot (descarta id, userId, isDefault, timestamps) |
| formatAddress | función | AddressSnapshot → texto en una línea |
| listAddresses, createAddress, updateAddress, deleteAddress, setDefaultAddress | funciones | Cliente HTTP crudo |
| Address, AddressSnapshot, CreateAddressInput, UpdateAddressInput, AddressSelection, UseAddressesResult | tipos | — |
Props
AddressBook — apiUrl, confirmDelete? (por defecto window.confirm), className?
AddressSelector — apiUrl, value?, onChange, emptyFallback?, className?
AddressList — addresses, onEdit?, onDelete?, onSetDefault?, busy?, emptyLabel?, className?
AddressForm — initial?, onSubmit, onCancel?, submitting?, className?
Estilos
Sin CSS propio. Las clases llevan prefijo qc-: qc-address-book, qc-address-list, qc-address-form, qc-address-selector y sus modificadores.
Requisitos
react>=18,react-dom>=18(peer)- Backend con
@quadcore-lib/addresses-servermontado ybootstrapQuadcoreApp(prefijo/api+ envelope{ data, error }) setAuthToken(...)llamado con un JWT válido antes de usar los componentes
