feat: initial monorepo scaffold - Next.js 15 + Prisma + Python SDK stubs

- Turborepo monorepo with apps/web and packages/database, sdk-python
- Next.js 15 app with professional landing page (dark theme, emerald accent)
- Prisma schema: Trace, DecisionPoint, Span, Event models with full indexing
- Docker Compose: web (port 4200), postgres:16, redis:7, migrate service
- Python SDK package stubs: init, trace decorator, log_decision, integrations
- Multi-stage Dockerfile for standalone Next.js production build
This commit is contained in:
Vectry
2026-02-09 22:46:16 +00:00
parent 572fd7e234
commit 9264866d1f
31 changed files with 3244 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Trace {
id String @id @default(cuid())
sessionId String?
name String
status TraceStatus @default(RUNNING)
tags String[] @default([])
metadata Json?
totalCost Float?
totalTokens Int?
totalDuration Int?
startedAt DateTime @default(now())
endedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
decisionPoints DecisionPoint[]
spans Span[]
events Event[]
@@index([sessionId])
@@index([status])
@@index([createdAt])
@@index([name])
}
model DecisionPoint {
id String @id @default(cuid())
traceId String
trace Trace @relation(fields: [traceId], references: [id], onDelete: Cascade)
type DecisionType
reasoning String?
chosen Json
alternatives Json[]
contextSnapshot Json?
durationMs Int?
costUsd Float?
parentSpanId String?
span Span? @relation(fields: [parentSpanId], references: [id])
timestamp DateTime @default(now())
@@index([traceId])
@@index([type])
@@index([timestamp])
}
model Span {
id String @id @default(cuid())
traceId String
trace Trace @relation(fields: [traceId], references: [id], onDelete: Cascade)
parentSpanId String?
parentSpan Span? @relation("SpanTree", fields: [parentSpanId], references: [id])
childSpans Span[] @relation("SpanTree")
name String
type SpanType
input Json?
output Json?
tokenCount Int?
costUsd Float?
durationMs Int?
status SpanStatus @default(RUNNING)
statusMessage String?
startedAt DateTime @default(now())
endedAt DateTime?
metadata Json?
decisionPoints DecisionPoint[]
@@index([traceId])
@@index([parentSpanId])
@@index([type])
@@index([startedAt])
}
model Event {
id String @id @default(cuid())
traceId String
trace Trace @relation(fields: [traceId], references: [id], onDelete: Cascade)
spanId String?
type EventType
name String
metadata Json?
timestamp DateTime @default(now())
@@index([traceId])
@@index([type])
@@index([timestamp])
}
enum TraceStatus {
RUNNING
COMPLETED
ERROR
}
enum DecisionType {
TOOL_SELECTION
ROUTING
RETRY
ESCALATION
MEMORY_RETRIEVAL
PLANNING
CUSTOM
}
enum SpanType {
LLM_CALL
TOOL_CALL
MEMORY_OP
CHAIN
AGENT
CUSTOM
}
enum SpanStatus {
RUNNING
COMPLETED
ERROR
}
enum EventType {
ERROR
RETRY
FALLBACK
CONTEXT_OVERFLOW
USER_FEEDBACK
CUSTOM
}