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
This commit is contained in:
commit
c5ca1e0214
9 changed files with 137 additions and 0 deletions
9
.env.example
Normal file
9
.env.example
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Copy to .env and fill. Never commit the filled version.
|
||||||
|
OPENAI_API_KEY=
|
||||||
|
ANTHROPIC_API_KEY=
|
||||||
|
SUPABASE_URL=
|
||||||
|
SUPABASE_SERVICE_ROLE_KEY=
|
||||||
|
SUPABASE_BUCKET=
|
||||||
|
FACE_ENDPOINT_TOKEN=
|
||||||
|
DEPLOY_SSH_HOST=3dct
|
||||||
|
DEPLOY_TARGET_PATH=/var/www/3dcaketopper.nl/configurator-next/
|
||||||
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# ── Secrets ──
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
id_ed25519*
|
||||||
|
secrets/
|
||||||
|
|
||||||
|
# ── Python ──
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
.pytest_cache/
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# ── Node ──
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.next/
|
||||||
|
|
||||||
|
# ── Generated geometry: large + reproducible. Use LFS if a baseline is needed ──
|
||||||
|
*.stl
|
||||||
|
*.3mf
|
||||||
|
*.obj
|
||||||
|
*.glb
|
||||||
|
!tests/golden/**/*.3mf
|
||||||
|
|
||||||
|
# ── OS ──
|
||||||
|
.DS_Store
|
||||||
75
README.md
Normal file
75
README.md
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
# 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.
|
||||||
1
configurator/.gitkeep
Normal file
1
configurator/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Placeholder. Remove when real content lands here.
|
||||||
16
lefthook.yml
Normal file
16
lefthook.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Pre-commit gate. Installed with: lefthook install
|
||||||
|
pre-commit:
|
||||||
|
parallel: true
|
||||||
|
commands:
|
||||||
|
gitleaks:
|
||||||
|
run: gitleaks protect --staged --no-banner --redact
|
||||||
|
no-large-files:
|
||||||
|
run: |
|
||||||
|
git diff --cached --name-only --diff-filter=A | while read -r f; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
sz=$(wc -c < "$f")
|
||||||
|
if [ "$sz" -gt 10485760 ]; then
|
||||||
|
echo "BLOCKED: $f is $((sz/1048576))MB. Use Git LFS or exclude it."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
1
stl/.gitkeep
Normal file
1
stl/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Placeholder. Remove when real content lands here.
|
||||||
1
templates/.gitkeep
Normal file
1
templates/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Placeholder. Remove when real content lands here.
|
||||||
1
tests/fixtures/.gitkeep
vendored
Normal file
1
tests/fixtures/.gitkeep
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Placeholder. Remove when real content lands here.
|
||||||
1
tests/golden/.gitkeep
Normal file
1
tests/golden/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Placeholder. Remove when real content lands here.
|
||||||
Loading…
Add table
Reference in a new issue