init data-connector
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
import { ObjectType, Field } from '@nestjs/graphql';
|
||||
|
||||
@ObjectType('Interval')
|
||||
export class IntervalObjectType {
|
||||
@Field()
|
||||
start: Date;
|
||||
@Field()
|
||||
end: Date;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Type } from '@nestjs/common';
|
||||
import { ArgsType, Field, Int, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
@ArgsType()
|
||||
export class PaginationArgs {
|
||||
@Field(() => Int)
|
||||
take = 10;
|
||||
@Field(() => String, { nullable: true })
|
||||
cursor?: string;
|
||||
}
|
||||
|
||||
// interface IEdgeType<T> {
|
||||
// cursor: string;
|
||||
// node: T;
|
||||
// }
|
||||
|
||||
export interface IPaginatedType<T> {
|
||||
// edges: IEdgeType<T>[];
|
||||
nodes: T[];
|
||||
prevCursor: string;
|
||||
endCursor: string;
|
||||
totalCount: number;
|
||||
hasNextPage: boolean;
|
||||
}
|
||||
|
||||
export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
|
||||
// @ObjectType(`${classRef.name}Edge`)
|
||||
// abstract class EdgeType {
|
||||
// @Field(() => String)
|
||||
// cursor: string;
|
||||
// @Field(() => classRef)
|
||||
// node: T;
|
||||
// }
|
||||
|
||||
@ObjectType({ isAbstract: true })
|
||||
abstract class PaginatedType implements IPaginatedType<T> {
|
||||
// @Field(() => [EdgeType], { nullable: true })
|
||||
// edges: EdgeType[];
|
||||
|
||||
@Field(() => [classRef])
|
||||
nodes: T[];
|
||||
|
||||
@Field(() => String)
|
||||
prevCursor: string;
|
||||
|
||||
@Field(() => String)
|
||||
endCursor: string;
|
||||
|
||||
@Field(() => Int)
|
||||
totalCount: number;
|
||||
|
||||
@Field()
|
||||
hasNextPage: boolean;
|
||||
}
|
||||
|
||||
return PaginatedType as Type<IPaginatedType<T>>;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export function encodeCursor(cursor: string | number): string {
|
||||
return Buffer.from(`${cursor}`).toString('base64');
|
||||
}
|
||||
|
||||
export function decodeCursor(cursor: string): string {
|
||||
return Buffer.from(cursor, 'base64').toString('ascii');
|
||||
}
|
||||
|
||||
export function decodeOffsetCursor(cursor: string): number {
|
||||
return Number.parseInt(decodeCursor(cursor));
|
||||
}
|
||||
@@ -24,4 +24,19 @@ export class ConfigService extends NestConfigService {
|
||||
dyflexisV2ApiKey(): string {
|
||||
return this.get('DYFLEXIS_V2_API_KEY');
|
||||
}
|
||||
databasePort(): string {
|
||||
return this.get('DATABASE_PORT');
|
||||
}
|
||||
databaseHost(): string {
|
||||
return this.get('DATABASE_HOST');
|
||||
}
|
||||
databaseUser(): string {
|
||||
return this.get('DATABASE_USERNAME');
|
||||
}
|
||||
databasePassword(): string {
|
||||
return this.get('DATABASE_PASSWORD');
|
||||
}
|
||||
databaseName(): string {
|
||||
return this.get('DATABASE_DATABASE');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ConfigurableModuleBuilder } from '@nestjs/common';
|
||||
import { KyselyModuleAsyncOptions } from './database.module';
|
||||
|
||||
export const {
|
||||
ConfigurableModuleClass,
|
||||
MODULE_OPTIONS_TOKEN,
|
||||
ASYNC_OPTIONS_TYPE,
|
||||
OPTIONS_TYPE,
|
||||
} = new ConfigurableModuleBuilder<KyselyModuleAsyncOptions>()
|
||||
.setClassMethodName('forRoot')
|
||||
.setExtras<{ isGlobal?: boolean }>(
|
||||
{ isGlobal: false },
|
||||
(definition, extras) => ({ ...definition, global: extras.isGlobal }),
|
||||
)
|
||||
.build();
|
||||
@@ -1,8 +1,33 @@
|
||||
import { DynamicModule, Global, Module, Provider } from '@nestjs/common';
|
||||
import {
|
||||
DynamicModule,
|
||||
Global,
|
||||
Module,
|
||||
ModuleMetadata,
|
||||
Provider,
|
||||
Type,
|
||||
} from '@nestjs/common';
|
||||
import { KyselyConfig } from 'kysely';
|
||||
import { createKyselyProvider } from './kysely-client.factory';
|
||||
|
||||
export const KYSELY_CLIENT_PROVIDER_TOKEN = 'KyselyClientProviderToken';
|
||||
export const KYSELY_CONFIG_TOKEN = 'KYSELY_CONFIG_TOKEN';
|
||||
|
||||
export interface KyselyConfigFactory {
|
||||
createKyselyConfig(): Promise<KyselyConfig> | KyselyConfig;
|
||||
}
|
||||
|
||||
export interface KyselyModuleAsyncOptions
|
||||
extends Pick<ModuleMetadata, 'imports'> {
|
||||
isGlobal?: boolean;
|
||||
useExisting?: Type<KyselyConfigFactory>;
|
||||
useClass?: Type<KyselyConfigFactory>;
|
||||
useFactory?: (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...args: any[]
|
||||
) => KyselyConfig;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
inject?: any[];
|
||||
}
|
||||
|
||||
@Global()
|
||||
@Module({})
|
||||
@@ -16,4 +41,83 @@ export class DatabaseModule {
|
||||
providers: [provider],
|
||||
};
|
||||
}
|
||||
|
||||
public static forRootAsync(options: KyselyModuleAsyncOptions): DynamicModule {
|
||||
return {
|
||||
global: options.isGlobal,
|
||||
module: DatabaseModule,
|
||||
imports: options.imports || [],
|
||||
providers: this.createAsyncProviders(options),
|
||||
};
|
||||
}
|
||||
|
||||
private static createAsyncProviders(
|
||||
options: KyselyModuleAsyncOptions,
|
||||
): Provider[] {
|
||||
if (options.useExisting || options.useFactory) {
|
||||
return this.createAsyncOptionsProvider(options);
|
||||
}
|
||||
|
||||
if (options.useClass) {
|
||||
return [
|
||||
...this.createAsyncOptionsProvider(options),
|
||||
{
|
||||
provide: options.useClass,
|
||||
useClass: options.useClass,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [...this.createAsyncOptionsProvider(options)];
|
||||
}
|
||||
|
||||
private static createAsyncOptionsProvider(
|
||||
options: KyselyModuleAsyncOptions,
|
||||
): Provider[] {
|
||||
if (options.useFactory) {
|
||||
const config = options.useFactory(options.inject);
|
||||
return [
|
||||
// {
|
||||
// provide: KYSELY_CONFIG_TOKEN,
|
||||
// useFactory: options.useFactory,
|
||||
// inject: options.inject || [],
|
||||
// },
|
||||
{
|
||||
provide: KYSELY_CLIENT_PROVIDER_TOKEN,
|
||||
useExisting: createKyselyProvider(config)
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
if (options.useExisting) {
|
||||
return [
|
||||
{
|
||||
provide: KYSELY_CONFIG_TOKEN,
|
||||
useFactory: async (optionsFactory: KyselyConfigFactory) =>
|
||||
await optionsFactory.createKyselyConfig(),
|
||||
inject: [options.useExisting],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (options.useClass) {
|
||||
return [
|
||||
{
|
||||
provide: KYSELY_CONFIG_TOKEN,
|
||||
useFactory: async (optionsFactory: KyselyConfigFactory) =>
|
||||
await optionsFactory.createKyselyConfig(),
|
||||
inject: [options.useClass],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
provide: KYSELY_CONFIG_TOKEN,
|
||||
useFactory: async (optionsFactory: KyselyConfigFactory) =>
|
||||
await optionsFactory.createKyselyConfig(),
|
||||
inject: [],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ModuleMetadata, Type } from "@nestjs/common";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { ModuleMetadata, Type } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
export interface PrismaModuleOptions {
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
# ------------------------------------------------------
|
||||
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
|
||||
# ------------------------------------------------------
|
||||
|
||||
input AccountingFilterArgs {
|
||||
deviation: [String!]
|
||||
missing: [String!]
|
||||
}
|
||||
|
||||
enum AccountingState {
|
||||
Billable
|
||||
Billed
|
||||
PreparedForBilling
|
||||
}
|
||||
|
||||
type Anomaly {
|
||||
createdAt: DateTime!
|
||||
description: String!
|
||||
groupDescription: String!
|
||||
groupKey: String!
|
||||
id: String!
|
||||
manuallyResolved: Boolean
|
||||
resolvedAt: DateTime
|
||||
sleepSince: DateTime
|
||||
sleepTimer: Int!
|
||||
solution: [SolutionTarget!]!
|
||||
tour: Tour
|
||||
type: String!
|
||||
workedOnBy: String!
|
||||
}
|
||||
|
||||
type AnomalyGroup {
|
||||
anomalies: [Anomaly!]!
|
||||
key: String!
|
||||
}
|
||||
|
||||
type ApprovalInfo {
|
||||
answeredFrom: String
|
||||
isNeeded: Boolean
|
||||
location: String
|
||||
whoRequested: String
|
||||
}
|
||||
|
||||
input ApprovalInfoArgs {
|
||||
answeredFrom: String
|
||||
isNeeded: Boolean
|
||||
location: String
|
||||
whoRequested: String
|
||||
}
|
||||
|
||||
enum ApprovalState {
|
||||
APPROVED
|
||||
FREE
|
||||
REQUESTED
|
||||
REQUIRED
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
"""
|
||||
A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date-time format.
|
||||
"""
|
||||
scalar DateTime
|
||||
|
||||
type DocumentInfo {
|
||||
approval: ApprovalInfo!
|
||||
tdLocation: String
|
||||
}
|
||||
|
||||
type Interval {
|
||||
end: DateTime!
|
||||
start: DateTime!
|
||||
}
|
||||
|
||||
type KPI {
|
||||
meta: KPIMetadata!
|
||||
value: Float!
|
||||
}
|
||||
|
||||
type KPIByCar {
|
||||
carName: String!
|
||||
kpi: KPI!
|
||||
}
|
||||
|
||||
type KPIMetadata {
|
||||
availableTime: Float!
|
||||
baseValue: Float!
|
||||
breakEven: Float!
|
||||
tourAmount: Float!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
acceptAnomaly(id: String!): Anomaly!
|
||||
setAnomalyToSleep(id: String!): Anomaly!
|
||||
setDocumentInfo(approval: ApprovalInfoArgs, tdLocation: String, ticketId: String!): Ticket!
|
||||
}
|
||||
|
||||
type PaginatedAnomaly {
|
||||
endCursor: String!
|
||||
hasNextPage: Boolean!
|
||||
nodes: [Anomaly!]!
|
||||
prevCursor: String!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type PaginatedAnomalyGroup {
|
||||
endCursor: String!
|
||||
hasNextPage: Boolean!
|
||||
nodes: [AnomalyGroup!]!
|
||||
prevCursor: String!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type PaginatedTicket {
|
||||
endCursor: String!
|
||||
hasNextPage: Boolean!
|
||||
nodes: [Ticket!]!
|
||||
prevCursor: String!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type PaginatedTour {
|
||||
endCursor: String!
|
||||
hasNextPage: Boolean!
|
||||
nodes: [Tour!]!
|
||||
prevCursor: String!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type Query {
|
||||
accountingStateMeta(state: AccountingState!): TourStateMeta!
|
||||
accountingTours(cursor: String, filters: AccountingFilterArgs, state: AccountingState!, take: Int! = 10): PaginatedTour!
|
||||
anomalies(cursor: String, take: Int! = 10): PaginatedAnomaly!
|
||||
anomaliesProto: [Anomaly!]!
|
||||
anomaly(id: String!): Anomaly!
|
||||
groupedAnomalies(cursor: String, take: Int! = 10): PaginatedAnomalyGroup!
|
||||
searchTickets(query: String!): [Ticket!]!
|
||||
ticket(id: String!): Ticket!
|
||||
ticketStateKeyFigures(state: TicketValidationState!): TicketStateKeyFigures!
|
||||
ticketStateMeta(state: TicketValidationState!): TicketStateMeta!
|
||||
tickets(cursor: String, filters: TicketFilterArgs, state: TicketValidationState!, take: Int! = 10): PaginatedTicket!
|
||||
timePerTourMetricForDay(day: DateTime!, ordinanceType: String!): [TimePerTourMetric!]!
|
||||
timePerTourMetricForMonth(day: DateTime!, ordinanceType: String!): [TimePerTourMetric!]!
|
||||
toursPerTimeKPI(ordinanceTypes: String!): [TimePerTourKPISummary!]!
|
||||
}
|
||||
|
||||
type SolutionTarget {
|
||||
anomalyId: String!
|
||||
id: String!
|
||||
name: String!
|
||||
steps: [SolutionTargetStep!]!
|
||||
}
|
||||
|
||||
type SolutionTargetStep {
|
||||
description: String!
|
||||
id: String!
|
||||
solutionTargetId: String!
|
||||
}
|
||||
|
||||
type Subscription {
|
||||
ticketsUpdated: TicketsUpdated!
|
||||
timePerTourUpdated: TimePerTourUpdate!
|
||||
}
|
||||
|
||||
type Ticket {
|
||||
approvalState: ApprovalState
|
||||
createdAt: DateTime!
|
||||
currentState: TicketValidationState!
|
||||
documentInfo: DocumentInfo
|
||||
errors: [String!]!
|
||||
id: String!
|
||||
isUrgent: Boolean!
|
||||
notes: [String!]!
|
||||
tours: [Tour!]!
|
||||
urgency: DateTime!
|
||||
}
|
||||
|
||||
input TicketFilterArgs {
|
||||
approvalStates: [ApprovalState!]
|
||||
documentInfo: [String!]
|
||||
errors: [String!]
|
||||
}
|
||||
|
||||
type TicketStateKeyFigures {
|
||||
dwellTime: Int!
|
||||
}
|
||||
|
||||
type TicketStateMeta {
|
||||
approvalNotCompanyCount: Int
|
||||
approvalRequiredCount: Int
|
||||
approvalUnknownCount: Int
|
||||
count: Int!
|
||||
tdNotCompanyCount: Int
|
||||
}
|
||||
|
||||
enum TicketValidationState {
|
||||
ARCHIVED
|
||||
CREATED
|
||||
DOCUMENTS_MISSING
|
||||
TD_UNCERTAIN
|
||||
USER_INTERACTION_REQUIRED
|
||||
}
|
||||
|
||||
type TicketsUpdated {
|
||||
count: Int!
|
||||
}
|
||||
|
||||
type TimePerTourKPISummary {
|
||||
cars: [KPIByCar!]!
|
||||
interval: Interval!
|
||||
kpi: KPI!
|
||||
}
|
||||
|
||||
type TimePerTourMetric {
|
||||
availableTime: Float!
|
||||
averageRevenue: Float!
|
||||
breakEven: Float!
|
||||
categoryAmounts: [TimePerTourMetricCategoryAmount!]!
|
||||
consumptionCost: Float!
|
||||
forecast: Float!
|
||||
forecastRevenue: Float!
|
||||
interval: Interval!
|
||||
personnelCost: Float!
|
||||
revenue: Float!
|
||||
tourAmount: Float!
|
||||
}
|
||||
|
||||
type TimePerTourMetricCategoryAmount {
|
||||
amount: Int!
|
||||
category: String!
|
||||
}
|
||||
|
||||
type TimePerTourUpdate {
|
||||
job: String!
|
||||
}
|
||||
|
||||
type Tour {
|
||||
billDate: DateTime
|
||||
billNumber: String
|
||||
carName: String
|
||||
category: String
|
||||
check: Int!
|
||||
codriverId: String
|
||||
codriverName: String
|
||||
consumptionCosts: Float!
|
||||
createdAt: DateTime
|
||||
deletedAt: DateTime
|
||||
direction: String!
|
||||
done: Boolean!
|
||||
driverId: String
|
||||
driverName: String
|
||||
empty: String
|
||||
hasInfection: Boolean
|
||||
healthInsurance: String
|
||||
healthInsuranceNumber: String
|
||||
id: String!
|
||||
infectionName: String
|
||||
occupiedKm: Float!
|
||||
operationId: String!
|
||||
ordinanceType: String
|
||||
patientCity: String
|
||||
patientId: String
|
||||
patientName: String
|
||||
patientStreet: String
|
||||
patientSurname: String
|
||||
patientZip: String
|
||||
rangeEndDate: DateTime
|
||||
revenue: Float!
|
||||
revenueDeviation: Float!
|
||||
revenueDispoLive: Float!
|
||||
startBegin: String
|
||||
startCity: String
|
||||
startDate: DateTime
|
||||
startEnd: String
|
||||
startInstitution: String
|
||||
startStreet: String
|
||||
startZip: String
|
||||
target: String
|
||||
targetBegin: String
|
||||
targetCity: String
|
||||
targetInstitution: String
|
||||
targetStreet: String
|
||||
targetZip: String
|
||||
ticket: Ticket
|
||||
ticketId: String
|
||||
totalKm: Float!
|
||||
transportType: String
|
||||
type: String!
|
||||
}
|
||||
|
||||
type TourStateMeta {
|
||||
count: Int!
|
||||
revenueSum: Float
|
||||
}
|
||||
Reference in New Issue
Block a user