Apps Domain
The Apps domain provides endpoints for managing a client's applications. An app is a client-scoped record that links a client to a Catalog App and adds client-specific metadata such as favorite status and license tracking.
The underlying apps table is an overlay on the shared catalog_applications table. Catalog data (name, logo, vendor, categories) comes from the catalog; client-specific data (is_favorite, license_count) lives on the app record itself.
For embedding and endpoint design decisions, see the Design Guidelines.
Endpoints
| Endpoint | Method | Description |
|---|---|---|
| List Apps | GET | Paginated list of the client's apps |
| Get App | GET | Fetch a single app by ID |
| Update App | PATCH | Update client-specific fields (favorite, approved, license count) |
| Add Favorites | POST | Bulk add apps to favorites |
| Remove Favorites | POST | Bulk remove apps from favorites |
| Approve Apps | POST | Bulk approve apps |
| Reject Apps | POST | Bulk reject apps |
Why catalog_app is embedded
The catalog app is the identity of an app -- you need its name, logo, vendor, and categories to display anything meaningful. It passes all three conditions of the embedding rule:
| Relationship | Bounded? | Always needed? | Static? | Decision |
|---|---|---|---|---|
| App → CatalogApp | Yes (always 1) | Yes | Yes | Embed |
| CatalogApp → Vendor | Yes (always 1) | Yes | Yes | Embed (inside catalog_app) |
| CatalogApp → Categories | Yes (1–5) | Yes | Yes | Embed (inside catalog_app) |
The embedded catalog_app reuses the existing CatalogApp DTO. This avoids defining a near-identical Ref type and keeps the shape consistent across domains.
Data Transfer Objects (DTOs)
AppRef
Lightweight app reference for embedding inside analytics and cross-domain responses. Contains only the fields needed to identify and display an app in a table row or list item. Consumers call Get App for the full object.
The rule for what belongs in AppRef: ask "does every place this app appears as a non-primary resource need this field to render a meaningful row?" If yes, it belongs here. If only the app's own endpoints need it (e.g. vendor, categories, license count), it belongs in App only.
{
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"canonical_name": "Slack",
"logo": "https://cdn.example.com/logos/slack.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
}
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string (uuid) | No | Stable unique identifier for this client-app record |
canonical_name | string | No | Display name from the catalog |
logo | string | Yes | Logo URL from the catalog. null if no logo is available. |
type | string | No | Catalog app type (e.g. desktop, browser) |
is_favorite | boolean | No | Whether this app is marked as a favorite for the client |
is_approved | boolean | No | Whether this app is approved for use by the client |
DB source:
| DTO Field | DB Column |
|---|---|
id | apps.id |
canonical_name | catalog_applications.canonical_name (via apps.catalog_application_id) |
logo | catalog_applications.logo |
type | catalog_applications.type |
is_favorite | apps.is_favorite |
is_approved | apps.is_approved |
Used in: App Utilization (analytics domain)
App
Full client-app object returned by list and detail endpoints. Wraps the CatalogApp DTO with client-specific fields.
{
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"catalog_app": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"canonical_name": "Slack",
"description": "A messaging and collaboration platform for teams",
"display_colour": "#4A154B",
"logo": "https://cdn.example.com/logos/slack.png",
"type": "desktop",
"vendor": {
"id": "f6a7b8c9-d0e1-2345-fabc-678901234567",
"name": "Salesforce, Inc.",
"url": "https://www.salesforce.com"
},
"categories": [
{ "id": "a7b8c9d0-e1f2-3456-abcd-789012345678", "name": "Communication" }
],
"created_at": "2025-06-15T10:00:00.000Z",
"updated_at": "2026-02-10T09:15:00.000Z"
},
"is_favorite": true,
"is_approved": true,
"license_count": 25,
"created_at": "2026-01-15T10:00:00.000Z",
"updated_at": "2026-02-20T14:30:00.000Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string (uuid) | No | Stable unique identifier for this client-app record |
catalog_app | CatalogApp | No | The catalog application this record is linked to, with vendor and categories embedded |
is_favorite | boolean | No | Whether this app is marked as a favorite for the client |
is_approved | boolean | No | Whether this app is approved for use by the client |
license_count | integer | Yes | Number of tracked licenses. null if not tracked. |
created_at | string (ISO 8601) | No | When this app record was first created |
updated_at | string (ISO 8601) | No | When this app record was last modified |
DB source:
| DTO Field | DB Column |
|---|---|
id | apps.id |
catalog_app | Joined via apps.catalog_application_id → full CatalogApp DTO |
is_favorite | apps.is_favorite |
is_approved | apps.is_approved |
license_count | apps.license_count |
created_at | apps.created_at |
updated_at | apps.updated_at |
Omitted internal fields: client_id (in URL path), partner_id, created_by, updated_by, catalog_application_id (replaced by embedded catalog_app)
Used in: List Apps, Get App, Update App (response)
Embedded DTOs from other domains
The App DTO embeds the following DTOs defined elsewhere:
- CatalogApp — Full catalog app with vendor and categories embedded
- CatalogVendor — Vendor identity (inside
catalog_app.vendor) - CatalogCategory — Category identity (inside
catalog_app.categories)