Files
multitenetsaas/specs/001-1-target-sectors/contracts/api.yaml
AHMET YILMAZ b3fff546e9
Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
project initialization
2025-10-05 02:37:33 +08:00

1331 lines
31 KiB
YAML

openapi: 3.0.0
info:
title: Multi-Tenant SaaS Platform API
description: API for Malaysian SME SaaS platform with industry-specific modules
version: 1.0.0
contact:
name: API Support
email: support@platform.com
servers:
- url: https://api.platform.com/v1
description: Production server
- url: https://staging-api.platform.com/v1
description: Staging server
- url: http://localhost:8000/v1
description: Development server
security:
- BearerAuth: []
paths:
# Authentication endpoints
/auth/login:
post:
summary: User login
tags: [Authentication]
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, password]
properties:
email:
type: string
format: email
password:
type: string
format: password
tenant_slug:
type: string
description: Tenant identifier for login
responses:
'200':
description: Login successful
content:
application/json:
schema:
type: object
properties:
access_token:
type: string
refresh_token:
type: string
user:
$ref: '#/components/schemas/User'
tenant:
$ref: '#/components/schemas/Tenant'
'401':
description: Invalid credentials
'404':
description: Tenant not found
/auth/logout:
post:
summary: User logout
tags: [Authentication]
responses:
'200':
description: Logout successful
'401':
description: Unauthorized
/auth/refresh:
post:
summary: Refresh access token
tags: [Authentication]
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [refresh_token]
properties:
refresh_token:
type: string
responses:
'200':
description: Token refreshed successfully
content:
application/json:
schema:
type: object
properties:
access_token:
type: string
'401':
description: Invalid refresh token
# Tenant management endpoints
/tenants:
get:
summary: List tenants (admin only)
tags: [Tenants]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: search
in: query
type: string
responses:
'200':
description: List of tenants
content:
application/json:
schema:
type: object
properties:
tenants:
type: array
items:
$ref: '#/components/schemas/Tenant'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create new tenant
tags: [Tenants]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, email, business_type]
properties:
name:
type: string
email:
type: string
format: email
phone:
type: string
address:
$ref: '#/components/schemas/Address'
business_type:
$ref: '#/components/schemas/BusinessType'
responses:
'201':
description: Tenant created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Tenant'
'400':
description: Invalid input
/tenants/{tenant_id}:
get:
summary: Get tenant details
tags: [Tenants]
parameters:
- name: tenant_id
in: path
required: true
type: string
responses:
'200':
description: Tenant details
content:
application/json:
schema:
$ref: '#/components/schemas/Tenant'
'404':
description: Tenant not found
put:
summary: Update tenant
tags: [Tenants]
parameters:
- name: tenant_id
in: path
required: true
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TenantUpdate'
responses:
'200':
description: Tenant updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Tenant'
'404':
description: Tenant not found
# User management endpoints
/users:
get:
summary: List users
tags: [Users]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: role
in: query
type: string
responses:
'200':
description: List of users
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create new user
tags: [Users]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, first_name, last_name, role]
properties:
email:
type: string
format: email
first_name:
type: string
last_name:
type: string
phone:
type: string
role:
$ref: '#/components/schemas/UserRole'
permissions:
type: array
items:
type: string
responses:
'201':
description: User created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid input
/users/{user_id}:
get:
summary: Get user details
tags: [Users]
parameters:
- name: user_id
in: path
required: true
type: string
responses:
'200':
description: User details
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
put:
summary: Update user
tags: [Users]
parameters:
- name: user_id
in: path
required: true
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserUpdate'
responses:
'200':
description: User updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
# Subscription management endpoints
/subscriptions:
get:
summary: List subscriptions
tags: [Subscriptions]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: status
in: query
type: string
responses:
'200':
description: List of subscriptions
content:
application/json:
schema:
type: object
properties:
subscriptions:
type: array
items:
$ref: '#/components/schemas/Subscription'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create new subscription
tags: [Subscriptions]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [tenant_id, plan_type, billing_cycle]
properties:
tenant_id:
type: string
plan_type:
$ref: '#/components/schemas/PlanType'
billing_cycle:
$ref: '#/components/schemas/BillingCycle'
payment_method:
type: string
module_ids:
type: array
items:
type: string
responses:
'201':
description: Subscription created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
'400':
description: Invalid input
/subscriptions/{subscription_id}:
get:
summary: Get subscription details
tags: [Subscriptions]
parameters:
- name: subscription_id
in: path
required: true
type: string
responses:
'200':
description: Subscription details
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
'404':
description: Subscription not found
put:
summary: Update subscription
tags: [Subscriptions]
parameters:
- name: subscription_id
in: path
required: true
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionUpdate'
responses:
'200':
description: Subscription updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
'404':
description: Subscription not found
# Module management endpoints
/modules:
get:
summary: List available modules
tags: [Modules]
parameters:
- name: industry
in: query
type: string
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
responses:
'200':
description: List of modules
content:
application/json:
schema:
type: object
properties:
modules:
type: array
items:
$ref: '#/components/schemas/Module'
pagination:
$ref: '#/components/schemas/Pagination'
/modules/{module_id}:
get:
summary: Get module details
tags: [Modules]
parameters:
- name: module_id
in: path
required: true
type: string
responses:
'200':
description: Module details
content:
application/json:
schema:
$ref: '#/components/schemas/Module'
'404':
description: Module not found
# Payment endpoints
/payments:
post:
summary: Process payment
tags: [Payments]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [subscription_id, amount, payment_method]
properties:
subscription_id:
type: string
amount:
type: number
format: decimal
currency:
type: string
default: MYR
payment_method:
type: string
description:
type: string
responses:
'201':
description: Payment processed successfully
content:
application/json:
schema:
$ref: '#/components/schemas/PaymentTransaction'
'400':
description: Invalid input
'402':
description: Payment failed
# Retail module endpoints
/retail/products:
get:
summary: List products (Retail module)
tags: [Retail]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: category
in: query
type: string
responses:
'200':
description: List of products
content:
application/json:
schema:
type: object
properties:
products:
type: array
items:
$ref: '#/components/schemas/Product'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create product (Retail module)
tags: [Retail]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: Product created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: Invalid input
/retail/sales:
post:
summary: Create sale (Retail module)
tags: [Retail]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SaleCreate'
responses:
'201':
description: Sale created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Sale'
'400':
description: Invalid input
# Healthcare module endpoints
/healthcare/patients:
get:
summary: List patients (Healthcare module)
tags: [Healthcare]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: search
in: query
type: string
responses:
'200':
description: List of patients
content:
application/json:
schema:
type: object
properties:
patients:
type: array
items:
$ref: '#/components/schemas/Patient'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create patient (Healthcare module)
tags: [Healthcare]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatientCreate'
responses:
'201':
description: Patient created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Patient'
'400':
description: Invalid input
/healthcare/appointments:
get:
summary: List appointments (Healthcare module)
tags: [Healthcare]
parameters:
- name: page
in: query
type: integer
default: 1
- name: limit
in: query
type: integer
default: 20
- name: date
in: query
type: string
format: date
responses:
'200':
description: List of appointments
content:
application/json:
schema:
type: object
properties:
appointments:
type: array
items:
$ref: '#/components/schemas/Appointment'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create appointment (Healthcare module)
tags: [Healthcare]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AppointmentCreate'
responses:
'201':
description: Appointment created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
'400':
description: Invalid input
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
# Core schemas
Tenant:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
slug:
type: string
email:
type: string
format: email
phone:
type: string
address:
$ref: '#/components/schemas/Address'
business_type:
$ref: '#/components/schemas/BusinessType'
subscription_plan:
$ref: '#/components/schemas/PlanType'
pricing_model:
$ref: '#/components/schemas/PricingModel'
status:
$ref: '#/components/schemas/TenantStatus'
logo_url:
type: string
format: uri
settings:
type: object
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
User:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
email:
type: string
format: email
first_name:
type: string
last_name:
type: string
phone:
type: string
role:
$ref: '#/components/schemas/UserRole'
status:
$ref: '#/components/schemas/UserStatus'
last_login:
type: string
format: date-time
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
mfa_enabled:
type: boolean
Subscription:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
plan_type:
$ref: '#/components/schemas/PlanType'
billing_cycle:
$ref: '#/components/schemas/BillingCycle'
status:
$ref: '#/components/schemas/SubscriptionStatus'
starts_at:
type: string
format: date-time
ends_at:
type: string
format: date-time
renews_at:
type: string
format: date-time
amount:
type: number
format: decimal
currency:
type: string
default: MYR
payment_method:
type: string
module_limit:
type: integer
user_limit:
type: integer
features:
type: object
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Module:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
slug:
type: string
description:
type: string
industry:
$ref: '#/components/schemas/BusinessType'
version:
type: string
status:
$ref: '#/components/schemas/ModuleStatus'
features:
type: object
requirements:
type: object
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
PaymentTransaction:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
subscription_id:
type: string
format: uuid
type:
$ref: '#/components/schemas/PaymentType'
amount:
type: number
format: decimal
currency:
type: string
default: MYR
status:
$ref: '#/components/schemas/PaymentStatus'
payment_method:
type: string
transaction_id:
type: string
description:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
# Retail module schemas
Product:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
name:
type: string
sku:
type: string
description:
type: string
category:
type: string
price:
type: number
format: decimal
cost:
type: number
format: decimal
stock_quantity:
type: integer
reorder_point:
type: integer
supplier_id:
type: string
format: uuid
status:
$ref: '#/components/schemas/ProductStatus'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Sale:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
invoice_number:
type: string
customer_id:
type: string
format: uuid
subtotal:
type: number
format: decimal
tax:
type: number
format: decimal
total:
type: number
format: decimal
payment_method:
type: string
status:
$ref: '#/components/schemas/SaleStatus'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
# Healthcare module schemas
Patient:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
medical_record_number:
type: string
first_name:
type: string
last_name:
type: string
ic_number:
type: string
date_of_birth:
type: string
format: date
gender:
$ref: '#/components/schemas/Gender'
phone:
type: string
email:
type: string
format: email
address:
$ref: '#/components/schemas/Address'
blood_type:
type: string
allergies:
type: array
items:
type: string
medical_conditions:
type: array
items:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Appointment:
type: object
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
patient_id:
type: string
format: uuid
doctor_id:
type: string
format: uuid
appointment_date:
type: string
format: date-time
duration:
type: integer
status:
$ref: '#/components/schemas/AppointmentStatus'
type:
$ref: '#/components/schemas/AppointmentType'
notes:
type: string
reminder_sent:
type: boolean
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
# Supporting schemas
Address:
type: object
properties:
street:
type: string
city:
type: string
state:
type: string
postal_code:
type: string
country:
type: string
default: Malaysia
Pagination:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
pages:
type: integer
# Enum schemas
BusinessType:
type: string
enum: [RETAIL, HEALTHCARE, EDUCATION, LOGISTICS, BEAUTY]
PlanType:
type: string
enum: [STARTER, GROWTH, PRO, ENTERPRISE]
BillingCycle:
type: string
enum: [MONTHLY, YEARLY, ONE_TIME]
PricingModel:
type: string
enum: [SUBSCRIPTION, PERPETUAL]
TenantStatus:
type: string
enum: [PENDING, ACTIVE, SUSPENDED, TERMINATED]
UserRole:
type: string
enum: [ADMIN, MANAGER, STAFF, VIEWER]
UserStatus:
type: string
enum: [PENDING, ACTIVE, INACTIVE, DISABLED]
SubscriptionStatus:
type: string
enum: [ACTIVE, CANCELLED, EXPIRED, PENDING]
ModuleStatus:
type: string
enum: [ACTIVE, INACTIVE, BETA]
PaymentType:
type: string
enum: [CHARGE, REFUND, CREDIT, ADJUSTMENT]
PaymentStatus:
type: string
enum: [PENDING, COMPLETED, FAILED, REFUNDED]
ProductStatus:
type: string
enum: [ACTIVE, INACTIVE, DISCONTINUED]
SaleStatus:
type: string
enum: [PENDING, COMPLETED, REFUNDED]
Gender:
type: string
enum: [MALE, FEMALE, OTHER]
AppointmentStatus:
type: string
enum: [SCHEDULED, CONFIRMED, COMPLETED, CANCELLED, NO_SHOW]
AppointmentType:
type: string
enum: [CONSULTATION, FOLLOW_UP, PROCEDURE]
# Request schemas
TenantUpdate:
type: object
properties:
name:
type: string
phone:
type: string
address:
$ref: '#/components/schemas/Address'
logo_url:
type: string
format: uri
settings:
type: object
UserUpdate:
type: object
properties:
first_name:
type: string
last_name:
type: string
phone:
type: string
role:
$ref: '#/components/schemas/UserRole'
permissions:
type: array
items:
type: string
SubscriptionUpdate:
type: object
properties:
plan_type:
$ref: '#/components/schemas/PlanType'
billing_cycle:
$ref: '#/components/schemas/BillingCycle'
payment_method:
type: string
module_ids:
type: array
items:
type: string
ProductCreate:
type: object
required: [name, sku, price, cost]
properties:
name:
type: string
sku:
type: string
description:
type: string
category:
type: string
price:
type: number
format: decimal
cost:
type: number
format: decimal
stock_quantity:
type: integer
reorder_point:
type: integer
supplier_id:
type: string
format: uuid
SaleCreate:
type: object
required: [customer_id, items]
properties:
customer_id:
type: string
format: uuid
items:
type: array
items:
type: object
properties:
product_id:
type: string
format: uuid
quantity:
type: integer
unit_price:
type: number
format: decimal
payment_method:
type: string
PatientCreate:
type: object
required: [first_name, last_name, ic_number, date_of_birth]
properties:
first_name:
type: string
last_name:
type: string
ic_number:
type: string
date_of_birth:
type: string
format: date
gender:
$ref: '#/components/schemas/Gender'
phone:
type: string
email:
type: string
format: email
address:
$ref: '#/components/schemas/Address'
blood_type:
type: string
allergies:
type: array
items:
type: string
medical_conditions:
type: array
items:
type: string
AppointmentCreate:
type: object
required: [patient_id, doctor_id, appointment_date, duration]
properties:
patient_id:
type: string
format: uuid
doctor_id:
type: string
format: uuid
appointment_date:
type: string
format: date-time
duration:
type: integer
type:
$ref: '#/components/schemas/AppointmentType'
notes:
type: string
# Error schemas
Error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: object
timestamp:
type: string
format: date-time
ValidationError:
type: object
properties:
code:
type: string
default: VALIDATION_ERROR
message:
type: string
errors:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
UnauthorizedError:
type: object
properties:
code:
type: string
default: UNAUTHORIZED
message:
type: string
timestamp:
type: string
format: date-time
NotFoundError:
type: object
properties:
code:
type: string
default: NOT_FOUND
message:
type: string
timestamp:
type: string
format: date-time