Claude
Skills
Sign in
Back

nest-server-core-vendoring

Included with Lifetime
$97 forever

Provides knowledge and resources for projects that have vendored the @lenne.tech/nest-server core directly into their source tree (under projects/api/src/core/ instead of consuming via npm). Covers the vendor model, the flatten-fix pattern, the Upstream-to-Project sync workflow, the Project-to-Upstream PR workflow, typical conflicts, and how cosmetic changes are distinguished from substantial upstream candidates. Activates for vendored nest-server core discussions, "sync core from upstream", "port local core change to upstream", conflict resolution during vendor sync, or questions about the vendor pattern. Delegates execution to lt-dev:nest-server-core-updater (for syncs) and lt-dev:nest-server-core-contributor (for upstream PR preparation). NOT for npm-based nest-server updates (use nest-server-updating). NOT for writing new NestJS code (use generating-nest-servers).

Backend & APIs

What this skill does


# Vendored nest-server core Knowledge Base

## Gotchas

- **Flatten-fix edge case on `core-persistence-model.interface.ts`** — During flatten-fix, most files get `'../../..'` rewritten to `'../..'`. This file is an exception: it sits one directory deeper and needs `'../../..'` → `'../..'` → `'..'`. Missing this step causes a silent `Cannot find module` at runtime, not compile-time.
- **`migrate` CLI disappears after vendoring** — The upstream `@lenne.tech/nest-server` package exports a `migrate` binary in its `package.json`. When vendored (no longer a dependency), this binary is gone. Projects that relied on `pnpm migrate` will need to run the migration script directly from `src/core/`.
- **Cosmetic commits are tempting upstream PR candidates** — Formatting-only, linting-only, or rename-only commits look substantive but offer no value as upstream PRs. The contributor agent filters these — if authoring manually, verify the commit changes behavior, not just style.
- **Local patches in `src/core/` are invisible to future `/update-nest-server-core` runs** — The updater does AI-driven curation but cannot read your intent. Document every intentional local deviation in `src/core/LOCAL-PATCHES.md` so the next sync doesn't silently undo your work.

This skill provides **knowledge and resources** for lenne.tech projects that have
vendored the @lenne.tech/nest-server core into their source tree. For automated
execution, use the matching agents:

- `lt-dev:nest-server-core-updater` via `/lt-dev:backend:update-nest-server-core` —
  pulls upstream changes into the vendored core, with AI-driven curation against
  local patches
- `lt-dev:nest-server-core-contributor` via `/lt-dev:backend:contribute-nest-server-core` —
  identifies substantial local changes to the vendored core and prepares them as
  Upstream-Pull-Requests to the nest-server repository

## When This Skill Activates

- Discussing the vendored nest-server core pattern
- Asking how to sync from upstream into a vendored project
- Asking how to port a local fix back to the upstream repository
- Troubleshooting import-path or flatten-fix issues in the vendor tree
- Planning an upstream-sync with conflict resolution
- Explaining the difference to the classic npm-based update flow

## Skill Boundaries

| User Intent                                                | Correct Skill                  |
| ---------------------------------------------------------- | ------------------------------ |
| "Sync vendored core from upstream v11.26.0"                | **THIS SKILL**                 |
| "Port this CrudService fix back to nest-server"            | **THIS SKILL**                 |
| "Apply flatten-fix after upstream copy"                    | **THIS SKILL**                 |
| "Update nest-server via npm"                               | nest-server-updating           |
| "Migrate from nest-server 11.17 to 11.24"                  | nest-server-updating           |
| "Create a new NestJS module"                               | generating-nest-servers        |
| "Fix a CVE via npm audit"                                  | maintaining-npm-packages       |
| "Modify @lenne.tech/nest-server itself and test via pnpm link" | contributing-to-lt-framework |

## Detecting a Vendored Project

A project is considered **vendored** if **all** of the following are true:

1. `projects/api/src/core/VENDOR.md` exists
2. `projects/api/package.json` does **not** list `@lenne.tech/nest-server` in
   `dependencies` or `devDependencies`
3. `projects/api/src/core/` contains at least `common/`, `modules/`, `index.ts`,
   `core.module.ts`

A project is **npm-based** (classic) if:

- `@lenne.tech/nest-server` is a regular dependency in `package.json`
- There is no `VENDOR.md` under `src/core/`

The `nest-server-updater` (classic agent) detects this automatically and delegates
to `nest-server-core-updater` for vendored projects.

## Modification Policy (when to touch `src/core/`)

Vendoring copies the framework source into the project tree so Claude Code
can read it directly — this is a **comprehension aid**, not an invitation to
fork. The policy:

1. **Change `src/core/` ONLY when the change is generally useful to all
   nest-server consumers.** Valid reasons:
   - Bugfixes that apply to every consumer
   - Framework enhancements with broad applicability
   - Closing security vulnerabilities
   - Build/TypeScript compatibility fixes that every consumer would hit
2. **Every other change belongs in project code** (outside `src/core/`),
   via modification, inheritance, extension, or `ICoreModuleOverrides`.
   Project-specific business rules, customer enums, or proprietary
   integration adapters must never live in the vendored core.
3. **Generally-useful changes MUST be submitted as an upstream PR** to
   `github.com/lenneTech/nest-server`. Use
   `/lt-dev:backend:contribute-nest-server-core` to prepare the PR. Do not
   let useful fixes rot in a single project's vendor tree — they belong
   upstream so every consumer benefits and the local patch disappears on
   the next sync.
4. **When in doubt, ask before editing `src/core/`.** The contributor
   agent exists precisely to keep the vendor tree close to upstream.

The `nest-server-core-contributor` agent enforces this distinction by
categorizing every local commit as **upstream-candidate** (generic) vs.
**project-specific** (stays local) vs. **unclear** (asks the human).

## The Vendor Model (one-way curation)

The vendored core lives as **first-class project code**. Flow is:

```
Upstream (github.com/lenneTech/nest-server)
    |
    | /lt-dev:backend:update-nest-server-core  (curated, one-way)
    v
Project vendor (projects/api/src/core/)
    |
    | /lt-dev:backend:contribute-nest-server-core  (manual review, cherry-pick)
    v
Upstream PR (via normal GitHub review process)
```

**Local patches are expected.** Projects legitimately modify the vendored core
when business rules, integration adapters, or bugfixes are needed before upstream
ships them. Those patches persist through syncs.

**Changes are never auto-pushed.** The contributor agent prepares PR drafts —
a human reviews and submits them through normal GitHub workflow. No git-subtree
push, no automatic upstream replay.

## The Flatten-Fix Pattern

Upstream organizes its tree as:

```
nest-server/
├── src/
│   ├── index.ts          ← re-export hub (imports './core/common/...')
│   ├── core.module.ts    ← CoreModule factory (imports './core/modules/...')
│   ├── core/
│   │   ├── common/
│   │   └── modules/
│   ├── test/
│   │   └── test.helper.ts  ← imports '../core/common/helpers/db.helper'
│   ├── templates/
│   ├── types/
│   └── ...
└── LICENSE
```

When vendored, the project gets a **flat** structure under `src/core/`:

```
projects/api/src/core/
├── VENDOR.md             ← NEW
├── LICENSE               ← copied for provenance
├── index.ts              ← moved up from upstream src/, imports rewritten
├── core.module.ts        ← moved up from upstream src/, imports rewritten
├── common/               ← copied as-is
├── modules/              ← copied as-is
├── test/                 ← test.helper.ts, with imports rewritten
├── templates/
└── types/
```

This requires a **single one-shot import-path rewrite** on exactly three files:

1. `index.ts` — strip `./core/` prefix from every relative import/export
   specifier. About 161 rewrites. (ts-morph AST-based.)
2. `core.module.ts` — same strip pattern, about 27 rewrites.
3. `test/test.helper.ts` — upstream uses `../core/common/helpers/db.helper`;
   after flatten the correct path is `../common/helpers/db.helper`. The
   `../core/` prefix gets stripped here too, exactly once.

Internal imports inside `common/`, `modules/`, etc. are **not touched** —
their relative paths between each other are identical before and after
the flatten.

One additional edge case:
`src/core/common/interfaces/core-persistence-model.interface.ts` imports
`CorePersistenceModel` from `'../../..'`. Upstre

Related in Backend & APIs