mirror of
https://github.com/hanzoai/commerce.git
synced 2026-10-30 15:08:42 +00:00
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans, usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0. Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
60 lines
3.2 KiB
Go
60 lines
3.2 KiB
Go
package affiliate
|
|
|
|
import (
|
|
"github.com/zap-proto/zip"
|
|
|
|
"github.com/hanzoai/commerce/middleware"
|
|
mdlaffiliate "github.com/hanzoai/commerce/models/affiliate"
|
|
"github.com/hanzoai/commerce/models/contributor"
|
|
"github.com/hanzoai/commerce/util/permission"
|
|
"github.com/hanzoai/commerce/util/rest"
|
|
)
|
|
|
|
// Route registers affiliate and contributor routes.
|
|
// This builds on top of the referral base layer: revenue share,
|
|
// commissions, payouts, OSS contributor attribution.
|
|
func Route(r *zip.Group, args ...zip.Handler) {
|
|
tokenRequired := middleware.TokenRequired()
|
|
adminRequired := middleware.TokenRequired(permission.Admin)
|
|
|
|
// mintRequired gates the treasury payout machinery on the internal service
|
|
// token OR a platform global admin ONLY — NEVER an org-level Admin (a legacy
|
|
// per-org access token or a gateway-minted org owner). executePayouts
|
|
// DISBURSES real value (CreditGrants, queued Stripe transfers, on-chain HUSD);
|
|
// calculatePayouts computes the split; the SBOM writes feed that attribution.
|
|
// adminRequired alone let any org owner drive the treasury (latent while
|
|
// mainnet HUSD is off, HIGH once enabled) — the same C1 org-owner-mint hole
|
|
// PlatformOnly closes on the billing routes. Reads stay admin/token-scoped.
|
|
mintRequired := middleware.PlatformOnly()
|
|
|
|
// --- Affiliate CRUD + custom endpoints ---
|
|
affiliateRest := rest.New(mdlaffiliate.Affiliate{})
|
|
affiliateRest.Create = affiliateCreate(affiliateRest)
|
|
affiliateRest.GET("/:affiliateid/connect", tokenRequired, middleware.Namespace(), affiliateConnect)
|
|
affiliateRest.GET("/:affiliateid/referrals", append(args, affiliateGetReferrals)...)
|
|
affiliateRest.GET("/:affiliateid/referrers", append(args, affiliateGetReferrers)...)
|
|
affiliateRest.GET("/:affiliateid/orders", append(args, affiliateGetOrders)...)
|
|
affiliateRest.GET("/:affiliateid/transactions", append(args, affiliateGetTransactions)...)
|
|
affiliateRest.Route(r, args...)
|
|
|
|
// --- Contributor CRUD + custom endpoints ---
|
|
contributorRest := rest.New(contributor.Contributor{})
|
|
contributorRest.Create = contributorCreate(contributorRest)
|
|
contributorRest.POST("/register", tokenRequired, registerContributor)
|
|
contributorRest.GET("/by-login/:login", tokenRequired, contributorGetByLogin)
|
|
// Money-OUT / payout machinery: adminRequired FIRST resolves the org and
|
|
// stamps the service-token marker + permissions; mintRequired (PlatformOnly)
|
|
// then NARROWS to the service token / global admin. PlatformOnly must run
|
|
// AFTER TokenRequired (it reads what TokenRequired sets), so both are chained.
|
|
contributorRest.POST("/sbom", adminRequired, mintRequired, createSBOMEntry)
|
|
contributorRest.GET("/sbom", adminRequired, listSBOMEntries)
|
|
contributorRest.GET("/sbom/:sbomid", adminRequired, getSBOMEntry)
|
|
contributorRest.PUT("/sbom/:sbomid", adminRequired, mintRequired, updateSBOMEntry)
|
|
contributorRest.POST("/payouts/calculate", adminRequired, mintRequired, calculatePayouts)
|
|
contributorRest.GET("/payouts/preview", adminRequired, previewPayouts)
|
|
contributorRest.POST("/payouts/execute", adminRequired, mintRequired, executePayouts)
|
|
contributorRest.GET("/:contributorid/earnings", tokenRequired, getEarnings)
|
|
contributorRest.GET("/:contributorid/attributions", tokenRequired, getAttributions)
|
|
contributorRest.Route(r, args...)
|
|
}
|