{"id":24438642,"url":"https://github.com/sgcarstrends/sgcarstrends","last_synced_at":"2026-04-05T12:02:36.191Z","repository":{"id":215821254,"uuid":"714541586","full_name":"sgcarstrends/sgcarstrends","owner":"sgcarstrends","description":"Monorepo for SG Cars Trends backend services","archived":false,"fork":false,"pushed_at":"2026-04-04T09:58:00.000Z","size":18296,"stargazers_count":20,"open_issues_count":23,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-04T10:14:51.226Z","etag":null,"topics":["api","aws-lambda","backend","hono","job-scheduler","neon-postgres","neondb","sst","typescript","upstash","upstash-qstash","upstash-redis","upstash-workflow","zod"],"latest_commit_sha":null,"homepage":"https://web-sgcarstrends-projects.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sgcarstrends.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":"sgcarstrends","buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2023-11-05T06:41:21.000Z","updated_at":"2026-04-04T09:58:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"d4a79368-c03e-4877-8a80-20967976669c","html_url":"https://github.com/sgcarstrends/sgcarstrends","commit_stats":{"total_commits":61,"total_committers":1,"mean_commits":61.0,"dds":0.0,"last_synced_commit":"d9e3d1ddd227187c21245c18bf745e4380fbafe0"},"previous_names":["ruchernchong/lta-cars-dataset","sgcarstrends/api","sgcarstrends/backend","sgcarstrends/sgcarstrends"],"tags_count":275,"template":false,"template_full_name":null,"purl":"pkg:github/sgcarstrends/sgcarstrends","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgcarstrends%2Fsgcarstrends","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgcarstrends%2Fsgcarstrends/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgcarstrends%2Fsgcarstrends/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgcarstrends%2Fsgcarstrends/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sgcarstrends","download_url":"https://codeload.github.com/sgcarstrends/sgcarstrends/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgcarstrends%2Fsgcarstrends/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31434625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T08:13:15.228Z","status":"ssl_error","status_checked_at":"2026-04-05T08:13:11.839Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","aws-lambda","backend","hono","job-scheduler","neon-postgres","neondb","sst","typescript","upstash","upstash-qstash","upstash-redis","upstash-workflow","zod"],"created_at":"2025-01-20T19:17:20.727Z","updated_at":"2026-04-05T12:02:36.185Z","avatar_url":"https://github.com/sgcarstrends.png","language":"TypeScript","funding_links":["https://polar.sh/sgcarstrends"],"categories":[],"sub_categories":[],"readme":"# SG Cars Trends\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n## Overview\n\nThis monorepo provides a complete platform for SG Cars Trends, tracking Singapore's car registration statistics and Certificate of Entitlement (COE) data. The system includes:\n\n- **Web Application**: Next.js 16 frontend with Cache Components, co-located route components, enhanced homepage featuring latest COE results, interactive charts, analytics, AI-generated blog content, and integrated admin interface at `/admin` path. Also hosts the data updater workflows.\n- **Integrated Data Updater**: Vercel WDK workflow-based system for fetching and processing LTA data (consolidated into web application)\n- **LLM Blog Generation**: Automated blog post creation using Vercel AI SDK with Google Gemini for market insights (runs within web workflows)\n- **Social Media Integration**: Automated posting to Discord, LinkedIn, Telegram, and Twitter with trackable redirect routes (triggered by web workflows)\n- **MCP Server**: Published npm package for blog post CRUD operations via Claude Code\n- **Documentation Site**: Fumadocs-powered documentation for technical guides and API reference\n- **Infrastructure**: Vercel deployment with automatic CI/CD\n\n## System Overview\n\n```mermaid\ngraph TB\n    subgraph \"Frontend \u0026 Workflows\"\n        WEB[Web App\u003cbr/\u003eNext.js 16]\n        BLOG[Blog Posts\u003cbr/\u003eAI Generated]\n        WORKFLOWS[Data Workflows\u003cbr/\u003eVercel WDK]\n        LLM[Vercel AI SDK\u003cbr/\u003eBlog Generation]\n    end\n\n    subgraph \"Data Layer\"\n        DB[(PostgreSQL\u003cbr/\u003eNeon)]\n        REDIS[(Redis Cache\u003cbr/\u003eUpstash)]\n    end\n\n    subgraph \"External APIs\"\n        LTA[LTA DataMall\u003cbr/\u003eGov Data]\n    end\n\n    subgraph \"Social Platforms\"\n        DISCORD[Discord]\n        LINKEDIN[LinkedIn]\n        TWITTER[Twitter]\n        TELEGRAM[Telegram]\n    end\n\n    subgraph \"Infrastructure\"\n        VERCEL[Vercel\u003cbr/\u003eEdge Network]\n    end\n\n    WEB --\u003e WORKFLOWS\n    WEB --\u003e DB\n    WEB --\u003e REDIS\n\n    WORKFLOWS --\u003e LTA\n    WORKFLOWS --\u003e DB\n    WORKFLOWS --\u003e LLM\n    LLM --\u003e BLOG\n\n    WORKFLOWS --\u003e DISCORD\n    WORKFLOWS --\u003e LINKEDIN\n    WORKFLOWS --\u003e TWITTER\n    WORKFLOWS --\u003e TELEGRAM\n\n    WEB --\u003e VERCEL\n\n    classDef frontend fill:#e1f5fe\n    classDef backend fill:#f3e5f5\n    classDef data fill:#e8f5e8\n    classDef external fill:#fff3e0\n    classDef social fill:#fce4ec\n    classDef infra fill:#f1f8e9\n\n    class WEB,BLOG,WORKFLOWS,LLM frontend\n    class DB,REDIS data\n    class LTA external\n    class DISCORD,LINKEDIN,TWITTER,TELEGRAM social\n    class VERCEL infra\n```\n\n## Project Structure\n\n```\nsgcarstrends/\n├── apps/\n│   ├── docs/         # Fumadocs documentation site (Next.js 16)\n│   │   ├── content/         # MDX documentation files\n│   │   ├── src/app/         # Next.js App Router with docs layout\n│   │   └── src/lib/         # Fumadocs source adapter and shared config\n│   ├── mcp/          # MCP server for blog post CRUD (published to npm)\n│   │   └── src/             # TypeScript server implementation\n│   ├── web/          # Next.js 16 frontend application with integrated workflows\n│   │   ├── src/app/         # Next.js App Router pages and layouts\n│   │   │   ├── (social)/    # Social media redirect routes with UTM tracking\n│   │   │   ├── admin/       # Integrated admin interface for content management\n│   │   │   ├── blog/        # Blog pages with AI-generated content\n│   │   │   └── api/workflows/  # Vercel WDK workflow endpoints\n│   │   ├── src/lib/workflows/  # Data updater workflows and social media integration\n│   │   ├── src/queries/     # Data fetching queries (cars, COE, logos) with comprehensive tests\n│   │   ├── src/actions/     # Server actions (maintenance tasks)\n│   │   ├── src/components/  # React components with comprehensive tests\n│   │   ├── src/utils/       # Web-specific utility functions\n│   │   └── src/config/      # Database, Redis, and platform configurations\n├── packages/\n│   ├── ai/           # AI-powered blog generation package\n│   │   ├── src/generate-post.ts  # 2-step blog generation\n│   │   ├── src/schemas.ts        # Zod schemas for structured output\n│   │   └── src/instrumentation.ts # Langfuse telemetry\n│   ├── database/     # Database schema and migrations (Drizzle ORM)\n│   │   ├── src/schema/      # Schema definitions for all tables\n│   │   └── migrations/      # Database migration files\n│   ├── logos/        # Car logo management with Vercel Blob storage\n│   ├── types/        # Shared TypeScript types\n│   ├── ui/           # Shared UI component library (shadcn/ui, Radix UI, Tailwind CSS)\n│   │   ├── src/components/  # shadcn/ui components\n│   │   ├── src/hooks/       # Custom React hooks\n│   │   ├── src/lib/         # Utility functions\n│   │   └── src/styles/      # Global styles\n│   └── utils/        # Shared utility functions and Redis configuration\n```\n\n## Technologies\n\n- **Frontend**: Next.js 16.1 with Cache Components, React 19.2, TypeScript 5.8\n- **UI Library**: HeroUI (NextUI successor) with professional design system\n- **Styling**: Tailwind CSS v4.1 with custom configuration\n- **Backend**: Node.js 22, TypeScript with strict mode\n- **API Framework**: Hono with OpenAPI documentation\n- **Database**: Neon Serverless PostgreSQL with Drizzle ORM\n- **Caching**: Upstash Redis for API responses and analytics\n- **Infrastructure**: Vercel with automatic deployments\n- **Scheduling**: Vercel WDK Workflows with Vercel Cron for data processing\n- **LLM Integration**: Vercel AI SDK with Google Gemini for blog content generation\n- **Package Management**: pnpm v10.22.0 workspace with catalog for centralised dependency management\n- **Build Tools**: Turbo v2.6.3 for monorepo orchestration, Turbopack for fast development builds\n- **Testing**: Vitest v4.0.15 (unit), Playwright (E2E) with comprehensive coverage\n- **Linting \u0026 Formatting**: Biome v2.3.0 for consistent code style, formatting, and import organisation\n\n## Documentation\n\nFor developers working on this codebase, detailed component-specific guidance is available:\n\n- **[Root CLAUDE.md](CLAUDE.md)** - Overall project guidance and conventions\n- **[Web Application](apps/web/CLAUDE.md)** - Next.js development, HeroUI components, blog features, and data updater workflows\n- **[AI Package](packages/ai/CLAUDE.md)** - AI-powered blog generation with Vercel AI SDK and Google Gemini\n- **[Database Package](packages/database/CLAUDE.md)** - Schema management, migrations, and TypeScript integration\n- **[Logos Package](packages/logos/CLAUDE.md)** - Car logo management with Vercel Blob storage\n- **[UI Package](packages/ui/CLAUDE.md)** - Shared component library with shadcn/ui and Tailwind CSS\n\n### Architecture Documentation\n\nSystem architecture diagrams are available in the `docs/` directory:\n\n- **[docs/architecture/](docs/architecture/)** - Architecture documentation with Mermaid diagrams\n- **[docs/diagrams/](docs/diagrams/)** - Source Mermaid diagram files\n\n## Getting Started\n\n### Prerequisites\n\n- Node.js \u003e= 22\n- pnpm v10.22.0\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/sgcarstrends/sgcarstrends.git\ncd sgcarstrends\n\n# Install dependencies\npnpm install\n```\n\n#### Dependency Management\n\nThis project uses **pnpm catalog** for centralised dependency version management. Shared dependencies (React, Next.js, TypeScript, testing tools, etc.) are defined in `pnpm-workspace.yaml` and referenced by workspace packages using the `catalog:` protocol.\n\n**Key catalog packages:**\n- React ecosystem: `react` (^19.2.3), `react-dom` (^19.2.3), `next` (^16.1.0)\n- TypeScript \u0026 types: `typescript` (^5.8.3), `@types/node` (^22.16.4), `@types/react` (^19.2.0), `@types/react-dom` (^19.2.0)\n- Testing tools: `vitest` (^4.0.15), `@vitest/coverage-v8` (^4.0.15)\n- AI \u0026 LLM: `ai` (^6.0.1), `@ai-sdk/google` (^3.0.6), `@langfuse/otel` (^4.4.2)\n- Utilities: `date-fns` (^3.6.0), `zod` (^4.1.13), `sonner` (2.0.7)\n\n**Root-level dependencies** (not in catalog):\n- Build tools: `turbo` (^2.6.3)\n- Code quality: `@biomejs/biome` (2.3.0), `husky` (^9.1.7), `lint-staged` (^16.1.5)\n- Release management: `semantic-release` (^24.0.0)\n\nThis ensures version consistency across all workspace packages and simplifies dependency upgrades.\n\n### Development\n\n```bash\n# Development\npnpm dev                    # Run all development servers\npnpm dev:web               # Web application only\ncd apps/web \u0026\u0026 pnpm dev    # Web application development\n\n# Build\npnpm build                 # Build all applications\npnpm build:web             # Build web application only\n\n# Testing\npnpm test                  # Run all unit tests\npnpm test:watch            # Run tests in watch mode\npnpm test:coverage         # Run tests with coverage\npnpm test:web              # Run web tests only\ncd apps/web \u0026\u0026 pnpm test   # Web tests only\n\n# E2E Testing (Web App)\npnpm -F @sgcarstrends/web test:e2e       # Run Playwright E2E tests\npnpm -F @sgcarstrends/web test:e2e:ui    # Run E2E tests with Playwright UI\n\n# Code Quality\npnpm lint                  # Run Biome linting on all packages\npnpm format                # Run Biome formatting on all packages\npnpm lint:web              # Lint web application only\ncd apps/web \u0026\u0026 pnpm lint   # Lint web application only\n\n# Database\npnpm db:migrate            # Run database migrations\npnpm db:migrate:check      # Check migration status\npnpm db:generate           # Generate new migrations\npnpm db:push               # Push schema changes\npnpm db:drop               # Drop database\n```\n\n### Deployment\n\nDeployment is handled automatically by Vercel:\n- **Production**: Push to `main` branch triggers automatic deployment\n- **Preview**: Pull requests get automatic preview deployments\n\n## API Endpoints\n\n### Web Application Workflows (apps/web)\n\n**Workflow Endpoints (Vercel Cron Triggered):**\n- `GET /api/workflows/cars` - Car data processing workflow\n- `GET /api/workflows/coe` - COE data processing workflow\n- `GET /api/workflows/deregistrations` - Vehicle deregistration processing workflow\n\n## Repo Activity\n\n![Alt](https://repobeats.axiom.co/api/embed/01e0d81ecb779bfb5be18d4c7f79a33d75db9e7b.svg \"Repobeats analytics image\")\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgcarstrends%2Fsgcarstrends","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsgcarstrends%2Fsgcarstrends","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgcarstrends%2Fsgcarstrends/lists"}