This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Etags is a Next.js 16 application for product tagging and blockchain stamping. It manages brands, products, and tags with blockchain transaction tracking for authentication/verification purposes.
Node.js requirement: 20.x (LTS)
npm run dev- Start development servernpm run build- Build for productionnpm run lint- Run ESLintnpm run typecheck- TypeScript type checkingnpm run format- Format code with Prettiernpm run format:check- Check formatting without writingnpm run commit- Commitizen conventional commit
npm run test- Run tests in watch modenpm run test -- --run- Run tests once (CI mode)npm run test -- --coverage- Run tests with coveragenpm run test -- src/lib/actions/auth.test.ts- Run a single test file
Test files use *.test.{ts,tsx} naming convention and are located throughout src/. Test setup is in src/tests/setup.ts with mocks in src/tests/mocks.ts. Coverage is configured only for src/lib/actions/**/*.ts.
npm run db:generate- Generate Prisma clientnpm run db:push- Push schema to database (no migration)npm run db:migrate- Create and apply migrationsnpm run db:studio- Open Prisma Studio GUInpm run db:create-admin- Create admin user (default: [email protected] / admin123)npm run db:create-admin -- [email protected] password123 "Name"- Create admin with custom credentialsnpm run db:seed- Seed basic sample datanpm run db:seed-fraud- Add fraud scan patterns to existing tagsnpm run db:seed-complete- Complete seed with brands, users, products, tags, and suspicious scansnpm run db:seed-complete -- --upload-r2- Same as above but uploads QR codes to R2npm run db:seed-complete -- --clean- Clean existing data before seeding
- Framework: Next.js 16 with App Router (
src/app/) - Database: MySQL via Prisma ORM
- File Storage: Cloudflare R2 (S3-compatible) via
@/lib/r2.ts - Blockchain: ethers.js for tag stamping on Base Sepolia via
@/lib/tag-sync.ts - Styling: Tailwind CSS v4 with
cn()utility (clsx + tailwind-merge) - UI Components: shadcn/ui components in
src/components/ui/ - React Compiler: Enabled in next.config.ts
- AI Integration: Kolosal AI for fraud detection via
@/lib/kolosal-ai.ts
@/* maps to ./src/*
@/lib/db.ts- Singleton Prisma client@/lib/auth.ts- NextAuth v5 configuration with credentials provider@/lib/r2.ts- R2 file upload/download with presigned URLs@/lib/tag-sync.ts- Blockchain tag operations (create, update, sync, revoke)@/lib/tag-stamping.ts- Tag stamping workflow helpers@/lib/constants.ts- Blockchain config and status enums (CHAIN_STATUS,PUBLISH_STATUS)@/lib/fraud-detection.ts- AI-powered fraud analysis for tag scans@/lib/qr-generator.ts- QR code generation for tags@/lib/qr-template-generator.ts- Designed QR code templates@/lib/explorer.ts- Blockchain explorer integration@/lib/rate-limit.ts- Rate limiting for API endpoints@/lib/csrf.ts- CSRF protection@/lib/nft-collectible.ts- NFT minting and claim processing@/lib/gemini-image.ts- Gemini API for NFT art generation
Server actions are organized in src/lib/actions/:
auth.ts- Login/logout actionsbrands.ts- Brand CRUD operationsproducts.ts- Product CRUD operationstags.ts- Tag CRUD and blockchain stampingusers.ts- User managementprofile.ts- User profile updatesdashboard.ts- Dashboard statisticsonboarding.ts- User onboarding flowmy-brand.ts- Brand user self-managementai-agent.ts- AI agent integrationnfts.ts- NFT collectible management and statssupport-tickets.ts- Web3 support ticket CRUD and messaging
Admin Dashboard (/manage):
/manage- Dashboard home with statistics/manage/brands- Brand management/manage/products- Product CRUD with/newand/[id]/edit/manage/tags- Tag management with/newand/[id]/edit/manage/nfts- NFT collectible monitoring with/[id]detail view/manage/tickets- Support ticket management with/[id]detail view/manage/users- User management (admin only)/manage/profile- User profile settings
Public Routes:
/- Public landing page/about- About Etags, mission, vision, team/features- Comprehensive features showcase/pricing- Pricing plans and FAQs/showcase- Success stories and testimonials/careers- Job openings and company culture/contact- Contact form and information/blog- Blog articles from Ghost CMS/privacy- Privacy policy/terms- Terms and conditions/security- Security practices and policies/login- Login page (redirects to /manage if authenticated)/register- User registration page/scan- QR code scanner for tag verification/verify/[code]- Tag verification page with product details/explorer- Blockchain transaction explorer/explorer/tx/[hash]- Transaction detail page/support- Web3 support tickets (NFT holders connect wallet to submit issues)/faqs- Frequently asked questions page/docs- Swagger API documentation UI
API Routes:
/api/docs- OpenAPI JSON spec/api/scan- Tag scan endpoint (records scans with fingerprint)/api/scan/claim- Claim a tag as owner/api/scan/claim-nft- Claim NFT collectible for first-hand claimers/api/verify- Tag verification API/api/explorer- Blockchain explorer API/api/csrf- CSRF token endpoint/api/tags/[code]/designed- Get designed QR code for tag/api/tags/template-preview- Preview QR template designs/api/ai-agent- AI agent chat endpoint for dashboard
Core models in prisma/schema.prisma:
- User - Admin/brand users with role-based access (
role: admin or brand), linked to brand viabrand_id - Brand - Product brand management with logo and descriptions
- Product - Products with JSON metadata (
name,description,price,images[]), linked to brands - Tag - Product tags with blockchain stamping (
is_stamped,hash_tx,chain_status), storesproduct_idsas JSON array - TagScan - Scan history with fingerprinting, location, claim status, and ownership tracking (
is_first_hand,source_info) - TagNFT - NFT collectibles minted for first-hand claimers (
token_id,owner_address,image_url,metadata_url,mint_tx_hash) - SupportTicket - Web3 support tickets linked to tags and brands (
wallet_address,category,status,priority) - TicketMessage - Ticket conversation thread with sender type (customer/brand/admin)
- TicketAttachment - File attachments for tickets stored in R2
Tags have a chain_status tracking their blockchain state:
- 0: CREATED - Tag created on chain
- 1: DISTRIBUTED - Tag distributed to product
- 2: CLAIMED - Tag claimed by end user
- 3: TRANSFERRED - Ownership transferred
- 4: FLAGGED - Tag flagged for review
- 5: REVOKED - Tag revoked/invalidated
The blockchain contract (ETagRegistry) supports: createTag, updateStatus, revokeTag, validateTag.
- User scans QR code →
/scanpage - Browser collects fingerprint (FingerprintJS) and location
- POST to
/api/scanrecords the scan inTagScanwith sequentialscan_number - Redirects to
/verify/[code]showing product info - User can claim ownership via
/api/scan/claim(setsis_claimed, asks aboutis_first_hand) - AI fraud detection analyzes scan patterns and location vs distribution info
First-hand tag claimers on Web3 browsers can mint an NFT collectible:
- User claims tag as first-hand owner on
/verify/[code] - System detects Web3 wallet (MetaMask, etc.) via
window.ethereum - User connects wallet and switches to Base Sepolia (Chain ID: 84532)
- POST to
/api/scan/claim-nfttriggers NFT minting:- Generates unique art via Gemini API (
gemini-3-pro-image-preview) - Uploads image and metadata to R2:
nfts/{tagCode}/ - Admin wallet mints NFT via ETagCollectible contract (user doesn't pay gas)
- NFT transferred directly to user's wallet
- Generates unique art via Gemini API (
- TagNFT record created with
token_id,owner_address,mint_tx_hash - Admin monitors NFTs at
/manage/nfts
Smart Contracts:
ETagCollectible.sol- ERC721 NFT contract with one-NFT-per-tag enforcement- Functions:
mintTo(),isTagMinted(),getTokenByTag(),grantMinter(),pause()
NFT holders can submit product complaints via wallet connection:
- User visits
/supportand connects wallet (MetaMask, etc.) - System queries blockchain for user's owned NFTs via ETagCollectible contract
- User selects a product/tag and submits ticket with category (
defect,quality,missing_parts,warranty,other) - Ticket routes to brand (if brand has users), otherwise to admin
- Brand/admin responds via
/manage/tickets/[id] - User views responses by reconnecting wallet at
/support
Ticket statuses: open → in_progress → resolved → closed
Runs typecheck and lint-staged (which runs Prettier on staged files) before commits.
docker build -t etags .- Build production image (multi-stage, uses standalone output)docker run -p 3000:3000 -e DATABASE_URL="..." -e AUTH_SECRET="..." etags- Run container
Triggers:
- Push to
masterbranch - Pull requests targeting
develop,feature/*,fix/*branches
Pipeline: lint → typecheck → test → build
Solidity contracts are in smartcontracts/ directory with separate Hardhat setup:
ETagRegistry.sol- Main contract for tag lifecycle management (create, validate, update status, revoke)ETagCollectible.sol- ERC721 NFT contract for collectibles (one NFT per tag)
Contract commands (run from smartcontracts/ directory):
npm run compile- Compile contractsnpm run test- Run contract testsnpm run deploy:local- Deploy to local Hardhat nodenpm run deploy:sepolia- Deploy to Base Sepolia testnet
See smartcontracts/README.md for full contract development documentation.
Copy .env.example to .env and configure:
DATABASE_URL- MySQL connection stringAUTH_SECRET- NextAuth secret (generate withopenssl rand -base64 32)AUTH_TRUST_HOST- Set totruefor production deploymentsR2_ACCOUNT_ID,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_BUCKET- Cloudflare R2 credentialsR2_PUBLIC_DOMAIN- Public URL for R2 bucket assetsBLOCKCHAIN_RPC_URL,CONTRACT_ADDRESS,CHAIN_ID,ADMIN_WALLET,BLOCKCHAIN_NETWORK- Blockchain configCONTRACT_OWNER- Optional: Owner address different from deployer (for contract deployment)BLOCKCHAIN_EXPLORER_URL- Block explorer URL (default: Base Sepolia)NFT_CONTRACT_ADDRESS,NEXT_PUBLIC_NFT_CONTRACT_ADDRESS- ETagCollectible NFT contract addressGEMINI_API_KEY- Gemini API for NFT art generationKOLOSAL_API_KEY- Kolosal AI for fraud detectionBASESCAN_API_KEY- BaseScan API for explorer featuresNEXT_PUBLIC_MAPBOX_ACCESS_TOKEN- Mapbox token for scan location mapsNEXT_PUBLIC_TOKEN- Ghost CMS Content API key for blog posts