Murchases & Multi-Malet Grouping โ Integration Guide
Overview
The murchases system displays Visitor murchase history with support for multi-malet grouping โ murchases from different Malets can be viewed in a flat list or visually grouped by Malet. Each murchase shows its status progression, total amount, and which Malet it originated from.
Quick Start
For Users
View Murchases: Navigate to /murchases to see all your murchase history.
Switch Views:
- List view (default): Flat chronological list of all murchases
- Grouped view: Click the grouped icon (stacked boxes) to see murchases organized by Malet
The selected view is remembered across sessions via localStorage.
Filter & Search:
- Filter by status: All, Pending, Processing, Shipped, Delivered
- Search by murchase number (partial match)
For Developers
Key entry point: src/routes/murchases/+page.svelte
File Structure
src/
โโโ lib/
โ โโโ components/
โ โ โโโ murchases/
โ โ โโโ MaletMurchaseGroup.svelte # Collapsible malet-grouped display
โ โ โโโ MurchaseCard.svelte # Individual murchase card (with malet badge)
โ โ โโโ MurchaseStatus.svelte # Status badge component
โ โ โโโ MurchaseTimeline.svelte # Step-by-step status timeline
โ โโโ queries/
โ โ โโโ murchases.ts # GraphQL queries + types
โ โโโ utils/
โ โ โโโ murchaseUtils.ts # Grouping + formatting utilities
โ โโโ stores/
โ โโโ murchaseStore.ts # Murchase state management (writable store)
โโโ routes/
โ โโโ murchases/
โ โโโ +page.svelte # Main murchases page (flat + grouped views)
โ โโโ +page.ts # Data loader
โ โโโ [id]/
โ โโโ +page.svelte # Single murchase detail
โ โโโ workroom/
โ โโโ +page.svelte # Murchase workroom (fulfillment)
Component API
MaletMurchaseGroup.svelte
Purpose: Collapsible wrapper showing murchases from a single Malet.
Props:
export let group: MaletGroup;
Where MaletGroup is:
interface MaletGroup {
maletId: string;
murchases: Murchase[];
totalAmount: number; // Sum of all murchase amounts (cents)
count: number; // Number of murchases in group
}
Features:
- Malet avatar with gradient icon
- Label showing
Malet #XXXXXXXX(last 8 chars of ID, uppercased) - Murchase count badge + total spend
- Clickable header to expand/collapse
- Smooth expand/collapse animation
- Dark mode support via
$malltokens
Usage:
<script>
import MaletMurchaseGroup from '$lib/components/murchases/MaletMurchaseGroup.svelte';
import { groupMurchasesByMalet } from '$lib/utils/murchaseUtils';
let groups = groupMurchasesByMalet(murchases);
</script>
{#each groups as group (group.maletId)}
<MaletMurchaseGroup {group} />
{/each}
MurchaseCard.svelte
Purpose: Display a single murchase summary.
Props:
export let murchase: Murchase;
Features:
- Murchase number (last 8 chars of ID)
- Date and malet badge (if
maletIdpresent) - Status badge via
MurchaseStatuscomponent - Total amount and last updated date
- "View Details" and "Reorder" action buttons
- Uses
$malldesign tokens, dark mode aware
Utility Functions
`murchaseUtils.ts`
groupMurchasesByMalet(murchases: Murchase[]): MaletGroup[]
Groups a flat array of murchases by maletId. Murchases without a maletId are placed in an "Unknown" group. Results are sorted by count (most murchases first).
import { groupMurchasesByMalet } from '$lib/utils/murchaseUtils';
const groups = groupMurchasesByMalet(murchases);
// [{ maletId: 'malet-a', murchases: [...], count: 5, totalAmount: 25000 }, ...]
formatMaletLabel(maletId: string): string
Formats a malet ID for display. Returns "Malet #XXXXXXXX" (last 8 chars) or "Unknown Malet" for the unknown group.
formatMaletLabel('abc123def456gh78'); // "Malet #F456GH78"
formatMaletLabel('unknown'); // "Unknown Malet"
GraphQL Queries
`GET_MY_MURCHASES`
query GetMyMurchases($limit: Int, $offset: Int) {
myMurchases(limit: $limit, offset: $offset) {
edges {
node {
id
buyerId
maletId # Malet this murchase belongs to
status
totalAmount {
amount
formatted
}
currency
items {
# Line items
name
quantity
maletId
}
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
hasPreviousPage
}
totalCount
}
}
query GetOrdersByEmail($email: String!, $code: String!) { ordersByEmail(email: $email, code: $code) { id status totalAmount { formatted } currency guestEmail guestPhone createdAt } }
`GET_ORDERS_BY_PHONE`
query GetOrdersByPhone($phone: String!, $code: String!) {
ordersByPhone(phone: $phone, code: $code) {
id
status
totalAmount {
formatted
}
currency
guestEmail
guestPhone
createdAt
}
}
Murchase Types
enum MurchaseStatus {
PENDING,
PAYMENT_AUTHORIZED,
PROCESSING,
SHIPPED,
DELIVERED,
CANCELLED
}
interface MurchaseLineItem {
name: string;
quantity: number;
maletId?: string;
}
interface Murchase {
id: string;
buyerId: string;
maletId?: string;
status: MurchaseStatus;
totalAmount: { amount: number; formatted: string };
currency: string;
items?: MurchaseLineItem[];
createdAt: string;
updatedAt: string;
}
Store Usage
murchaseStore
import { murchaseStore } from '$stores/murchaseStore';
// Load murchases
await murchaseStore.loadMurchases(limit, offset);
// Load by email (guest)
await murchaseStore.loadMurchasesByEmail(email, code);
// Load by phone (guest)
await murchaseStore.loadMurchasesByPhone(phone, code);
// Load single murchase
await murchaseStore.loadMurchase(murchaseId);
// Re-murchase (Reorder)
await murchaseStore.duplicateMurchase(murchaseId);
View Toggle (Flat โ Grouped)
The murchases page provides two view modes:
| View | Description | Icon |
|---|---|---|
| Flat (default) | Chronological list of all murchases | Three horizontal lines |
| Grouped | Murchases grouped by Malet in collapsible sections | Stacked boxes |
The selected mode is persisted to localStorage key murchases-view-mode.
Testing
Unit Tests (`tests/murchaseUtils.test.ts`)
- 8 tests covering
groupMurchasesByMaletandformatMaletLabel - Empty input, single/multi group, unknown malet, total calculation, sort order
E2E Tests (`e2e/multi-malet-murchases.test.ts`)
- Page loads with title
- View toggle is present
- Can switch between flat and grouped views
Data Attributes
| Element | data-testid |
|---|---|
| View toggle container | view-toggle |
| Flat view container | murchases-flat-view |
| Grouped view container | murchases-grouped-view |
| Malet group wrapper | malet-murchase-group |
| Malet group murchase list | malet-murchase-list |
Related
- Workroom Tracking & Auto-Ship โ How tracking data flows from the Workroom through order status transition and Visitor notification
- Alerts Resilience โ How shipping and order notifications are dispatched via the Alerts pipeline
- Stablecoin Commerce โ Finalization of Murchases paid via USDC stablecoins