@duabalabs/reviews-sdk
v0.2.0
Published
Framework-agnostic client for the centralized 3y3anaa reviews platform.
Maintainers
Readme
@duabalabs/reviews-sdk
Framework-agnostic client for the centralized 3y3anaa reviews platform — the shared review/rating store for Duabalabs subsidiaries. Reviews target a subject namespaced by (sourceApp, subjectType, externalId); reviewers are external identities (no Parse account needed). Your app authenticates with a per-app key.
Call this server-side — the app key must stay secret.
Install
npm i @duabalabs/reviews-sdkUsage
import { createReviewsClient } from "@duabalabs/reviews-sdk";
const reviews = createReviewsClient({
appKey: process.env.THREEYANAA_APP_KEY!, // your per-app key (rk_<app>_…), sent as Bearer
// baseUrl defaults to https://api.3y3anaa.com — override for self-host/staging
});
// Submit (one review per subject+author; re-submitting edits it)
await reviews.submitReview({
subjectType: "product",
externalId: "prod_123",
subjectDisplayName: "Kente Tote Bag",
author: { externalUserId: "user_42", displayName: "Ama", role: "buyer" },
rating: 5,
body: "Beautiful craftsmanship, fast delivery.",
verified: true,
});
// Read a subject's reviews + aggregate
const { items, aggregate } = await reviews.getReviews({ subjectType: "product", externalId: "prod_123" });
// Batch aggregates (product grids / cards)
const aggs = await reviews.getAggregates([
{ subjectType: "product", externalId: "prod_123" },
{ subjectType: "product", externalId: "prod_456" },
]);Proxyfidelity model — artisans, clients & businesses review each other
Reviews are not just buyer→product. The same subjectType + author.role pair
models any party reviewing any other. Canonical subjects/roles:
artisan, business, client (plus commerce: product, shop, supplier,
courier). Any string is accepted, but these are typed for autocomplete.
// A client reviews a business
await reviews.submitReview({
subjectType: "business", externalId: "biz_001",
author: { externalUserId: "client_77", displayName: "Kwame", role: "client" },
rating: 5, body: "Reliable and professional.",
});
// A business reviews an artisan it hired
await reviews.submitReview({
subjectType: "artisan", externalId: "artisan_9",
author: { externalUserId: "biz_001", displayName: "Accra Tiles Ltd", role: "business" },
rating: 4, body: "Great tiling work, slightly late.",
});
// An artisan reviews a client
await reviews.submitReview({
subjectType: "client", externalId: "client_77",
author: { externalUserId: "artisan_9", displayName: "Kofi", role: "artisan" },
rating: 5, body: "Clear brief, paid on time.",
});Your app reads back its own reviews with getReviews(...). 3y3anaa surfaces
the whole network's reviews for a subject — across every integrated app — on
that business/artisan's profile (its host getSubjectReviews aggregates them).
Provisioning — give your app credential the subject scopes it needs (empty scopes = all allowed):
provisionAppCredential({ appName: "sellub",
scopes: ["product","shop","supplier","courier","artisan","business","client"] })API
submitReview(input)→{ review, aggregate }getReviews({ subjectType, externalId, limit?, skip?, sort? })→{ items, total, hasMore, aggregate }getAggregate({ subjectType, externalId })→{ avgRating, reviewCount, ratingBreakdown }getAggregates([{subjectType, externalId}, …])→ aggregates[]markHelpful({ reviewId, voterExternalUserId })respondToReview({ reviewId, responderExternalUserId, responderDisplayName?, text })getReviewsByAuthor({ authorExternalUserId, limit?, skip? })
Provisioning an app key
Get your key either self-serve (the 3y3anaa portal → Settings → API Keys) or, for admins, by running the master-key provisionAppCredential cloud function with { appName: "sellub", scopes: ["product","shop","supplier","courier"] }. It returns the plaintext key once — store it in the subsidiary's server env as THREEYANAA_APP_KEY. That single key is all the SDK needs.
Build
npm run build # tsup → CJS + ESM + .d.ts