Tech & Electronics
The Tech vertical powers electronics retailers, SaaS vendors, gadget makers, and IT service providers with four integrated systems: product specification engine, software licensing, warranty management, and trade-in programs. Malet Owners configure these features via the Storefront Window layout system.
NOTE
These features live in the experiences subgraph โ the same cross-vertical Feature Plane that houses Entertainment & Experiences, Professional Services, Wellness & Beauty, and Culture & Arts. The architecture is documented in docs/architecture/18-progressive-vertical-extraction.md.
Architecture: Two-Plane Design
The Tech vertical uses the same Control + Feature plane separation as its sibling verticals:
- Control Plane (
maletssubgraph): VerticalConfig feature flags decide which Tech modules are enabled per Malet โspecEngine,softwareLicensing,warrantyManagement,tradeInProgram. - Feature Plane (
experiencessubgraph): Self-containedSpecSheetModuleandWarrantyModule. Each can be extracted to its own subgraph when a dedicated Tech vertical Team forms. - Extensions (
servicessubgraph): License type and activation fields on existing Service entities.
Three new Storefront Window layout slot types are available: SPEC_COMPARISON, WARRANTY_CENTER, and TRADE_IN_PORTAL.
What Tech Reuses
| Reused System | From Vertical | Tech Use Case |
|---|---|---|
| Digital Credit Wallets | Entertainment | Trade-in value deposited as Malet-scoped wallet balance |
| Gamified Loyalty | Entertainment | Reward repeat buyers, warranty registrations, and reviews |
Product Specification Engine
Create structured, machine-readable spec sheets for products with comparison capabilities and "Works with" compatibility linking.
Spec Entries
Each SpecEntry is a key-value pair with optional unit and grouping:
| Field | Type | Example |
|---|---|---|
key |
String! |
"Processor", "RAM", "Battery" |
value |
String! |
"Apple M3 Pro", "16", "22-hour" |
unit |
String |
"GB", "GHz", "mAh" |
group |
String |
"Performance", "Display", "Battery" |
Mutations
# Add a spec entry to a product (upserts on maletId + productId)
mutation {
upsertProductSpec(
maletId: "m_techshop"
productId: "prod_macbook"
key: "Processor"
value: "Apple M3 Pro"
group: "Performance"
) {
id
productId
entries {
key
value
unit
group
}
}
}
# Add another spec entry
mutation {
upsertProductSpec(
maletId: "m_techshop"
productId: "prod_macbook"
key: "RAM"
value: "16"
unit: "GB"
group: "Performance"
) {
id
entries {
key
value
unit
group
}
}
}
# Remove a spec entry by key
mutation {
removeProductSpecEntry(productId: "prod_macbook", key: "RAM") {
id
entries {
key
value
}
}
}
# Set compatible products ("Works with")
mutation {
setCompatibleProducts(
productId: "prod_macbook"
compatibleProductIds: ["prod_usbc_hub", "prod_magic_mouse", "prod_sleeve_14"]
) {
id
compatibleProductIds
}
}
Queries
# Get specs for a single product (public โ product detail page)
query {
productSpec(productId: "prod_macbook") {
id
productId
entries {
key
value
unit
group
}
compatibleProductIds
}
}
# Compare 2-4 products side-by-side
query {
compareProductSpecs(productIds: ["prod_macbook", "prod_thinkpad", "prod_xps15"]) {
productId
entries {
key
value
unit
group
}
}
}
# All spec sheets for a Malet (Malet Owner)
query {
maletProductSpecs(maletId: "m_techshop") {
id
productId
entries {
key
value
unit
group
}
compatibleProductIds
}
}
Comparison Tool
The compareProductSpecs query accepts 2-4 product IDs and returns their full spec sheets. The frontend renders a side-by-side table aligned by key:
| Spec | MacBook Pro 14" | ThinkPad X1 | Dell XPS 15 |
|---|---|---|---|
| Processor | Apple M3 Pro | Intel i7-1365U | Intel i7-13700H |
| RAM | 16 GB | 16 GB | 32 GB |
| Storage | 512 GB SSD | 512 GB SSD | 1 TB SSD |
| Battery | 22 hours | 15 hours | 13 hours |
TIP
Group specs by their group field for organized display. Common groups: "Performance", "Display", "Storage", "Battery", "Connectivity", "Physical".
Software Licensing
Extended service fields for digital license products on the existing services subgraph:
Service Fields
| Field | Type | Description |
|---|---|---|
licenseType |
LicenseType |
PERPETUAL, SUBSCRIPTION, TRIAL |
maxActivations |
Int |
Maximum license activations allowed |
License Types
| Type | Description | Example |
|---|---|---|
PERPETUAL |
One-time purchase, permanent access | Desktop software, firmware updates |
SUBSCRIPTION |
Recurring billing, time-limited access | SaaS tools, cloud services |
TRIAL |
Free time-limited evaluation | 30-day trial, freemium tier |
Example: Create a Licensed Software Product
mutation {
createOneService(
input: {
service: {
name: "PhotoEdit Pro โ Perpetual License"
description: "Professional photo editing software with lifetime updates"
price: 9900 # $99.00 (cents)
maletId: "m_techshop"
licenseType: PERPETUAL
maxActivations: 3
}
}
) {
id
name
licenseType
maxActivations
}
}
Warranty Management
Register warranties on purchase and manage claims through a full lifecycle. Warranty is tracked via two entities: WarrantyRegistration (the coverage) and WarrantyClaim (a claim against the coverage).
Warranty Status
ACTIVE โ EXPIRED (automatic on date)
โ VOIDED (manual by Malet Owner)
Claim Lifecycle
SUBMITTED โ REVIEWING โ APPROVED โ RESOLVED
โ DENIED
Registration Mutations
# Register warranty on purchase (Malet Owner or auto on Murchase)
mutation {
registerWarranty(
maletId: "m_techshop"
productId: "prod_macbook"
buyerId: "user_kagiso"
murchaseId: "murch_1"
warrantyMonths: 12
serialNumber: "SN-2025-MACBOOK-001"
) {
id
serialNumber
registeredAt
expiresAt
warrantyMonths
status
}
}
# Void a warranty (Malet Owner)
mutation {
voidWarranty(warrantyId: "war_1") {
id
status
}
}
Claim Mutations
# Submit a warranty claim (Buyer)
mutation {
submitWarrantyClaim(
registrationId: "war_1"
maletId: "m_techshop"
claimantId: "user_kagiso"
description: "Screen flickering after 3 months of normal use"
) {
id
status
submittedAt
}
}
# Begin reviewing a claim (Malet Owner)
mutation {
reviewWarrantyClaim(claimId: "claim_1") {
id
status
}
}
# Approve the claim
mutation {
approveWarrantyClaim(claimId: "claim_1") {
id
status
}
}
# Resolve with a specific resolution type
mutation {
resolveWarrantyClaim(
claimId: "claim_1"
resolution: REPAIR
resolutionNotes: "Screen panel replaced under warranty. Device tested and returned."
) {
id
status
resolution
resolutionNotes
resolvedAt
}
}
# Deny a claim
mutation {
denyWarrantyClaim(
claimId: "claim_1"
resolutionNotes: "Physical damage โ not covered under warranty terms."
) {
id
status
resolutionNotes
}
}
Resolution Types
| Resolution | Description | Follow-up |
|---|---|---|
REPAIR |
Device repaired and returned | Repair booking via Workroom |
REPLACE |
Device replaced with equivalent | New Murchase created |
REFUND |
Refund issued to Buyer | Refund via payments |
Queries
# Buyer checks their warranties
query {
myWarranties(buyerId: "user_kagiso") {
id
productId
serialNumber
registeredAt
expiresAt
status
}
}
# Malet Owner views all warranties
query {
maletWarranties(maletId: "m_techshop", status: ACTIVE) {
id
productId
buyerId
serialNumber
expiresAt
}
}
# Get a single warranty by ID
query {
warranty(id: "war_1") {
id
serialNumber
status
expiresAt
}
}
# Get claims for a warranty
query {
warrantyClaims(registrationId: "war_1") {
id
description
photoUrls
status
resolution
resolutionNotes
submittedAt
resolvedAt
}
}
# Malet Owner views all claims by status
query {
maletWarrantyClaims(maletId: "m_techshop", status: SUBMITTED) {
id
registrationId
claimantId
description
status
}
}
Warranty Enforcement
Claims are validated against the warranty registration:
- Active check: Only
ACTIVEwarranties accept claims - Expiry check: If
expiresAt < now(), the claim is rejected withBadRequestException - Evidence: Claims support
photoUrls[]for visual evidence of the issue
Trade-In Program
Trade-in value is deposited into the Buyer's Credit Wallet as Malet-scoped credit. The existing CreditWallet from the Entertainment vertical provides:
- Atomic
$incbalance updates - Full transaction ledger
- Balance guard (prevents negative balance)
PURCHASE/SPEND/REFUND/BONUS/ADJUSTMENTtransaction types
Trade-In Flow
- Buyer selects a product for trade-in
- Malet Owner assesses device condition (Phase 1: manual, Phase 2: guided questionnaire)
- Trade-in value is determined and deposited as
BONUScredit:
mutation {
addCredits(
maletId: "m_techshop"
userId: "user_kagiso"
amount: 35000 # R350.00 trade-in credit
description: "Trade-in: iPhone 13 Pro (Good condition)"
referenceId: "tradein_001"
) {
id
balance
transactions {
type
amount
description
createdAt
}
}
}
- Buyer applies credit toward new Murchase via
SPENDtransaction
Workroom Steps
The Tech vertical ships with 4 default Workroom steps for warranty and repair lifecycle management:
| Step | Type | Assignee | Description |
|---|---|---|---|
| Warranty Registration | APPROVAL |
Malet Owner | Verify purchase and register warranty with serial number |
| Diagnostic Assessment | FORM |
Malet Owner | Run diagnostics, assess device condition for repair or trade-in |
| Repair / Resolution | APPROVAL |
Malet Owner | Complete repair, replacement, or refund based on claim outcome |
| Device Return | APPROVAL |
Buyer | Confirm device received in working condition after repair |
These steps are automatically configured on new Tech Malets via the vertical seed (slate/cyan branding).
Deferred Features
The following capabilities are planned for future phases using in-house, open-source/standard solutions โ no third-party SaaS dependencies:
| Feature | Phase | Approach |
|---|---|---|
| License Key Pool | Phase 2 | licensePool: LicenseKey[] on Product with claim-on-purchase via $pop |
| Trade-In Assessment | Phase 2 | Guided condition questionnaire + algorithmic quote engine |
| Download Portal | Phase 2 | Time-limited pre-signed R2/S3 URLs via media subgraph |
| Subscription Seats | Phase 2 | Extend MembershipSubscription with seatCount + assignedSeats[] |
TIP
All Phase 2 deferred features are tracked in the consolidated docs/PHASE2_BACKLOG.md. The softwareLicensing and tradeInProgram feature flags are already present in the Control Plane.
Frontend Implementation
Three Svelte 5 storefront widgets render the Tech vertical in the Visitor-facing storefront:
Components
| Widget | File | Description |
|---|---|---|
SpecComparison |
src/lib/components/tech/SpecComparison.svelte |
Grouped specification table with optional compare mode for side-by-side product specs. Shows compatibility badge for "Works with" products. |
WarrantyTracker |
src/lib/components/tech/WarrantyTracker.svelte |
Warranty registration cards with status badges (Active/Expired/Voided), serial numbers, expiry countdown progress bars, and 30-day expiry warnings. Auth-gated. |
TradeInPortal |
src/lib/components/tech/TradeInPortal.svelte |
4-step trade-in flow cards (Select Product, Describe Condition, Get Estimate, Ship & Earn) with CTA linking to the Malet's trade-in page. |
File Map
| File | Purpose |
|---|---|
src/lib/queries/tech.ts |
GraphQL queries (GET_PRODUCT_SPEC, GET_MY_WARRANTIES, GET_WARRANTY_CLAIMS) + TypeScript interfaces |
src/lib/utils/techUtils.ts |
10 utility functions โ spec grouping by category, warranty status/duration, claim lifecycle status, resolution labels |
src/lib/components/storefront/WidgetRegistry.svelte |
Widget registration: SPEC_COMPARISON, WARRANTY_TRACKER, TRADE_IN_PORTAL |
tests/techUtils.test.ts |
15 unit tests covering all utility functions |
Layout Slot Types
| Slot Type | Widget | Auth Required |
|---|---|---|
SPEC_COMPARISON |
SpecComparison |
No |
WARRANTY_TRACKER |
WarrantyTracker |
โ Yes |
TRADE_IN_PORTAL |
TradeInPortal |
No |
NOTE
For Visitor-facing documentation on specifications, warranties, and trade-in, see the Support Manual: Specs, Warranties & Trade-In.
Related
- Entertainment & Experiences โ Provides Credit Wallets for trade-in credits and Gamified Loyalty for purchase rewards
- Culture & Arts โ Sibling vertical in the shared
experiencessubgraph Feature Plane - Wellness & Beauty โ Sibling vertical; Membership Engine pattern reusable for subscription seat management
- Storefront Sections โ Configure
SPEC_COMPARISON,WARRANTY_TRACKER, andTRADE_IN_PORTALlayout slots - Teams & Sub-Groups โ Organize tech support staff with the org โ team โ member hierarchy
- Arcade & Gaming โ Sibling vertical with digital key vaults and game profiles in the shared
experiencessubgraph - Cross-Malet Comparison & Quick Actions โ Platform-wide product comparison deck and card quick action menu
- Support: Specs, Warranties & Trade-In โ Visitor-facing guide