chore: migrate to pnpm workspaces monorepo with Turborepo
- Restructure directories: apps/api, apps/admin, apps/website - Add root pnpm-workspace.yaml, turbo.json, .prettierrc, .gitignore - Rename packages to @inkreach/api, @inkreach/admin, @inkreach/website - Add shared packages: packages/tsconfig, packages/shared-types - Add pnpm.onlyBuiltDependencies for native builds - Update docs: README.md, structs.md - All three projects build successfully
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
// InkReach Product Center Prisma Schema
|
||||
// Generated based on docs/dev/database-table-design.md
|
||||
// All TIMESTAMPTZ columns use DateTime @db.Timestamptz(6)
|
||||
// All BIGINT columns use BigInt
|
||||
// snake_case table & column names via @@map / @map
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ---------- Origin Goods ----------
|
||||
model OriginGood {
|
||||
id BigInt @id @default(autoincrement()) @map("origin_good_id")
|
||||
sdsGoodId String @unique @map("sds_good_id")
|
||||
// Cached SDS product metadata (filled during sync)
|
||||
sdsCategoryId String? @map("sds_category_id")
|
||||
goodName String? @map("good_name")
|
||||
goodImage String? @map("good_image")
|
||||
goodPrice Decimal? @map("good_price") @db.Decimal(12, 2)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
goods Good[]
|
||||
|
||||
@@index([sdsCategoryId])
|
||||
@@map("origin_goods")
|
||||
}
|
||||
|
||||
// ---------- Countries ----------
|
||||
model Country {
|
||||
id BigInt @id @default(autoincrement()) @map("country_id")
|
||||
countryName String @unique @map("country_name")
|
||||
countryIcon String? @map("country_icon")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
goods Good[]
|
||||
positions Position[]
|
||||
|
||||
@@map("countries")
|
||||
}
|
||||
|
||||
// ---------- Categories (self-referential tree) ----------
|
||||
model Category {
|
||||
id BigInt @id @default(autoincrement()) @map("category_id")
|
||||
parentCategoryId BigInt? @map("parent_category_id")
|
||||
categoryName String @map("category_name")
|
||||
categoryIcon String? @map("category_icon")
|
||||
sdsCategoryId String? @unique @map("sds_category_id")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
parent Category? @relation("CategoryToCategory", fields: [parentCategoryId], references: [id], onDelete: Restrict, onUpdate: NoAction)
|
||||
children Category[] @relation("CategoryToCategory")
|
||||
goods Good[]
|
||||
positions Position[]
|
||||
|
||||
@@index([parentCategoryId])
|
||||
@@map("categories")
|
||||
}
|
||||
|
||||
// ---------- Tag Groups ----------
|
||||
model TagGroup {
|
||||
id BigInt @id @default(autoincrement()) @map("tag_group_id")
|
||||
groupName String @unique @map("group_name")
|
||||
groupIcon String? @map("group_icon")
|
||||
groupColor String? @map("group_color")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
tags Tag[]
|
||||
|
||||
@@map("tag_groups")
|
||||
}
|
||||
|
||||
// ---------- Tags ----------
|
||||
model Tag {
|
||||
id BigInt @id @default(autoincrement()) @map("tag_id")
|
||||
tagName String @unique @map("tag_name")
|
||||
tagColor String? @map("tag_color")
|
||||
tagFontColor String? @map("tag_font_color")
|
||||
timing String?
|
||||
tagGroupId BigInt? @map("tag_group_id")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
goods Good[]
|
||||
goodTags GoodTag[]
|
||||
tagGroup TagGroup? @relation(fields: [tagGroupId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
|
||||
@@index([tagGroupId])
|
||||
@@index([tagGroupId, sortOrder])
|
||||
@@map("tags")
|
||||
}
|
||||
|
||||
// ---------- Positions ----------
|
||||
model Position {
|
||||
id BigInt @id @default(autoincrement()) @map("position_id")
|
||||
indexVal Int @map("index_val")
|
||||
countryId BigInt? @map("country_id")
|
||||
categoryId BigInt? @map("category_id")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
country Country? @relation(fields: [countryId], references: [id], onDelete: Cascade, onUpdate: NoAction)
|
||||
category Category? @relation(fields: [categoryId], references: [id], onDelete: Cascade, onUpdate: NoAction)
|
||||
goods Good[]
|
||||
|
||||
@@index([countryId])
|
||||
@@index([categoryId])
|
||||
@@index([countryId, categoryId])
|
||||
@@map("positions")
|
||||
}
|
||||
|
||||
// ---------- Goods ----------
|
||||
model Good {
|
||||
id BigInt @id @default(autoincrement()) @map("good_id")
|
||||
originGoodId BigInt @map("origin_good_id")
|
||||
countryId BigInt @map("country_id")
|
||||
categoryId BigInt @map("category_id")
|
||||
tagId BigInt? @map("tag_id")
|
||||
positionId BigInt? @map("position_id")
|
||||
goodName String @map("good_name")
|
||||
goodImage String? @map("good_image")
|
||||
goodPriority Int @default(0) @map("good_priority")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
originGood OriginGood @relation(fields: [originGoodId], references: [id], onDelete: Restrict, onUpdate: NoAction)
|
||||
country Country @relation(fields: [countryId], references: [id], onDelete: Restrict, onUpdate: NoAction)
|
||||
category Category @relation(fields: [categoryId], references: [id], onDelete: Restrict, onUpdate: NoAction)
|
||||
tag Tag? @relation(fields: [tagId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
position Position? @relation(fields: [positionId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
goodTags GoodTag[]
|
||||
|
||||
@@index([originGoodId])
|
||||
@@index([countryId])
|
||||
@@index([categoryId])
|
||||
@@index([tagId])
|
||||
@@index([positionId])
|
||||
@@index([goodPriority(sort: Desc)])
|
||||
@@index([countryId, goodPriority(sort: Desc)])
|
||||
@@index([categoryId, countryId])
|
||||
@@map("goods")
|
||||
}
|
||||
|
||||
// ---------- Good-Tag Junction (M:N) ----------
|
||||
model GoodTag {
|
||||
goodId BigInt @map("good_id")
|
||||
tagId BigInt @map("tag_id")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
good Good @relation(fields: [goodId], references: [id], onDelete: Cascade, onUpdate: NoAction)
|
||||
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade, onUpdate: NoAction)
|
||||
|
||||
@@id([goodId, tagId])
|
||||
@@index([tagId])
|
||||
@@map("good_tags")
|
||||
}
|
||||
|
||||
// ---------- Users (admin authentication) ----------
|
||||
model User {
|
||||
id BigInt @id @default(autoincrement())
|
||||
username String @unique
|
||||
passwordHash String @map("password_hash")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
// ---------- Sync Logs ----------
|
||||
enum SyncType {
|
||||
CATEGORIES
|
||||
PRODUCTS
|
||||
}
|
||||
|
||||
enum SyncStatus {
|
||||
RUNNING
|
||||
SUCCESS
|
||||
FAILED
|
||||
}
|
||||
|
||||
model SyncLog {
|
||||
id BigInt @id @default(autoincrement())
|
||||
type SyncType
|
||||
status SyncStatus
|
||||
message String?
|
||||
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz(6)
|
||||
finishedAt DateTime? @map("finished_at") @db.Timestamptz(6)
|
||||
|
||||
@@index([type, startedAt])
|
||||
@@map("sync_logs")
|
||||
}
|
||||
Reference in New Issue
Block a user