Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,23 @@ composes them in one process.
- `createNodeRequestHandler` returns its argument unchanged, so the exported
`reqHandler` *is* the Express app and mounts directly as middleware.

**The App Hosting buildpack reads `engines.pnpm`, and ignores `packageManager`.**
It resolves that field as a *range* against the npm registry and installs the
highest match, so `">=10"` quietly became pnpm 12 on the build machine while
local and CI stayed on 10.14.0. The buildpack's own >= 11 branch is broken — it
unpacks the standalone GitHub tarball, then launches it as
`node <layer>/bin/dist/pnpm.mjs`, which only exists in the npm package layout —
so the build died with `MODULE_NOT_FOUND` before installing a single dependency.
`engines.pnpm` is now an exact `10.14.0` matching `packageManager`. Bumping it
past 11 breaks the deploy and nothing else, so no local check will catch it.

**Never give `NODE_ENV` BUILD availability in `apphosting.yaml`.** The buildpack
installs with `pnpm install --prod`, which under `NODE_ENV=production` drops
every devDependency — and this build *is* devDependencies: the Angular CLI, the
Nest CLI, typescript. Nothing in the build reads `NODE_ENV` anyway (Angular
takes `production` from `angular.json`); the single reader in the repo is
`EnvService.partnerOrigin`, per request, at runtime.

**`NG_ALLOWED_HOSTS` is load-bearing, and it fails silently.** Angular 21 checks
the `Host` header against an allowlist (SSRF protection). Off the list it does not
error — it falls back to **client-side rendering**, quietly discarding the SSR and
Expand Down
39 changes: 34 additions & 5 deletions apphosting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
# subdirectory; `rootDir: "/"` in firebase.json keeps pnpm-workspace.yaml and
# pnpm-lock.yaml at the root of the build workspace, where the installer looks.

# The pnpm version is pinned EXACTLY in package.json `engines.pnpm`, not as a
# range. The App Hosting Node buildpack resolves `engines.pnpm` against the npm
# registry and takes the highest match — it ignores `packageManager` — so the
# old `">=10"` silently selected pnpm 12. Its own >= 11 branch is broken: it
# downloads the standalone GitHub tarball and then launches it as
# `node <layer>/bin/dist/pnpm.mjs`, a path that only exists in the npm package
# layout, and the build dies with MODULE_NOT_FOUND before installing anything.
# Keep `engines.pnpm` an exact 10.x that matches `packageManager`; bumping it
# past 11 re-breaks the deploy while local and CI stay green.

runConfig:
cpu: 1
memoryMiB: 1024
Expand All @@ -29,9 +39,17 @@ env:
# Marks this as the deployed environment. EnvService reads it to decide that
# PARTNER_DEMO_ORIGIN has no localhost default here — otherwise /agent would
# embed an iframe pointing at each visitor's own machine.
#
# RUNTIME only, and that is load-bearing. `EnvService.partnerOrigin` is the
# only reader in the repo and it runs per request; nothing in the build looks
# at NODE_ENV (Angular takes `production` from angular.json, not the env). But
# the buildpack installs with `pnpm install --prod` under NODE_ENV=production,
# which drops every devDependency — and the whole build is devDependencies:
# the Angular CLI, the Nest CLI, typescript. Granting this BUILD availability
# produces a build that cannot find `ng`.
- variable: NODE_ENV
value: production
availability: [BUILD, RUNTIME]
availability: [RUNTIME]

# Angular 21 refuses to server-render a request whose Host header is not on an
# allowlist (SSRF protection). Off the allowlist it does NOT fail loudly — it
Expand All @@ -49,7 +67,7 @@ env:
# Verify after a deploy: the HTML for `/` must contain `ng-server-context`.
# If it does not, this value is wrong and the site is rendering client-side.
- variable: NG_ALLOWED_HOSTS
value: "*.web.app,*.run.app,*.firebaseapp.com,*.programmersingh.dev"
value: "*.hosted.app,*.run.app,*.web.app,*.firebaseapp.com,*.programmersingh.dev"
availability: [RUNTIME]

# The Supabase project URL is not a credential; the service-role key below is.
Expand Down Expand Up @@ -83,10 +101,21 @@ env:
# from and the value has to be present while the build runs.
#
# Unset, every URL stays root-relative — valid, but the sitemap is not
# spec-compliant and scrapers may not resolve og:image. Set it to the
# backend's real hostname.
# spec-compliant and scrapers may not resolve og:image.
#
# This is an ORIGIN, so it must carry the scheme. stamp-seo.mjs substitutes the
# value verbatim (it only trims trailing slashes), so a bare hostname yields
# `<loc>actuo.programmersingh.dev/</loc>` — not a URL, and `new URL()` rejects
# it. Nothing fails the build; the sitemap is just quietly invalid.
#
# PREREQUISITE: this domain must actually resolve and be attached to the
# backend. It was NXDOMAIN when this value was set, and a canonical pointing at
# a host that does not resolve is worse than a relative one — it tells crawlers
# the real URL is dead. Add it as a custom domain on the App Hosting backend,
# point DNS at it, then confirm with `host actuo.programmersingh.dev`. Until
# that is done the deploy is fine and only the SEO metadata is wrong.
- variable: PUBLIC_ORIGIN
value: "actuo.programmersingh.dev"
value: "https://actuo.programmersingh.dev"
availability: [BUILD]

# --- Optional, with sane defaults in EnvService --------------------------
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "AI-native expense intelligence platform with a universal WebMCP Copilot",
"engines": {
"node": ">=22",
"pnpm": ">=10"
"pnpm": ">=9.0.0 <10.0.0"
},
"scripts": {
"dev": "pnpm run build:shared && concurrently -n backend,frontend,partner -c blue,magenta,yellow \"pnpm run dev:backend\" \"pnpm run dev:frontend\" \"pnpm run dev:partner\"",
Expand All @@ -23,5 +23,5 @@
"concurrently": "^10.0.5",
"supabase": "^2.116.0"
},
"packageManager": "pnpm@10.14.0"
"packageManager": "pnpm@9.15.5+sha512.845196026aab1cc3f098a0474b64dfbab2afe7a1b4e91dd86895d8e4aa32a7a6d03049e2d0ad770bbe4de023a7122fb68c1a1d6e0d033c7076085f9d5d4800d4"
}
24 changes: 12 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading