Skip to content

Sandipxg/connected-repo

 
 

Repository files navigation

Full-Stack TypeScript Monorepo

Production-ready Turborepo monorepo for building full-stack TypeScript applications with end-to-end type safety.

Note

This project follows a Bimodal Documentation System.

  • Human-friendly: Use this README.md for high-level concepts, architectural overviews, and onboarding.
  • Agent-optimized: See AGENTS.md for technical deep dives, implementation patterns, and machine-centric decision records.

Tech Stack

Backend

  • Runtime: Node.js 22+
  • API Layer: oRPC (internal APIs) + REST/OpenAPI (external APIs)
  • Database: PostgreSQL with Orchid ORM
  • Task Queue: pg-tbus (PostgreSQL-based event bus)
  • Authentication: Better Auth (Google OAuth)
  • Notifications: SuprSend
  • Observability: OpenTelemetry, Sentry
  • Security: Helmet, CORS, Rate Limiting, API key auth

Frontend

  • Framework: React 19 + Vite with SWC
  • Routing: React Router 7
  • State: TanStack Query (server), Zustand (global), React Hook Form (forms)
  • UI: Material-UI (via @connected-repo/ui-mui)
  • PWA: Vite PWA plugin with offline support
  • Offline Storage: Dexie.js (IndexedDB wrapper)
  • Sync: SSE-based delta sync with real-time updates
  • Workers: Two-worker architecture (DataWorker + MediaWorker)
  • Testing: Playwright (E2E)

Tooling

  • Monorepo: Turborepo
  • Package Manager: Yarn 1.22.22
  • Linting: Biome (tabs, 100 chars, double quotes)
  • TypeScript: v5.9.x strict mode

Project Structure

.
├── apps/
│   ├── backend/                    # oRPC server
│   │   ├── src/
│   │   │   ├── modules/            # Feature modules
│   │   │   ├── routers/            # Route organization
│   │   │   ├── procedures/         # oRPC procedures
│   │   │   ├── db/                 # Database layer
│   │   │   ├── events/             # pg-tbus events & tasks
│   │   │   ├── cron_jobs/          # Cron job handlers
│   │   │   └── server.ts           # Entry point
│   │   └── package.json
│   └── frontend/                   # React + Vite
│       ├── src/
│       │   ├── modules/            # Feature modules
│       │   ├── worker/             # Web Workers (DataWorker, MediaWorker)
│       │   ├── sw/                 # Service Worker (SSE sync)
│       │   ├── components/         # Shared components
│       │   └── main.tsx            # Entry
│       └── package.json
├── packages/
│   ├── typescript-config/          # Shared TS configs
│   ├── ui-mui/                   # Material-UI components
│   └── zod-schemas/              # Shared Zod schemas
└── turbo.json

Getting Started

Prerequisites

  • Node.js 22+
  • Yarn 1.22.22
  • PostgreSQL

Installation

  1. Clone the repository:
git clone git@github.com:shipmyapp/connected-repo.git
cd connected-repo
  1. Set up environment variables:
cp apps/backend/.env.example apps/backend/.env
cp apps/frontend/.env.example apps/frontend/.env
  1. Configure your database connection in apps/backend/.env

  2. Install dependencies & build packages:

yarn install
yarn build
  1. Create databases and run migrations:
yarn db create
yarn db up
yarn db seed
yarn test:db:setup  # Setup test database

Development

Start both frontend and backend:

yarn dev

Or individually:

cd apps/backend && yarn dev   # Backend only (http://localhost:3000)
cd apps/frontend && yarn dev  # Frontend only (http://localhost:5173)

Available Scripts

Development

  • yarn dev - Start all apps in watch mode
  • yarn build - Build all apps and packages
  • yarn lint - Run Biome linter
  • yarn format - Format code with Biome
  • yarn check-types - Type check all workspaces
  • yarn clean - Remove node_modules and build artifacts

Database

  • yarn db g <name> - Generate migration
  • yarn db up - Run migrations
  • yarn db seed - Seed database
  • yarn test:db:setup - Setup test database

Testing

Backend (Vitest):

yarn test              # Run unit tests
yarn test:ui           # UI mode
yarn test:coverage     # Coverage report

Frontend E2E (Playwright):

yarn test:e2e          # Run E2E tests
yarn test:e2e -b       # Build before testing
yarn test:e2e:ui       # UI mode

Key Features

Dual API Architecture

oRPC for Internal APIs:

  • Type-safe APIs for frontend-backend communication
  • Zero code generation - types flow automatically
  • Routes: /orpc/*
  • Example: orpc.moduleName.create.useMutation()

REST/OpenAPI for External APIs:

  • Automatic Swagger documentation at /api
  • OpenAPI 3.1.0 spec from Zod schemas
  • Routes: /api/v1/*
  • Full middleware: API key auth, rate limiting, CORS, IP whitelist, subscription tracking

Event-Driven Architecture (pg-tbus)

PostgreSQL-based event bus for background tasks and notifications:

// Define event
export const userCreatedEventDef = defineEvent({
  event_name: "user.created",
  schema: Type.Object({ userId: Type.String() }),
});

// Define task
export const notificationTaskDef = defineTask({
  task_name: "send_notification",
  schema: Type.Object({ userId: Type.String(), message: Type.String() }),
  config: { retryLimit: 3, retryDelay: 10, retryBackoff: true },
});

// Emit event
tbus.emit(userCreatedEventDef, { userId: "123" });

// Register task handler
tbus.registerTask(notificationTaskDef, async ({ input }) => {
  await sendNotification(input.userId, input.message);
});

PWA (Progressive Web App)

Frontend includes PWA support:

  • Offline functionality with service worker
  • Install prompts for iOS and Android
  • Update prompts for new versions
  • Offline blocker UI when connection is lost

Offline-First Architecture

Full offline support with Dexie.js (IndexedDB):

Data Synchronization:

  • Delta Sync: SSE-based streaming sync (delta-on-connect + live monitoring)
  • Local Database: IndexedDB with separate tables for synced data and pending changes
  • Reactive UI: Hooks automatically re-render when local DB changes
  • Conflict Resolution: Soft deletes, server-wins for conflicts

Worker Architecture:

UI Thread (React)
  ├─► DataWorker (Dexie DB, Sync, SSE)
  └─► MediaWorker (CDN uploads, thumbnails, exports)

File Uploads:

  • S3 presigned URLs for direct browser-to-S3 uploads
  • File blobs cached in IndexedDB for offline access
  • Automatic sync when connection restored

Two-Worker Architecture

DataWorker: Handles all IndexedDB access and sync

  • Dexie.js database operations
  • SyncOrchestrator for background sync
  • SSE connection management
  • Only worker allowed to access IndexedDB

MediaWorker: Stateless processing worker

  • Image compression (browser-image-compression)
  • PDF thumbnail generation (pdfjs-dist)
  • Video thumbnail generation (mp4box + WebCodecs)
  • CDN uploads via presigned URLs
  • CSV/PDF exports

Communication: Comlink proxy pattern for worker-to-worker calls

Real-Time Sync (SSE)

Server-Sent Events for live data synchronization:

Backend (Orchid ORM hooks):

// Tables emit events on create/update/delete
this.afterCreate(schema.keyof().options, (entries) => {
  pushToSync("create", entries);
});

Frontend (Service Worker):

  • Connects on login, disconnects on logout
  • Receives delta chunks on initial connection
  • Real-time updates via streaming SSE
  • Heartbeat every 10s for connectivity monitoring

Cron Jobs

Per-minute cron jobs using node-cron with mutex locking:

// In src/cron_jobs/services/per_minute_cron.ts
cron.schedule('* * * * *', async () => {
  if (isCronJobRunning) return; // Prevent concurrent runs
  await scheduleReminders();
});

Webhook Processing

Automated webhook queue with retry logic:

  • Webhooks triggered at 90% subscription usage
  • pg-tbus handles retries with exponential backoff
  • Audit logging via pg_tbus_task_log table

Database Migrations

CRITICAL: Always auto-generate migrations:

yarn db g <migration_name>   # Generate only
yarn db up                   # Apply migrations

CRITICAL: Deployment & Compatibility Standards

Zero-downtime deployments require strict adherence to the following rules. Breaking these is considered a P0 blocker.

1. Database Migrations

  • Additive Only: All migrations must be additive. Never rename or drop a column/table in a single deployment.
  • Nullable Columns: New columns must be nullable or have a default value to avoid breaking the existing backend that doesn't know they exist yet.
  • Two-Step Deletion: To remove a field:
  1. Deploy code that stops using the field.
  2. In a subsequent release, deploy the migration to drop it.

2. API Versioning & Contracts

  • N-1 Compatibility: The current Backend must support the previous version of the Frontend.
  • No Breaking Payload Changes: Do not remove fields from JSON responses or change data types (e.g., String to Int) without a version bump (e.g., /v1/ to /v2/).
  • Graceful Failure: Agents/Frontends must ignore unknown keys in API responses rather than crashing.

Dual Team Model

Separate teams for UI and API access:

Aspect teams_app (UI) teams_api (External)
Auth Session/Cookie API Key
Use Case Journal entries, prompts Webhook integrations
Tables teams_app, team_members teams_api

End-to-End Type Safety

Shared Zod schemas in packages/zod-schemas/:

  • Entity schemas: <entity>CreateInputZod, <entity>UpdateInputZod, <entity>SelectAllZod
  • Direct TypeScript imports from backend to frontend
  • No code generation required

Documentation

API Endpoints

License

AGPL-3.0 - Copyright (c) 2025 Hexatech Hub Solutions LLP, India

About

Boilerplate Monorepo with end-to-end typesafety using Nodejs + oRPC + Reactjs + Capacitorjs

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 99.0%
  • Other 1.0%