CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Documentation Access
When working with external libraries or frameworks, use the Context7 MCP tools to get up-to-date documentation:
- Use
mcp__context7__resolve-library-idto find the correct library ID for any package - Use
mcp__context7__get-library-docsto retrieve comprehensive documentation and examples
This ensures you have access to the latest API documentation for dependencies like Hono, Next.js, Drizzle ORM, Vitest, and others used in this project.
SG Cars Trends - Developer Reference Guide
Project-Specific CLAUDE.md Files
This repository includes directory-specific CLAUDE.md files with detailed guidance for each component:
- apps/api/CLAUDE.md: API service development with Hono, workflows, tRPC, and social media integration
- apps/web/CLAUDE.md: Web application development with Next.js 15, HeroUI, blog features, and analytics
- packages/database/CLAUDE.md: Database schema management with Drizzle ORM, migrations, and TypeScript integration
- infra/CLAUDE.md: Infrastructure configuration with SST v3, AWS deployment, and domain management
Refer to these files for component-specific development guidance and best practices.
Architecture Documentation
Comprehensive system architecture documentation with visual diagrams is available in the Mintlify documentation site:
-
apps/docs/architecture/: Complete architecture documentation with Mermaid diagrams
- system.md: System architecture overview and component relationships
- workflows.md: Data processing workflow sequence diagrams
- database.md: Database schema and entity relationships
- api.md: API architecture with Hono framework structure
- infrastructure.md: AWS deployment topology and domain strategy
- social.md: Social media integration workflows
-
apps/docs/diagrams/: Source Mermaid diagram files (
.mmdformat)
These architectural resources provide visual understanding of system components, data flows, and integration patterns for effective development and maintenance.
SG Cars Trends Platform - Overview
Project Overview
SG Cars Trends (v4.11.0) is a full-stack platform providing access to Singapore vehicle registration data and Certificate of Entitlement (COE) bidding results. The monorepo includes:
- API Service: RESTful endpoints for accessing car registration and COE data (Hono framework)
- Web Application: Next.js frontend with interactive charts, analytics, and blog functionality
- Integrated Updater: Workflow-based data update system with scheduled jobs that fetch and process data from LTA DataMall (QStash workflows)
- LLM Blog Generation: Automated blog post creation using Google Gemini AI to analyse market data and generate insights
- Social Media Integration: Automated posting to Discord, LinkedIn, Telegram, and Twitter when new data is available
- Documentation: Comprehensive developer documentation using Mintlify
Commands
Common Commands
All commands use pnpm v10.13.1 as the package manager:
Build Commands:
- Build all:
pnpm build - Build web:
pnpm build:web - Build admin:
pnpm build:admin
Development Commands:
- Develop all:
pnpm dev - API dev server:
pnpm dev:api - Web dev server:
pnpm dev:web - Admin dev server:
pnpm dev:admin
Testing Commands:
- Test all:
pnpm test - Test watch:
pnpm test:watch - Test coverage:
pnpm test:coverage - Test API:
pnpm test:api - Test web:
pnpm test:web - Run single test:
pnpm -F @sgcarstrends/api test -- src/utils/__tests__/slugify.test.ts
Linting Commands:
- Lint all:
pnpm lint(uses Biome with automatic formatting) - Lint API:
pnpm lint:api - Lint web:
pnpm lint:web
Start Commands:
- Start web:
pnpm start:web
Blog Commands
- View all blog posts: Navigate to
/blogon the web application - View specific blog post: Navigate to
/blog/[slug]where slug is the post's URL slug - Blog posts are automatically generated via workflows when new data is processed
- Blog posts include dynamic Open Graph images and SEO metadata
Social Media Redirect Routes
The web application includes domain-based social media redirect routes that provide trackable, SEO-friendly URLs:
- /discord: Redirects to Discord server with UTM tracking
- /twitter: Redirects to Twitter profile with UTM tracking
- /instagram: Redirects to Instagram profile with UTM tracking
- /linkedin: Redirects to LinkedIn profile with UTM tracking
- /telegram: Redirects to Telegram channel with UTM tracking
- /github: Redirects to GitHub organisation with UTM tracking
All redirects include standardized UTM parameters:
utm_source=sgcarstrendsutm_medium=social_redirectutm_campaign={platform}_profile
UTM Tracking Implementation
The platform implements comprehensive UTM (Urchin Tracking Module) tracking for campaign attribution and analytics, following industry best practices:
UTM Architecture
API UTM Tracking (apps/api/src/utils/utm.ts):
- Social Media Posts: Automatically adds UTM parameters to all blog links shared on social platforms
- Parameters:
utm_source={platform},utm_medium=social,utm_campaign=blog, optionalutm_contentandutm_term - Platform Integration: Used by
SocialMediaManagerfor LinkedIn, Twitter, Discord, and Telegram posts
Web UTM Utilities (apps/web/src/utils/utm.ts):
- External Campaigns:
createExternalCampaignURL()for email newsletters and external marketing - Parameter Reading:
useUTMParams()React hook for future analytics implementation - Type Safety: Full TypeScript support with
UTMParamsinterface
UTM Best Practices
Follows Industry Standards:
utm_source: Platform name (e.g., "linkedin", "twitter", "newsletter")utm_medium: Traffic type (e.g., "social", "email", "referral")utm_campaign: Campaign identifier (e.g., "blog", "monthly_report")utm_term: Keywords or targeting criteria (optional)utm_content: Content variant or placement (optional)
Internal Link Policy:
- No UTM on internal links: Follows best practices by not tracking internal navigation
- External campaigns only: UTM parameters reserved for measuring external traffic sources
- Social media exceptions: External social platform posts include UTM for attribution
Database Commands
- Run migrations:
pnpm db:migrate - Check pending migrations:
pnpm db:migrate:check - Generate migrations:
pnpm db:generate - Push schema:
pnpm db:push - Drop database:
pnpm db:drop
Documentation Commands
- Docs dev server:
pnpm docs:dev - Docs build:
pnpm docs:build - Check broken links:
cd apps/docs && pnpm mintlify broken-links
Release Commands
- Create release:
pnpm release(runs semantic-release locally, not recommended for production) - Manual version check:
npx semantic-release --dry-run(preview next version without releasing)
Note: Semantic releases are now configured to use the "release" branch instead of "main" branch.
Deployment Commands
Infrastructure Deployment:
- Deploy all to dev:
pnpm deploy:dev - Deploy all to staging:
pnpm deploy:staging - Deploy all to production:
pnpm deploy:prod
API Deployment:
- Deploy API to dev:
pnpm deploy:api:dev - Deploy API to staging:
pnpm deploy:api:staging - Deploy API to production:
pnpm deploy:api:prod
Web Deployment:
- Deploy web to dev:
pnpm deploy:web:dev - Deploy web to staging:
pnpm deploy:web:staging - Deploy web to production:
pnpm deploy:web:prod
Code Structure
- apps/api: Unified API service using Hono framework with integrated updater workflows
- src/v1: API endpoints for data access
- src/lib/workflows: Workflow-based data update system and social media integration
- src/lib/gemini: LLM blog generation using Google Gemini AI
- src/routes: API route handlers including workflow endpoints
- src/config: Database, Redis, QStash, and platform configurations
- src/trpc: Type-safe tRPC router with authentication
- apps/web: Next.js frontend application
- src/app: Next.js App Router pages and layouts with blog functionality
- src/components: React components with comprehensive tests
- src/actions: Server actions for blog and analytics functionality
- src/utils: Web-specific utility functions
- apps/admin: Administrative interface for content management (unreleased)
- apps/docs: Mintlify documentation site
- architecture/: Complete system architecture documentation with Mermaid diagrams
- diagrams/: Source Mermaid diagram files for architecture documentation
- packages/database: Database schema and migrations using Drizzle ORM
- src/db: Schema definitions for cars, COE, posts, and analytics tables
- migrations: Database migration files with version tracking
- packages/types: Shared TypeScript type definitions
- packages/utils: Shared utility functions and Redis configuration
- packages/config: Shared configuration utilities (currently unused)
- infra: SST v3 infrastructure configuration for AWS deployment
Monorepo Build System
The project uses Turbo for efficient monorepo task orchestration:
Key Build Characteristics
- Dependency-aware: Tasks automatically run in dependency order with
dependsOn: ["^build"]and topological ordering - Caching: Build outputs cached with intelligent invalidation based on file inputs
- Parallel execution: Independent tasks run concurrently for optimal performance
- Environment handling: Strict environment mode with global dependencies on
.envfiles,tsconfig.json, andNODE_ENV - CI Integration: Global pass-through environment variables for GitHub and Vercel tokens
Enhanced Task Configuration
- Build tasks: Generate
dist/**,.next/**outputs with environment variable support - Test tasks: Comprehensive input tracking with topological dependencies
- Development tasks:
devandtest:watchusecache: false,persistent: true, and interactive mode - Migration tasks: Track
migrations/**/*.sqlfiles with environment variables for database operations - Deployment tasks: Cache-disabled with environment variable support for AWS and Vercel
- TypeScript checking: Dedicated
typechecktask with TypeScript configuration dependencies
Performance Optimization
- TUI Interface: Enhanced terminal user interface for better development experience
- Strict Environment Mode: Improved security and reliability with explicit environment variable handling
- Input Optimization: Uses
$TURBO_DEFAULT$for standard file tracking patterns - Coverage Outputs: Dedicated
coverage/**directories for test reports - E2E Outputs:
test-results/**andplaywright-report/**for end-to-end test artifacts
Dependency Management
The project uses pnpm v10.13.1 with catalog for centralized dependency version management.
pnpm Catalog
Centralized version definitions in pnpm-workspace.yaml ensure consistency across all workspace packages:
catalog:
'@types/node': ^22.16.4
'@types/react': 19.1.0
'@types/react-dom': 19.1.0
'@vitest/coverage-v8': ^3.2.4
'date-fns': ^3.6.0
next: ^15.4.7
react: 19.1.0
'react-dom': 19.1.0
sst: ^3.17.10
typescript: ^5.8.3
vitest: ^3.2.4
zod: ^3.25.76
Catalog Usage
Workspace packages reference catalog versions using the catalog: protocol:
{
"dependencies": {
"react": "catalog:",
"zod": "catalog:"
},
"devDependencies": {
"typescript": "catalog:",
"vitest": "catalog:"
}
}
Catalog Benefits
- Single source of truth: All shared dependency versions defined in one place
- Version consistency: Ensures all packages use the same versions
- Easier upgrades: Update version once in catalog, applies everywhere
- Type safety: TypeScript and types packages aligned across workspace
- Testing consistency: Testing tools (vitest, typescript) use same versions
Root vs Catalog
- Root package.json dependencies: Packages actually installed and used by root workspace (e.g., turbo, semantic-release, husky)
- Catalog entries: Version definitions that workspace packages reference (e.g., react, next, typescript)
- Both can reference catalog: Root can use
"sst": "catalog:"to maintain version consistency
Workspace Binaries
When packages are installed at the root level, their CLI binaries (in node_modules/.bin) are automatically available to all workspace packages. This means:
- Root dependencies with CLIs (e.g.,
sst,turbo) can be used in any workspace package's scripts - No need to duplicate CLI tools in individual packages
- Scripts in workspace packages can invoke binaries from root installation
Code Style
- TypeScript with strict type checking (noImplicitAny, strictNullChecks)
- Biome: Used for formatting, linting, and import organization
- Double quotes for strings (enforced)
- 2 spaces for indentation (enforced)
- Automatic import organization (enforced)
- Recommended linting rules enabled
- Excludes
.claude,.sst,coverage,migrations, and*.d.tsfiles
- Function/variable naming: camelCase
- Class naming: PascalCase
- Constants: UPPER_CASE for true constants
- Error handling: Use try/catch for async operations with specific error types
- Use workspace imports for shared packages:
@sgcarstrends/utils(includes Redis),@sgcarstrends/database, etc. - Path aliases: Use
@api/for imports in API app - Avoid using
anytype - prefer unknown with type guards - Group imports by: 1) built-in, 2) external, 3) internal
- Commit messages: Use conventional commit format with SHORT, concise messages enforced by commitlint:
- Preferred style: Keep messages brief and direct (e.g.,
feat: add user auth,fix: login error) feat: add new feature(minor version bump)fix: resolve bug(patch version bump)feat!: breaking changeorfeat: add feature\ \ BREAKING CHANGE: description(major version bump)chore:,docs:,style:,refactor:,test:(no version bump)- IMPORTANT: Keep commit messages SHORT - single line with max 50 characters preferred, 72 characters absolute maximum
- Avoid verbose descriptions - focus on what changed, not why or how
- **Optiona
- Preferred style: Keep messages brief and direct (e.g.,