605 lines
20 KiB
YAML
605 lines
20 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Insforge Tables API
|
|
version: 1.0.0
|
|
|
|
paths:
|
|
/api/database/tables:
|
|
get:
|
|
summary: List Tables
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
responses:
|
|
'200':
|
|
description: List of table names
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example:
|
|
- "posts"
|
|
- "comments"
|
|
- "categories"
|
|
|
|
post:
|
|
summary: Create Table
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- tableName
|
|
- columns
|
|
properties:
|
|
tableName:
|
|
type: string
|
|
columns:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required:
|
|
- name
|
|
- type
|
|
- nullable
|
|
properties:
|
|
name:
|
|
type: string
|
|
type:
|
|
type: string
|
|
enum: [string, datetime, integer, float, boolean, uuid, json, file]
|
|
nullable:
|
|
type: boolean
|
|
unique:
|
|
type: boolean
|
|
defaultValue:
|
|
type: string
|
|
foreignKeys:
|
|
type: array
|
|
description: Table-level foreign key constraints
|
|
items:
|
|
$ref: '#/components/schemas/ForeignKeyConstraint'
|
|
rlsEnabled:
|
|
type: boolean
|
|
default: false
|
|
description: Enable Row Level Security on the table
|
|
responses:
|
|
'201':
|
|
description: Table created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
table_name:
|
|
type: string
|
|
example:
|
|
message: "Table created successfully"
|
|
tableName: "posts"
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "VALIDATION_ERROR"
|
|
message: "Table name already exists"
|
|
statusCode: 400
|
|
nextActions: "Choose a different table name"
|
|
'422':
|
|
description: Unprocessable entity
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "INVALID_FIELD_TYPE"
|
|
message: "Invalid field type: 'text'. Valid types are: string, integer, float, boolean, datetime, uuid, json, file"
|
|
statusCode: 422
|
|
nextActions: "Use one of the valid field types"
|
|
|
|
/api/database/tables/{tableName}/schema:
|
|
get:
|
|
summary: Get Table Schema
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
parameters:
|
|
- name: tableName
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Table schema
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
table_name:
|
|
type: string
|
|
columns:
|
|
type: array
|
|
items:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
type:
|
|
type: string
|
|
nullable:
|
|
type: boolean
|
|
unique:
|
|
type: boolean
|
|
default:
|
|
type: string
|
|
nullable: true
|
|
isPrimaryKey:
|
|
type: boolean
|
|
foreignKeys:
|
|
type: array
|
|
description: Table-level foreign key constraints (one entry per constraint)
|
|
items:
|
|
$ref: '#/components/schemas/ForeignKeyConstraint'
|
|
example:
|
|
tableName: "posts"
|
|
columns:
|
|
- name: "id"
|
|
type: "uuid"
|
|
nullable: false
|
|
unique: true
|
|
default: "gen_random_uuid()"
|
|
isPrimaryKey: true
|
|
- name: "title"
|
|
type: "string"
|
|
nullable: false
|
|
unique: false
|
|
default: null
|
|
isPrimaryKey: false
|
|
- name: "userId"
|
|
type: "uuid"
|
|
nullable: false
|
|
unique: false
|
|
default: null
|
|
isPrimaryKey: false
|
|
foreignKeys:
|
|
- constraintName: "fk_userId_auth_users_id"
|
|
referenceTable: "auth.users"
|
|
referenceColumns:
|
|
- sourceColumn: "userId"
|
|
referenceColumn: "id"
|
|
onDelete: "CASCADE"
|
|
onUpdate: "CASCADE"
|
|
'404':
|
|
description: Table not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "TABLE_NOT_FOUND"
|
|
message: "Table 'nonexistent' does not exist"
|
|
statusCode: 404
|
|
nextActions: "Check table name and try again"
|
|
|
|
patch:
|
|
summary: Update Table Schema
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
parameters:
|
|
- name: tableName
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
addColumns:
|
|
type: array
|
|
description: Add new columns to the table
|
|
items:
|
|
type: object
|
|
required:
|
|
- columnName
|
|
- type
|
|
properties:
|
|
columnName:
|
|
type: string
|
|
description: Name of the new column
|
|
type:
|
|
type: string
|
|
enum: [string, integer, float, boolean, datetime, uuid, json, file]
|
|
description: Data type of the column
|
|
isNullable:
|
|
type: boolean
|
|
default: true
|
|
description: Whether the column allows NULL values
|
|
isUnique:
|
|
type: boolean
|
|
default: false
|
|
description: Whether the column values must be unique
|
|
defaultValue:
|
|
type: string
|
|
description: Default value for the column
|
|
dropColumns:
|
|
type: array
|
|
description: Remove columns from the table
|
|
items:
|
|
type: string
|
|
description: Name of the column to drop
|
|
updateColumns:
|
|
type: array
|
|
description: Modify existing columns (rename or change default)
|
|
items:
|
|
type: object
|
|
required:
|
|
- columnName
|
|
properties:
|
|
columnName:
|
|
type: string
|
|
description: Current name of the column
|
|
newColumnName:
|
|
type: string
|
|
description: New name for the column (optional)
|
|
minLength: 1
|
|
maxLength: 64
|
|
defaultValue:
|
|
type: string
|
|
description: New default value for the column (optional)
|
|
addForeignKeys:
|
|
type: array
|
|
description: Add foreign key constraints (one entry per constraint; composite keys list multiple column mappings)
|
|
items:
|
|
$ref: '#/components/schemas/ForeignKeyConstraint'
|
|
dropForeignKeys:
|
|
type: array
|
|
description: Constraint names of foreign keys to drop
|
|
items:
|
|
type: string
|
|
description: Name of the foreign key constraint to drop
|
|
renameTable:
|
|
type: object
|
|
description: Rename the table
|
|
required:
|
|
- newTableName
|
|
properties:
|
|
newTableName:
|
|
type: string
|
|
description: New name for the table
|
|
minLength: 1
|
|
maxLength: 64
|
|
responses:
|
|
'200':
|
|
description: Table schema updated successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
description: Success message
|
|
tableName:
|
|
type: string
|
|
description: Name of the updated table
|
|
operations:
|
|
type: array
|
|
description: List of operations performed
|
|
items:
|
|
type: string
|
|
example:
|
|
message: "Table schema updated successfully"
|
|
tableName: "posts"
|
|
operations:
|
|
- "added 2 columns"
|
|
- "dropped 1 columns"
|
|
- "renamed 1 columns"
|
|
- "added 1 foreign keys"
|
|
- "dropped 1 foreign keys"
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
columnExists:
|
|
value:
|
|
error: "COLUMN_EXISTS"
|
|
message: "Column 'title' already exists in table 'posts'"
|
|
statusCode: 400
|
|
nextActions: "Choose a different column name or drop it first"
|
|
columnNotFound:
|
|
value:
|
|
error: "COLUMN_NOT_FOUND"
|
|
message: "Column 'nonexistent' not found in table 'posts'"
|
|
statusCode: 400
|
|
nextActions: "Check column name with GET /api/tables/{tableName}/schema"
|
|
foreignKeyExists:
|
|
value:
|
|
error: "FOREIGN_KEY_EXISTS"
|
|
message: "Foreign key on column 'user_id' already exists"
|
|
statusCode: 400
|
|
nextActions: "Drop the existing foreign key first or use a different column"
|
|
'404':
|
|
description: Table not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "TABLE_NOT_FOUND"
|
|
message: "Table 'nonexistent' does not exist"
|
|
statusCode: 404
|
|
nextActions: "Check table name and try again"
|
|
|
|
/api/database/tables/{tableName}:
|
|
delete:
|
|
summary: Delete Table
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
parameters:
|
|
- name: tableName
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Table deleted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
table_name:
|
|
type: string
|
|
example:
|
|
message: "Table deleted successfully"
|
|
tableName: "posts"
|
|
'404':
|
|
description: Table not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "TABLE_NOT_FOUND"
|
|
message: "Table 'nonexistent' does not exist"
|
|
statusCode: 404
|
|
nextActions: "Check table name and try again"
|
|
|
|
/api/database/migrations:
|
|
get:
|
|
summary: List Database Migrations
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
responses:
|
|
'200':
|
|
description: List successful custom migrations
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- migrations
|
|
properties:
|
|
migrations:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Migration'
|
|
example:
|
|
migrations:
|
|
- version: "20260416170500"
|
|
name: "create_posts_table"
|
|
statements:
|
|
- "CREATE TABLE posts (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title TEXT NOT NULL);"
|
|
createdAt: "2026-04-16T17:05:00.000Z"
|
|
|
|
post:
|
|
summary: Create and Execute Database Migration
|
|
tags:
|
|
- Admin
|
|
security:
|
|
- bearerAuth: []
|
|
- apiKey: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- version
|
|
- name
|
|
- sql
|
|
properties:
|
|
version:
|
|
type: string
|
|
description: Numeric migration version. Accepts Drizzle-style sequential prefixes (e.g. `0001`) or a `YYYYMMDDHHmmss` timestamp. Versions are compared numerically.
|
|
pattern: '^\d{1,64}$'
|
|
maxLength: 64
|
|
name:
|
|
type: string
|
|
description: Migration name
|
|
minLength: 1
|
|
sql:
|
|
type: string
|
|
description: SQL text to parse and execute immediately
|
|
minLength: 1
|
|
example:
|
|
version: "20260416170500"
|
|
name: "create_posts_table"
|
|
sql: "CREATE TABLE posts (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title TEXT NOT NULL);"
|
|
responses:
|
|
'201':
|
|
description: Migration executed and recorded successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: '#/components/schemas/Migration'
|
|
- type: object
|
|
required:
|
|
- message
|
|
properties:
|
|
message:
|
|
type: string
|
|
example:
|
|
version: "20260416170500"
|
|
name: "create_posts_table"
|
|
statements:
|
|
- "CREATE TABLE posts (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title TEXT NOT NULL);"
|
|
createdAt: "2026-04-16T17:05:00.000Z"
|
|
message: "Migration executed successfully"
|
|
'400':
|
|
description: Invalid migration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
invalidPayload:
|
|
value:
|
|
error: "INVALID_INPUT"
|
|
message: "sql: Migration SQL is required"
|
|
statusCode: 400
|
|
transactionStatement:
|
|
value:
|
|
error: "DATABASE_FORBIDDEN"
|
|
message: "Custom migrations cannot manage their own transactions."
|
|
statusCode: 400
|
|
'409':
|
|
description: Migration version already exists or is not newer than the latest applied migration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error: "ALREADY_EXISTS"
|
|
message: "Migration version already exists."
|
|
statusCode: 409
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
apiKey:
|
|
type: apiKey
|
|
in: header
|
|
name: X-API-Key
|
|
|
|
schemas:
|
|
ForeignKeyConstraint:
|
|
type: object
|
|
description: A table-level foreign key constraint. One entry per constraint; composite keys list multiple column mappings.
|
|
required:
|
|
- referenceTable
|
|
- referenceColumns
|
|
- onDelete
|
|
- onUpdate
|
|
properties:
|
|
constraintName:
|
|
type: string
|
|
description: Constraint name. Returned when reading the schema; derived by the backend on create.
|
|
referenceTable:
|
|
type: string
|
|
minLength: 1
|
|
description: Table being referenced
|
|
referenceColumns:
|
|
type: array
|
|
minItems: 1
|
|
description: Ordered (source → reference) column pairs
|
|
items:
|
|
type: object
|
|
required:
|
|
- sourceColumn
|
|
- referenceColumn
|
|
properties:
|
|
sourceColumn:
|
|
type: string
|
|
description: Column in the current table
|
|
referenceColumn:
|
|
type: string
|
|
description: Column in the referenced table
|
|
onDelete:
|
|
type: string
|
|
enum: [CASCADE, SET NULL, SET DEFAULT, NO ACTION, RESTRICT]
|
|
onUpdate:
|
|
type: string
|
|
enum: [CASCADE, SET NULL, SET DEFAULT, NO ACTION, RESTRICT]
|
|
Migration:
|
|
type: object
|
|
required:
|
|
- version
|
|
- name
|
|
- statements
|
|
- createdAt
|
|
properties:
|
|
version:
|
|
type: string
|
|
pattern: '^\d{1,64}$'
|
|
name:
|
|
type: string
|
|
statements:
|
|
type: array
|
|
items:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error
|
|
- message
|
|
- statusCode
|
|
properties:
|
|
error:
|
|
type: string
|
|
description: Error code for programmatic handling
|
|
message:
|
|
type: string
|
|
description: Human-readable error message
|
|
statusCode:
|
|
type: integer
|
|
description: HTTP status code
|
|
nextActions:
|
|
type: string
|
|
description: Suggested action to resolve the error
|