Some checks failed
deploy-site / deploy (push) Failing after 3m26s
The manual install path still needed 7-Zip, which the target machine does not have, so "installable without a certificate" was not yet true. The channel now also publishes the app as byte-split zip parts, and the install script joins them and extracts with the built-in Windows Expand-Archive after verifying every part and the joined archive. Version 1.3.1 republishes the channel from a single build, because a version's artifacts can only match one build and published volumes are never overwritten.
782 lines
20 KiB
JSON
782 lines
20 KiB
JSON
{
|
|
"openapi": "3.0.3",
|
|
"info": {
|
|
"title": "D3RO-VOICE Admin API",
|
|
"description": "Admin CRM Edge Functions for user management, subscription CRUD, payment history, and audit logs.",
|
|
"version": "1.3.1"
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "https://{supabaseRef}.supabase.co/functions/v1",
|
|
"description": "Production",
|
|
"variables": {
|
|
"supabaseRef": {
|
|
"default": "your-project-ref"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"url": "http://localhost:54321/functions/v1",
|
|
"description": "Local development"
|
|
}
|
|
],
|
|
"security": [
|
|
{
|
|
"BearerAuth": []
|
|
}
|
|
],
|
|
"components": {
|
|
"securitySchemes": {
|
|
"BearerAuth": {
|
|
"type": "http",
|
|
"scheme": "bearer",
|
|
"bearerFormat": "JWT",
|
|
"description": "Supabase access_token (admin or super_admin role required)"
|
|
}
|
|
},
|
|
"schemas": {
|
|
"Profile": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"nullable": true
|
|
},
|
|
"avatar_url": {
|
|
"type": "string",
|
|
"nullable": true
|
|
},
|
|
"locale": {
|
|
"type": "string"
|
|
},
|
|
"tier": {
|
|
"type": "string",
|
|
"enum": [
|
|
"free",
|
|
"pro",
|
|
"pro_plus"
|
|
]
|
|
},
|
|
"role": {
|
|
"type": "string",
|
|
"enum": [
|
|
"user",
|
|
"admin",
|
|
"super_admin"
|
|
]
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"Subscription": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"user_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"tier": {
|
|
"type": "string",
|
|
"enum": [
|
|
"free",
|
|
"pro",
|
|
"pro_plus"
|
|
]
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"active",
|
|
"canceled",
|
|
"past_due",
|
|
"expired"
|
|
]
|
|
},
|
|
"payment_provider": {
|
|
"type": "string",
|
|
"enum": [
|
|
"none",
|
|
"stripe",
|
|
"payple"
|
|
]
|
|
},
|
|
"current_period_start": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true
|
|
},
|
|
"current_period_end": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"nullable": true
|
|
},
|
|
"overage_credits": {
|
|
"type": "integer"
|
|
},
|
|
"admin_note": {
|
|
"type": "string",
|
|
"nullable": true
|
|
},
|
|
"renewal_failures": {
|
|
"type": "integer"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"AuditLog": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer"
|
|
},
|
|
"admin_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"admin_name": {
|
|
"type": "string"
|
|
},
|
|
"action": {
|
|
"type": "string"
|
|
},
|
|
"target_type": {
|
|
"type": "string"
|
|
},
|
|
"target_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"before_data": {
|
|
"type": "object",
|
|
"nullable": true
|
|
},
|
|
"after_data": {
|
|
"type": "object",
|
|
"nullable": true
|
|
},
|
|
"memo": {
|
|
"type": "string"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"Error": {
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"paths": {
|
|
"/admin-users": {
|
|
"get": {
|
|
"tags": [
|
|
"Users"
|
|
],
|
|
"summary": "List or get user details",
|
|
"description": "Admin+. Pass userId for single user detail, or omit for paginated list.",
|
|
"parameters": [
|
|
{
|
|
"name": "userId",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"description": "Specific user ID for detail view"
|
|
},
|
|
{
|
|
"name": "page",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 1
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 20
|
|
}
|
|
},
|
|
{
|
|
"name": "search",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string"
|
|
},
|
|
"description": "Name search (ilike)"
|
|
},
|
|
{
|
|
"name": "role",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"user",
|
|
"admin",
|
|
"super_admin"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "User list or detail",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"profiles": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Profile"
|
|
}
|
|
},
|
|
"total": {
|
|
"type": "integer"
|
|
},
|
|
"page": {
|
|
"type": "integer"
|
|
},
|
|
"limit": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"profile": {
|
|
"$ref": "#/components/schemas/Profile"
|
|
},
|
|
"subscription": {
|
|
"$ref": "#/components/schemas/Subscription"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Not admin",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/Error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"tags": [
|
|
"Users"
|
|
],
|
|
"summary": "Change user role",
|
|
"description": "Super admin only. Changes both auth.users.app_metadata.role and profiles.role.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"userId",
|
|
"newRole",
|
|
"memo"
|
|
],
|
|
"properties": {
|
|
"userId": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"newRole": {
|
|
"type": "string",
|
|
"enum": [
|
|
"user",
|
|
"admin",
|
|
"super_admin"
|
|
]
|
|
},
|
|
"memo": {
|
|
"type": "string",
|
|
"description": "Required reason for audit log"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Role changed successfully"
|
|
},
|
|
"403": {
|
|
"description": "Not super_admin"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/admin-subscriptions": {
|
|
"get": {
|
|
"tags": [
|
|
"Subscriptions"
|
|
],
|
|
"summary": "List or get subscription details",
|
|
"parameters": [
|
|
{
|
|
"name": "userId",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
},
|
|
{
|
|
"name": "page",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 1
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 20
|
|
}
|
|
},
|
|
{
|
|
"name": "status",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"active",
|
|
"canceled",
|
|
"past_due",
|
|
"expired"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"name": "tier",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"free",
|
|
"pro",
|
|
"pro_plus"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Subscription list or detail"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"tags": [
|
|
"Subscriptions"
|
|
],
|
|
"summary": "Create subscription (VIP grant / record recovery)",
|
|
"description": "Super admin only.",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"userId",
|
|
"tier",
|
|
"memo"
|
|
],
|
|
"properties": {
|
|
"userId": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"tier": {
|
|
"type": "string",
|
|
"enum": [
|
|
"free",
|
|
"pro",
|
|
"pro_plus"
|
|
]
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"active",
|
|
"canceled",
|
|
"past_due",
|
|
"expired"
|
|
],
|
|
"default": "active"
|
|
},
|
|
"currentPeriodEnd": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"adminNote": {
|
|
"type": "string"
|
|
},
|
|
"memo": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Subscription created"
|
|
},
|
|
"409": {
|
|
"description": "Subscription already exists"
|
|
}
|
|
}
|
|
},
|
|
"patch": {
|
|
"tags": [
|
|
"Subscriptions"
|
|
],
|
|
"summary": "Update subscription",
|
|
"description": "Super admin only.",
|
|
"parameters": [
|
|
{
|
|
"name": "userId",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"memo"
|
|
],
|
|
"properties": {
|
|
"tier": {
|
|
"type": "string",
|
|
"enum": [
|
|
"free",
|
|
"pro",
|
|
"pro_plus"
|
|
]
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"active",
|
|
"canceled",
|
|
"past_due",
|
|
"expired"
|
|
]
|
|
},
|
|
"currentPeriodEnd": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"overageCredits": {
|
|
"type": "integer"
|
|
},
|
|
"adminNote": {
|
|
"type": "string"
|
|
},
|
|
"memo": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Subscription updated"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": [
|
|
"Subscriptions"
|
|
],
|
|
"summary": "Soft-delete subscription",
|
|
"description": "Super admin only. Sets status=expired, tier=free.",
|
|
"parameters": [
|
|
{
|
|
"name": "userId",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": [
|
|
"memo"
|
|
],
|
|
"properties": {
|
|
"memo": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Subscription soft-deleted"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/admin-payments": {
|
|
"get": {
|
|
"tags": [
|
|
"Payments"
|
|
],
|
|
"summary": "Get payment history for a user",
|
|
"description": "Admin+. Returns DB subscription data + audit logs. Pass source=payple for Payple API history.",
|
|
"parameters": [
|
|
{
|
|
"name": "userId",
|
|
"in": "query",
|
|
"required": true,
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
},
|
|
{
|
|
"name": "source",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"db",
|
|
"payple"
|
|
]
|
|
},
|
|
"description": "Add 'payple' to also fetch from Payple API"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Payment history",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"subscription": {
|
|
"$ref": "#/components/schemas/Subscription"
|
|
},
|
|
"auditLogs": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/AuditLog"
|
|
}
|
|
},
|
|
"paypleHistory": {
|
|
"type": "object",
|
|
"description": "Payple API response (when source=payple)"
|
|
},
|
|
"paypleError": {
|
|
"type": "string",
|
|
"description": "Error message if Payple API call failed"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/admin-audit-log": {
|
|
"get": {
|
|
"tags": [
|
|
"Audit Log"
|
|
],
|
|
"summary": "List or get audit log entries",
|
|
"description": "Admin+. Pass id for single entry detail.",
|
|
"parameters": [
|
|
{
|
|
"name": "id",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer"
|
|
},
|
|
"description": "Specific log entry ID"
|
|
},
|
|
{
|
|
"name": "page",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 1
|
|
}
|
|
},
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "integer",
|
|
"default": 20
|
|
}
|
|
},
|
|
{
|
|
"name": "target_type",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"enum": [
|
|
"subscription",
|
|
"profile"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"name": "admin_id",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
},
|
|
{
|
|
"name": "target_id",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
}
|
|
},
|
|
{
|
|
"name": "from",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date"
|
|
},
|
|
"description": "Start date (YYYY-MM-DD)"
|
|
},
|
|
{
|
|
"name": "to",
|
|
"in": "query",
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "date"
|
|
},
|
|
"description": "End date (YYYY-MM-DD)"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Audit log list or detail",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"logs": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/AuditLog"
|
|
}
|
|
},
|
|
"total": {
|
|
"type": "integer"
|
|
},
|
|
"page": {
|
|
"type": "integer"
|
|
},
|
|
"limit": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"log": {
|
|
"$ref": "#/components/schemas/AuditLog"
|
|
},
|
|
"admin": {
|
|
"$ref": "#/components/schemas/Profile"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|