Apps
Thingslab-print

Studios
| Studio | Route | What it makes |
|---|---|---|
| Keychain | /make/keychain | Name tag in Thai/English, outline or shaped backing, 2-3 colors |
| Clicker | /make/clicker | Keycaps on cherry MX switches with a base and key ring |
| Shoe charm | /make/charm | Crocs-style charms with a plug on the back |
| Box & tray | /make/box | Bento trays with compartments, or a box with a sliding lid |
| Pipe clamps | /make/clamp | Snap clips, saddles, P-clips, and cable rails for Thai PVC pipe sizes, with a screw list |
| Standoffs | /make/standoff | Pin that float cut-out letters 6-50 mm of a wall, plus a fit-test set |
| End caps & feet | /make/endcap | Plugs and caps for box steel and round tube, and screw-in leveling feet |
| Nuts & screws | /make/fastener | Printable metric/UNC screws, nuts, and sign standoffs |
| Gears | /make/gear | Involute spur, helical, and herringbone gears, pairs, and backlash test sets |
| Tool tray & Gridfinity | /make/tray | Insert traced from a photo of your tools on paper, Gridfinity storage bins, and baseplates |
Every page exists in Thai (/th/...) and English (/en/...).
The tool tray traces photos entirely in the browser (src/lib/trace.ts): it finds the sheet of paper, corrects the perspective to true millimetres, separates the tools from the paper and traces their outlines. No image is uploaded. It needs the paper on a darker surface and even light.
How it works
src/
app/[lang]/ pages (home, studios, cart, checkout, order/[code], admin)
app/api/orders/ place order · upload slip
components/ studio shell, 3D stage, controls, cart, checkout, admin
generators/ per-product zod schemas, presets, pricing, filament list
geometry/ WASM geometry: text, shapes, one builder per studio, 3MF/STL export, worker
lib/trace.ts photo → tool outlines (paper detection, perspective warp, contour trace)
dictionaries/ Thai and English text
supabase/migrations/ database schema
public/fonts/ fonts used to build letters (SIL Open Font License)
- Designs live in the URL. Each studio keeps its settings in ?d=, so links, the cart's "Edit" button and the TH/EN switch all reopen the same design.
- Prices are computed twice. The browser shows a live price. The order API validates every design with the same schemas, rebuilds the geometry in Node and re-prices it, so prices sent from the browser are ignored.
- Order codes look like TL-7KQ2MXRA: random and hard to guess. The order page at /th/order/<code> is the customer's tracking link.
- 3MF export puts each colour in its own part, so a slicer can assign a filament to each. Pieces that print separately (clicker caps vs base, box vs lid) become separate objects, laid out for the bed.
- Stock follows orders. Each order item stores estimated grams per colour. When an order moves to printing, a database trigger deducts it from filament stock.
