src/users/dto/customization.dto.ts
Properties |
|
| Optional aiEnabled |
Type : boolean
|
Decorators :
@ApiPropertyOptional({description: 'Global toggle for the Intelligence Center features (Ask Assistant, Route Optimizer, etc.).'})
|
|
Defined in src/users/dto/customization.dto.ts:153
|
| Optional bayTimeout |
Type : literal type
|
Decorators :
@ApiPropertyOptional({description: undefined, example: undefined})
|
|
Defined in src/users/dto/customization.dto.ts:188
|
| Optional currency |
Type : string
|
Decorators :
@ApiPropertyOptional({description: 'Org currency (ISO 4217 code). Used by tariffs, reports, and invoices.', example: 'KES'})
|
|
Defined in src/users/dto/customization.dto.ts:214
|
| Optional navLabels |
Type : Record<string | string>
|
Decorators :
@ApiPropertyOptional({description: 'Map of nav href → custom label. Used by the sidebar to override default labels.', example: undefined})
|
|
Defined in src/users/dto/customization.dto.ts:135
|
| Optional orderColumns |
Type : OrderColumnDto[]
|
Decorators :
@ApiPropertyOptional({description: 'Order list column configuration (visibility + label overrides).', type: undefined})
|
|
Defined in src/users/dto/customization.dto.ts:145
|
| Optional telematics |
Type : TelematicsConfigDto
|
Decorators :
@ApiPropertyOptional({description: undefined, type: TelematicsConfigDto})
|
|
Defined in src/users/dto/customization.dto.ts:166
|
| Optional timezone |
Type : string
|
Decorators :
@ApiPropertyOptional({description: undefined, example: 'Africa/Nairobi'})
|
|
Defined in src/users/dto/customization.dto.ts:205
|
| Optional tracking |
Type : TrackingConfigDto
|
Decorators :
@ApiPropertyOptional({description: undefined, type: TrackingConfigDto})
|
|
Defined in src/users/dto/customization.dto.ts:178
|
import { ApiPropertyOptional } from '@nestjs/swagger';
import {
IsArray,
IsBoolean,
IsIn,
IsObject,
IsOptional,
IsString,
MaxLength,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
class OrderColumnDto {
@IsString()
key!: string;
@IsString()
label!: string;
@IsOptional()
@IsBoolean()
visible?: boolean;
}
/**
* Telematics provider configuration stored at the organization level.
* Different providers need different credential shapes — we accept the
* superset and let the provider-specific code pick the fields it cares
* about. Sensitive fields (apiKey/clientSecret/password) are write-only
* via this DTO and are never returned by GET endpoints — the read side
* masks them and returns boolean `has*` flags instead.
*/
export const TELEMATICS_PROVIDERS = [
'mix_telematics',
'geotab',
'samsara',
'webfleet',
'verizon_connect',
'cartrack',
'teltonika',
'other',
] as const;
export type TelematicsProvider = (typeof TELEMATICS_PROVIDERS)[number];
/**
* Tracking mode for an organization. Default is `demo`, which runs the
* built-in GPS simulator (vehicles move along Kenyan road routes so the
* UI / geofencing / dispatch flow is testable without a real provider).
*
* Switching to `live` requires a verified telematics provider configured
* for this org. The live worker pulls real positions from that provider
* on a 30-second cron and writes them into the same vehicles columns
* the demo path uses, so the rest of the platform doesn't care which
* one is feeding it.
*/
export const TRACKING_MODES = ['demo', 'live'] as const;
export type TrackingMode = (typeof TRACKING_MODES)[number];
export class TrackingConfigDto {
@ApiPropertyOptional({ enum: TRACKING_MODES, description: 'demo (simulator) or live (telematics)' })
@IsString()
@IsIn(TRACKING_MODES as unknown as string[])
mode!: TrackingMode;
}
export class TelematicsConfigDto {
@ApiPropertyOptional({
enum: TELEMATICS_PROVIDERS,
description: 'Telematics provider key',
})
@IsString()
@IsIn(TELEMATICS_PROVIDERS as unknown as string[])
provider!: TelematicsProvider;
@ApiPropertyOptional({ description: 'API base URL — provider-specific' })
@IsOptional()
@IsString()
@MaxLength(500)
baseUrl?: string;
@ApiPropertyOptional({ description: 'API key / bearer token (Samsara, Cartrack, Teltonika)' })
@IsOptional()
@IsString()
@MaxLength(500)
apiKey?: string;
@ApiPropertyOptional({ description: 'OAuth client ID (Mix Telematics)' })
@IsOptional()
@IsString()
@MaxLength(200)
clientId?: string;
@ApiPropertyOptional({ description: 'OAuth client secret (Mix Telematics)' })
@IsOptional()
@IsString()
@MaxLength(500)
clientSecret?: string;
@ApiPropertyOptional({
description: 'Provider org/group/database ID (Mix org group, Geotab database, Webfleet account)',
})
@IsOptional()
@IsString()
@MaxLength(200)
organizationId?: string;
@ApiPropertyOptional({ description: 'Username (Geotab, Webfleet, Verizon Connect)' })
@IsOptional()
@IsString()
@MaxLength(200)
username?: string;
@ApiPropertyOptional({ description: 'Password (Geotab, Webfleet, Verizon Connect)' })
@IsOptional()
@IsString()
@MaxLength(500)
password?: string;
@ApiPropertyOptional({ description: 'Account identifier (Webfleet)' })
@IsOptional()
@IsString()
@MaxLength(200)
account?: string;
}
export class UpdateCustomizationDto {
@ApiPropertyOptional({
description:
'Map of nav href → custom label. Used by the sidebar to override default labels.',
example: { '/orders': 'Loads', '/clients': 'Sites' },
})
@IsOptional()
@IsObject()
navLabels?: Record<string, string>;
@ApiPropertyOptional({
description: 'Order list column configuration (visibility + label overrides).',
type: [OrderColumnDto],
})
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => OrderColumnDto)
orderColumns?: OrderColumnDto[];
@ApiPropertyOptional({
description:
'Global toggle for the Intelligence Center features (Ask Assistant, Route Optimizer, etc.).',
})
@IsOptional()
@IsBoolean()
aiEnabled?: boolean;
@ApiPropertyOptional({
description:
'Telematics provider configuration. Stored at the org level under settings.telematics. ' +
'Sensitive fields (apiKey, clientSecret, password) are write-only — they are never returned ' +
'on read endpoints. Submit only the fields you want to change; existing sensitive fields ' +
'are preserved when omitted.',
type: TelematicsConfigDto,
})
@IsOptional()
@ValidateNested()
@Type(() => TelematicsConfigDto)
telematics?: TelematicsConfigDto;
@ApiPropertyOptional({
description:
'Tracking mode for this organization. Default `demo` runs the built-in GPS simulator. ' +
'Set to `live` to pull positions from the configured telematics provider on a cron — ' +
'requires a saved + verified provider in `telematics`.',
type: TrackingConfigDto,
})
@IsOptional()
@ValidateNested()
@Type(() => TrackingConfigDto)
tracking?: TrackingConfigDto;
@ApiPropertyOptional({
description:
'Loading bay timeout config. maxWaitMinutes = how long a bay stays OCCUPIED before being marked LATE. ' +
'autoReleaseMinutes = grace period after LATE before auto-releasing. alertOnLate = send a platform alert.',
example: { maxWaitMinutes: 120, autoReleaseMinutes: 60, alertOnLate: true },
})
@IsOptional()
@IsObject()
bayTimeout?: {
maxWaitMinutes?: number;
autoReleaseMinutes?: number;
alertOnLate?: boolean;
};
@ApiPropertyOptional({
description:
'IANA timezone string for this organization. All client widgets that render dates/times ' +
'(dispatch Gantt, loading bays calendar, alerts, audit log) use this so the dispatcher ' +
'always sees their local time regardless of where their browser is located. ' +
'Examples: Africa/Nairobi, Africa/Lagos, Europe/London, America/New_York.',
example: 'Africa/Nairobi',
})
@IsOptional()
@IsString()
@MaxLength(64)
timezone?: string;
@ApiPropertyOptional({
description: 'Org currency (ISO 4217 code). Used by tariffs, reports, and invoices.',
example: 'KES',
})
@IsOptional()
@IsString()
@MaxLength(8)
currency?: string;
}