Skip to content

Fullstack Cheatsheet

  • Monorepo
    • Turbo (recommended) or nx
  • Full-stack TS
  • Docker
  • Cloud Platform
    • GCP (recommended) or AWS
  • Compute
    • Cloud Run
  • 3 environments: dev, stage, prod
  • Packages
    • Reuse as much as you can
  • Error tracking
    • Sentry or Rollbar
    • Global error handler
  • Error notifications
    • Errors should ping us in Slack. False positives should be muted. Error notifs should be maintained
  • Logging
    • Logs Explorer (GCP)
  • Telemetry
    • Open Telemetry Auto instrumentation
  • Linter & auto-formatter
    • Prettier, eslint - husky commit hooks to auto format w/ prettier
  • Package manager
    • pnpm or yarn
  • Branching strategy
    • dev for dev
    • stg for stage
    • prd for prod
  • CI/CD
    • GitHub Actions (recommended)
    • Should autodeploy by branch
    • Preview deploys on topic branches
    • MUST run unit tests & e2e tests
    • Canary deploys
  • Testing
    • Unit tests: fast, use vitest or jest (mock external calls)
    • e2e tests: slower, can call REAL dev or testing DB - scope the data accordingly, build cleanup accordingly
      • Note: NeonDB supports branching to prevent test data leaking through into dev
  • Secret Management: ALL secrets must be managed, never checked into source control
    • GCP Secrets Manager (recommended)
  • Shared types
    • Depending on backend: shared package (nestjs) OR tRPC
  • Vulnerability Scanning
    • Dependabot
    • Grype (CI/CD)
  • Disaster recovery
    • DB backup strategy
  • Feature flags (Optional - depending on need)
    • Remote config, home-grown, etc…
  • CLI (OPTIONAL): Custom cli for ops tasks (oclif)
    • Oclif (recommended)
  • IaC (OPTIONAL): Reproducable infra
    • Terraform (recommended)
  • SLAs & SLOs (OPTIONAL)
    • CPU & Memory usage notifications
  • Framework
    • NestJS (recommended)
    • Consider: Hono (more lightweight)
    • MUST have swagger auto-doc for endpoints
  • Database
    • Postgres (recommended)
      • NeonDB (recommended), Supabase, or GCP Cloud SQL
    • Firestore (vendor lockin)
    • MongoDB
  • ORM
    • Prisma (recommended) - various alternatives
    • OR Drizzle ORM
  • Auth
    • Always go for managed auth - NEVER roll your own auth
    • Firebase auth, Auth0, Clerk, Better Auth
    • RBAC
    • Multi-tenant? (depending on need)
  • Security
    • Helmet, CORS
    • AppCheck
  • Async processing (OPTIONAL - depends on requirements)
    • Any long-running tasks shouldn’t make the user wait
    • GCP PubSub (recommended)
    • At least once processing
    • Idempotent
    • Replay or retry
    • Scheduled tasks
    • DLQs
  • File storage
    • GCS + CDN
  • Rate limiting (for public APIs)
    • Nestjs throttler (recommended)
  • Input validation
    • zod or class-validator
  • Emails
    • Mailgun, sendgrid
  • React or React Native (recommended)
    • Web: NextJS (recommended, depending on project!)
  • Caching solution
    • Tanstack Query
  • Forms
    • Tanstack forms
    • Validation: zod
  • Store (optional)
    • zustand (recommended)
  • Component lib
    • Shadcn (recommended) - fully customisable, themeable, darkmode
    • RN: Need component lib recommendation (ideally supports Nativewind)
    • Storybook for component management (optional)
  • Styling & theming
  • Design system
    • Tailwind’s system is good
  • Analytics
    • GA or PostHog auto-instrumentation
  • Accessibility
  • i18n
  • SEO
  • Error boundaries
  • Consider: Performance e.g. Lighthouse CI
  • Design Tokens
    • Tailwind config IS your token layer — spacing, color, typography, shadows, radii, motion
    • Shadcn’s HSL CSS variables (recommended) — swap themes without touching components
    • Sync tokens to Figma variables for design-code parity
  • Spacing System
    • 4px base grid (Tailwind default) — #1 differentiator between amateur and professional UI
    • Stick to Tailwind’s scale — arbitrary values (mt-[13px]) are a smell
  • Typography
    • Modular type scale (1.25 ratio) — max 4–5 sizes in the whole app
    • Inter or system font stack (recommended) — one family, two weights covers 90% of apps
  • Color System
    • Semantic tokens only: background, foreground, muted, accent, destructive — never raw hex
    • Neutral palette matters more than brand color
    • WCAG AA contrast minimums — non-negotiable
    • Dark mode from day one, not bolted on
  • Visual Hierarchy
    • Size > Weight > Color — use in that order to create emphasis
    • Every screen: ONE primary action. If everything is bold, nothing is bold
    • When in doubt, more whitespace
  • Layout
    • Mobile-first, max content width ~1280px centered
    • Grid for page layout, Flexbox for component layout
    • Build reusable page shells early
  • Iconography
    • One set everywhere — Lucide (recommended, ships with Shadcn)
    • Pair with text labels; consistent sizing (16/20/24px)
  • Motion
    • Purposeful, not decorative — communicates state change
    • Framer Motion (recommended)
    • Interactions < 200ms, layout shifts 300–500ms
    • Respect prefers-reduced-motion
  • Responsive
    • Design 3 layouts (mobile, tablet, desktop) — not per-device pixel-perfects
    • Touch targets: 44x44px minimum (Apple HIG)
  • UX Patterns
    • Loading: skeletons > spinners (no layout jump)
    • Empty states: never blank — guide user to first action
    • Error states: inline, contextual, actionable
    • Optimistic updates where safe
    • Destructive actions require confirmation
  • Microcopy
    • Design with real content, never lorem ipsum
    • Button labels, empty states, error messages are UX — not afterthoughts
  • Tooling
    • Figma (recommended) — single source of truth
    • Mirror Shadcn library in Figma 1:1
    • Figma MCP for AI-assisted design-to-code
  • AGENTS.md
    • Maintain this well
    • Symlink a CLAUDE.md file to it if using claude
    • Bonus: Scope per project (web, api, etc…)
  • Context Engineering
    • Always give AI context
  • Dictation
    • WisprFlow or VoiceInk
  • Plans & reports
    • Before work: Have AI generate plan files in the plans folder
    • After work: Have AI generate a report file in the docs folder
    • Prefix AI generated files w/ the ISO datetime 2026-04-01_filename.md
      • Easier to find
    • Plans are how you decide how to work
    • Reports are how you remember what you did, and what you want AI to reference first if you go back to tweak a feature
    • Both should include paths to all relevant files
    • Plans should include blocking questions
  • Testing loop
    • THE VALUE OF THIS CANNOT BE OVERSTATED
    • AI should be given as much capability to check its own work as possible
    • AI should follow TDD
    • AI should be taught to boot up the app and check it itself when building a new feature - browser verification
    • Remove as many blockers to this loop as possible
    • Unit / e2e split is valuable
    • Error messages, clean failure context
    • Review test cases as part of the plan
  • Commands & Skills
    • Commands for context you want to load manually
    • Skills for things you want agents to auto-load when doing certain tasks
  • Model: Claude Opus 4.6
  • Harness: Claude Code or Cursor
  • MCP: Context7, Database access, Figma
  • Agent orchestration?
  • Server-side caching (if needed)
    • Redis, memorystore
  • Feature flags
    • Remote config, many alternatives

---
title: System Architecture Overview
---
graph TB
    %% ─── Client Layer ───────────────────────────────────────────────
    subgraph CLIENT["👤 Client Layer"]
        Browser["Browser / Mobile App"]
    end

    %% ─── Frontend ───────────────────────────────────────────────────
    subgraph FRONTEND["⚛️ Frontend (Next.js)"]
        direction TB
        Pages["Pages & Routes"]
        UI["UI Components (Shadcn + Tailwind)"]
        Cache["Client Cache (TanStack Query)"]
        Forms["Forms (TanStack Forms + Zod)"]
        Store["Global State (Zustand)"]
        Analytics["Analytics (GA / PostHog)"]
    end

    %% ─── Shared Layer ───────────────────────────────────────────────
    subgraph SHARED["📦 Shared Packages (Monorepo)"]
        Types["Shared Types (tRPC or shared pkg)"]
        Utils["Shared Utilities"]
        Config["Shared Config"]
    end

    %% ─── Backend ────────────────────────────────────────────────────
    subgraph BACKEND["🖥️ Backend (NestJS)"]
        direction TB
        API["REST API (Swagger auto-docs)"]
        Guards["Auth Guards (token validation)"]
        Services["Business Logic Services"]
        ORM["ORM Layer (Prisma)"]
    end

    %% ─── Auth Provider ──────────────────────────────────────────────
    subgraph AUTH["🔐 Managed Auth"]
        AuthProvider["Firebase Auth / Auth0 / Clerk"]
    end

    %% ─── Async Processing ───────────────────────────────────────────
    subgraph ASYNC["⚡ Async Processing (Optional)"]
        PubSub["GCP PubSub"]
        Workers["Background Workers"]
    end

    %% ─── Data Layer ─────────────────────────────────────────────────
    subgraph DATA["🗄️ Data Layer"]
        Postgres["PostgreSQL (NeonDB)"]
        RedisCache["Redis / Memorystore (Optional)"]
    end

    %% ─── Observability ──────────────────────────────────────────────
    subgraph OBS["📊 Observability"]
        Sentry["Error Tracking (Sentry)"]
        Logs["GCP Logs Explorer"]
        OTel["OpenTelemetry"]
        Slack["Slack Notifications"]
    end

    %% ─── Cloud Platform ─────────────────────────────────────────────
    subgraph CLOUD["☁️ GCP"]
        Secrets["Secrets Manager"]
        Hosting["Cloud Run / GKE"]
    end

    %% ─── Connections ────────────────────────────────────────────────
    Browser -->|"HTTPS"| FRONTEND
    FRONTEND -->|"API calls"| API
    FRONTEND ---|"imports"| SHARED
    BACKEND ---|"imports"| SHARED

    API --> Guards
    Guards -->|"validate token"| AuthProvider
    Guards --> Services
    Services --> ORM
    ORM -->|"queries"| Postgres
    Services -->|"cache read/write"| RedisCache
    Services -->|"publish message"| PubSub
    PubSub -->|"triggers"| Workers
    Workers --> ORM

    Browser -->|"login/signup"| AuthProvider
    AuthProvider -->|"JWT token"| Browser

    BACKEND --> Sentry
    FRONTEND --> Sentry
    Sentry -->|"alerts"| Slack
    BACKEND --> OTel
    OTel --> Logs
    BACKEND -->|"reads secrets at boot"| Secrets
sequenceDiagram
    actor User
    participant FE as ⚛️ Frontend
    participant Cache as 📋 TanStack Query
    participant Auth as 🔐 Auth Provider
    participant API as 🖥️ NestJS API
    participant Guard as 🛡️ Auth Guard
    participant Svc as ⚙️ Services
    participant DB as 🗄️ PostgreSQL
    participant Sentry as 📊 Sentry
    participant PubSub as ⚡ PubSub

    Note over User,DB: 🟢 Happy Path

    User->>FE: Click / submit
    FE->>FE: Validate input (Zod)
    FE->>Cache: Check cache

    alt Cache hit
        Cache-->>FE: Cached data
        FE-->>User: Render instantly
    else Cache miss
        FE->>API: HTTP request + JWT
        API->>Guard: Intercept
        Guard->>Auth: Verify JWT
        Auth-->>Guard: Valid (uid, roles)
        Guard->>Svc: User context attached
        Svc->>DB: Query via Prisma
        DB-->>Svc: Result
        Svc-->>API: Response
        API-->>FE: JSON (200)
        FE->>Cache: Store result
        FE-->>User: Render
    end

    Note over User,DB: 🟡 Async Path (long-running tasks)

    User->>FE: Trigger async action
    FE->>API: Request + JWT
    API->>Svc: Handle
    Svc->>PubSub: Publish message
    Svc-->>API: Accepted (202)
    API-->>FE: Processing...
    FE-->>User: Show loading state
    PubSub->>Svc: Worker picks up
    Svc->>DB: Write result

    Note over User,DB: 🔴 Error Path

    User->>FE: Action triggers error
    FE->>API: Request
    API->>Svc: Handle
    Svc->>DB: Query fails
    DB-->>Svc: Error
    Svc-->>API: Exception
    API->>Sentry: Capture error
    Note right of Sentry: Alerts Slack<br/>(false positives muted)
    API-->>FE: Error (4xx/5xx)
    FE-->>User: Show error message