# 3dct-client-mirror Read-only snapshots of **the client's existing production system** for `3dcaketopper.nl`, `birthdaycaketopper.nl` and `weddingcaketopper.nl`. > [!important] This is not our code > Everything here is the property of the client. It is mirrored with written permission, solely so that we have a reproducible baseline of the system as it stood before our engagement began. **Nothing in this repository is transferred to us, and nothing here is covered by the IP assignment in our proposal.** Do not develop against this tree — our delivery code lives in `3D_Cake_topper`. --- ## Snapshots | Snapshot | Taken | Source | | --- | --- | --- | | `snapshot-2026-08-15/` | 2026-08-15 | `matthijsexpand@149.210.159.152` (TransIP VPS, Lelystad NL) | Each snapshot is a point-in-time copy. Never edit one — take a new snapshot instead. The value of this repository is that the old ones remain untouched. ### Layout ``` snapshot-YYYY-MM-DD/ ├── home-weddingcaketopper/ ~/weddingcaketopper — Next.js app + proxy.py ├── var-www/ /var/www — static webroots for all three domains ├── etc-nginx/ /etc/nginx/sites-available — vhost configs └── secrets-DO-NOT-COMMIT/ env files — gitignored, local disk only ``` ### Deliberate exclusions | Excluded | Why | | --- | --- | | `node_modules/` (704 MB) | Third-party packages, regenerable with `npm install`. Not client IP, and permanent git bloat. | | `.next/` (17 MB) | Build output, regenerable with `npm run build`. | | Env file **contents** | See below. | --- ## Why the secrets are not committed The two env files were pulled and **are present on local disk** at `snapshot-*/secrets-DO-NOT-COMMIT/`. Nothing was lost. They are excluded from git only. | File | Contains | | --- | --- | | `etc-weddingcaketopper.env` | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` | | `weddingcaketopper.env.local` | `SUPABASE_SERVICE_ROLE_KEY`, `ADYEN_API_KEY`, `ADYEN_CLIENT_KEY`, `ADYEN_MERCHANT_ACCOUNT`, `OPENAI_API_KEY` | Three reasons this line is drawn at the commit rather than the pull: 1. **Git history is permanent.** "We'll decide later" works for a file on disk. It does not work for a commit — removal requires `filter-repo`, which rewrites every hash and breaks every clone. The reversible choice is to keep them out now and add them deliberately later if wanted; the irreversible choice is the reverse. 2. **These are the client's live credentials, not ours.** A Supabase *service-role* key bypasses all row-level security on the customer database. The Adyen keys are payment infrastructure. Committing them to our git server materially increases *the client's* exposure, and that is not a risk we can accept on their behalf. 3. **They are already flagged as compromised.** Risk S-01 in the project Risk Register: an open unauthenticated relay served these keys to the public internet with no logging. They should be rotated, which makes the current values worth preserving as evidence — not as configuration. **If you later decide they must be versioned**, the correct mechanism is encryption at rest — `git-crypt`, `age`, or SOPS — so the repository holds ciphertext and the key lives elsewhere. Say the word and it can be set up. `.env.example` **is** committed: it records which variables the system requires, without any value. --- ## How a snapshot is taken ```bash BASE=snapshot-$(date +%F) mkdir -p "$BASE"/{home-weddingcaketopper,var-www,etc-nginx,secrets-DO-NOT-COMMIT} rsync -az --exclude node_modules --exclude .next \ 3dct:/home/matthijsexpand/weddingcaketopper/ "$BASE/home-weddingcaketopper/" rsync -az 3dct:/var/www/ "$BASE/var-www/" rsync -az 3dct:/etc/nginx/sites-available/ "$BASE/etc-nginx/" rsync -az 3dct:/etc/weddingcaketopper.env "$BASE/secrets-DO-NOT-COMMIT/etc-weddingcaketopper.env" mv "$BASE/home-weddingcaketopper/.env.local" "$BASE/secrets-DO-NOT-COMMIT/weddingcaketopper.env.local" ``` `3dct` is the SSH host alias in `~/.ssh/config`. --- ## What the 2026-08-15 snapshot documents Full analysis in the project vault: `01-context/Infrastructure and Live Stack Audit`. - `proxy/proxy.py` — 60-line `http.server` script; the open relay behind finding S-01 - `app/api/` — Adyen session/webhook, OpenAI preview, order creation routes - `supabase/schema.sql` — `orders` and `uploads` tables, no row-level security - `README.md` — the previous developer's own list of six items outstanding before production - `var-www/3dcaketopper.nl/ontwerp/` — the live vanilla-JS configurator being replaced - `etc-nginx/` — the three vhosts, previously existing only on the server with no history