3D_Cake_topper/README.md
Mannu c5ca1e0214 chore: scaffold delivery repository
Layout, secret hygiene and workflow per the engagement's version control
plan. Nothing functional yet — this establishes the shape before code
lands, so the conventions are enforced from the first real commit.

- .gitignore + .env.example: no secret can reach a commit object
- lefthook + gitleaks pre-commit gate; blocks new files >10MB
- templates/ holds config files, never per-template scripts
- deploy/nginx/ version controlled rather than hand-edited on the server

Refs ADR-007
2026-08-15 08:59:11 +05:30

75 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 3D_Cake_topper
Delivery code for the **3dcaketopper.nl** personalised cake-topper platform, built for Van der Eijk Investments B.V.
> [!important] This repository is assigned to the client
> Under the engagement's gate-by-gate IP assignment, everything here transfers to the client. **Keep it clean of internal material** — commercial reasoning, pricing, risk assessments and client correspondence belong in the private Obsidian vault, never here. Git history is permanent; anything committed is handed over, even if later deleted.
>
> Related repositories:
> - `Obsidian_vault` — internal notes, ADRs, risk register (**never transferred**)
> - `3dct-client-mirror` — read-only snapshots of the client's pre-existing system
---
## What this builds
A configurator that lets a customer personalise a figurine template — garment colours, skin tone, hair colour, hairstyle, name, age, date — and produces a print-ready 3MF for Bambu Lab FDM printing.
The architectural principle, and the reason the economics work:
**Everything except the face is deterministic.** Colour changes are a WebGL recolour in the browser (`out = albedo × L + S`) — free, instant, and identical every time, which matters because the customer is approving a physical product. Only the face-likeness step calls a model.
The system it replaces makes **two** paid image-generation calls per configuration and regenerates the entire figure whenever any attribute changes.
## Layout
```
docs/ architecture summary (client-safe) + deploy runbook
pipeline/ extract.py, pipeline.py, build.py — template authoring
configurator/ runtime.html, studio.html, shaders
templates/ per-template CONFIG FILES — never scripts
stl/ assembly, manifold3d printability gates, 3MF export
tests/golden/ regression baselines
deploy/nginx/ vhost fragments — version controlled, not hand-edited on the box
deploy/systemd/ unit files for the API service
```
Two conventions this layout enforces:
**`templates/` holds configuration, not code.** One configurable pipeline with N config files — never one script per template. A `.py` file appearing in `templates/` means the architecture has regressed. This was learned the hard way: the first prototype was built and tested against a single design, then produced nothing at all on the second, because it had quietly learned "navy" instead of "clothing".
**`deploy/nginx/` is version controlled.** The client's production nginx config currently exists only on the server, hand-edited, with no history. Every config change here is a commit before it is a deployment — that is what makes rollback real rather than aspirational.
## Setup
```bash
cp .env.example .env # fill in; never commit
brew install gitleaks lefthook
lefthook install # installs the pre-commit gate
```
The pre-commit hook runs `gitleaks` on staged content and blocks any new file over 10 MB. Both are there because this project has already seen a `664` env file holding live payment keys, and a 195 MB webroot. Neither belongs in git history, and history is permanent.
## Workflow
Trunk-based. `main` is always deployable and protected; work happens on short-lived `feat/` or `fix/` branches merged by pull request, even when working alone — the PR is where the diff gets read as a whole.
Commits follow Conventional Commits (`feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `ops`) and reference the vault in the body — `Refs ADR-007`, `Closes S-01`. That thread between decision record and implementation is what makes a cold reading possible in six months.
**Every gate deliverable is tagged** (`gate-0`, `gate-1`…). On a fixed-price contract with per-gate IP assignment, those tags are the contractual record of what was delivered and accepted on what date.
## Deployment
Per ADR-007, release is a parallel-path cutover rather than an in-place overwrite:
```bash
python build.py --config templates/<name>.json --out dist/
rsync -avz --delete dist/ 3dct:/var/www/3dcaketopper.nl/configurator-next/
curl -I https://www.3dcaketopper.nl/configurator-next/ # verify before traffic
# cut over: one nginx location change, committed first
# roll back: revert that commit, nginx -s reload (~10 seconds)
```
The existing `/ontwerp/` configurator stays live and untouched throughout, which is what makes rollback instant.
**Never edit files directly on the server.** Commit, push, deploy.