Files
blog-nest/.github/.copilot-instructions.md

18 KiB

applyTo
applyTo
**/*

Copilot Instructions for blog-nest Monorepo

0. Mission

Produce production-grade changes that are correct, verifiable, maintainable, and aligned with this Turbo monorepo's architecture.


1. Project Context

Workspace Structure

  • Monorepo Tool: Turbo + pnpm workspaces
  • apps/api: NestJS backend (TypeScript)
  • apps/frontend: Next.js frontend with App Router (TypeScript)
  • apps/mobile: Expo mobile app with Expo Router (TypeScript)
  • Linting: Biome (biome.json in root and per-app)
  • Testing: Jest (per-app configuration)
  • Git Hooks: Lefthook (lefthook.yml)

Key Dependencies & Tools

  • Backend (apps/api):
    • NestJS 11.0.1
    • Prisma ORM 7.4.2 with @prisma/client 7.4.2
    • TypeScript 5.7.3
    • Jest 30.0.0
    • class-validator & class-transformer (DTOs)
  • Frontend (apps/frontend):
    • Next.js 16.1.6 with App Router
    • React 19.2.3
    • Tailwind CSS 4
    • Jest 30.2.0
    • TypeScript 5
  • Mobile (apps/mobile):
    • Expo 55.0.5 with Expo Router
    • React Native 0.83.2
    • React 19.2.0
  • Tooling:
    • Biome 2.4.6 (linting + formatting)
    • Turbo 2.8.13 (monorepo orchestration)
    • Lefthook 2.1.2 (git hooks)
    • TypeScript strict mode enabled across all apps

Runtime & Package Manager

  • Node.js: v24.14.0 (see .nvmrc for version pinning)
  • Package Manager: [email protected].3
  • Commands: pnpm dev, pnpm test, pnpm lint, pnpm build
  • Monorepo Command: pnpm --filter <workspace-name> <task>
    • Workspace names: api, frontend, mobile
  • Turbo Commands: turbo run <task> (respects pnpm workspaces)

Production Deployment

  • Strategy: Self-managed VPS with Docker Compose
  • Database: PostgreSQL 17
  • Cache: Redis 7
  • Reverse Proxy: Nginx with SSL/TLS
  • SSL: Let's Encrypt with auto-renewal
  • See: DEPLOY_VPS.md for complete deployment guide

2. Rule Priority and Conflict Resolution

When instructions conflict, follow this order:

  1. Safety, correctness, and policy compliance
  2. User-requested behavior
  3. This repository instruction file
  4. Existing codebase patterns and conventions
  5. Style preferences

If two rules still conflict, choose the option that preserves behavior and testability, then document the tradeoff in the final summary.


3. Operational Mode

  • Execute end-to-end without pausing for non-blocking confirmations.
  • Keep responses concise during execution; provide one complete summary at the end.
  • Do not claim completion until all required checks pass.
  • If blocked by missing requirements, ask the smallest possible clarifying question.
  • Use pnpm --filter to run workspace-specific commands efficiently.

4. Definition of Done (Mandatory)

A task is complete only when all applicable items pass:

  1. ✓ Requested behavior implemented.
  2. ✓ All touched files are lint/error clean (run pnpm lint or pnpm --filter <app> run biome check --write).
  3. ✓ Tests relevant to the change pass:
    • Backend: pnpm --filter api test (or targeted test file)
    • Frontend: pnpm --filter frontend test (if test harness exists)
    • Mobile: pnpm --filter mobile test (if test harness exists)
  4. ✓ Coverage for touched backend files is at least 90% when running pnpm --filter api run test:cov.
  5. ✓ No duplicated logic introduced when a reusable abstraction is appropriate.
  6. ✓ Public API changes include all call-site and type updates across apps.
  7. ✓ Final diff is minimal and free of unrelated edits.

5. Mandatory Execution Workflow

Initialization

  1. Understand context before editing. Reuse existing patterns and components where possible.
  2. Check existing implementations in the target app (apps/api, apps/frontend, apps/mobile).
  3. Review related DTOs, types, and interfaces.

Implementation

  1. Implement in small, verifiable increments.
  2. Run integrity checks immediately on touched files:
    pnpm lint  # Runs Biome across all touched files
    
  3. If Prisma schema changes (backend only):
    pnpm --filter api run prisma:migrate:dev --name <migration-name>
    pnpm --filter api run prisma:generate
    
  4. Run focused tests for changed behavior:
    # Backend
    pnpm --filter api test -- <file-pattern>
    
    # Frontend
    pnpm --filter frontend test -- <file-pattern>
    
    # Mobile
    pnpm --filter mobile test -- <file-pattern>
    

Verification

  1. Run coverage checks when available (backend):
    pnpm --filter api run test:cov
    
    • Refactor if quality gates fail (aim for ≥90% coverage on touched files).
  2. Finalize only after all gates pass.

Additional Workflow Constraints

  • When changing exported interfaces or types, search the repo and update all call sites.
  • Never skip verification because a change appears "small."
  • Never revert requested functional behavior solely to satisfy tests or coverage; fix tests and add missing coverage.
  • If pnpm dev fails after changes, investigate logs and fix before finalizing.

6. Code Purity and Output Rules

  • Generate raw executable code only.
  • Forbidden: commented-out code, inline rationale comments, placeholder comments, emojis.
  • Allowed: required JSDoc/docstrings explaining non-obvious logic.
  • Keep code deterministic, explicit, and readable.
  • Follow Biome's auto-formatting output; do not argue style choices.
  • Never use emojis in code, documentation, commit messages, or any project files.

7. Backend Rules (NestJS + Prisma) — apps/api

7.1 Architecture

  • Keep controllers thin; move business logic into services.
  • Use DTOs with class-validator and class-transformer.
  • Prefer module-level composition and dependency injection over manual instantiation.
  • Use ConfigService for configuration; avoid direct process.env access in services.
  • Follow NestJS folder structure: modules/<feature>/{*.controller.ts, *.service.ts, *.module.ts, dto/}

7.2 Prisma and Data Access

  • Prisma v7 Configuration:
    • Connection URL configured in apps/api/prisma.config.ts (NOT in schema file)
    • Config file loads root .env from ../../.env
    • Schema location: apps/api/prisma/schema.prisma
    • Migrations: apps/api/prisma/migrations/
  • Use Prisma Client for data access; avoid raw SQL unless strictly necessary.
  • Model relations in Prisma schema, not as loose id fields.
  • Use transactions for multi-step writes.
  • Avoid N+1 queries: use include/select and batching.
  • Keep Prisma schema well-organized by model.
  • Always use workspace scripts: prisma:generate, prisma:migrate:dev, prisma:studio

7.3 Auth, Cache, and Integrations

  • Use @nestjs/jwt and guards for authentication.
  • Redis interactions should be centralized in services and typed.
  • External integrations must be wrapped with clear interfaces and tested with mocks.

7.4 Migrations

  • Always generate migrations via pnpm --filter api run prisma:migrate:dev --name <name>.
  • Never hand-edit migration files unless absolutely necessary for data migration.
  • Commit schema, config, and migration files together.
  • For production: use pnpm --filter api run prisma:migrate:deploy.

7.5 Error Handling

  • Use NestJS HttpException and custom exceptions from @nestjs/common.
  • Validate incoming DTOs with class-validator.
  • Return consistent error response shapes.

8. Web Rules (Next.js App Router) — apps/frontend

8.1 Rendering and Data Fetching

  • Default to Server Components; add "use client" only when required (interactivity, hooks, browser APIs).
  • Keep client components small and isolated.
  • Use fetch with Next.js caching semantics where appropriate.
  • Leverage server-side rendering for SEO-critical content.

8.2 Environment and API Access

  • Use NEXT_PUBLIC_* for browser-facing env vars only.
  • Centralize API URL usage; do not hardcode base URLs.
  • Use server-side environment variables for sensitive tokens.

8.3 UI and Structure

  • Keep layouts and pages inside App Router conventions (src/app/).
  • Favor simple, composable components and avoid prop drilling when context fits.
  • Use TypeScript for all component props.

8.4 Styling

  • Follow existing stylesheet approach; maintain consistency with current setup (CSS modules, Tailwind, or PostCSS).
  • Keep global styles in globals.css.

9. Mobile Rules (Expo + Expo Router) — apps/mobile

9.1 Routing and Structure

  • Follow Expo Router conventions under src/app/.
  • Use file-based routing; keep layout hierarchy clean.
  • Separate screens into focused components stored in src/app/.
  • Move reusable UI into components/.

9.2 Styling and UI

  • Prefer NativeWind className for styling.
  • Avoid inline styles unless absolutely necessary.
  • Use existing UI components before creating new ones.
  • Keep theme constants in constants/theme.ts.

9.3 Platform APIs

  • Use expo-secure-store for sensitive storage.
  • Use expo-notifications through dedicated service utilities when possible.
  • Check platform-specific files (.web.tsx, .ts for native).

9.4 Assets and Config

  • Store images in assets/images/.
  • Keep app configuration in app.json.
  • Icon and theme assets in assets/.

10. Shared Package Rules — packages/shared (if applicable)

  • Keep utilities pure and side-effect free.
  • Export all public APIs through src/index.ts.
  • Do not import app-specific modules into shared.
  • Mark exports clearly for cross-app consumption.

11. Shared Coding Standards

11.1 Import Order

// 1. Standard Library
import fs from 'fs';

// 2. Third-Party
import React from 'react';
import { Module } from '@nestjs/common';

// 3. Local
import { MyService } from './my.service';

11.2 General Conventions

  • Keep imports top-level; do not use inline imports to bypass circular dependencies.
  • Use ASCII for filenames and identifiers.
  • Keep complexity low; refactor deeply nested or branching-heavy code.
  • Use explicit types; avoid any unless absolutely necessary.
  • Use TypeScript strict mode (enabled in tsconfig.json).

11.3 File Naming

  • Backend: kebab-case with suffixes (e.g., user.service.ts, auth.guard.ts, create-user.dto.ts)
  • Frontend: kebab-case or PascalCase for components (e.g., user-profile.tsx, UserCard.tsx)
  • Mobile: kebab-case for utilities, PascalCase for components (e.g., use-color-scheme.ts, AppTabs.tsx)

12. Testing and Verification Standards

12.1 Baseline Requirements

  • Backend changes: run targeted pnpm --filter api test <pattern> or E2E tests if relevant.
  • Frontend changes: run relevant tests if a harness exists (pnpm --filter frontend test).
  • Mobile changes: run relevant tests if a harness exists (pnpm --filter mobile test).
  • All changes: always run Biome lint checks on touched files and pass all formatting.
  • Backend logic changes: run pnpm --filter api run test:cov to verify coverage ≥90%.

12.2 Required Test Scenarios by Change Type

  • Bug fix: add or update a test that fails before the fix and passes after.
  • New API endpoint: test success case, validation errors, and auth/authorization.
  • Service logic: test all branches, happy path, and error cases.
  • Component: test render, user interactions, and error states if applicable.

12.3 Test File Locations

  • Backend: src/<module>/<feature>.spec.ts (unit), test/<feature>.e2e-spec.ts (E2E)
  • Frontend: src/<feature>.spec.tsx (unit)
  • Mobile: src/<feature>.spec.tsx (unit)

13. Commit Standards

13.1 Commit Message Format

<type>(<scope>): <description>

<body>

[optional footer]

13.2 Specifications

  • Types: feat, fix, refactor, test, chore, perf, docs
  • Scope: app name or feature name (e.g., api, frontend, auth, user-service)
  • Description: imperative, lowercase, no period, ≤50 chars
  • Body: required; explain what changed and why (not how)
  • Breaking changes: use feat!: or include BREAKING CHANGE: footer

13.3 Example

feat(api): add user profile endpoint

Implement GET /users/:id endpoint with profile data.
Includes auth guard and validation of user ownership.
Adds test coverage for success and auth failure cases.

14. Non-Negotiable Prohibitions

  • ✋ No broad exception swallowing (avoid catch (e) {}).
  • ✋ No inline-import circular-dependency hacks.
  • ✋ No test-only hacks in production code.
  • ✋ No per-item fan-out API calls when a bulk endpoint exists or should exist.
  • ✋ No read-time data cleanup for persisted model attributes.
  • ✋ No console.log in production code unless explicitly requested.
  • ✋ No TODO/FIXME comments without context or tracking.

15. Quality Gate Failure Policy

If any quality gate fails, do not finalize:

  1. Re-read error output carefully.
  2. Fix root cause (test, type, lint, coverage).
  3. Re-run the specific failing check to confirm pass.
  4. Mark the task complete only after all gates pass.

16. Debugging Commands Reference

Monorepo Health

pnpm install              # Install all dependencies
pnpm clean                # Clean build artifacts
pnpm lint                 # Biome check + format all
pnpm test                 # Run all tests
pnpm build                # Build all apps
pnpm dev                  # Start dev servers (Turbo orchestrated)

Workspace-Specific

# Backend (apps/api)
pnpm --filter api test
pnpm --filter api run test:cov
pnpm --filter api run prisma:migrate:dev --name <name>
pnpm --filter api run prisma:studio
pnpm --filter api run prisma:generate

# Frontend (apps/frontend)
pnpm --filter frontend dev
pnpm --filter frontend test
pnpm --filter frontend build

# Mobile (apps/mobile)
pnpm --filter mobile dev
pnpm --filter mobile test

Linting

pnpm lint                             # Check all
pnpm lint --write                     # Format all
pnpm lint apps/api                    # Check specific app
pnpm lint --write apps/frontend       # Format specific app

Troubleshooting

# Kill stray processes
pkill -f "next dev"
pkill -f "nest start"

# Nuke cache and reinstall
pnpm clean
rm -rf node_modules
pnpm install
pnpm dev

# Check Turbo cache
turbo --version
turbo prune --docker --scope=api  # For monorepo analysis

# Prisma-specific troubleshooting
pnpm --filter api run prisma:generate  # Regenerate client
pnpm --filter api exec prisma validate --config prisma.config.ts  # Validate schema

17. Final Verification Checklist

Before marking a task complete:

  • Feature implemented as requested
  • All files pass Biome lint and format
  • All targeted tests pass
  • Backend coverage ≥90% (if backend logic changed)
  • No console.log or debug code left
  • No commented-out code
  • Types updated everywhere
  • Commit message follows format
  • pnpm dev starts without errors (if integration needed)
  • All non-blocking tasks completed

18. Quick Help

"My change broke tests"

→ Fix the test or the code. Never leave failing tests. If the test is wrong, update it. If code is wrong, fix it.

"I'm not sure which app to change"

→ Ask yourself: Is this backend logic (API), frontend UI (website), or mobile UI? Find the right apps/ folder.

"How do I know if my change is good?"

→ Run the entire Definition of Done checklist (section 4). All items must pass.

"What if I need to share code?"

→ Check if packages/shared exists and is set up. If sharing between apps, extract to a shared utility and re-export from each app if needed. Avoid circular dependencies.

"Do I need to write tests?"

→ Yes, unless the change is purely structural/refactor with no behavior change. When in doubt, test it.


19. Automated Metadata Sync

For Agents Only: If you read this file and the Last Updated date is 7 or more days in the past, perform a full audit and update the file as needed.

Full Audit Checklist for Agents

  1. Read Key Project Files

    • package.json (root)
    • apps/api/package.json
    • apps/frontend/package.json
    • apps/mobile/package.json
    • apps/*/tsconfig.json (check TypeScript versions)
    • biome.json (root)
    • Any README.md files in apps/
    • Folder structure under each app
  2. Compare Against Documented State (Section 1 & 7-9)

    • ✓ Verify listed dependencies match actual packages (NestJS, Prisma, Next.js, Expo, Biome, Jest)
    • ✓ Check version ranges; if major version bump occurred, note it
    • ✓ Verify app folder structure still exists and matches documented paths
    • ✓ Check if new apps/packages have been added
    • ✓ Verify linting and test tools haven't changed
    • ✓ Confirm workspace name patterns (api, etc.) match package.json
  3. Document Any Changes

    • If package versions changed significantly (major bump), update Section 1
    • If new apps/packages were added, update Section 1 and relevant sections (7-9)
    • If frameworks/tools changed, update the corresponding sections
    • If workspace naming convention changed, update throughout
  4. Update the File

    • Do NOT just timestamp; make meaningful updates if you discovered changes
    • Update Section 1 (Project Context) with new/updated dependencies
    • Update Section 7-9 if app architectures or tools changed
    • Update Section 16 (Debugging Commands) if package manager scripts changed
    • Always update the Last Updated timestamp to today
  5. Commit & Push

    • If only timestamp changed: chore: sync copilot instructions (automated audit)
    • If content changed: chore: update copilot instructions (dependency/architecture updates)
    • Commit message body should list what changed (e.g., "Updated Next.js version, added new mobile dependency")

Example Audit Workflow

1. Read root package.json → Note version of @nestjs/common
2. Read .github/.copilot-instructions.md line "NestJS + Prisma"
3. Compare → If versions diverge significantly, update section 1
4. Check apps/api/package.json → Verify listed packages exist
5. Check if new apps added → If yes, update section 1 workspace structure
6. Check typescript versions → If changed, note in sections 1 & 10
7. Run date check → If 7+ days old, update timestamp
8. Commit all changes with descriptive message

Key Rules

  • Only update if audit reveals actual changes OR date is stale
  • Never skip the audit just because the date is recent (do it at least monthly)
  • If uncertain whether a change is significant, document it to be safe
  • Automated agents should prioritize correctness over brevity

Last Updated: Thursday, March 6, 2026
Monorepo Type: Turbo + pnpm
Primary PM: pnpm
Linter: Biome