Terminal
Introduction
The Terminal entity represents an organization-scoped terminal or facility. Terminals can be associated with a port, searched by name/code/custom values, and soft-deleted without losing historical references.
Entity Structure
| Property Name | Type | Required | Description |
|---|---|---|---|
| TerminalId | int | Yes | Unique terminal identifier |
| OrganizationId | int | Yes | Tenant scope |
| Name | string | Yes | Terminal display name |
| Code | string? | No | Organization-specific terminal code |
| PortId | string? | No | Optional FK to Port (OrganizationId + PortId) |
| CustomValues | Dictionary<string, object?> | No | Extensible terminal metadata stored as JSONB |
| IsDeleted | bool | Yes | Soft delete flag; default false |
| Created | DateTime | Yes | Creation timestamp |
| CreatedBy | string | Yes | Creating user ID |
| LastModified | DateTime | Yes | Last update timestamp |
| LastModifiedBy | string | Yes | Last updating user ID |
Relationships
| Relationship | Type | Description |
|---|---|---|
| Port | Port | Optional associated port |
| Organization | Organization | Owning organization |
| CreatedUser | User | User that created the terminal |
| UpdatedUser | User | User that last updated the terminal |
Indexes and Uniqueness
Terminal codes are unique per organization only for active terminals:
UNIQUE (OrganizationId, Code)
WHERE Code IS NOT NULL AND IsDeleted = false
This means a soft-deleted terminal no longer blocks reuse of its Code, while active terminals still cannot duplicate a non-null code inside the same organization. CustomValues also has a JSONB GIN index for containment/search use cases.
GraphQL
Root queries:
getTerminal(organizationId, terminalId)— returns one terminalgetTerminals(organizationId, filter, search, orderBy)— paged list with projection, Lucene filtering, search, and sorting
Example:
query {
getTerminals(organizationId: 1, search: "LAX", take: 20) {
items {
terminalId
code
name
port { portId name }
}
}
}