openvibers/openvibe.contracts Commits
v0.25.0: OpenVibe.Coupons is alpha (coupons.* capabilities)
Changes
nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "id": "coupons.coupon.lookup",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Read a merchant's active codes (status, confidence, report aggregates, restrictions, expiry or unknown, evidence) or one code. Public data only, the same response for every caller; anonymous callers may use the routes with tighter rate limits. The charter's coupons.lookup.",++ "permissions": [++ "coupons:read"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-lookup",++ "events": [],++ "implementedBy": [++ "GET /api/v1/merchants/:id/coupons",++ "GET /api/v1/merchants/:id",++ "GET /api/v1/coupons/:id"++ ]++}nnew file mode 100644@@@ -0,0 +1,25 @@++{++ "id": "coupons.coupon.submit",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Submit a coupon code for a merchant (by merchant id, host or URL) on behalf of a person (X-OV-Subject) or as AI output (X-OV-Origin: ai, held for staff review). The code starts with status unknown; a status, confidence or 'verified' field is refused. A site no merchant covers becomes a pending merchant for staff review. The charter's coupons.submit.",++ "permissions": [++ "coupons:write"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-write",++ "events": [++ "coupons.coupon.created",++ "coupons.coupon.updated",++ "coupons.confidence.changed",++ "coupons.index_document.upserted",++ "coupons.index_document.deleted"++ ],++ "implementedBy": [++ "POST /api/v1/coupons/submit"++ ]++}nnew file mode 100644@@@ -0,0 +1,25 @@++{++ "id": "coupons.merchant.manage",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Create merchants with their domain rules (never on a public suffix), add domain rules, and approve or disable merchants. Approving a pending merchant publishes the codes members submitted for it; disabling one takes its codes out of active results and Search.",++ "permissions": [++ "coupons:moderate"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-write",++ "events": [++ "coupons.coupon.updated",++ "coupons.index_document.upserted",++ "coupons.index_document.deleted"++ ],++ "implementedBy": [++ "POST /api/v1/merchants",++ "POST /api/v1/merchants/:id/domains",++ "POST /api/v1/merchants/:id/status"++ ]++}nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "coupons.merchant.resolve",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Resolve a hostname to an active merchant (normalized host, eTLD+1 from a bundled public-suffix subset, subdomain rules; path rules never match host-only lookups). Public data only; anonymous callers may use the route with tighter rate limits.",++ "permissions": [++ "coupons:read"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-lookup",++ "events": [],++ "implementedBy": [++ "GET /api/v1/merchants/resolve?host="++ ]++}nnew file mode 100644@@@ -0,0 +1,24 @@++{++ "id": "coupons.report.create",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Report that a code worked or failed, on behalf of a person (X-OV-Subject). One report per person, code and UTC day; only the latest per person counts; rate-limited per person; AI output (X-OV-Origin: ai) is refused. The response carries aggregates only, never a reporter. The charter's coupons.report.",++ "permissions": [++ "coupons:report"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-report",++ "events": [++ "coupons.report.created",++ "coupons.coupon.updated",++ "coupons.confidence.changed",++ "coupons.index_document.upserted"++ ],++ "implementedBy": [++ "POST /api/v1/coupons/:id/report"++ ]++}nnew file mode 100644@@@ -0,0 +1,26 @@++{++ "id": "coupons.status.update",++ "version": "1.0",++ "owner": "coupons",++ "status": "active",++ "visibility": "first-party",++ "description": "Moderate a code: disable it, mark it expired, or return it to active results (its status is then recomputed from people's reports and time). reported_working and reported_failed cannot be set by anyone.",++ "permissions": [++ "coupons:moderate"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "coupons-write",++ "events": [++ "coupons.coupon.disabled",++ "coupons.coupon.expired",++ "coupons.coupon.updated",++ "coupons.confidence.changed",++ "coupons.index_document.upserted",++ "coupons.index_document.deleted"++ ],++ "implementedBy": [++ "POST /api/v1/coupons/:id/status"++ ]++}@@@ -1,16 +1,39 @@{"version": "0.1.0","contractRanges": {-- "openvibe-contracts": "^0.1.0"++ "openvibe-contracts": ">=0.19.0 <1.0.0"},"id": "coupons","name": "OpenVibe.Coupons",-- "status": "placeholder",++ "status": "alpha","repository": "OpenVibers/OpenVibe.Coupons",-- "domains": [],-- "capabilities": [],-- "eventsProduced": [],++ "domains": [++ "openvibe.coupons"++ ],++ "publicOrigin": "https://openvibe.coupons",++ "health": "/api/health",++ "ready": "/api/ready",++ "capabilities": [++ "coupons.coupon.submit",++ "coupons.report.create",++ "coupons.merchant.resolve",++ "coupons.coupon.lookup",++ "coupons.status.update",++ "coupons.merchant.manage"++ ],++ "eventsProduced": [++ "coupons.coupon.created",++ "coupons.coupon.updated",++ "coupons.coupon.expired",++ "coupons.coupon.disabled",++ "coupons.report.created",++ "coupons.confidence.changed",++ "coupons.index_document.upserted",++ "coupons.index_document.deleted"++ ],"eventsConsumed": [],-- "namespacesOwned": [],-- "notes": "Coupon codes with merchant matching, restrictions, expiry and real-people validity reports. Charter only; no runtime."++ "namespacesOwned": [++ "coupons.*"++ ],++ "notes": "Port 4850. Owns coupon_merchants, coupon_merchant_domains, coupons, coupon_sources, coupon_restrictions, coupon_validation_reports, coupon_status_history, coupon_application_hints, coupon_watches in its own SQLite, plus extension_installs (cpx_ browser-helper tokens, scopes coupons.lookup and coupons.report, hashed, revocable). Consumes OpenVibe.Network (SSO, JWKS) and OpenVibe.Sources (sources.item.read, category coupons); publishes through OpenVibe.Events (events.event.publish); OpenVibe.Search reads coupons.index_document.* from Events. The browser helper lives in OpenVibers/OpenVibe.Extensions (ADR-023)."}@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.24.0",++ "version": "0.25.0","description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.","main": "index.js","types": "generated/typescript/index.d.ts",
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "id": "coupons.coupon.lookup",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Read a merchant's active codes (status, confidence, report aggregates, restrictions, expiry or unknown, evidence) or one code. Public data only, the same response for every caller; anonymous callers may use the routes with tighter rate limits. The charter's coupons.lookup.",
+ "permissions": [
+ "coupons:read"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-lookup",
+ "events": [],
+ "implementedBy": [
+ "GET /api/v1/merchants/:id/coupons",
+ "GET /api/v1/merchants/:id",
+ "GET /api/v1/coupons/:id"
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+{
+ "id": "coupons.coupon.submit",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Submit a coupon code for a merchant (by merchant id, host or URL) on behalf of a person (X-OV-Subject) or as AI output (X-OV-Origin: ai, held for staff review). The code starts with status unknown; a status, confidence or 'verified' field is refused. A site no merchant covers becomes a pending merchant for staff review. The charter's coupons.submit.",
+ "permissions": [
+ "coupons:write"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-write",
+ "events": [
+ "coupons.coupon.created",
+ "coupons.coupon.updated",
+ "coupons.confidence.changed",
+ "coupons.index_document.upserted",
+ "coupons.index_document.deleted"
+ ],
+ "implementedBy": [
+ "POST /api/v1/coupons/submit"
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+{
+ "id": "coupons.merchant.manage",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Create merchants with their domain rules (never on a public suffix), add domain rules, and approve or disable merchants. Approving a pending merchant publishes the codes members submitted for it; disabling one takes its codes out of active results and Search.",
+ "permissions": [
+ "coupons:moderate"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-write",
+ "events": [
+ "coupons.coupon.updated",
+ "coupons.index_document.upserted",
+ "coupons.index_document.deleted"
+ ],
+ "implementedBy": [
+ "POST /api/v1/merchants",
+ "POST /api/v1/merchants/:id/domains",
+ "POST /api/v1/merchants/:id/status"
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "coupons.merchant.resolve",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Resolve a hostname to an active merchant (normalized host, eTLD+1 from a bundled public-suffix subset, subdomain rules; path rules never match host-only lookups). Public data only; anonymous callers may use the route with tighter rate limits.",
+ "permissions": [
+ "coupons:read"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-lookup",
+ "events": [],
+ "implementedBy": [
+ "GET /api/v1/merchants/resolve?host="
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
+{
+ "id": "coupons.report.create",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Report that a code worked or failed, on behalf of a person (X-OV-Subject). One report per person, code and UTC day; only the latest per person counts; rate-limited per person; AI output (X-OV-Origin: ai) is refused. The response carries aggregates only, never a reporter. The charter's coupons.report.",
+ "permissions": [
+ "coupons:report"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-report",
+ "events": [
+ "coupons.report.created",
+ "coupons.coupon.updated",
+ "coupons.confidence.changed",
+ "coupons.index_document.upserted"
+ ],
+ "implementedBy": [
+ "POST /api/v1/coupons/:id/report"
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
+{
+ "id": "coupons.status.update",
+ "version": "1.0",
+ "owner": "coupons",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Moderate a code: disable it, mark it expired, or return it to active results (its status is then recomputed from people's reports and time). reported_working and reported_failed cannot be set by anyone.",
+ "permissions": [
+ "coupons:moderate"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "coupons-write",
+ "events": [
+ "coupons.coupon.disabled",
+ "coupons.coupon.expired",
+ "coupons.coupon.updated",
+ "coupons.confidence.changed",
+ "coupons.index_document.upserted",
+ "coupons.index_document.deleted"
+ ],
+ "implementedBy": [
+ "POST /api/v1/coupons/:id/status"
+ ]
+}
@@ -1,16 +1,39 @@
@@ -1,16 +1,39 @@
{
{
"version": "0.1.0",
"version": "0.1.0",
"contractRanges": {
"contractRanges": {
- "openvibe-contracts": "^0.1.0"
+ "openvibe-contracts": ">=0.19.0 <1.0.0"
},
},
"id": "coupons",
"id": "coupons",
"name": "OpenVibe.Coupons",
"name": "OpenVibe.Coupons",
- "status": "placeholder",
+ "status": "alpha",
"repository": "OpenVibers/OpenVibe.Coupons",
"repository": "OpenVibers/OpenVibe.Coupons",
- "domains": [],
- "capabilities": [],
- "eventsProduced": [],
+ "domains": [
+ "openvibe.coupons"
+ ],
+ "publicOrigin": "https://openvibe.coupons",
+ "health": "/api/health",
+ "ready": "/api/ready",
+ "capabilities": [
+ "coupons.coupon.submit",
+ "coupons.report.create",
+ "coupons.merchant.resolve",
+ "coupons.coupon.lookup",
+ "coupons.status.update",
+ "coupons.merchant.manage"
+ ],
+ "eventsProduced": [
+ "coupons.coupon.created",
+ "coupons.coupon.updated",
+ "coupons.coupon.expired",
+ "coupons.coupon.disabled",
+ "coupons.report.created",
+ "coupons.confidence.changed",
+ "coupons.index_document.upserted",
+ "coupons.index_document.deleted"
+ ],
"eventsConsumed": [],
"eventsConsumed": [],
- "namespacesOwned": [],
- "notes": "Coupon codes with merchant matching, restrictions, expiry and real-people validity reports. Charter only; no runtime."
+ "namespacesOwned": [
+ "coupons.*"
+ ],
+ "notes": "Port 4850. Owns coupon_merchants, coupon_merchant_domains, coupons, coupon_sources, coupon_restrictions, coupon_validation_reports, coupon_status_history, coupon_application_hints, coupon_watches in its own SQLite, plus extension_installs (cpx_ browser-helper tokens, scopes coupons.lookup and coupons.report, hashed, revocable). Consumes OpenVibe.Network (SSO, JWKS) and OpenVibe.Sources (sources.item.read, category coupons); publishes through OpenVibe.Events (events.event.publish); OpenVibe.Search reads coupons.index_document.* from Events. The browser helper lives in OpenVibers/OpenVibe.Extensions (ADR-023)."
}
}
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.24.0",
+ "version": "0.25.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
"types": "generated/typescript/index.d.ts",