数据源修改
This commit is contained in:
parent
b10b1c44db
commit
ec15f40323
@ -37,6 +37,11 @@ export type Strategy = Prisma.StrategyModel
|
||||
*
|
||||
*/
|
||||
export type Indicator = Prisma.IndicatorModel
|
||||
/**
|
||||
* Model IndicatorPoint
|
||||
*
|
||||
*/
|
||||
export type IndicatorPoint = Prisma.IndicatorPointModel
|
||||
/**
|
||||
* Model Econ_SowInventory
|
||||
*
|
||||
|
||||
@ -61,6 +61,11 @@ export type Strategy = Prisma.StrategyModel
|
||||
*
|
||||
*/
|
||||
export type Indicator = Prisma.IndicatorModel
|
||||
/**
|
||||
* Model IndicatorPoint
|
||||
*
|
||||
*/
|
||||
export type IndicatorPoint = Prisma.IndicatorPointModel
|
||||
/**
|
||||
* Model Econ_SowInventory
|
||||
*
|
||||
|
||||
@ -150,6 +150,46 @@ export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
_max?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type BoolFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||
}
|
||||
|
||||
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type FloatFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
||||
}
|
||||
|
||||
export type FloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type StringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
@ -359,6 +399,35 @@ export type NestedJsonFilterBase<$PrismaModel = never> = {
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
}
|
||||
|
||||
export type NestedBoolFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||
}
|
||||
|
||||
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedFloatWithAggregatesFilter<$PrismaModel> | number
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -388,6 +388,7 @@ export const ModelName = {
|
||||
Article: 'Article',
|
||||
Strategy: 'Strategy',
|
||||
Indicator: 'Indicator',
|
||||
IndicatorPoint: 'IndicatorPoint',
|
||||
Econ_SowInventory: 'Econ_SowInventory',
|
||||
ScraperCache: 'ScraperCache'
|
||||
} as const
|
||||
@ -405,7 +406,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
omit: GlobalOmitOptions
|
||||
}
|
||||
meta: {
|
||||
modelProps: "user" | "article" | "strategy" | "indicator" | "econ_SowInventory" | "scraperCache"
|
||||
modelProps: "user" | "article" | "strategy" | "indicator" | "indicatorPoint" | "econ_SowInventory" | "scraperCache"
|
||||
txIsolationLevel: TransactionIsolationLevel
|
||||
}
|
||||
model: {
|
||||
@ -673,6 +674,72 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
}
|
||||
}
|
||||
}
|
||||
IndicatorPoint: {
|
||||
payload: Prisma.$IndicatorPointPayload<ExtArgs>
|
||||
fields: Prisma.IndicatorPointFieldRefs
|
||||
operations: {
|
||||
findUnique: {
|
||||
args: Prisma.IndicatorPointFindUniqueArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload> | null
|
||||
}
|
||||
findUniqueOrThrow: {
|
||||
args: Prisma.IndicatorPointFindUniqueOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
findFirst: {
|
||||
args: Prisma.IndicatorPointFindFirstArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload> | null
|
||||
}
|
||||
findFirstOrThrow: {
|
||||
args: Prisma.IndicatorPointFindFirstOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
findMany: {
|
||||
args: Prisma.IndicatorPointFindManyArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>[]
|
||||
}
|
||||
create: {
|
||||
args: Prisma.IndicatorPointCreateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
createMany: {
|
||||
args: Prisma.IndicatorPointCreateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
delete: {
|
||||
args: Prisma.IndicatorPointDeleteArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
update: {
|
||||
args: Prisma.IndicatorPointUpdateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
deleteMany: {
|
||||
args: Prisma.IndicatorPointDeleteManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
updateMany: {
|
||||
args: Prisma.IndicatorPointUpdateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
upsert: {
|
||||
args: Prisma.IndicatorPointUpsertArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$IndicatorPointPayload>
|
||||
}
|
||||
aggregate: {
|
||||
args: Prisma.IndicatorPointAggregateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.AggregateIndicatorPoint>
|
||||
}
|
||||
groupBy: {
|
||||
args: Prisma.IndicatorPointGroupByArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.IndicatorPointGroupByOutputType>[]
|
||||
}
|
||||
count: {
|
||||
args: Prisma.IndicatorPointCountArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.IndicatorPointCountAggregateOutputType> | number
|
||||
}
|
||||
}
|
||||
}
|
||||
Econ_SowInventory: {
|
||||
payload: Prisma.$Econ_SowInventoryPayload<ExtArgs>
|
||||
fields: Prisma.Econ_SowInventoryFieldRefs
|
||||
@ -885,7 +952,11 @@ export const IndicatorScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
groupName: 'groupName',
|
||||
data: 'data',
|
||||
title: 'title',
|
||||
unit: 'unit',
|
||||
source: 'source',
|
||||
frequency: 'frequency',
|
||||
hidden: 'hidden',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
@ -893,6 +964,18 @@ export const IndicatorScalarFieldEnum = {
|
||||
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorPointScalarFieldEnum = {
|
||||
id: 'id',
|
||||
indicatorId: 'indicatorId',
|
||||
period: 'period',
|
||||
value: 'value',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
|
||||
export type IndicatorPointScalarFieldEnum = (typeof IndicatorPointScalarFieldEnum)[keyof typeof IndicatorPointScalarFieldEnum]
|
||||
|
||||
|
||||
export const Econ_SowInventoryScalarFieldEnum = {
|
||||
id: 'id',
|
||||
month: 'month',
|
||||
@ -986,12 +1069,23 @@ export type StrategyOrderByRelevanceFieldEnum = (typeof StrategyOrderByRelevance
|
||||
|
||||
export const IndicatorOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
groupName: 'groupName'
|
||||
groupName: 'groupName',
|
||||
title: 'title',
|
||||
unit: 'unit',
|
||||
source: 'source',
|
||||
frequency: 'frequency'
|
||||
} as const
|
||||
|
||||
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorPointOrderByRelevanceFieldEnum = {
|
||||
period: 'period'
|
||||
} as const
|
||||
|
||||
export type IndicatorPointOrderByRelevanceFieldEnum = (typeof IndicatorPointOrderByRelevanceFieldEnum)[keyof typeof IndicatorPointOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
||||
month: 'month'
|
||||
} as const
|
||||
@ -1056,6 +1150,13 @@ export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$Prisma
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Boolean'
|
||||
*/
|
||||
export type BooleanFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Boolean'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Float'
|
||||
*/
|
||||
@ -1161,6 +1262,7 @@ export type GlobalOmitConfig = {
|
||||
article?: Prisma.ArticleOmit
|
||||
strategy?: Prisma.StrategyOmit
|
||||
indicator?: Prisma.IndicatorOmit
|
||||
indicatorPoint?: Prisma.IndicatorPointOmit
|
||||
econ_SowInventory?: Prisma.Econ_SowInventoryOmit
|
||||
scraperCache?: Prisma.ScraperCacheOmit
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ export const ModelName = {
|
||||
Article: 'Article',
|
||||
Strategy: 'Strategy',
|
||||
Indicator: 'Indicator',
|
||||
IndicatorPoint: 'IndicatorPoint',
|
||||
Econ_SowInventory: 'Econ_SowInventory',
|
||||
ScraperCache: 'ScraperCache'
|
||||
} as const
|
||||
@ -116,7 +117,11 @@ export const IndicatorScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
groupName: 'groupName',
|
||||
data: 'data',
|
||||
title: 'title',
|
||||
unit: 'unit',
|
||||
source: 'source',
|
||||
frequency: 'frequency',
|
||||
hidden: 'hidden',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
@ -124,6 +129,18 @@ export const IndicatorScalarFieldEnum = {
|
||||
export type IndicatorScalarFieldEnum = (typeof IndicatorScalarFieldEnum)[keyof typeof IndicatorScalarFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorPointScalarFieldEnum = {
|
||||
id: 'id',
|
||||
indicatorId: 'indicatorId',
|
||||
period: 'period',
|
||||
value: 'value',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
|
||||
export type IndicatorPointScalarFieldEnum = (typeof IndicatorPointScalarFieldEnum)[keyof typeof IndicatorPointScalarFieldEnum]
|
||||
|
||||
|
||||
export const Econ_SowInventoryScalarFieldEnum = {
|
||||
id: 'id',
|
||||
month: 'month',
|
||||
@ -217,12 +234,23 @@ export type StrategyOrderByRelevanceFieldEnum = (typeof StrategyOrderByRelevance
|
||||
|
||||
export const IndicatorOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
groupName: 'groupName'
|
||||
groupName: 'groupName',
|
||||
title: 'title',
|
||||
unit: 'unit',
|
||||
source: 'source',
|
||||
frequency: 'frequency'
|
||||
} as const
|
||||
|
||||
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorPointOrderByRelevanceFieldEnum = {
|
||||
period: 'period'
|
||||
} as const
|
||||
|
||||
export type IndicatorPointOrderByRelevanceFieldEnum = (typeof IndicatorPointOrderByRelevanceFieldEnum)[keyof typeof IndicatorPointOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
||||
month: 'month'
|
||||
} as const
|
||||
|
||||
@ -12,6 +12,7 @@ export type * from './models/User.ts'
|
||||
export type * from './models/Article.ts'
|
||||
export type * from './models/Strategy.ts'
|
||||
export type * from './models/Indicator.ts'
|
||||
export type * from './models/IndicatorPoint.ts'
|
||||
export type * from './models/Econ_SowInventory.ts'
|
||||
export type * from './models/ScraperCache.ts'
|
||||
export type * from './commonInputTypes.ts'
|
||||
@ -38,6 +38,11 @@ export type IndicatorMinAggregateOutputType = {
|
||||
id: number | null
|
||||
name: string | null
|
||||
groupName: string | null
|
||||
title: string | null
|
||||
unit: string | null
|
||||
source: string | null
|
||||
frequency: string | null
|
||||
hidden: boolean | null
|
||||
createdAt: Date | null
|
||||
updatedAt: Date | null
|
||||
}
|
||||
@ -46,6 +51,11 @@ export type IndicatorMaxAggregateOutputType = {
|
||||
id: number | null
|
||||
name: string | null
|
||||
groupName: string | null
|
||||
title: string | null
|
||||
unit: string | null
|
||||
source: string | null
|
||||
frequency: string | null
|
||||
hidden: boolean | null
|
||||
createdAt: Date | null
|
||||
updatedAt: Date | null
|
||||
}
|
||||
@ -54,7 +64,11 @@ export type IndicatorCountAggregateOutputType = {
|
||||
id: number
|
||||
name: number
|
||||
groupName: number
|
||||
data: number
|
||||
title: number
|
||||
unit: number
|
||||
source: number
|
||||
frequency: number
|
||||
hidden: number
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
_all: number
|
||||
@ -73,6 +87,11 @@ export type IndicatorMinAggregateInputType = {
|
||||
id?: true
|
||||
name?: true
|
||||
groupName?: true
|
||||
title?: true
|
||||
unit?: true
|
||||
source?: true
|
||||
frequency?: true
|
||||
hidden?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
}
|
||||
@ -81,6 +100,11 @@ export type IndicatorMaxAggregateInputType = {
|
||||
id?: true
|
||||
name?: true
|
||||
groupName?: true
|
||||
title?: true
|
||||
unit?: true
|
||||
source?: true
|
||||
frequency?: true
|
||||
hidden?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
}
|
||||
@ -89,7 +113,11 @@ export type IndicatorCountAggregateInputType = {
|
||||
id?: true
|
||||
name?: true
|
||||
groupName?: true
|
||||
data?: true
|
||||
title?: true
|
||||
unit?: true
|
||||
source?: true
|
||||
frequency?: true
|
||||
hidden?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
_all?: true
|
||||
@ -185,7 +213,11 @@ export type IndicatorGroupByOutputType = {
|
||||
id: number
|
||||
name: string
|
||||
groupName: string
|
||||
data: runtime.JsonValue
|
||||
title: string
|
||||
unit: string
|
||||
source: string
|
||||
frequency: string
|
||||
hidden: boolean
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
_count: IndicatorCountAggregateOutputType | null
|
||||
@ -217,18 +249,28 @@ export type IndicatorWhereInput = {
|
||||
id?: Prisma.IntFilter<"Indicator"> | number
|
||||
name?: Prisma.StringFilter<"Indicator"> | string
|
||||
groupName?: Prisma.StringFilter<"Indicator"> | string
|
||||
data?: Prisma.JsonFilter<"Indicator">
|
||||
title?: Prisma.StringFilter<"Indicator"> | string
|
||||
unit?: Prisma.StringFilter<"Indicator"> | string
|
||||
source?: Prisma.StringFilter<"Indicator"> | string
|
||||
frequency?: Prisma.StringFilter<"Indicator"> | string
|
||||
hidden?: Prisma.BoolFilter<"Indicator"> | boolean
|
||||
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||
points?: Prisma.IndicatorPointListRelationFilter
|
||||
}
|
||||
|
||||
export type IndicatorOrderByWithRelationInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
groupName?: Prisma.SortOrder
|
||||
data?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
unit?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
frequency?: Prisma.SortOrder
|
||||
hidden?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
points?: Prisma.IndicatorPointOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.IndicatorOrderByRelevanceInput
|
||||
}
|
||||
|
||||
@ -239,16 +281,25 @@ export type IndicatorWhereUniqueInput = Prisma.AtLeast<{
|
||||
OR?: Prisma.IndicatorWhereInput[]
|
||||
NOT?: Prisma.IndicatorWhereInput | Prisma.IndicatorWhereInput[]
|
||||
groupName?: Prisma.StringFilter<"Indicator"> | string
|
||||
data?: Prisma.JsonFilter<"Indicator">
|
||||
title?: Prisma.StringFilter<"Indicator"> | string
|
||||
unit?: Prisma.StringFilter<"Indicator"> | string
|
||||
source?: Prisma.StringFilter<"Indicator"> | string
|
||||
frequency?: Prisma.StringFilter<"Indicator"> | string
|
||||
hidden?: Prisma.BoolFilter<"Indicator"> | boolean
|
||||
createdAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"Indicator"> | Date | string
|
||||
points?: Prisma.IndicatorPointListRelationFilter
|
||||
}, "id" | "name">
|
||||
|
||||
export type IndicatorOrderByWithAggregationInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
groupName?: Prisma.SortOrder
|
||||
data?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
unit?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
frequency?: Prisma.SortOrder
|
||||
hidden?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_count?: Prisma.IndicatorCountOrderByAggregateInput
|
||||
@ -265,7 +316,11 @@ export type IndicatorScalarWhereWithAggregatesInput = {
|
||||
id?: Prisma.IntWithAggregatesFilter<"Indicator"> | number
|
||||
name?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
groupName?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
data?: Prisma.JsonWithAggregatesFilter<"Indicator">
|
||||
title?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
unit?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
source?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
frequency?: Prisma.StringWithAggregatesFilter<"Indicator"> | string
|
||||
hidden?: Prisma.BoolWithAggregatesFilter<"Indicator"> | boolean
|
||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"Indicator"> | Date | string
|
||||
}
|
||||
@ -273,42 +328,66 @@ export type IndicatorScalarWhereWithAggregatesInput = {
|
||||
export type IndicatorCreateInput = {
|
||||
name: string
|
||||
groupName: string
|
||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: string
|
||||
unit?: string
|
||||
source?: string
|
||||
frequency?: string
|
||||
hidden?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
points?: Prisma.IndicatorPointCreateNestedManyWithoutIndicatorInput
|
||||
}
|
||||
|
||||
export type IndicatorUncheckedCreateInput = {
|
||||
id?: number
|
||||
name: string
|
||||
groupName: string
|
||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: string
|
||||
unit?: string
|
||||
source?: string
|
||||
frequency?: string
|
||||
hidden?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
points?: Prisma.IndicatorPointUncheckedCreateNestedManyWithoutIndicatorInput
|
||||
}
|
||||
|
||||
export type IndicatorUpdateInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
points?: Prisma.IndicatorPointUpdateManyWithoutIndicatorNestedInput
|
||||
}
|
||||
|
||||
export type IndicatorUncheckedUpdateInput = {
|
||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
points?: Prisma.IndicatorPointUncheckedUpdateManyWithoutIndicatorNestedInput
|
||||
}
|
||||
|
||||
export type IndicatorCreateManyInput = {
|
||||
id?: number
|
||||
name: string
|
||||
groupName: string
|
||||
data: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: string
|
||||
unit?: string
|
||||
source?: string
|
||||
frequency?: string
|
||||
hidden?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@ -316,7 +395,11 @@ export type IndicatorCreateManyInput = {
|
||||
export type IndicatorUpdateManyMutationInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@ -325,7 +408,11 @@ export type IndicatorUncheckedUpdateManyInput = {
|
||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
data?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@ -340,7 +427,11 @@ export type IndicatorCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
groupName?: Prisma.SortOrder
|
||||
data?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
unit?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
frequency?: Prisma.SortOrder
|
||||
hidden?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@ -353,6 +444,11 @@ export type IndicatorMaxOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
groupName?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
unit?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
frequency?: Prisma.SortOrder
|
||||
hidden?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@ -361,6 +457,11 @@ export type IndicatorMinOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
groupName?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
unit?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
frequency?: Prisma.SortOrder
|
||||
hidden?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@ -369,15 +470,139 @@ export type IndicatorSumOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type IndicatorScalarRelationFilter = {
|
||||
is?: Prisma.IndicatorWhereInput
|
||||
isNot?: Prisma.IndicatorWhereInput
|
||||
}
|
||||
|
||||
export type BoolFieldUpdateOperationsInput = {
|
||||
set?: boolean
|
||||
}
|
||||
|
||||
export type IndicatorCreateNestedOneWithoutPointsInput = {
|
||||
create?: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||
connectOrCreate?: Prisma.IndicatorCreateOrConnectWithoutPointsInput
|
||||
connect?: Prisma.IndicatorWhereUniqueInput
|
||||
}
|
||||
|
||||
export type IndicatorUpdateOneRequiredWithoutPointsNestedInput = {
|
||||
create?: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||
connectOrCreate?: Prisma.IndicatorCreateOrConnectWithoutPointsInput
|
||||
upsert?: Prisma.IndicatorUpsertWithoutPointsInput
|
||||
connect?: Prisma.IndicatorWhereUniqueInput
|
||||
update?: Prisma.XOR<Prisma.XOR<Prisma.IndicatorUpdateToOneWithWhereWithoutPointsInput, Prisma.IndicatorUpdateWithoutPointsInput>, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||
}
|
||||
|
||||
export type IndicatorCreateWithoutPointsInput = {
|
||||
name: string
|
||||
groupName: string
|
||||
title?: string
|
||||
unit?: string
|
||||
source?: string
|
||||
frequency?: string
|
||||
hidden?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
|
||||
export type IndicatorUncheckedCreateWithoutPointsInput = {
|
||||
id?: number
|
||||
name: string
|
||||
groupName: string
|
||||
title?: string
|
||||
unit?: string
|
||||
source?: string
|
||||
frequency?: string
|
||||
hidden?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
|
||||
export type IndicatorCreateOrConnectWithoutPointsInput = {
|
||||
where: Prisma.IndicatorWhereUniqueInput
|
||||
create: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||
}
|
||||
|
||||
export type IndicatorUpsertWithoutPointsInput = {
|
||||
update: Prisma.XOR<Prisma.IndicatorUpdateWithoutPointsInput, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||
create: Prisma.XOR<Prisma.IndicatorCreateWithoutPointsInput, Prisma.IndicatorUncheckedCreateWithoutPointsInput>
|
||||
where?: Prisma.IndicatorWhereInput
|
||||
}
|
||||
|
||||
export type IndicatorUpdateToOneWithWhereWithoutPointsInput = {
|
||||
where?: Prisma.IndicatorWhereInput
|
||||
data: Prisma.XOR<Prisma.IndicatorUpdateWithoutPointsInput, Prisma.IndicatorUncheckedUpdateWithoutPointsInput>
|
||||
}
|
||||
|
||||
export type IndicatorUpdateWithoutPointsInput = {
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type IndicatorUncheckedUpdateWithoutPointsInput = {
|
||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
groupName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
title?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
unit?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
source?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
frequency?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
hidden?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count Type IndicatorCountOutputType
|
||||
*/
|
||||
|
||||
export type IndicatorCountOutputType = {
|
||||
points: number
|
||||
}
|
||||
|
||||
export type IndicatorCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
points?: boolean | IndicatorCountOutputTypeCountPointsArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorCountOutputType without action
|
||||
*/
|
||||
export type IndicatorCountOutputTypeDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the IndicatorCountOutputType
|
||||
*/
|
||||
select?: Prisma.IndicatorCountOutputTypeSelect<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorCountOutputType without action
|
||||
*/
|
||||
export type IndicatorCountOutputTypeCountPointsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
where?: Prisma.IndicatorPointWhereInput
|
||||
}
|
||||
|
||||
|
||||
export type IndicatorSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
groupName?: boolean
|
||||
data?: boolean
|
||||
title?: boolean
|
||||
unit?: boolean
|
||||
source?: boolean
|
||||
frequency?: boolean
|
||||
hidden?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
points?: boolean | Prisma.Indicator$pointsArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["indicator"]>
|
||||
|
||||
|
||||
@ -386,21 +611,35 @@ export type IndicatorSelectScalar = {
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
groupName?: boolean
|
||||
data?: boolean
|
||||
title?: boolean
|
||||
unit?: boolean
|
||||
source?: boolean
|
||||
frequency?: boolean
|
||||
hidden?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}
|
||||
|
||||
export type IndicatorOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "groupName" | "data" | "createdAt" | "updatedAt", ExtArgs["result"]["indicator"]>
|
||||
export type IndicatorOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "groupName" | "title" | "unit" | "source" | "frequency" | "hidden" | "createdAt" | "updatedAt", ExtArgs["result"]["indicator"]>
|
||||
export type IndicatorInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
points?: boolean | Prisma.Indicator$pointsArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $IndicatorPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "Indicator"
|
||||
objects: {}
|
||||
objects: {
|
||||
points: Prisma.$IndicatorPointPayload<ExtArgs>[]
|
||||
}
|
||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||
id: number
|
||||
name: string
|
||||
groupName: string
|
||||
data: runtime.JsonValue
|
||||
title: string
|
||||
unit: string
|
||||
source: string
|
||||
frequency: string
|
||||
hidden: boolean
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}, ExtArgs["result"]["indicator"]>
|
||||
@ -743,6 +982,7 @@ readonly fields: IndicatorFieldRefs;
|
||||
*/
|
||||
export interface Prisma__IndicatorClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
||||
readonly [Symbol.toStringTag]: "PrismaPromise"
|
||||
points<T extends Prisma.Indicator$pointsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Indicator$pointsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPointPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
@ -775,7 +1015,11 @@ export interface IndicatorFieldRefs {
|
||||
readonly id: Prisma.FieldRef<"Indicator", 'Int'>
|
||||
readonly name: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly groupName: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly data: Prisma.FieldRef<"Indicator", 'Json'>
|
||||
readonly title: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly unit: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly source: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly frequency: Prisma.FieldRef<"Indicator", 'String'>
|
||||
readonly hidden: Prisma.FieldRef<"Indicator", 'Boolean'>
|
||||
readonly createdAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
||||
readonly updatedAt: Prisma.FieldRef<"Indicator", 'DateTime'>
|
||||
}
|
||||
@ -794,6 +1038,10 @@ export type IndicatorFindUniqueArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter, which Indicator to fetch.
|
||||
*/
|
||||
@ -812,6 +1060,10 @@ export type IndicatorFindUniqueOrThrowArgs<ExtArgs extends runtime.Types.Extensi
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter, which Indicator to fetch.
|
||||
*/
|
||||
@ -830,6 +1082,10 @@ export type IndicatorFindFirstArgs<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter, which Indicator to fetch.
|
||||
*/
|
||||
@ -878,6 +1134,10 @@ export type IndicatorFindFirstOrThrowArgs<ExtArgs extends runtime.Types.Extensio
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter, which Indicator to fetch.
|
||||
*/
|
||||
@ -926,6 +1186,10 @@ export type IndicatorFindManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter, which Indicators to fetch.
|
||||
*/
|
||||
@ -974,6 +1238,10 @@ export type IndicatorCreateArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* The data needed to create a Indicator.
|
||||
*/
|
||||
@ -1003,6 +1271,10 @@ export type IndicatorUpdateArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* The data needed to update a Indicator.
|
||||
*/
|
||||
@ -1043,6 +1315,10 @@ export type IndicatorUpsertArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* The filter to search for the Indicator to update in case it exists.
|
||||
*/
|
||||
@ -1069,6 +1345,10 @@ export type IndicatorDeleteArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
/**
|
||||
* Filter which Indicator to delete.
|
||||
*/
|
||||
@ -1089,6 +1369,30 @@ export type IndicatorDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator.points
|
||||
*/
|
||||
export type Indicator$pointsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the IndicatorPoint
|
||||
*/
|
||||
select?: Prisma.IndicatorPointSelect<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the IndicatorPoint
|
||||
*/
|
||||
omit?: Prisma.IndicatorPointOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorPointInclude<ExtArgs> | null
|
||||
where?: Prisma.IndicatorPointWhereInput
|
||||
orderBy?: Prisma.IndicatorPointOrderByWithRelationInput | Prisma.IndicatorPointOrderByWithRelationInput[]
|
||||
cursor?: Prisma.IndicatorPointWhereUniqueInput
|
||||
take?: number
|
||||
skip?: number
|
||||
distinct?: Prisma.IndicatorPointScalarFieldEnum | Prisma.IndicatorPointScalarFieldEnum[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator without action
|
||||
*/
|
||||
@ -1101,4 +1405,8 @@ export type IndicatorDefaultArgs<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorInclude<ExtArgs> | null
|
||||
}
|
||||
|
||||
1321
generated/prisma/models/IndicatorPoint.ts
Normal file
1321
generated/prisma/models/IndicatorPoint.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -234,15 +234,15 @@ export type StrategyOrderByWithRelationInput = {
|
||||
|
||||
export type StrategyWhereUniqueInput = Prisma.AtLeast<{
|
||||
id?: number
|
||||
name?: string
|
||||
AND?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
||||
OR?: Prisma.StrategyWhereInput[]
|
||||
NOT?: Prisma.StrategyWhereInput | Prisma.StrategyWhereInput[]
|
||||
name?: Prisma.StringFilter<"Strategy"> | string
|
||||
description?: Prisma.StringFilter<"Strategy"> | string
|
||||
data?: Prisma.JsonFilter<"Strategy">
|
||||
createdAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"Strategy"> | Date | string
|
||||
}, "id" | "name">
|
||||
}, "id">
|
||||
|
||||
export type StrategyOrderByWithAggregationInput = {
|
||||
id?: Prisma.SortOrder
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
-- 经济指标: 明细数据拆到独立表, 兼容年/季/月/日频率
|
||||
-- 第一步: 建 IndicatorPoint 表 + Indicator 加元数据列 (data 列暂保留, 由迁移脚本搬运后删除)
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `IndicatorPoint` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`indicatorId` INTEGER NOT NULL,
|
||||
`period` VARCHAR(191) NOT NULL,
|
||||
`value` DOUBLE NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `IndicatorPoint_indicatorId_period_key`(`indicatorId`, `period`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AlterTable: 元数据列 (data JSON 拆出)
|
||||
ALTER TABLE `Indicator` ADD COLUMN `title` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `unit` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `source` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `frequency` VARCHAR(191) NOT NULL DEFAULT 'month';
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `IndicatorPoint` ADD CONSTRAINT `IndicatorPoint_indicatorId_fkey` FOREIGN KEY (`indicatorId`) REFERENCES `Indicator`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@ -0,0 +1,3 @@
|
||||
-- 第二步: 明细数据已迁移到 IndicatorPoint, 删除 Indicator.data JSON 列
|
||||
-- AlterTable
|
||||
ALTER TABLE `Indicator` DROP COLUMN `data`;
|
||||
@ -0,0 +1,2 @@
|
||||
-- 指标隐藏标记: 数据与获取脚本保留, 前端展示过滤 hidden=true
|
||||
ALTER TABLE `Indicator` ADD COLUMN `hidden` BOOLEAN NOT NULL DEFAULT false;
|
||||
@ -41,12 +41,29 @@ model Strategy {
|
||||
}
|
||||
|
||||
model Indicator {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
groupName String
|
||||
data Json
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
title String @default("")
|
||||
unit String @default("")
|
||||
source String @default("")
|
||||
frequency String @default("month") // year | quarter | month | day
|
||||
hidden Boolean @default(false) // true = 数据/脚本保留, 但不在前端展示
|
||||
points IndicatorPoint[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model IndicatorPoint {
|
||||
id Int @id @default(autoincrement())
|
||||
indicatorId Int
|
||||
indicator Indicator @relation(fields: [indicatorId], references: [id], onDelete: Cascade)
|
||||
period String // "2024" | "2024-Q1" | "2024-01" | "2024-01-15"
|
||||
value Float
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([indicatorId, period])
|
||||
}
|
||||
|
||||
model Econ_SowInventory {
|
||||
@ -66,3 +83,5 @@ model ScraperCache {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
|
||||
|
||||
20
readme
20
readme
@ -6,18 +6,18 @@
|
||||
|
||||
|
||||
|
||||
|
||||
## 新闻模块
|
||||
增加一个新闻模块,数据来源是每日夜间 3点,通过妙想 MCP 获取国内外最新经济政治新闻,按影响大小排序10条。
|
||||
存入数据库。
|
||||
|
||||
|
||||
## 报警模块
|
||||
World Bank 中的数据只用来对比妙想 MCP 拉取的数据正确性。当同一时间的同一项数据不同时,记录一个报警。
|
||||
|
||||
|
||||
## 首页
|
||||
首页显示新闻模块和报警模块的数据,按照时间最新优先,无限滚动,直到数据库中没有数据为止。
|
||||
|
||||
|
||||
### 新闻模块
|
||||
增加一个新闻模块,数据来源是每日夜间 3点,通过妙想 MCP 获取国内外最新经济政治新闻,按影响大小排序10条。
|
||||
存入数据库。
|
||||
|
||||
|
||||
### 报警模块
|
||||
World Bank 中的数据只用来对比妙想 MCP 拉取的数据正确性。当同一时间的同一项数据不同时,记录一个报警。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -50,6 +50,59 @@ const INDICATORS = [
|
||||
sheets.find((s) => s.items?.[0]?.[0]?.includes('GDP') && s.items[0][0].includes('同比'))
|
||||
|| sheets[0],
|
||||
},
|
||||
{
|
||||
// 国债收益率: MCP 返回日频, 用月末降采样成月频点
|
||||
name: 'china-bond-10y',
|
||||
groupName: 'china-macro',
|
||||
title: '中国国债 10 年期收益率',
|
||||
unit: '%',
|
||||
frequency: 'month',
|
||||
tool: 'mx_macro_data',
|
||||
query: '查询中国10年期国债到期收益率 2024年至今 每日数据',
|
||||
pickSheet: (sheets) =>
|
||||
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:10年')))
|
||||
|| sheets[0],
|
||||
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:10年'),
|
||||
},
|
||||
{
|
||||
name: 'china-bond-1y',
|
||||
groupName: 'china-macro',
|
||||
title: '中国国债 1 年期收益率',
|
||||
unit: '%',
|
||||
frequency: 'month',
|
||||
tool: 'mx_macro_data',
|
||||
query: '查询中国1年期国债到期收益率 2024年至今 每日数据',
|
||||
pickSheet: (sheets) =>
|
||||
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:1年')))
|
||||
|| sheets[0],
|
||||
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:1年'),
|
||||
},
|
||||
{
|
||||
name: 'china-lpr-1y',
|
||||
groupName: 'china-macro',
|
||||
title: '中国 LPR 1 年期',
|
||||
unit: '%',
|
||||
frequency: 'month',
|
||||
tool: 'mx_macro_data',
|
||||
query: '查询中国LPR 1年期贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
|
||||
pickSheet: (sheets) =>
|
||||
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|
||||
|| sheets[0],
|
||||
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):1年'),
|
||||
},
|
||||
{
|
||||
name: 'china-lpr-5y',
|
||||
groupName: 'china-macro',
|
||||
title: '中国 LPR 5 年期',
|
||||
unit: '%',
|
||||
frequency: 'month',
|
||||
tool: 'mx_macro_data',
|
||||
query: '查询中国LPR 5年期以上贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
|
||||
pickSheet: (sheets) =>
|
||||
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|
||||
|| sheets[0],
|
||||
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):5年'),
|
||||
},
|
||||
]
|
||||
|
||||
export const META = {
|
||||
@ -139,6 +192,44 @@ function defaultParseSheet(sheet) {
|
||||
return out.reverse() // 从老到新
|
||||
}
|
||||
|
||||
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 日频列降采样为月末值
|
||||
// 例: columns=["指标","来源","2026-08-05","2026-08-04",...] → [{period:"2024-01",value},...]
|
||||
function monthEndSample(sheet, keyword) {
|
||||
if (!sheet || !sheet.columns || !sheet.items) return []
|
||||
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
|
||||
if (!row) return []
|
||||
const cols = sheet.columns
|
||||
const dates = cols.slice(2) // 新 → 老
|
||||
const values = row.slice(2)
|
||||
const out = []
|
||||
const seen = new Set()
|
||||
for (let i = 0; i < dates.length; i++) {
|
||||
const v = parseFloat(values[i])
|
||||
const m = String(dates[i] || '').slice(0, 7) // "2024-01-02" → "2024-01"
|
||||
if (!/^\d{4}-\d{2}$/.test(m) || Number.isNaN(v)) continue
|
||||
if (seen.has(m)) continue // 列是降序, 第一次遇到的即当月最后一个交易日
|
||||
seen.add(m)
|
||||
out.push({ period: m, value: v })
|
||||
}
|
||||
return out.reverse() // 从老到新
|
||||
}
|
||||
|
||||
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 保留原频率 (月/季/年)
|
||||
function pickRowByKeyword(sheet, keyword) {
|
||||
if (!sheet || !sheet.columns || !sheet.items) return []
|
||||
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
|
||||
if (!row) return []
|
||||
const cols = sheet.columns
|
||||
const dates = cols.slice(2)
|
||||
const values = row.slice(2)
|
||||
const out = []
|
||||
for (let i = 0; i < dates.length; i++) {
|
||||
const v = parseFloat(values[i])
|
||||
if (!Number.isNaN(v)) out.push({ period: String(dates[i]), value: v })
|
||||
}
|
||||
return out.reverse() // 从老到新
|
||||
}
|
||||
|
||||
// ====== fetcher 入口 ======
|
||||
|
||||
export async function listAvailableTools() {
|
||||
@ -156,6 +247,7 @@ export async function fetchAll(opts = {}) {
|
||||
throw new Error('eastmoney-mcp: INDICATORS 数组为空, 加新指标见文件顶部注释')
|
||||
}
|
||||
const skip = opts.skipNames || new Set()
|
||||
const force = opts.forceNames || new Set()
|
||||
const only = opts.onlyNames || null
|
||||
|
||||
const key = process.env.EM_API_KEY
|
||||
@ -165,7 +257,7 @@ export async function fetchAll(opts = {}) {
|
||||
|
||||
const results = []
|
||||
for (const cfg of INDICATORS) {
|
||||
if (skip.has(cfg.name)) {
|
||||
if (skip.has(cfg.name) && !force.has(cfg.name)) {
|
||||
console.log(`[MCP] ${cfg.name} 跳过 (DB 已存在)`)
|
||||
continue
|
||||
}
|
||||
@ -199,7 +291,7 @@ export async function fetchAll(opts = {}) {
|
||||
}
|
||||
}
|
||||
// 全部被 DB 优先跳过时, 返回显式标记而不是空数组 (避免被误判为失败)
|
||||
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name))) {
|
||||
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name) && !force.has(cfg.name))) {
|
||||
return { skipped: true, reason: 'DB 已存在全部指标' }
|
||||
}
|
||||
return results
|
||||
@ -208,3 +300,4 @@ export async function fetchAll(opts = {}) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -36,7 +36,8 @@ export function checkEnv(required) {
|
||||
|
||||
// 加载并运行所有启用的 fetcher, 返回 [{ name, ok, items, error, skipped }]
|
||||
// 错误隔离: 一个 fetcher 挂了不影响其他
|
||||
// opts.skipNames: Set<string> — DB 优先, 已存在的指标名, 透传给 fetcher
|
||||
// opts.skipNames: Set<string> — DB 优先, 已存在的指标名, 透传给 fetcher
|
||||
// opts.forceNames: Set<string> — 强制刷新名单, 即使 skipNames 里有也照拉
|
||||
export async function runFetchers(opts = {}) {
|
||||
const results = []
|
||||
for (const meta of FETCHERS) {
|
||||
@ -57,7 +58,7 @@ export async function runFetchers(opts = {}) {
|
||||
throw new Error('fetcher 必须导出 META 和 fetchAll')
|
||||
}
|
||||
console.log(`[Fetcher] ${meta.name} 开始...`)
|
||||
const out = await mod.fetchAll({ skipNames: opts.skipNames, onlyNames: opts.onlyNames })
|
||||
const out = await mod.fetchAll({ skipNames: opts.skipNames, onlyNames: opts.onlyNames, forceNames: opts.forceNames })
|
||||
// fetcher 可返回 { skipped: true, reason } 表示"全部被 DB 优先跳过", 不算失败
|
||||
if (out && out.skipped) {
|
||||
results.push({ name: meta.name, skipped: true, reason: out.reason })
|
||||
|
||||
84
scripts/migrate-indicator-points.cjs
Normal file
84
scripts/migrate-indicator-points.cjs
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 一次性数据迁移: 把 Indicator.data (JSON) 拆分到 IndicatorPoint 明细表
|
||||
* 用法: 在迁移 A (建表+加列) 之后、迁移 B (删 data 列) 之前运行
|
||||
* 幂等: 同 (indicatorId, period) 重复插入会更新 value, 可安全重跑
|
||||
*/
|
||||
require('dotenv').config()
|
||||
const mysql = require('mysql2/promise')
|
||||
|
||||
function parseUrl(url) {
|
||||
const u = new URL(url)
|
||||
return {
|
||||
host: u.hostname,
|
||||
port: Number(u.port) || 3306,
|
||||
user: decodeURIComponent(u.username),
|
||||
password: decodeURIComponent(u.password),
|
||||
database: u.pathname.replace(/^\//, ''),
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 row 的时间字段推断频率: year | quarter | month | day
|
||||
function inferFrequency(row) {
|
||||
if (row && row.month !== undefined) return 'month'
|
||||
if (row && row.year !== undefined) return 'year'
|
||||
const p = String((row && row.period) || '')
|
||||
if (/^\d{4}$/.test(p)) return 'year'
|
||||
if (/^\d{4}-Q[1-4]$/.test(p)) return 'quarter'
|
||||
if (/^\d{4}-\d{2}$/.test(p)) return 'month'
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(p)) return 'day'
|
||||
return 'month'
|
||||
}
|
||||
|
||||
// 统一 row 的时间字段为 period
|
||||
function periodOf(row) {
|
||||
if (!row) return ''
|
||||
return String(row.period !== undefined ? row.period : (row.month !== undefined ? row.month : row.year))
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
||||
try {
|
||||
const [rows] = await conn.execute('SELECT id, name, groupName, data FROM Indicator')
|
||||
console.log('[Migrate] 读取', rows.length, '个 Indicator')
|
||||
|
||||
let points = 0, updated = 0
|
||||
for (const ind of rows) {
|
||||
// mysql2 对 JSON 列已自动解析为对象, 兼容字符串兜底
|
||||
let data = ind.data
|
||||
if (typeof data === 'string') {
|
||||
try { data = JSON.parse(data) } catch { data = null }
|
||||
}
|
||||
const title = (data && data.title) || ind.name
|
||||
const unit = (data && data.unit) || ''
|
||||
const source = (data && data.source) || ''
|
||||
const rowsArr = (data && Array.isArray(data.rows)) ? data.rows : []
|
||||
const freq = rowsArr.length ? inferFrequency(rowsArr[0]) : 'month'
|
||||
|
||||
// 更新 Indicator 元数据列
|
||||
await conn.execute(
|
||||
'UPDATE Indicator SET title=?, unit=?, source=?, frequency=?, updatedAt=NOW(3) WHERE id=?',
|
||||
[title, unit, source, freq, ind.id],
|
||||
)
|
||||
updated++
|
||||
|
||||
// 写入明细
|
||||
for (const r of rowsArr) {
|
||||
const period = periodOf(r)
|
||||
const value = Number(r.value)
|
||||
if (!period || Number.isNaN(value)) continue
|
||||
const [res] = await conn.execute(
|
||||
'INSERT INTO IndicatorPoint (indicatorId, period, value, createdAt, updatedAt) VALUES (?, ?, ?, NOW(3), NOW(3)) ' +
|
||||
'ON DUPLICATE KEY UPDATE value=VALUES(value), updatedAt=NOW(3)',
|
||||
[ind.id, period, value],
|
||||
)
|
||||
points += (res.affectedRows > 0 ? 1 : 0)
|
||||
}
|
||||
console.log('[Migrate]', ind.name, '->', rowsArr.length, '个点, 频率', freq)
|
||||
}
|
||||
console.log('[Migrate] 完成: 更新', updated, '个 Indicator, 写入/更新', points, '个明细点')
|
||||
} finally {
|
||||
await conn.end()
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => { console.error('[Migrate] 失败:', e); process.exit(1) })
|
||||
@ -1,7 +1,12 @@
|
||||
/**
|
||||
* 拉所有启用的数据源, upsert 到 Indicator 表
|
||||
* 用法: npm run data:refresh
|
||||
* 幂等: 同 name 覆盖 data, 跨源独立, 错误隔离
|
||||
* 拉所有启用的数据源, upsert 到 Indicator + IndicatorPoint 明细表
|
||||
* 用法:
|
||||
* npm run data:refresh # 只拉 DB 里没有的指标
|
||||
* npm run data:refresh -- --force a,b,c # 强制刷新指定指标 (忽略 DB 已有)
|
||||
*
|
||||
* 数据结构 (2026-08 重构):
|
||||
* Indicator 元数据: name/groupName/title/unit/source/frequency/hidden
|
||||
* IndicatorPoint 明细: (indicatorId, period, value), period 兼容年/季/月/日
|
||||
*
|
||||
* DB 优先策略:
|
||||
* 1. 先从 DB 查已存在的 name 集合
|
||||
@ -14,6 +19,15 @@
|
||||
require('dotenv').config()
|
||||
const mysql = require('mysql2/promise')
|
||||
|
||||
// 隐藏指标: 数据与获取脚本保留, 但不参与前端展示 (API 过滤)
|
||||
const HIDDEN_INDICATORS = new Set([
|
||||
'china-gdp-usd', // 中国 GDP (现价美元)
|
||||
'china-gdp-growth', // 中国 GDP 同比 (World Bank)
|
||||
'china-gdp-yoy', // 中国 GDP 同比 (妙想季度)
|
||||
'china-unemploy', // 中国失业率
|
||||
'usa-gdp-usd', // 美国 GDP
|
||||
])
|
||||
|
||||
function parseUrl(url) {
|
||||
const u = new URL(url)
|
||||
return {
|
||||
@ -25,13 +39,63 @@ function parseUrl(url) {
|
||||
}
|
||||
}
|
||||
|
||||
async function upsertIndicator(conn, payload) {
|
||||
const sql =
|
||||
'INSERT INTO `Indicator` (`name`, `groupName`, `data`, `createdAt`, `updatedAt`) ' +
|
||||
'VALUES (?, ?, ?, NOW(3), NOW(3)) ' +
|
||||
'ON DUPLICATE KEY UPDATE `groupName` = VALUES(`groupName`), `data` = VALUES(`data`), `updatedAt` = NOW(3)'
|
||||
const [r] = await conn.execute(sql, [payload.name, payload.groupName, JSON.stringify(payload.data)])
|
||||
return r.affectedRows
|
||||
function parseForceArg(argv) {
|
||||
const i = argv.indexOf('--force')
|
||||
if (i === -1) return new Set()
|
||||
return new Set(String(argv[i + 1] || '').split(',').map((s) => s.trim()).filter(Boolean))
|
||||
}
|
||||
|
||||
// 推断频率: year | quarter | month | day (优先用 fetcher 显式声明)
|
||||
function inferFrequency(data) {
|
||||
if (data && data.frequency) return data.frequency
|
||||
const p = String(((data && data.rows) || [])[0]?.period || '')
|
||||
if (/^\d{4}$/.test(p)) return 'year'
|
||||
if (/^\d{4}-Q[1-4]$/.test(p)) return 'quarter'
|
||||
if (/^\d{4}-\d{2}$/.test(p)) return 'month'
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(p)) return 'day'
|
||||
return 'month'
|
||||
}
|
||||
|
||||
// 写 Indicator 元数据 + 全量替换明细点 (每指标一个事务)
|
||||
async function upsertIndicatorWithPoints(conn, payload) {
|
||||
const { name, groupName, data, hidden } = payload
|
||||
const title = data.title || name
|
||||
const unit = data.unit || ''
|
||||
const source = data.source || ''
|
||||
const frequency = inferFrequency(data)
|
||||
const rows = Array.isArray(data.rows) ? data.rows : []
|
||||
|
||||
await conn.beginTransaction()
|
||||
try {
|
||||
const [res] = await conn.execute(
|
||||
'INSERT INTO `Indicator` (`name`, `groupName`, `title`, `unit`, `source`, `frequency`, `hidden`, `createdAt`, `updatedAt`) ' +
|
||||
'VALUES (?, ?, ?, ?, ?, ?, ?, NOW(3), NOW(3)) ' +
|
||||
'ON DUPLICATE KEY UPDATE `groupName` = VALUES(`groupName`), `title` = VALUES(`title`), ' +
|
||||
'`unit` = VALUES(`unit`), `source` = VALUES(`source`), `frequency` = VALUES(`frequency`), ' +
|
||||
'`hidden` = VALUES(`hidden`), `updatedAt` = NOW(3)',
|
||||
[name, groupName, title, unit, source, frequency, hidden ? 1 : 0],
|
||||
)
|
||||
const indicatorId = res.insertId
|
||||
|
||||
// 明细: 先删旧点再插入新点 (全量替换, 保证与数据源一致)
|
||||
await conn.execute('DELETE FROM `IndicatorPoint` WHERE `indicatorId` = ?', [indicatorId])
|
||||
let points = 0
|
||||
for (const r of rows) {
|
||||
const period = String(r.period !== undefined ? r.period : (r.month !== undefined ? r.month : r.year))
|
||||
const value = Number(r.value)
|
||||
if (!period || Number.isNaN(value)) continue
|
||||
await conn.execute(
|
||||
'INSERT INTO `IndicatorPoint` (`indicatorId`, `period`, `value`, `createdAt`, `updatedAt`) VALUES (?, ?, ?, NOW(3), NOW(3))',
|
||||
[indicatorId, period, value],
|
||||
)
|
||||
points++
|
||||
}
|
||||
await conn.commit()
|
||||
return { indicatorId, points }
|
||||
} catch (e) {
|
||||
await conn.rollback()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchExistingNames(conn) {
|
||||
@ -44,48 +108,63 @@ async function main() {
|
||||
console.error('缺少 DATABASE_URL 环境变量')
|
||||
process.exit(1)
|
||||
}
|
||||
const force = parseForceArg(process.argv.slice(2))
|
||||
if (force.size) console.log('[Refresh] 强制刷新: ' + [...force].join(', '))
|
||||
|
||||
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
||||
try {
|
||||
// 1) 查 DB 已存在的指标名
|
||||
const existing = await fetchExistingNames(conn)
|
||||
console.log(`[Refresh] DB 已有 ${existing.size} 个指标: ${[...existing].join(', ') || '(空)'}`)
|
||||
console.log('[Refresh] DB 已有 ' + existing.size + ' 个指标: ' + ([...existing].join(', ') || '(空)'))
|
||||
|
||||
// 2) 跑所有 fetcher, 传入 existing (DB 优先)
|
||||
// 2) 跑所有 fetcher, 传入 existing + force (DB 优先, force 覆盖)
|
||||
const { runFetchers } = await import('./fetchers/index.js')
|
||||
const fetcherResults = await runFetchers({ skipNames: existing })
|
||||
const fetcherResults = await runFetchers({ skipNames: existing, forceNames: force })
|
||||
|
||||
// 3) 汇总
|
||||
// 3) 汇总: force 名单里的指标即使 DB 已有也写入
|
||||
const allItems = []
|
||||
let skipped = 0, failed = 0
|
||||
for (const r of fetcherResults) {
|
||||
if (r.skipped) { skipped++; continue }
|
||||
if (!r.ok) { failed++; continue }
|
||||
// fetcher 内部已经按 skipNames 过滤过, 这里再做一次防御性去重
|
||||
for (const it of r.items) {
|
||||
if (existing.has(it.name)) continue
|
||||
if (existing.has(it.name) && !force.has(it.name)) continue
|
||||
allItems.push(it)
|
||||
}
|
||||
}
|
||||
console.log(`\n[Refresh] 汇总: ${allItems.length} 个新指标 (跳过 ${skipped} 个数据源, 失败 ${failed} 个, DB 已存在 ${existing.size} 个)`)
|
||||
console.log('\n[Refresh] 汇总: ' + allItems.length + ' 个指标待写 (跳过 ' + skipped + ' 个数据源, 失败 ' + failed + ' 个, DB 已存在 ' + existing.size + ' 个)')
|
||||
|
||||
if (failed > 0) {
|
||||
console.error('[Refresh] 警告: 有数据源失败, 仅写入成功的指标')
|
||||
}
|
||||
|
||||
// 5) 同步隐藏标记: 即使指标被 DB 优先跳过, 名单内的也确保 hidden=true
|
||||
if (HIDDEN_INDICATORS.size > 0) {
|
||||
const names = [...HIDDEN_INDICATORS]
|
||||
const ph = names.map(() => '?').join(',')
|
||||
const sql = "UPDATE `Indicator` SET `hidden` = 1, `updatedAt` = NOW(3) WHERE `name` IN (" + ph + ")"
|
||||
await conn.execute(sql, names)
|
||||
console.log('[Refresh] 同步隐藏标记: ' + names.length + ' 个指标 hidden=true (数据保留, 不展示)')
|
||||
}
|
||||
|
||||
if (allItems.length === 0) {
|
||||
console.log('[Refresh] 无新指标, 不写库 (DB 优先策略生效)')
|
||||
console.log('[Refresh] 无指标待写, 不写库 (DB 优先策略生效)')
|
||||
return
|
||||
}
|
||||
|
||||
// 4) 写库
|
||||
console.log('[Refresh] 写入数据库...')
|
||||
let ins = 0, upd = 0
|
||||
let ins = 0, upd = 0, totalPoints = 0
|
||||
for (const it of allItems) {
|
||||
const n = await upsertIndicator(conn, { name: it.name, groupName: it.groupName, data: it.data })
|
||||
if (n === 1) ins++
|
||||
else if (n === 2) upd++
|
||||
const hidden = HIDDEN_INDICATORS.has(it.name)
|
||||
const { points } = await upsertIndicatorWithPoints(conn, { name: it.name, groupName: it.groupName, data: it.data, hidden })
|
||||
if (points > 0) ins++
|
||||
else upd++
|
||||
totalPoints += points
|
||||
console.log('[Refresh] ' + it.name + (hidden ? ' (hidden)' : '') + ': ' + points + ' 个明细点')
|
||||
}
|
||||
console.log(`[Refresh] 写入完成: ${ins} 新增, ${upd} 更新\n`)
|
||||
console.log('[Refresh] 写入完成: ' + ins + ' 个指标有数据, ' + upd + ' 个无数据, 共 ' + totalPoints + ' 个明细点\n')
|
||||
|
||||
} finally {
|
||||
await conn.end()
|
||||
}
|
||||
@ -95,3 +174,4 @@ main().catch((e) => {
|
||||
console.error('[Refresh] 异常:', e)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
|
||||
@ -92,16 +92,8 @@ async function main() {
|
||||
}
|
||||
console.log('[Strategy] upsert 策略: ' + n2 + ' 行 (1=新增, 2=更新)');
|
||||
|
||||
// Indicator 表: 改由 scripts/refresh-indicators.cjs 从 World Bank API 拉取最新数据
|
||||
// 旧 4 个金融指标 (国债/LPR) 无稳定 JSON 数据源, 暂不维护
|
||||
const indicators = [];
|
||||
let n3 = 0;
|
||||
for (const i of indicators) {
|
||||
n3 += await upsertByName(conn, 'Indicator',
|
||||
{ name: i.name, groupName: i.groupName, data: JSON.stringify(i.data), updatedAt: new Date() },
|
||||
'name');
|
||||
}
|
||||
console.log('[Indicator] upsert 指标: ' + n3 + ' 行 (1=新增, 2=更新)');
|
||||
// Indicator 表: 改由 scripts/refresh-indicators.cjs 管理 (2026-08 重构后数据存 IndicatorPoint 明细表)
|
||||
// 本脚本不再写入 Indicator, 如需初始化指标请运行 npm run data:refresh
|
||||
|
||||
const article = {
|
||||
title: '欢迎使用 iBoard',
|
||||
|
||||
@ -6,10 +6,26 @@ const router = Router()
|
||||
|
||||
router.use(authRequired)
|
||||
|
||||
// 指标列表: 元数据 + 明细点, 过滤 hidden (数据与脚本保留, 仅不展示)
|
||||
router.get('/indicators', async (_req, res, next) => {
|
||||
try {
|
||||
const rows = await prisma.indicator.findMany({ orderBy: [{ groupName: 'asc' }, { name: 'asc' }] })
|
||||
res.json({ indicators: rows })
|
||||
const rows = await prisma.indicator.findMany({
|
||||
where: { hidden: false },
|
||||
include: { points: { orderBy: { period: 'asc' } } },
|
||||
orderBy: [{ groupName: 'asc' }, { name: 'asc' }],
|
||||
})
|
||||
// 组装前端友好结构: points 保持从老到新
|
||||
const indicators = rows.map((r) => ({
|
||||
id: r.id,
|
||||
name: r.name,
|
||||
groupName: r.groupName,
|
||||
title: r.title,
|
||||
unit: r.unit,
|
||||
source: r.source,
|
||||
frequency: r.frequency,
|
||||
points: r.points.map((p) => ({ period: p.period, value: p.value })),
|
||||
}))
|
||||
res.json({ indicators })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
|
||||
@ -45,10 +45,13 @@ export default function MacroPage() {
|
||||
if (next) navigate(next.path)
|
||||
}
|
||||
|
||||
// 详情页 /macro/articles/:slug 单独走 React Router 渲染, 不参与滑屏
|
||||
if (location.pathname.match(/^\/macro\/articles\/[^/]+$/)) {
|
||||
// 详情页 /macro/articles/:slug 和 /macro/data/:name 单独走 React Router 渲染, 不参与滑屏
|
||||
// 这样浏览器/手机物理返回键也能正常回到列表
|
||||
if (location.pathname.match(/^\/macro\/(articles|data|strategy)\/[^/]+$/)) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="data/:name" element={<DataView />} />
|
||||
<Route path="strategy/:name" element={<StrategyView />} />
|
||||
<Route path="articles/:slug" element={<ArticleDetail />} />
|
||||
</Routes>
|
||||
)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
||||
import { Card, List, NavBar } from 'antd-mobile'
|
||||
import { api } from '../../api/client.js'
|
||||
@ -7,6 +8,9 @@ import TrendBadge, { calcTrend, lastPoint } from '../../components/TrendBadge.js
|
||||
// 经济数据
|
||||
// 列表态 (默认): 列出所有指标, 每行显示最新值 + 趋势徽标, 点击进入详情
|
||||
// 详情态: 顶部 NavBar (返回) + 折线图 + 数据表
|
||||
// 频率中文标签 (对应 Indicator.frequency)
|
||||
const FREQ_LABEL = { year: '年', quarter: '季', month: '月', day: '日' }
|
||||
|
||||
// 统一数据行的时间字段: 兼容 {month}/{year}/{period} 三种存储形状
|
||||
function periodOf(r) {
|
||||
return (r && (r.period || r.month || r.year)) || ''
|
||||
@ -16,7 +20,9 @@ export default function DataView() {
|
||||
const [indicators, setIndicators] = useState([])
|
||||
const [err, setErr] = useState('')
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selected, setSelected] = useState(null) // null = 列表态, 名称 = 详情态
|
||||
// 路由驱动: /macro/data 列表, /macro/data/:name 详情, 浏览器/手机返回键天然可用
|
||||
const { name } = useParams()
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
@ -35,41 +41,33 @@ export default function DataView() {
|
||||
if (err) return <div className="error-banner">{err}</div>
|
||||
if (!indicators.length) return <div className="empty">暂无指标数据, 请先执行 npm run db:seed</div>
|
||||
|
||||
// 详情态
|
||||
if (selected) {
|
||||
const cur = indicators.find((i) => i.name === selected)
|
||||
if (cur) return <DataDetail indicator={cur} onBack={() => setSelected(null)} />
|
||||
// 详情态 (路径 /macro/data/:name)
|
||||
if (name) {
|
||||
const cur = indicators.find((i) => i.name === name)
|
||||
if (cur) return <DataDetail indicator={cur} onBack={() => navigate('/macro/data')} />
|
||||
}
|
||||
|
||||
// 列表态
|
||||
const labelOf = (i) => (i.data && i.data.title) || i.name
|
||||
const labelOf = (i) => i.title || i.name
|
||||
|
||||
return (
|
||||
<div className="list-page">
|
||||
<div className="page-title">经济数据</div>
|
||||
<List>
|
||||
{indicators.map((i) => {
|
||||
const lp = lastPoint(i.data)
|
||||
const { trend, change } = calcTrend(i.data && i.data.rows)
|
||||
const unit = (i.data && i.data.unit) || ''
|
||||
const lp = lastPoint({ rows: i.points || [] })
|
||||
const { trend, change } = calcTrend(i.points || [])
|
||||
const unit = i.unit || ''
|
||||
return (
|
||||
<List.Item
|
||||
key={i.name}
|
||||
title={labelOf(i)}
|
||||
description={lp ? <><b>{lp.value}{unit}</b> · {periodOf(lp)}</> : '暂无数据'}
|
||||
extra={
|
||||
<div className="row-meta">
|
||||
{lp && Math.abs(change) >= 1 && (
|
||||
<span className="row-change">
|
||||
{change > 0 ? '+' : ''}{change.toFixed(1)}%
|
||||
</span>
|
||||
)}
|
||||
<TrendBadge trend={trend} />
|
||||
</div>
|
||||
}
|
||||
extra={<TrendBadge trend={trend} />}
|
||||
|
||||
arrowIcon
|
||||
clickable
|
||||
onClick={() => setSelected(i.name)}
|
||||
onClick={() => navigate('/macro/data/' + i.name)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
@ -81,19 +79,19 @@ export default function DataView() {
|
||||
// 详情: 折线图 + 数据表
|
||||
function DataDetail({ indicator, onBack }) {
|
||||
const i = indicator
|
||||
const rows = (i.data && i.data.rows) || []
|
||||
const rows = (i.points || [])
|
||||
// 图表 X 轴统一用 period 字段
|
||||
const chartRows = rows.map((r) => ({ ...r, period: periodOf(r) }))
|
||||
const lp = lastPoint(i.data)
|
||||
const lp = lastPoint({ rows })
|
||||
const { trend } = calcTrend(rows)
|
||||
const title = (i.data && i.data.title) || i.name
|
||||
const title = i.title || i.name
|
||||
return (
|
||||
<div className="detail-page">
|
||||
<NavBar onBack={onBack}>{title}</NavBar>
|
||||
<Card className="detail-card">
|
||||
<div className="detail-meta">
|
||||
单位 {i.data.unit || '-'} · 来源 {i.data.source || 'seed'} ·
|
||||
{lp && <> 最新 <b style={{ color: 'var(--color-text)' }}>{lp.value}{i.data.unit || ''}</b> ({periodOf(lp)}) </>}
|
||||
单位 {i.unit || '-'} · 频率 {FREQ_LABEL[i.frequency] || i.frequency || '-'} · 来源 {i.source || 'seed'} ·
|
||||
{lp && <> 最新 <b style={{ color: 'var(--color-text)' }}>{lp.value}{i.unit || ''}</b> ({periodOf(lp)}) </>}
|
||||
<TrendBadge trend={trend} />
|
||||
</div>
|
||||
<div className="chart-wrap">
|
||||
@ -104,7 +102,7 @@ function DataDetail({ indicator, onBack }) {
|
||||
<YAxis tick={{ fontSize: 11 }} />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Line type="monotone" dataKey="value" name={i.data.unit || '值'} stroke="#1677ff" strokeWidth={2} dot={{ r: 3 }} />
|
||||
<Line type="monotone" dataKey="value" name={i.unit || '值'} stroke="#1677ff" strokeWidth={2} dot={{ r: 3 }} />
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
||||
import { Card, List, NavBar } from 'antd-mobile'
|
||||
import { api } from '../../api/client.js'
|
||||
@ -26,7 +27,9 @@ export default function StrategyView() {
|
||||
const [strategies, setStrategies] = useState([])
|
||||
const [err, setErr] = useState('')
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selected, setSelected] = useState(null)
|
||||
// 路由驱动: /macro/strategy 列表, /macro/strategy/:name 详情, 浏览器/手机返回键天然可用
|
||||
const { name } = useParams()
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
@ -42,10 +45,10 @@ export default function StrategyView() {
|
||||
if (err) return <div className="error-banner">{err}</div>
|
||||
if (!strategies.length) return <div className="empty">暂无策略数据</div>
|
||||
|
||||
// 详情态
|
||||
if (selected) {
|
||||
const cur = strategies.find((s) => s.name === selected)
|
||||
if (cur) return <StrategyDetail strategy={cur} onBack={() => setSelected(null)} />
|
||||
// 详情态 (路径 /macro/strategy/:name)
|
||||
if (name) {
|
||||
const cur = strategies.find((s) => s.name === name)
|
||||
if (cur) return <StrategyDetail strategy={cur} onBack={() => navigate('/macro/strategy')} />
|
||||
}
|
||||
|
||||
// 列表态: 主指标 = 债务/GDP, 趋势基于其最近变化
|
||||
@ -64,19 +67,10 @@ export default function StrategyView() {
|
||||
description={last
|
||||
? <><b>{last.debtToGdp}%</b> · 债务利息/GDP {last.interestToGdp}% · {last.year}</>
|
||||
: '暂无数据'}
|
||||
extra={
|
||||
<div className="row-meta">
|
||||
{last && Math.abs(change) >= 1 && (
|
||||
<span className="row-change">
|
||||
{change > 0 ? '+' : ''}{change.toFixed(1)}%
|
||||
</span>
|
||||
)}
|
||||
<TrendBadge trend={trend} />
|
||||
</div>
|
||||
}
|
||||
extra={<TrendBadge trend={trend} />}
|
||||
arrowIcon
|
||||
clickable
|
||||
onClick={() => setSelected(s.name)}
|
||||
onClick={() => navigate('/macro/strategy/' + s.name)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user