Rocky_Mountain_Vending/convex/schema.ts

223 lines
6.8 KiB
TypeScript

import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
const orderStatus = v.union(
v.literal("pending"),
v.literal("paid"),
v.literal("fulfilled"),
v.literal("cancelled"),
v.literal("refunded"),
);
export default defineSchema({
products: defineTable({
name: v.string(),
description: v.optional(v.string()),
price: v.number(),
currency: v.string(),
images: v.array(v.string()),
metadata: v.optional(v.record(v.string(), v.string())),
stripeProductId: v.optional(v.string()),
stripePriceId: v.optional(v.string()),
active: v.boolean(),
featured: v.optional(v.boolean()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_active", ["active"])
.index("by_stripeProductId", ["stripeProductId"]),
orders: defineTable({
customerEmail: v.string(),
customerName: v.optional(v.string()),
status: orderStatus,
totalAmount: v.number(),
currency: v.string(),
stripeSessionId: v.optional(v.string()),
stripePaymentIntentId: v.optional(v.string()),
shippingAddress: v.optional(
v.object({
name: v.optional(v.string()),
address: v.optional(v.string()),
city: v.optional(v.string()),
state: v.optional(v.string()),
zipCode: v.optional(v.string()),
country: v.optional(v.string()),
}),
),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_createdAt", ["createdAt"])
.index("by_status", ["status"])
.index("by_stripeSessionId", ["stripeSessionId"])
.index("by_customerEmail", ["customerEmail"]),
orderItems: defineTable({
orderId: v.id("orders"),
productId: v.optional(v.id("products")),
stripeProductId: v.optional(v.string()),
stripePriceId: v.string(),
productName: v.string(),
image: v.optional(v.string()),
price: v.number(),
quantity: v.number(),
createdAt: v.number(),
}).index("by_orderId", ["orderId"]),
manuals: defineTable({
filename: v.string(),
path: v.string(),
manufacturer: v.string(),
category: v.string(),
size: v.optional(v.number()),
lastModified: v.optional(v.number()),
searchTerms: v.optional(v.array(v.string())),
commonNames: v.optional(v.array(v.string())),
thumbnailUrl: v.optional(v.string()),
manualUrl: v.optional(v.string()),
hasParts: v.optional(v.boolean()),
assetSource: v.optional(v.string()),
sourcePath: v.optional(v.string()),
sourceSite: v.optional(v.string()),
sourceDomain: v.optional(v.string()),
siteVisibility: v.optional(v.array(v.string())),
importBatch: v.optional(v.string()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_manufacturer", ["manufacturer"])
.index("by_category", ["category"])
.index("by_path", ["path"]),
manualCategories: defineTable({
name: v.string(),
slug: v.string(),
description: v.optional(v.string()),
icon: v.optional(v.string()),
createdAt: v.number(),
updatedAt: v.number(),
}).index("by_slug", ["slug"]),
leadSubmissions: defineTable({
type: v.union(v.literal("contact"), v.literal("requestMachine")),
status: v.union(v.literal("pending"), v.literal("delivered"), v.literal("failed")),
firstName: v.string(),
lastName: v.string(),
email: v.string(),
phone: v.string(),
company: v.optional(v.string()),
intent: v.optional(v.string()),
message: v.optional(v.string()),
source: v.optional(v.string()),
page: v.optional(v.string()),
url: v.optional(v.string()),
employeeCount: v.optional(v.string()),
machineType: v.optional(v.string()),
machineCount: v.optional(v.string()),
serviceTextConsent: v.optional(v.boolean()),
marketingTextConsent: v.optional(v.boolean()),
consentVersion: v.optional(v.string()),
consentCapturedAt: v.optional(v.string()),
consentSourcePage: v.optional(v.string()),
marketingConsent: v.optional(v.boolean()),
termsAgreement: v.optional(v.boolean()),
error: v.optional(v.string()),
deliveredAt: v.optional(v.number()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_type", ["type"])
.index("by_status", ["status"])
.index("by_createdAt", ["createdAt"]),
adminUsers: defineTable({
email: v.string(),
name: v.optional(v.string()),
role: v.union(v.literal("admin")),
active: v.boolean(),
createdAt: v.number(),
updatedAt: v.number(),
lastLoginAt: v.optional(v.number()),
}).index("by_email", ["email"]),
adminSessions: defineTable({
adminUserId: v.id("adminUsers"),
tokenHash: v.string(),
expiresAt: v.number(),
createdAt: v.number(),
})
.index("by_tokenHash", ["tokenHash"])
.index("by_adminUserId", ["adminUserId"]),
siteSettings: defineTable({
key: v.string(),
value: v.string(),
description: v.optional(v.string()),
updatedAt: v.number(),
}).index("by_key", ["key"]),
syncJobs: defineTable({
kind: v.string(),
status: v.union(
v.literal("pending"),
v.literal("running"),
v.literal("completed"),
v.literal("failed"),
),
message: v.optional(v.string()),
metadata: v.optional(v.string()),
startedAt: v.optional(v.number()),
completedAt: v.optional(v.number()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_kind", ["kind"])
.index("by_status", ["status"]),
voiceSessions: defineTable({
roomName: v.string(),
participantIdentity: v.string(),
siteUrl: v.optional(v.string()),
pathname: v.optional(v.string()),
pageUrl: v.optional(v.string()),
source: v.optional(v.string()),
startedAt: v.number(),
endedAt: v.optional(v.number()),
recordingDisclosureAt: v.optional(v.number()),
recordingStatus: v.optional(
v.union(
v.literal("pending"),
v.literal("starting"),
v.literal("recording"),
v.literal("completed"),
v.literal("failed"),
),
),
recordingId: v.optional(v.string()),
recordingUrl: v.optional(v.string()),
recordingError: v.optional(v.string()),
metadata: v.optional(v.string()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_roomName", ["roomName"])
.index("by_participantIdentity", ["participantIdentity"])
.index("by_startedAt", ["startedAt"]),
voiceTranscriptTurns: defineTable({
sessionId: v.id("voiceSessions"),
roomName: v.string(),
participantIdentity: v.string(),
role: v.union(v.literal("user"), v.literal("assistant"), v.literal("system")),
kind: v.optional(v.string()),
text: v.string(),
isFinal: v.optional(v.boolean()),
language: v.optional(v.string()),
source: v.optional(v.string()),
createdAt: v.number(),
})
.index("by_sessionId", ["sessionId"])
.index("by_roomName", ["roomName"])
.index("by_createdAt", ["createdAt"]),
});