mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-10 22:01:16 +00:00
feat: fix channel scanning bugs, add package tags, and kickstarters tab
Bug fixes: - Fix channels not being scanned by paginating TDLib getChats (was only loading first batch, additional channels were unknown to TDLib) - Add per-channel getChat pre-load as safety net before scanning - Fix preview pictures not loading by checking previewData instead of previewMsgId for hasPreview flag - Prevent previewMsgId from being set when preview download fails Package Tags: - Add tags Text[] column to Package with migration backfilling from channel categories - Worker auto-inherits source channel category as initial tag - Tag filter dropdown and Tags column in STL Files table - Server actions for individual and bulk tag editing Kickstarters Tab: - New KickstarterHost, Kickstarter, and KickstarterPackage models - Full CRUD with delivery status, payment status, host management - Package linking (many-to-many with existing packages) - Sidebar entry with Gift icon - Table with search, filters, modal forms Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
-- Add tags array column to packages
|
||||
ALTER TABLE "packages" ADD COLUMN "tags" TEXT[] NOT NULL DEFAULT '{}';
|
||||
|
||||
-- Backfill: inherit source channel category as initial tag
|
||||
UPDATE "packages" p
|
||||
SET "tags" = ARRAY[c."category"]
|
||||
FROM "telegram_channels" c
|
||||
WHERE p."sourceChannelId" = c."id"
|
||||
AND c."category" IS NOT NULL
|
||||
AND c."category" != '';
|
||||
@@ -0,0 +1,50 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "DeliveryStatus" AS ENUM ('NOT_DELIVERED', 'PARTIAL', 'DELIVERED');
|
||||
CREATE TYPE "PaymentStatus" AS ENUM ('PAID', 'UNPAID');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "kickstarter_hosts" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "kickstarter_hosts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "kickstarters" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"link" TEXT,
|
||||
"filesUrl" TEXT,
|
||||
"deliveryStatus" "DeliveryStatus" NOT NULL DEFAULT 'NOT_DELIVERED',
|
||||
"paymentStatus" "PaymentStatus" NOT NULL DEFAULT 'UNPAID',
|
||||
"notes" TEXT,
|
||||
"hostId" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "kickstarters_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "kickstarter_packages" (
|
||||
"kickstarterId" TEXT NOT NULL,
|
||||
"packageId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "kickstarter_packages_pkey" PRIMARY KEY ("kickstarterId","packageId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "kickstarter_hosts_name_key" ON "kickstarter_hosts"("name");
|
||||
CREATE INDEX "kickstarters_hostId_idx" ON "kickstarters"("hostId");
|
||||
CREATE INDEX "kickstarters_userId_idx" ON "kickstarters"("userId");
|
||||
CREATE INDEX "kickstarters_deliveryStatus_idx" ON "kickstarters"("deliveryStatus");
|
||||
CREATE INDEX "kickstarters_paymentStatus_idx" ON "kickstarters"("paymentStatus");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "kickstarters" ADD CONSTRAINT "kickstarters_hostId_fkey" FOREIGN KEY ("hostId") REFERENCES "kickstarter_hosts"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "kickstarters" ADD CONSTRAINT "kickstarters_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "kickstarter_packages" ADD CONSTRAINT "kickstarter_packages_kickstarterId_fkey" FOREIGN KEY ("kickstarterId") REFERENCES "kickstarters"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "kickstarter_packages" ADD CONSTRAINT "kickstarter_packages_packageId_fkey" FOREIGN KEY ("packageId") REFERENCES "packages"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -38,6 +38,7 @@ model User {
|
||||
tags Tag[]
|
||||
settings UserSettings?
|
||||
telegramLink TelegramLink?
|
||||
kickstarters Kickstarter[]
|
||||
inviteCodes InviteCode[] @relation("InviteCreator")
|
||||
usedInvite InviteCode? @relation("InviteUser", fields: [usedInviteId], references: [id], onDelete: SetNull)
|
||||
usedInviteId String?
|
||||
@@ -468,6 +469,7 @@ model Package {
|
||||
isMultipart Boolean @default(false)
|
||||
partCount Int @default(1)
|
||||
fileCount Int @default(0)
|
||||
tags String[] @default([])
|
||||
previewData Bytes? // JPEG thumbnail from nearby Telegram photo (stored as raw bytes)
|
||||
previewMsgId BigInt? // Telegram message ID of the matched photo
|
||||
indexedAt DateTime @default(now())
|
||||
@@ -477,8 +479,9 @@ model Package {
|
||||
files PackageFile[]
|
||||
ingestionRun IngestionRun? @relation(fields: [ingestionRunId], references: [id])
|
||||
ingestionRunId String?
|
||||
sendRequests BotSendRequest[]
|
||||
extractRequests ArchiveExtractRequest[]
|
||||
sendRequests BotSendRequest[]
|
||||
extractRequests ArchiveExtractRequest[]
|
||||
kickstarterLinks KickstarterPackage[]
|
||||
|
||||
@@index([sourceChannelId])
|
||||
@@index([destChannelId])
|
||||
@@ -682,3 +685,63 @@ model ArchiveExtractRequest {
|
||||
@@index([status])
|
||||
@@map("archive_extract_requests")
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────
|
||||
// Purchased Kickstarters
|
||||
// ───────────────────────────────────────
|
||||
|
||||
enum DeliveryStatus {
|
||||
NOT_DELIVERED
|
||||
PARTIAL
|
||||
DELIVERED
|
||||
}
|
||||
|
||||
enum PaymentStatus {
|
||||
PAID
|
||||
UNPAID
|
||||
}
|
||||
|
||||
model KickstarterHost {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
kickstarters Kickstarter[]
|
||||
|
||||
@@map("kickstarter_hosts")
|
||||
}
|
||||
|
||||
model Kickstarter {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
link String?
|
||||
filesUrl String?
|
||||
deliveryStatus DeliveryStatus @default(NOT_DELIVERED)
|
||||
paymentStatus PaymentStatus @default(UNPAID)
|
||||
notes String?
|
||||
hostId String?
|
||||
userId String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
host KickstarterHost? @relation(fields: [hostId], references: [id], onDelete: SetNull)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
packages KickstarterPackage[]
|
||||
|
||||
@@index([hostId])
|
||||
@@index([userId])
|
||||
@@index([deliveryStatus])
|
||||
@@index([paymentStatus])
|
||||
@@map("kickstarters")
|
||||
}
|
||||
|
||||
model KickstarterPackage {
|
||||
kickstarterId String
|
||||
packageId String
|
||||
|
||||
kickstarter Kickstarter @relation(fields: [kickstarterId], references: [id], onDelete: Cascade)
|
||||
package Package @relation(fields: [packageId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([kickstarterId, packageId])
|
||||
@@map("kickstarter_packages")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user