181 lines
6.5 KiB
Plaintext
181 lines
6.5 KiB
Plaintext
// VR-P32b/VR-P32d — KWP inbound project capability.
|
|
//
|
|
// AD-21: this module owns its schema. Cross-module references intentionally
|
|
// remain bare scalars and are protected by the generated tenant-policy
|
|
// contract. KWP is read-only; no outbound mutation or KWP numbering model
|
|
// belongs in this file.
|
|
|
|
enum KwpCapabilityStatus {
|
|
active
|
|
paused
|
|
}
|
|
|
|
enum KwpProjectCatalogStatus {
|
|
pending
|
|
syncing
|
|
ready
|
|
partial
|
|
paused
|
|
}
|
|
|
|
enum KwpProjectCatalogItemState {
|
|
discovered
|
|
active
|
|
missing
|
|
}
|
|
|
|
model KwpApiContractSnapshot {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
capability String
|
|
apiVersion String
|
|
semanticFingerprint String
|
|
consumedContract Json
|
|
adapterRevision String
|
|
validatedAt DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([tenantId, dataConnectionId, capability, semanticFingerprint])
|
|
@@index([tenantId, dataConnectionId, createdAt(sort: Desc)])
|
|
}
|
|
|
|
model KwpCapabilityState {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
capability String
|
|
status KwpCapabilityStatus @default(active)
|
|
reasonCode String?
|
|
observedFingerprint String?
|
|
approvedFingerprint String?
|
|
adapterRevision String
|
|
revision Int @default(1)
|
|
pausedAt DateTime?
|
|
lastCheckedAt DateTime?
|
|
approvedAt DateTime?
|
|
approvedByUserId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([tenantId, dataConnectionId, capability])
|
|
@@index([tenantId, status])
|
|
}
|
|
|
|
model KwpErrorReport {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
capability String
|
|
code String
|
|
redactedDetails Json
|
|
createdAt DateTime @default(now())
|
|
resolvedAt DateTime?
|
|
resolvedByUserId String?
|
|
|
|
@@index([tenantId, dataConnectionId, createdAt(sort: Desc)])
|
|
@@index([tenantId, resolvedAt])
|
|
}
|
|
|
|
/// Stable provider-status to HiveGrid Pipeline/Stage routing. Names are never
|
|
/// used as runtime identifiers; archived/missing targets quarantine the item.
|
|
model KwpProjectRouting {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
externalStatus Int
|
|
pipelineId String
|
|
stageId String
|
|
revision Int @default(1)
|
|
createdByUserId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([tenantId, dataConnectionId, externalStatus])
|
|
@@index([tenantId, pipelineId, stageId])
|
|
}
|
|
|
|
/// Connection-level progress for the automatic read-only KWP project catalog.
|
|
/// Discovery is intentionally cursorless and represents only the project set
|
|
/// visible through the confirmed mandant's Projektampel settings.
|
|
model KwpProjectCatalogState {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
status KwpProjectCatalogStatus @default(pending)
|
|
discoveredCount Int @default(0)
|
|
hydratedCount Int @default(0)
|
|
revision Int @default(1)
|
|
lastDiscoveryAt DateTime?
|
|
nextDiscoveryAt DateTime @default(now())
|
|
lastCompletedAt DateTime?
|
|
lastErrorCode String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([tenantId, dataConnectionId], map: "KwpProjectCatalogState_tenant_connection_key")
|
|
@@index([tenantId, status, nextDiscoveryAt], map: "KwpProjectCatalogState_tenant_due_idx")
|
|
}
|
|
|
|
/// Safe, normalized project fields used for cache-first KWP search. No raw
|
|
/// provider payload and no prohibited financial/address-internal fields are
|
|
/// persisted here.
|
|
model KwpProjectCatalogItem {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
externalProjectNumber String
|
|
name String
|
|
searchText String
|
|
status Int?
|
|
projectAddressCode String?
|
|
invoiceAddressCode String?
|
|
clientAddressCode String?
|
|
startDate DateTime?
|
|
orderValue Decimal? @db.Decimal(18, 2)
|
|
normalizedFingerprint String
|
|
state KwpProjectCatalogItemState @default(discovered)
|
|
discoveredAt DateTime @default(now())
|
|
lastSeenAt DateTime @default(now())
|
|
lastSyncedAt DateTime?
|
|
nextRefreshAt DateTime @default(now())
|
|
missingSince DateTime?
|
|
refreshAttempts Int @default(0)
|
|
lastErrorCode String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([tenantId, dataConnectionId, externalProjectNumber], map: "KwpProjectCatalogItem_connection_external_key")
|
|
@@index([tenantId, dataConnectionId, state, nextRefreshAt], map: "KwpProjectCatalogItem_tenant_due_idx")
|
|
@@index([tenantId, dataConnectionId, externalProjectNumber], map: "KwpProjectCatalogItem_tenant_external_idx")
|
|
@@index([searchText(ops: raw("gin_trgm_ops"))], type: Gin, map: "KwpProjectCatalogItem_searchText_trgm_idx")
|
|
}
|
|
|
|
/// Read-only material/ERP position mirrored from the KWP project view. KWP is
|
|
/// authoritative for these fields; local project data remains independent.
|
|
model KwpMaterialPosition {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
dataConnectionId String
|
|
projektId String
|
|
externalId String
|
|
positionNumber String?
|
|
text String
|
|
longText String?
|
|
quantity Decimal? @db.Decimal(18, 4)
|
|
unit String?
|
|
unitPrice Decimal? @db.Decimal(18, 2)
|
|
totalPrice Decimal? @db.Decimal(18, 2)
|
|
positionMarker Int
|
|
normalizedFingerprint String
|
|
lastSeenAt DateTime
|
|
lastSyncedAt DateTime
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
archivedAt DateTime?
|
|
|
|
@@unique([tenantId, dataConnectionId, projektId, externalId])
|
|
@@index([tenantId, projektId, archivedAt, positionNumber])
|
|
@@index([tenantId, dataConnectionId, lastSyncedAt])
|
|
}
|