4.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Dragon's Stash is a self-hosted inventory management system for 3D printing filament, SLA resin, miniature paints, and supplies. It includes an integrated Telegram archive worker that scans channels for ZIP/RAR archives, indexes their contents, and a bot that lets users search and receive packages via Telegram.
Tech Stack
- App: Next.js 16 (App Router), TypeScript 5.9 (strict), Tailwind CSS 4, shadcn/ui
- Database: PostgreSQL 16+ via Prisma v7.4 with
@prisma/adapter-pg - Auth: Auth.js v5 (NextAuth) with credentials + optional GitHub OAuth
- Worker: TypeScript + TDLib (via
tdl) for Telegram channel scanning - Bot: TypeScript + TDLib for Telegram bot interface
- Forms: React Hook Form + Zod v4
Commands
App (root package.json)
npm run dev # Next.js dev server with hot reload
npm run build # Production build (standalone output)
npm run start # Production server
npm run lint # ESLint (next/core-web-vitals + TypeScript)
Database
npm run db:generate # Generate Prisma client
npm run db:migrate # Run migrations (dev mode)
npm run db:push # Push schema without migrations
npm run db:seed # Seed database with test data
npm run db:studio # Prisma Studio UI
npx prisma migrate dev --name <description> # Create new migration
Worker & Bot (each in their own directory)
cd worker && npm run dev # Dev mode with tsx watch
cd worker && npm run build # TypeScript compile to dist/
cd bot && npm run dev # Dev mode with tsx watch
cd bot && npm run build # TypeScript compile to dist/
Dev Environment Setup
docker compose -f docker-compose.dev.yml up -d # Start PostgreSQL + worker
npm run dev # Run app locally
Architecture
Three-Service Design
The project is split into three independent services sharing one PostgreSQL database:
- App (root
src/): Next.js web UI for inventory management and Telegram admin - Worker (
worker/): Scans Telegram source channels, processes archives, uploads to destination channel - Bot (
bot/): Telegram bot for user search, package delivery, keyword subscriptions
Services communicate asynchronously via pg_notify (e.g., on-demand channel fetches, bot send requests).
App Source Layout (src/)
app/(auth)/— Login/register pages (public)app/(app)/— Protected routes behind auth middleware (dashboard, filaments, resins, paints, supplies, vendors, locations, settings, stls, telegram, usage)app/api/— API routes (NextAuth, health check, bot endpoints)data/— Server-side Prisma query functions (*.queries.ts), one file per domain modelschemas/— Zod validation schemas, one file per domain modelcomponents/ui/— shadcn/ui primitivescomponents/shared/— Reusable business components (data-table, status-badge, color-swatch, stat-card, page-header)components/layout/— Sidebar and headerlib/— Auth config, Prisma singleton, constants, utilities, Telegram query helpershooks/— Custom React hooks (use-modal, use-debounce, use-current-user)types/— Shared TypeScript types
Key Patterns
- Server Components by default — pages are async server components that fetch data directly. Only interactive components use
"use client". - Server Actions for mutations — each page directory has an
actions.tsfile with create/update/delete actions. - Data queries centralized — all Prisma reads go through
src/data/*.queries.ts, not inline in components. - Modal-based CRUD — add/edit forms use dialog modals, not separate pages.
- TanStack Table with server-side pagination for all inventory tables.
- All Prisma PKs use
cuid()string IDs.
Worker Pipeline
- Authenticate Telegram account via TDLib (SMS code flow, managed via admin UI)
- Scan source channels for messages since
lastProcessedMessageId - Detect archives (ZIP/RAR), group multipart sets, extract file listings
- Hash for dedup, match preview images, extract creator from filename
- Split files >2GB, upload to destination channel, track progress
ESLint Scope
ESLint covers src/ only. The worker/, bot/, scripts/, and prisma/seed.ts directories are excluded from linting.
Docker Deployment
docker-compose.yml— Production: app + worker + bot + dbdocker-compose.dev.yml— Dev: db + worker only (app runs locally)docker-entrypoint.sh— Runs migrations, optional seeding, then starts app- Bot service uses Docker Compose profiles (
botorfull) — not started by default
Testing
No test framework is configured. Testing is manual.