Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions docs/docs/api-reference/api-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
---
id: api-endpoints
title: API Endpoints Reference
sidebar_label: API Endpoints
sidebar_position: 2
description: Comprehensive reference for Jet Admin's REST API routes, including schemas and auth requirements.
---

# API Endpoints Reference

Jet Admin exposes a comprehensive RESTful API for managing resources. The frontend SPA consumes these exact same endpoints.

*Note: All endpoints documented below are prefixed with `/api/v1/`.*

---

## Authentication (`/auth`)
Handles user identity and session management.

### `GET /auth/`
- **Description:** Returns the currently authenticated user's profile and permissions.
- **Auth:** Requires valid Session/JWT.
- **Side Effects:** Creates an audit log entry.

### `GET /auth/config/:tenantID`
- **Description:** Retrieves user-specific configuration for a given tenant.
- **Auth:** Requires valid Session/JWT.
- **Parameters:** `tenantID` (UUID in URL).

### `POST /auth/config/:tenantID`
- **Description:** Updates the user-specific configuration.
- **Auth:** Requires valid Session/JWT.
- **Parameters:** `tenantID` (UUID in URL).
- **Side Effects:** Updates DB record; creates an audit log entry.

---

## App Pages (`/tenants/:tenantID/appPages`)
Manages the individual views and widget layouts within an App.

### `GET /tenants/:tenantID/appPages`
- **Description:** Lists all pages for a specific tenant.
- **Auth:** Requires `tenant:appPage:list` permission.

### `POST /tenants/:tenantID/appPages`
- **Description:** Creates a new page.
- **Auth:** Requires `tenant:appPage:create` permission.
- **Body Schema:**
- `appPageTitle` (String, required)
- `appPageDescription` (String, optional)
- `appPageConfig` (Object, optional)

### `GET /tenants/:tenantID/appPages/:appPageID`
- **Description:** Retrieves the complete page definition, including the widget layout.
- **Auth:** Requires `tenant:appPage:read` permission.

### `PATCH /tenants/:tenantID/appPages/:appPageID`
- **Description:** Updates the page layout or configuration.
- **Auth:** Requires `tenant:appPage:update` permission.
- **Body Schema:** (Partial updates allowed)
- `appPageTitle` (String)
- `appPageConfig` (Object)

### `POST /tenants/:tenantID/appPages/:appPageID/clone`
- **Description:** Clones an existing page.
- **Auth:** Requires `tenant:appPage:clone` permission.

### `DELETE /tenants/:tenantID/appPages/:appPageID`
- **Description:** Deletes a page permanently.
- **Auth:** Requires `tenant:appPage:delete` permission.
- **Side Effects:** Cascading deletion of related layout records.

---

## Data Queries (`/tenants/:tenantID/queries`)
Manages the definitions and execution of data operations.

### `GET /tenants/:tenantID/queries`
- **Description:** Lists all saved queries.
- **Auth:** Requires `tenant:query:list` permission.

### `POST /tenants/:tenantID/queries`
- **Description:** Creates a new query definition.
- **Auth:** Requires `tenant:query:create` permission.
- **Body Schema:**
- `datasourceID` (UUID, required)
- `queryName` (String, required)
- `queryConfig` (Object, required)

### `GET /tenants/:tenantID/queries/:dataQueryID`
- **Description:** Retrieves a specific query definition.
- **Auth:** Requires `tenant:query:read` permission.

### `PATCH /tenants/:tenantID/queries/:dataQueryID`
- **Description:** Updates a query definition.
- **Auth:** Requires `tenant:query:update` permission.

### `POST /tenants/:tenantID/queries/:dataQueryID/run`
- **Description:** **(Critical Execution Endpoint)** Executes a saved query against its target datasource.
- **Auth:** Requires `tenant:query:read` permission.
- **Body Schema:**
- `inputs` (Object, optional) - Dynamic parameters injected into `{{bindings}}`.
- **Side Effects:** The backend connects to the external database/API, executes the command, runs any transformers, and returns the result.

### `PATCH /tenants/:tenantID/queries/queryTest`
- **Description:** Executes a query payload *without* saving it to the database. Useful for the builder's preview panel.
- **Auth:** Requires `tenant:query:test` permission.

---

## Workflows (`/tenants/:tenantID/workflow`)
Manages background processes and DAG definitions.

### `GET /tenants/:tenantID/workflow`
- **Description:** Lists workflow definitions.
- **Auth:** Requires `tenant:workflow:list` permission.

### `POST /tenants/:tenantID/workflow`
- **Description:** Creates a new workflow definition.
- **Auth:** Requires `tenant:workflow:create` permission.
- **Body Schema:**
- `title` (String, required)
- `workflowOptions` (Object, optional)

### `GET /tenants/:tenantID/workflow/:workflowID`
- **Description:** Retrieves a specific workflow definition, including nodes and edges.
- **Auth:** Requires `tenant:workflow:read` permission.

### `PATCH /tenants/:tenantID/workflow/:workflowID`
- **Description:** Updates the workflow DAG definition.
- **Auth:** Requires `tenant:workflow:update` permission.

### `POST /tenants/:tenantID/workflow/:workflowID/execute`
- **Description:** Triggers a saved workflow to run.
- **Auth:** Requires `tenant:workflow:execute` permission.
- **Side Effects:** Creates a `tblWorkflowInstances` record, enqueues pg-boss jobs, and returns an `instanceID` immediately (asynchronous execution).

### `POST /tenants/:tenantID/workflow/test`
- **Description:** Test-runs a workflow payload in memory without saving the definition.
- **Auth:** Requires `tenant:workflow:execute` permission.
- **Body Schema:**
- `nodes` (Array, required)
- `edges` (Array, required)
- `inputValues` (Object, optional)

### `GET /tenants/:tenantID/workflow/instances/:instanceID`
- **Description:** Retrieves the real-time status and complete XCom log payload for a specific execution instance.
- **Auth:** Requires `tenant:workflow:read` permission.
- **Response:** Includes `status`, `createdAt`, and `logs` array.

---

## Datasources (`/tenants/:tenantID/datasources`)
Manages integration connections. Credentials are encrypted upon save.

- `GET /tenants/:tenantID/datasources`: Lists datasources (passwords omitted).
- `POST /tenants/:tenantID/datasources`: Creates a new connection.
- `PATCH /tenants/:tenantID/datasources/:id`: Updates config/credentials.
- `DELETE /tenants/:tenantID/datasources/:id`: Deletes a datasource.
- `POST /tenants/:tenantID/datasources/test`: Tests connection reachability without saving.

## Listeners (`/tenants/:tenantID/listener`)
Manages incoming data streams and webhook ingestions.

- `GET /tenants/:tenantID/listener`: Lists active listeners.
- `POST /tenants/:tenantID/listener`: Creates a new listener definition.
- `PATCH /tenants/:tenantID/listener/:id`: Updates listener configuration.
- `DELETE /tenants/:tenantID/listener/:id`: Deletes a listener.

## Users & Roles (`/tenants/:tenantID/userManagement`, `/tenants/:tenantID/tenantRole`)
Manages RBAC and Tenant membership.

- `GET /tenants/:tenantID/userManagement/users`: Lists users.
- `PUT /tenants/:tenantID/userManagement/users/:id/role`: Updates user's assigned role.
- `GET /tenants/:tenantID/tenantRole`: Lists available roles.
- `POST /tenants/:tenantID/tenantRole`: Creates a custom role definition.

## System & Audit (`/system`, `/tenants/:tenantID/audit`)
Manages global settings and logs.

- `GET /system/health`: Basic health check endpoint.
- `GET /tenants/:tenantID/audit`: Retrieves paginated audit logs. Payloads containing passwords or tokens are automatically masked as `[FILTERED]` by middleware.
80 changes: 33 additions & 47 deletions docs/docs/api-reference/authentication.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,47 @@
---
sidebar_position: 2
title: Authentication
description: Authentication and Authorization guide
id: authentication
title: Authentication & Session Management
sidebar_label: Authentication
sidebar_position: 1
description: How Jet Admin authenticates users and manages sessions.
---

# Authentication
# Authentication & Session Management

The Jet Admin API mainly uses **Firebase Authentication** for user identity and **API Keys** for programmatic access.
Jet Admin relies on industry-standard stateless authentication mechanisms to verify user identity securely while allowing horizontal scaling of the backend API.

## Firebase Authentication (Bearer Token)
## Authentication Model

Most endpoints require a valid Firebase ID token passed in the `Authorization` header.
Jet Admin primarily uses **JSON Web Tokens (JWT)** for authentication.

### Header Format
### Token Issuance Lifecycle
1. **Login Request:** A user submits their credentials (e.g., email and password) to the `/api/v1/auth/login` endpoint.
2. **Verification:** The backend verifies the password hash against the `tblUsers` record.
3. **Token Generation:** Upon success, the backend generates a signed JWT. The token payload typically includes the `userID` and basic claims.
4. **Delivery:** The token is returned to the client. *[VERIFY: Jet Admin may store this in `localStorage`, or in a secure `HttpOnly` cookie depending on environment configuration. Assume standard bearer token logic for APIs.]*
5. **Subsequent Requests:** The client includes the token in the `Authorization: Bearer <token>` header of every subsequent API request.

```http
Authorization: Bearer <FIREBASE_ID_TOKEN>
```
### Session Management & Expiry
- **Statelessness:** Because JWTs are self-contained and cryptographically signed, the backend does not need to look up a session ID in a database or Redis cache for every request.
- **Expiry:** Tokens have a built-in TTL (Time To Live). When a token expires, the client must obtain a new one.
- **Invalidation:** *[VERIFY: To truly revoke JWTs before expiry, Jet Admin might implement a token blocklist or rely on short TTLs combined with refresh tokens.]*

### How to obtain a token
## Onboarding & Invite Flow

1. Sign in using the client SDK (Frontend).
2. Retrieve the ID Token:
```javascript
const token = await auth().currentUser.getIdToken();
```
3. Include this token in all API requests.
Adding new users to a Jet Admin Tenant follows an invite-based onboarding flow.

### Permissions
1. **Invitation:** An existing Tenant Admin uses the UI to invite a new user via email.
2. **Token Creation:** The backend generates a secure, single-use, time-bound invite token and stores its hash in the database, associating it with the target email and `tenantID`.
3. **Email Delivery:** An email is sent to the user containing a magic link with the invite token.
4. **Registration:** The user clicks the link, bringing them to a registration page. They provide their name and establish a password.
5. **Consumption:** The backend validates the invite token, creates the `tblUsers` record, assigns the default role in `tblTenantUsers`, invalidates the invite token, and issues a standard JWT to log the user in immediately.

The user represented by the token must be a member of the target Tenant. Permissions are enforced by role-based access control (RBAC) within the tenant.
## API Key Authentication (Machine-to-Machine)

---

## API Key Authentication

For server-to-server communication or external integrations, you can use an API Key.

### Header Format

```http
x-api-key: <YOUR_API_KEY>
```

### Managing API Keys

You can generate and manage API Keys via the **Tenant Settings > API Keys** section in the Jet Admin dashboard and then use those keys for supported backend endpoints.

> **Note**: API Keys have specific permissions scopes assigned to them. Ensure your key has the necessary permissions for the endpoints you are calling.

---

## Common Errors
For integrations that require external systems to trigger Jet Admin processes (e.g., triggering a Workflow via webhook, or an external script triggering a Query), User JWTs are inappropriate.

| Code | Status | Description |
|------|--------|-------------|
| `USER_AUTH_TOKEN_NOT_FOUND` | 401 | Missing Authorization header |
| `USER_AUTH_TOKEN_EXPIRED` | 401 | Token has expired |
| `INVALID_API_KEY` | 401 | Invalid or inactive API key |
| `PERMISSION_DENIED` | 403 | User/Key does not have required permissions |
Jet Admin utilizes **API Keys** (`tblAPIKeys`) for this purpose.
- API Keys are generated via the dashboard and assigned specific permissions or roles.
- The raw key is shown only once upon creation; the backend stores a cryptographic hash.
- External systems pass the API Key in a designated header (e.g., `X-Jet-Admin-Api-Key` or standard `Authorization`).
- The backend middleware identifies the API key, looks up the associated tenant and permissions, and authorizes the request.
64 changes: 64 additions & 0 deletions docs/docs/architecture/application-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
id: application-model
title: Application & Page Model
sidebar_label: Application Model
sidebar_position: 2
description: Understanding the Application lifecycle, Page routing, and Layout engine.
---

# Application & Page Model

At the highest level of Jet Admin's UI hierarchy are **Applications** and **Pages**. Understanding how these are modeled and rendered is key to understanding the frontend architecture.

## Application Lifecycle

An **Application** (or App) serves as a logical container for your tools.

1. **Creation:** An app is created within a specific Tenant. The creator is granted Owner permissions.
2. **Metadata Storage:** The app metadata (name, description, theme settings) is persisted in the PostgreSQL database.
3. **Configuration:** Developers add Pages, configure local queries, and bind datasources to the app.
4. **Publishing (Versioning):** *[VERIFY: Does Jet Admin support explicit app versioning/publishing flows, or are changes live immediately? Assuming live based on standard SPA behavior unless specified otherwise.]* Changes made in the builder are saved to the database and immediately reflect for users with "Viewer" access reloading the app.
5. **Deletion:** Deleting an app cascades to delete all its associated Pages.

## Page Model

A **Page** represents a single routable view within an Application.

### Schema and Routing
In the database (`tblAppPages`), a page stores:
- `appPageID`: Unique identifier.
- `appPageTitle`: Display name for the navigation sidebar.
- `appPageConfig`: JSON blob containing the widget layout and page-level settings.

Routing is handled client-side by React Router. The URL structure typically follows:
`/app/:appId/page/:pageId`

### State Scoping
Jet Admin differentiates between global state and page-level state:
- **Global State:** Information about the authenticated user, current tenant, and global UI theme. Managed in `useAuthStore` and `useUIStore`.
- **Page-Level State (Widget State):** The specific data, selections, and input values of the widgets currently mounted on the page. When a user navigates away from Page A to Page B, the widget state for Page A is unmounted and cleared. This ensures pages do not leak memory or cross-contaminate state.

### Page Load Lifecycle
When a user navigates to a page:
1. The frontend fetches the `appPageConfig` from the backend.
2. The layout engine mounts the widget components according to the config.
3. Any queries configured to "Run on Page Load" are triggered concurrently.
4. As queries resolve, TanStack Query updates the cache, triggering reactive re-renders of the mounted widgets.

## Layout Engine

The Jet Admin canvas uses a grid-based layout engine to render widgets.

### Grid System
The canvas is subdivided into a grid (typically 12 or 24 columns). When a widget is placed on the canvas, its configuration saves:
- `x`, `y` coordinates (grid cells, not pixels).
- `width`, `height` (span in grid cells).

### Rendering Pipeline
1. The `appPageConfig` contains an array or tree of widget definitions.
2. The layout engine iterates over these definitions.
3. For each definition, it looks up the React component in the **Widget Registry** (e.g., mapping `type: 'table'` to the `<TableWidget />` component).
4. The widget is rendered within a draggable/resizable bounding box (when in Edit mode) or statically positioned (when in View mode).

### Persistence and Restoration
When a user drags a widget or resizes it, the frontend calculates the new `x/y/w/h` values. These changes are debounced and patched to the backend `appPageConfig` JSON column. On subsequent loads, the engine reads these values to restore the exact layout.
Loading