Skip to main content

Ownership

Manage query ownership and transfer queries between users and teams.

Query Ownership Overview

Every query has an ownerId that determines:

  • Default Permissions - Owner has full access
  • Team Access - Team members inherit access via roles
  • Sharing Base - Who can grant additional shares
  • Natural ID - Slug-based ID includes owner

Ownership can be:

  • User - Individual user account (john.doe)
  • Team - Team identifier (team:analytics)

GET /api/queries/{id}/owner

Get the owner (user or team) of a query.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringQuery ID (UUID) or natural ID

Response (User Owner):

{
"id": "john.doe",
"username": "john.doe",
"displayName": "John Doe",
"email": "john.doe@company.com",
"avatar": "/api/users/john.doe/avatar",
"_links": {
"self": { "href": "/api/users/john.doe" }
}
}

Response (Team Owner):

{
"id": "team:analytics",
"name": "Analytics Team",
"slug": "analytics",
"description": "Data analytics and reporting team",
"memberCount": 12,
"_links": {
"self": { "href": "/api/teams/team:analytics" }
}
}

PUT /api/queries/{id}/owner

Transfer ownership of a query to a different user or team.

Authentication: Required Permission: query:write

Path Parameters:

ParameterTypeDescription
idstringQuery ID (UUID) or natural ID

Request Body:

{
"id": "team:analytics"
}

Or:

{
"username": "jane.smith"
}

Validation:

Provide either:

  • id - Principal ID (user or team)
  • username - User username

Response:

Returns the updated query with new owner.

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"naturalId": "team:analytics:sales-query",
"name": "Sales Analysis Query",
"ownerId": "team:analytics",
"updatedAt": "2024-02-09T12:00:00Z",
"_links": {
"self": { "href": "/api/queries/team:analytics:sales-query" }
}
}

Activity Tracking:

Transferring ownership creates a queryAssigned activity entry.

Natural ID Change

Transferring ownership changes the query's natural ID from oldOwner:slug to newOwner:slug. Update any references or bookmarks.


Ownership Best Practices

When to Use Team Ownership

ScenarioOwnership Type
Departmental queriesTeam
Personal/experimental queriesUser
Shared reporting queriesTeam
Production queriesTeam
Draft/development queriesUser
Administrative queriesTeam (admin team)

Transfer Workflow

  1. Verify Permissions - Ensure you have write access to the query
  2. Notify Stakeholders - Inform users of ownership change
  3. Transfer Ownership - Use PUT /api/queries/{id}/owner
  4. Update Documentation - Update any references to old natural ID
  5. Verify Access - Ensure new owner has necessary datasource access

Team Ownership Advantages

  1. Continuity - Queries persist when users leave
  2. Shared Responsibility - Team members can maintain queries
  3. Access Management - Automatic role-based permissions
  4. Organization - Queries grouped by team/department
  5. Discoverability - Easy to find team-related queries

Ownership Scenarios

Transfer User Query to Team

# User creates a query
POST /api/queries
{
"name": "Sales Analysis",
"language": "sql",
"datasourceId": "mysql-prod",
"payload": { "sql": "SELECT * FROM sales" }
}

# Query is owned by current user
# naturalId: john.doe:sales-analysis

# Transfer to team when promoting to production
PUT /api/queries/john.doe:sales-analysis/owner
{
"id": "team:analytics"
}

# Query now team-owned
# naturalId: team:analytics:sales-analysis

Transfer Between Teams

# Query currently owned by Analytics team
GET /api/queries/team:analytics:revenue-query

# Transfer to Finance team
PUT /api/queries/team:analytics:revenue-query/owner
{
"id": "team:finance"
}

# Query now owned by Finance
# naturalId: team:finance:revenue-query

Assign to Specific User

# Make a specific user responsible for maintenance
PUT /api/queries/team:analytics:sales-query/owner
{
"username": "jane.smith"
}

# Query now owned by Jane
# naturalId: jane.smith:sales-query

Ownership and Permissions

Permission Inheritance

Ownership affects permissions:

Owner TypePermission Model
UserOwner has all permissions; others need explicit shares
TeamTeam members get role-based permissions; non-members need shares

Team Role Permissions

For team-owned queries:

RolePermissions
AdminAll permissions
PublisherRun, edit, share
Data WizardRun, edit (if embedded)
DesignerRun, edit (if ad-hoc)
MemberRun only

Ownership Transfer Permissions

To transfer ownership, you must:

  1. Have query:write permission on the query
  2. Verify the target principal exists
  3. Be the current owner OR team admin
Ownership vs Write Permission

Having write permission doesn't automatically grant ownership transfer rights. Ownership transfer is a privileged operation typically reserved for owners and team admins.


Natural ID Management

Natural ID Structure

  • User-owned: username:slug (e.g., john.doe:sales-query)
  • Team-owned: team:teamSlug:slug (e.g., team:analytics:sales-query)
  • UUID fallback: If no slug, uses UUID

Handling Natural ID Changes

When ownership changes, the natural ID changes. To maintain references:

// Before transfer - store UUID
const query = await GET('/api/queries/john.doe:sales-query');
const queryUuid = query.id;

// Transfer ownership
await PUT(`/api/queries/${queryUuid}/owner`, {
id: 'team:analytics'
});

// After transfer - use UUID or new natural ID
const updated = await GET(`/api/queries/${queryUuid}`);
console.log(updated.naturalId); // team:analytics:sales-query

Slug Conflicts

If the target owner already has a query with the same slug:

  1. Informer may auto-append a number: sales-query-2
  2. Or return a conflict error
  3. Consider renaming before transfer to avoid conflicts

Bulk Ownership Transfer

Transfer multiple queries at once:

// Get all user's queries
const queries = await GET('/api/queries?owner=john.doe');

// Transfer to team
for (const query of queries.items) {
await PUT(`/api/queries/${query.id}/owner`, {
id: 'team:analytics'
});
}

Ownership Audit

List Queries by Owner

# Get all queries owned by user
GET /api/queries?owner=john.doe

# Get all queries owned by team
GET /api/queries?owner=team:analytics

# Get all queries (admins only)
GET /api/queries

Find Orphaned Queries

Queries owned by deleted users/teams may need reassignment:

// Check owner validity
const query = await GET('/api/queries/unknown-user:old-query');
if (query.ownerId && !query.owner) {
// Owner doesn't exist - reassign
await PUT(`/api/queries/${query.id}/owner`, {
id: 'team:admin'
});
}

Security Considerations

  1. Verify Access - Ensure new owner has datasource access
  2. Audit Transfers - Review ownership changes via activity log
  3. Limit Transfer Permission - Restrict who can transfer ownership
  4. Team Ownership - Prefer team ownership for shared resources
  5. Document Ownership - Maintain documentation of query ownership policies