From 842a439dc0b69453940b62878ab37c35e3111f9f Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Fri, 24 Jul 2026 16:08:53 +0300 Subject: [PATCH 1/2] Configure Codespaces autostart and fix SSR proxy headers - Trust X-Forwarded-* headers in the Angular SSR server so it reconstructs the correct request URL behind the Codespaces proxy (fixes the 'trustProxyHeaders was not set up' warning). - Devcontainer: auto-open codespaces.md, open a preview for the Angular client (port 4200), and start the server/client on attach. - Add codespaces.md welcome guide shown when the project opens. --- .devcontainer/devcontainer.json | 13 +++++- client/server.ts | 5 ++- codespaces.md | 78 +++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 codespaces.md diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 69b0f5f..bec3d08 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -9,6 +9,11 @@ } }, "customizations": { + "codespaces": { + "openFiles": [ + "codespaces.md" + ] + }, "vscode": { "extensions": [ "mongodb.mongodb-vscode" @@ -22,7 +27,8 @@ ], "portsAttributes": { "4200": { - "label": "Angular Client" + "label": "Angular Client", + "onAutoForward": "openPreview" }, "5300": { "label": "Express API" @@ -35,5 +41,10 @@ "postStartCommand": "bash -lc 'for i in {1..60}; do mongosh --quiet \"$DATABASE_URI\" --eval \"db.hello().isWritablePrimary\" | grep -q true && break; sleep 2; done; npm run seed'", "remoteEnv": { "DATABASE_URI": "mongodb://localhost:27017/meanStackExample?appName=mean-stack-example-devcontainer" + }, + "postAttachCommand": { + "server": "cd server && npm start", + "client": "export NG_CLI_ANALYTICS=\"false\"; cd client && npm start", + "portSetup": "sleep 5 && .devcontainer/portSetup.sh" } } diff --git a/client/server.ts b/client/server.ts index 0c04fb0..bce0391 100644 --- a/client/server.ts +++ b/client/server.ts @@ -14,7 +14,10 @@ export function app(): express.Express { const serverDistFolder = dirname(fileURLToPath(import.meta.url)); const browserDistFolder = resolve(serverDistFolder, '../browser'); - const angularApp = new AngularNodeAppEngine(); + // Codespaces (and other hosted dev/proxy setups) terminate TLS at a trusted + // reverse proxy that forwards the original request via X-Forwarded-* headers. + // Trust them so Angular reconstructs the correct request URL. + const angularApp = new AngularNodeAppEngine({ trustProxyHeaders: true }); // Example Express Rest API endpoints // server.get('/api/**', (req, res) => { }); diff --git a/codespaces.md b/codespaces.md new file mode 100644 index 0000000..3cff11a --- /dev/null +++ b/codespaces.md @@ -0,0 +1,78 @@ +# ๐Ÿ‘‹ Welcome to the MEAN Stack Example + +This Codespace is **already up and running** โ€” dependencies are installed, the database is seeded, and both the API and the Angular client have started for you. There's nothing to `npm install` or `npm start`; just wait a few seconds for the servers to finish booting. + +## ๐Ÿš€ What's running + +| Service | Port | Description | +|---------|------|-------------| +| **Angular Client** | `4200` | The web app (opens automatically in a Simple Browser preview) | +| **Express API** | `5300` | REST API for employee CRUD operations | +| **MongoDB** | `27017` | Local database, pre-seeded with sample employees | + +The **Angular Client** preview opens on its own when the client finishes compiling. If you don't see it (or you closed it), open the **Ports** tab, find port **4200** ("Angular Client"), and click the ๐ŸŒ globe icon to open the preview. + +> โณ First launch takes a moment while the client compiles. If the preview shows an error at first, give it a few seconds and refresh. + +## ๐Ÿงญ Try it out + +In the client preview you can: + +- **View** the seeded list of employees. +- **Add a New Employee** with the button below the list. +- **Edit** or **Delete** any row with the action buttons. + +Changes are saved through the Express API to MongoDB and reflected in the list immediately. + +You can also hit the API directly from the terminal: + +```bash +curl http://localhost:5300/healthcheck # โ†’ {"status":"ok"} +curl http://localhost:5300/employees # โ†’ the seeded employees +``` + +## ๐Ÿ—‚๏ธ Project structure + +``` +server/ Express + MongoDB REST API (TypeScript) + src/ + server.ts App entry, CORS, /healthcheck, mounts the router + employee.routes.ts CRUD routes for /employees + database.ts MongoDB connection + schema validation +client/ Angular 22 app (standalone, zoneless, SSR) + src/app/ + employees-list/ List view (Material table) + employee-form/ Shared reactive form + add-employee/ Create page + edit-employee/ Edit page (loaded via a route resolver) + employee.service.ts httpResource + CRUD calls to the API +``` + +## โœ๏ธ Making changes + +Both servers run in **watch mode** โ€” just edit and save: + +- Edit files under **`client/src/`** โ†’ the client rebuilds and the preview reloads. +- Edit files under **`server/src/`** โ†’ restart the API from the terminal if needed: + ```bash + cd server && npm start + ``` + +## ๐ŸŒฑ Reseeding the database + +The database is seeded on startup. To reset it to the sample data at any time: + +```bash +npm run seed +``` + +## ๐Ÿงช Running tests + +```bash +npm test # client + server unit tests +npm run test:integration # API integration tests (in-memory MongoDB) +``` + +## ๐Ÿ“š Learn more + +This project is the companion code for the [MEAN Stack Tutorial](https://www.mongodb.com/resources/languages/mean-stack-tutorial). Happy hacking! ๐ŸŽ‰ From 0d09f3978e376557656ebc58435c39b7ed05eb79 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Fri, 24 Jul 2026 16:11:58 +0300 Subject: [PATCH 2/2] Add Codespaces portSetup.sh to expose forwarded ports - Make forwarded ports (4200, 27017, 5300) public via the gh CLI. - Add a shebang and executable bit so postAttachCommand can run it directly. --- .devcontainer/portSetup.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 .devcontainer/portSetup.sh diff --git a/.devcontainer/portSetup.sh b/.devcontainer/portSetup.sh new file mode 100755 index 0000000..204117d --- /dev/null +++ b/.devcontainer/portSetup.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e + +if [ -z "$CODESPACE_NAME" ]; then + echo "Not running in a codespace, exiting." + exit +fi + +echo "Installing GH" + +(type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \ +&& sudo mkdir -p -m 755 /etc/apt/keyrings \ +&& out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ +&& cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ +&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ +&& sudo mkdir -p -m 755 /etc/apt/sources.list.d \ +&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ +&& sudo apt update \ +&& sudo apt install gh -y + +echo "Exposing ports" +gh codespace ports visibility 4200:public 27017:public 5300:public -c $CODESPACE_NAME \ No newline at end of file