forgecad 0.6.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +3 -12
  2. package/dist/assets/{AdminPage-CeqCUUgu.js → AdminPage-D4bocK4E.js} +250 -151
  3. package/dist/assets/{BlogPage-P_AJP0v9.js → BlogPage-CJEXL_zJ.js} +94 -70
  4. package/dist/assets/{DocsPage-CKRV2iq2.js → DocsPage-D3A_g8V3.js} +329 -163
  5. package/dist/assets/{EditorApp-CnC2k4cW.css → EditorApp-BWYUSpUN.css} +590 -136
  6. package/dist/assets/EditorApp-Cihhqcsq.js +11692 -0
  7. package/dist/assets/{EmbedViewer-DBlzmQ5i.js → EmbedViewer-kWjKaC_t.js} +2 -4
  8. package/dist/assets/LandingPageProofDriven-Bg2IUc3l.css +856 -0
  9. package/dist/assets/LandingPageProofDriven-DXkKlyhI.js +601 -0
  10. package/dist/assets/PricingPage-BsU5vzEx.js +232 -0
  11. package/dist/assets/{SettingsPage-BqCh9JcC.js → SettingsPage-PqvpAKIs.js} +129 -5
  12. package/dist/assets/{evalWorker-Ql-aKwLA.js → evalWorker-C-hzNUMy.js} +8949 -3161
  13. package/dist/assets/{Viewport-CoB46f5R.js → index-Pz321YAt.js} +38382 -7501
  14. package/dist/assets/{index-2hfs_ub0.css → index-ay13WNfa.css} +726 -53
  15. package/dist/assets/{javascript-DCxGoE5Y.js → javascript-DAl8Gmyo.js} +1 -1
  16. package/dist/assets/{manifold-CqNMHHKO.js → manifold-BcbjWLIo.js} +4 -3
  17. package/dist/assets/{manifold-Cce9wRFz.js → manifold-DBckbFgx.js} +1 -1
  18. package/dist/assets/{manifold-D6BeHIOo.js → manifold-O2AAGXyj.js} +1 -1
  19. package/dist/assets/{reportWorker-sFEFonXf.js → reportWorker-Dxr-5A7w.js} +8760 -3559
  20. package/dist/assets/{vendor-react-Dt7-aaJH.js → vendor-react-CG3i_wp0.js} +65 -8
  21. package/dist/docs/index.html +2 -2
  22. package/dist/docs-raw/CLI.md +341 -718
  23. package/dist/docs-raw/generated/assembly.md +699 -112
  24. package/dist/docs-raw/generated/concepts.md +1834 -1346
  25. package/dist/docs-raw/generated/core.md +1012 -1059
  26. package/dist/docs-raw/generated/curves.md +759 -116
  27. package/dist/docs-raw/generated/lib.md +43 -748
  28. package/dist/docs-raw/generated/output.md +139 -245
  29. package/dist/docs-raw/generated/sdf.md +208 -0
  30. package/dist/docs-raw/generated/sheet-metal.md +473 -21
  31. package/dist/docs-raw/generated/sketch.md +1518 -362
  32. package/dist/docs-raw/generated/viewport.md +368 -299
  33. package/dist/docs-raw/generated/wood.md +104 -0
  34. package/dist/index.html +2 -2
  35. package/dist/landing/proof-ams-adapter.png +0 -0
  36. package/dist/landing/proof-bolt-and-nut.png +0 -0
  37. package/dist/landing/proof-fillet-enclosure.png +0 -0
  38. package/dist/landing/proof-glasses.png +0 -0
  39. package/dist/landing/proof-gyroid.png +0 -0
  40. package/dist/sitemap.xml +6 -6
  41. package/dist-cli/forgecad.js +12321 -5700
  42. package/dist-cli/forgecad.js.map +1 -0
  43. package/dist-cli/solver-46FFSK2U.js +363 -0
  44. package/dist-cli/solver-46FFSK2U.js.map +1 -0
  45. package/dist-skill/CONTEXT.md +4890 -6302
  46. package/dist-skill/SKILL-dev.md +22 -66
  47. package/dist-skill/SKILL.md +20 -59
  48. package/dist-skill/docs/API/core/concepts.md +37 -92
  49. package/dist-skill/docs/CLI.md +341 -718
  50. package/dist-skill/docs/generated/assembly.md +699 -112
  51. package/dist-skill/docs/generated/core.md +1012 -1059
  52. package/dist-skill/docs/generated/curves.md +759 -116
  53. package/dist-skill/docs/generated/lib.md +43 -748
  54. package/dist-skill/docs/generated/output.md +139 -245
  55. package/dist-skill/docs/generated/sdf.md +208 -0
  56. package/dist-skill/docs/generated/sheet-metal.md +473 -21
  57. package/dist-skill/docs/generated/sketch.md +1518 -362
  58. package/dist-skill/docs/generated/viewport.md +368 -299
  59. package/dist-skill/docs/generated/wood.md +104 -0
  60. package/dist-skill/docs/guides/coordinate-system.md +11 -17
  61. package/dist-skill/docs/guides/geometry-conventions.md +13 -70
  62. package/dist-skill/docs/guides/joint-design.md +78 -0
  63. package/dist-skill/docs/guides/modeling-recipes.md +22 -195
  64. package/dist-skill/docs/guides/positioning.md +88 -147
  65. package/dist-skill/docs-dev/API/core/concepts.md +78 -0
  66. package/dist-skill/docs-dev/CLI.md +488 -0
  67. package/dist-skill/{docs → docs-dev}/blueprint-first.md +5 -0
  68. package/dist-skill/{docs → docs-dev}/coding-best-practices.md +6 -8
  69. package/dist-skill/{docs → docs-dev}/coding.md +2 -4
  70. package/dist-skill/docs-dev/component-model.md +164 -0
  71. package/dist-skill/docs-dev/generated/assembly.md +779 -0
  72. package/dist-skill/docs-dev/generated/core.md +1676 -0
  73. package/dist-skill/docs-dev/generated/curves.md +855 -0
  74. package/dist-skill/docs-dev/generated/lib.md +55 -0
  75. package/dist-skill/docs-dev/generated/output.md +234 -0
  76. package/dist-skill/docs-dev/generated/sdf.md +208 -0
  77. package/dist-skill/docs-dev/generated/sheet-metal.md +506 -0
  78. package/dist-skill/docs-dev/generated/sketch.md +1753 -0
  79. package/dist-skill/docs-dev/generated/viewport.md +513 -0
  80. package/dist-skill/docs-dev/generated/wood.md +104 -0
  81. package/dist-skill/docs-dev/guides/coordinate-system.md +46 -0
  82. package/dist-skill/docs-dev/guides/geometry-conventions.md +52 -0
  83. package/dist-skill/docs-dev/guides/joint-design.md +78 -0
  84. package/dist-skill/docs-dev/guides/modeling-recipes.md +77 -0
  85. package/dist-skill/docs-dev/guides/positioning.md +151 -0
  86. package/dist-skill/{docs → docs-dev}/guides/skill-maintenance.md +21 -10
  87. package/dist-skill/{docs → docs-dev}/internals/compiler.md +5 -6
  88. package/dist-skill/{docs → docs-dev}/internals/constraint-solver-quality.md +0 -1
  89. package/dist-skill/{docs → docs-dev}/internals/constraint-solver.md +0 -1
  90. package/dist-skill/{docs → docs-dev}/internals/sketch-2d-pipeline.md +2 -3
  91. package/examples/api/attachTo-basics.forge.js +8 -8
  92. package/examples/api/bill-of-materials.forge.js +9 -9
  93. package/examples/api/bolt-pattern.forge.js +5 -5
  94. package/examples/api/boolean-operations.forge.js +5 -5
  95. package/examples/api/bounding-box-visualizer.forge.js +3 -3
  96. package/examples/api/clone-duplicate.forge.js +2 -2
  97. package/examples/api/colors-union-vs-array.forge.js +6 -6
  98. package/examples/api/connector-assembly.forge.js +8 -6
  99. package/examples/api/connector-basics.forge.js +7 -7
  100. package/examples/api/constrained-sketch-mechanical.forge.js +4 -4
  101. package/examples/api/elbow-test.forge.js +3 -3
  102. package/examples/api/extrude-options.forge.js +8 -14
  103. package/examples/api/feature-created-faces.forge.js +6 -10
  104. package/examples/api/fillet-showcase.forge.js +2 -2
  105. package/examples/api/folded-service-panel-cover.forge.js +2 -2
  106. package/examples/api/gears-tier1.forge.js +5 -5
  107. package/examples/api/group-test.forge.js +3 -3
  108. package/examples/api/group-vs-union.forge.js +1 -1
  109. package/examples/api/highlight-debug.forge.js +4 -0
  110. package/examples/api/js-module-pillars.js +1 -1
  111. package/examples/api/js-module-scene.js +2 -2
  112. package/examples/api/mesh-import-slats.forge.js +4 -4
  113. package/examples/api/patterns.forge.js +3 -3
  114. package/examples/api/pointAlong-orientation.forge.js +3 -3
  115. package/examples/api/profile-2020-b-slot6.forge.js +4 -5
  116. package/examples/api/route-perimeter-flange.forge.js +1 -1
  117. package/examples/api/sdf-rover-demo.forge.js +10 -10
  118. package/examples/api/sketch-on-face-demo.forge.js +2 -2
  119. package/examples/api/sketch-regions.forge.js +4 -4
  120. package/examples/api/sketch-rounding-strategies.forge.js +1 -1
  121. package/examples/api/smooth-curve-connections.forge.js +1 -1
  122. package/examples/api/transition-curves.forge.js +4 -4
  123. package/examples/api/variable-sweep-pure-sdf-test.forge.js +162 -0
  124. package/examples/api/variable-sweep-test.forge.js +2 -2
  125. package/examples/api/wood-joinery.forge.js +60 -0
  126. package/examples/compiler-corpus/enclosure-shell-cuts.forge.js +3 -3
  127. package/examples/compiler-corpus/fastener-plate-variants.forge.js +2 -2
  128. package/examples/constraints/01-fully-constrained-rect.forge.js +2 -2
  129. package/examples/constraints/02-underconstrained-triangle.forge.js +1 -1
  130. package/examples/constraints/03-redundant-constraints.forge.js +2 -2
  131. package/examples/constraints/05-parallel-with-linedistance.forge.js +2 -2
  132. package/examples/constraints/06-complex-spectrogram.forge.js +1 -1
  133. package/examples/constraints/07-perpendicular-chain.forge.js +4 -4
  134. package/examples/constraints/08-symmetric-bracket.forge.js +4 -4
  135. package/examples/constraints/09-stress-spiral.forge.js +1 -1
  136. package/examples/constraints/10-stress-honeycomb.forge.js +1 -1
  137. package/examples/constraints/11-surface-grid.forge.js +2 -2
  138. package/examples/constraints/12-surface-nested.forge.js +4 -4
  139. package/examples/constraints/13-surface-complex.forge.js +1 -1
  140. package/examples/exact-arc-housing.forge.js +12 -0
  141. package/examples/experiments/drone-arm.forge.js +53 -0
  142. package/examples/furniture/adjustable-table.forge.js +15 -15
  143. package/examples/furniture/bathroom.forge.js +26 -26
  144. package/examples/furniture/chair.forge.js +13 -13
  145. package/examples/furniture/picture-frame.forge.js +6 -6
  146. package/examples/furniture/shoe-rack-doors.forge.js +8 -8
  147. package/examples/furniture/shoe-rack.forge.js +7 -7
  148. package/examples/furniture/table-lamp.forge.js +8 -8
  149. package/examples/gcode/lissajous-vase.forge.js +4 -4
  150. package/examples/gcode/math-surface.forge.js +3 -3
  151. package/examples/gcode/parametric-vase.forge.js +4 -4
  152. package/examples/gcode/spiral-tower.forge.js +4 -4
  153. package/examples/generative/crystal-growth.forge.js +9 -9
  154. package/examples/generative/frost-spires.forge.js +9 -9
  155. package/examples/generative/golden-spiral-tower.forge.js +11 -11
  156. package/examples/generative/molten-forge.forge.js +6 -6
  157. package/examples/generative/neon-coral.forge.js +7 -7
  158. package/examples/mechanical/3d-printer.forge.js +37 -37
  159. package/examples/mechanical/5-finger-robot-hand.forge.js +19 -19
  160. package/examples/mechanical/airplane-propeller.forge.js +9 -9
  161. package/examples/mechanical/bolt-and-nut.forge.js +10 -10
  162. package/examples/mechanical/door-with-hinges.forge.js +7 -7
  163. package/examples/mechanical/fillet-enclosure.forge.js +15 -11
  164. package/examples/mechanical/headphone-hanger-v2.forge.js +11 -11
  165. package/examples/mechanical/robot_hand.forge.js +24 -24
  166. package/examples/mechanical/robot_hand_2.forge.js +26 -26
  167. package/examples/nurbs-surface.forge.js +8 -0
  168. package/examples/nurbs-tube.forge.js +7 -0
  169. package/examples/products/bottle.forge.js +8 -8
  170. package/examples/products/chess-set.forge.js +25 -25
  171. package/examples/products/classical-piano.forge.js +20 -20
  172. package/examples/products/clock.forge.js +33 -33
  173. package/examples/products/cup.forge.js +5 -5
  174. package/examples/products/iphone.forge.js +20 -20
  175. package/examples/products/laptop.forge.js +24 -24
  176. package/examples/products/laser-cut-box.forge.js +6 -6
  177. package/examples/products/laser-cut-tray.forge.js +6 -6
  178. package/examples/products/liquid-soap-dispenser.forge.js +23 -23
  179. package/examples/products/origami-fish.forge.js +14 -12
  180. package/examples/products/spiderman-cake.forge.js +6 -6
  181. package/examples/shelf/container.forge.js +5 -5
  182. package/examples/shelf/shelf-unit.forge.js +6 -6
  183. package/examples/toolbox/bolted-joint.forge.js +7 -7
  184. package/package.json +9 -4
  185. package/dist/assets/EditorApp-B-vQvgam.js +0 -9888
  186. package/dist/assets/LandingPage-C5n9hDXI.js +0 -322
  187. package/dist/assets/PublishedModelPage-Dt7PCVBj.js +0 -146
  188. package/dist/assets/__vite-browser-external-CURh0WXD.js +0 -8
  189. package/dist/assets/deserializeRunResult-BLAFoiE0.js +0 -19365
  190. package/dist/assets/index-1CYp3zUp.js +0 -1455
  191. package/dist-skill/docs/API/API.md +0 -1666
  192. package/dist-skill/docs/API/README.md +0 -37
  193. package/dist-skill/docs/API/assembly/assembly.md +0 -617
  194. package/dist-skill/docs/API/core/edge-queries.md +0 -130
  195. package/dist-skill/docs/API/core/parameters.md +0 -122
  196. package/dist-skill/docs/API/core/reserved-terms.md +0 -137
  197. package/dist-skill/docs/API/core/sdf.md +0 -326
  198. package/dist-skill/docs/API/core/skill-cli.md +0 -194
  199. package/dist-skill/docs/API/core/skill-guide.md +0 -205
  200. package/dist-skill/docs/API/core/specs.md +0 -186
  201. package/dist-skill/docs/API/core/topology.md +0 -372
  202. package/dist-skill/docs/API/entities.md +0 -268
  203. package/dist-skill/docs/API/output/bom.md +0 -58
  204. package/dist-skill/docs/API/output/brep-export.md +0 -87
  205. package/dist-skill/docs/API/output/dimensions.md +0 -67
  206. package/dist-skill/docs/API/output/export.md +0 -110
  207. package/dist-skill/docs/API/output/gcode.md +0 -195
  208. package/dist-skill/docs/API/runtime/viewport.md +0 -420
  209. package/dist-skill/docs/API/sheet-metal/sheet-metal.md +0 -185
  210. package/dist-skill/docs/API/sketch/anchor.md +0 -37
  211. package/dist-skill/docs/API/sketch/booleans.md +0 -91
  212. package/dist-skill/docs/API/sketch/core.md +0 -73
  213. package/dist-skill/docs/API/sketch/extrude.md +0 -62
  214. package/dist-skill/docs/API/sketch/on-face.md +0 -104
  215. package/dist-skill/docs/API/sketch/operations.md +0 -78
  216. package/dist-skill/docs/API/sketch/path.md +0 -75
  217. package/dist-skill/docs/API/sketch/primitives.md +0 -146
  218. package/dist-skill/docs/API/sketch/regions.md +0 -80
  219. package/dist-skill/docs/API/sketch/text.md +0 -108
  220. package/dist-skill/docs/API/sketch/transforms.md +0 -65
  221. package/dist-skill/docs/API/toolbox/fasteners.md +0 -129
  222. package/dist-skill/docs/INDEX.md +0 -94
  223. package/dist-skill/docs/RELEASING.md +0 -55
  224. package/dist-skill/docs/cli-monetization.md +0 -111
  225. package/dist-skill/docs/deployment.md +0 -281
  226. package/dist-skill/docs/generated/concepts.md +0 -2112
  227. package/dist-skill/docs/internals/shape-from-slices.md +0 -152
  228. package/dist-skill/docs/platform/admin.md +0 -45
  229. package/dist-skill/docs/platform/architecture.md +0 -79
  230. package/dist-skill/docs/platform/auth.md +0 -110
  231. package/dist-skill/docs/platform/email.md +0 -67
  232. package/dist-skill/docs/platform/projects.md +0 -111
  233. package/dist-skill/docs/platform/sharing.md +0 -90
  234. package/dist-skill/docs/runbook.md +0 -345
@@ -1,281 +0,0 @@
1
- ---
2
- skill-group: dev-conventions
3
- skill-order: 3
4
- skill-tiers: [dev]
5
- ---
6
-
7
- # ForgeCAD Deployment & Environment
8
-
9
- See also the **[Runbook](runbook.md)** for day-to-day operations, testing, troubleshooting, and API reference.
10
-
11
- ForgeCAD runs as a Docker Compose stack. There are two compose files:
12
-
13
- - **`docker-compose.yml`** — Full self-hosted stack (Caddy + ForgeCAD + PostgreSQL + Redis). Use this for manual VPS deployment.
14
- - **`docker-compose.coolify.yml`** — Simplified stack for Coolify (ForgeCAD + PostgreSQL only). Coolify handles TLS and reverse proxy.
15
-
16
- Production runs on **Hetzner** via **Coolify**, which auto-deploys on push to `mainline`.
17
-
18
- ---
19
-
20
- ## Architecture
21
-
22
- ```
23
- Internet
24
-
25
- ├─ Coolify Proxy (Traefik) ← TLS termination, routing
26
- │ │
27
- │ └─ forgecad container ← Fastify app (Node.js)
28
- │ │
29
- │ ├─ Serves SPA (dist/) ← Vite-built React frontend
30
- │ ├─ API routes (/api/*) ← Auth, projects, files
31
- │ └─ connects to ──────► postgresql container
32
-
33
- └─ Volume: project-data ← User project files on disk
34
- ```
35
-
36
- In the self-hosted compose file, Caddy replaces Coolify's proxy, and Redis/Valkey is added for rate limiting.
37
-
38
- ---
39
-
40
- ## Environment Variables
41
-
42
- ### Server Core
43
-
44
- These configure the Fastify application server itself.
45
-
46
- | Variable | Required | Default | Purpose |
47
- |----------|----------|---------|---------|
48
- | `NODE_ENV` | no | `development` | Set to `production` for deployed instances |
49
- | `FORGE_PORT` | no | `5173` | HTTP port the server listens on |
50
- | `FORGE_HOST` | no | `127.0.0.1` | Bind address. Use `0.0.0.0` in Docker |
51
- | `FORGE_DIST_DIR` | no | — | Path to Vite build output (the SPA). In Docker: `/app/dist` |
52
-
53
- ### Database
54
-
55
- ForgeCAD uses PostgreSQL 16 for users, projects, sessions, and audit logs. The database schema is managed by Drizzle ORM with auto-migrations on server startup.
56
-
57
- | Variable | Required | Default | Purpose |
58
- |----------|----------|---------|---------|
59
- | `FORGE_DB_URL` | **yes** | — | PostgreSQL connection string |
60
-
61
- **How the connection is wired in Coolify:**
62
-
63
- Coolify auto-generates credentials for linked database services and injects them as `SERVICE_USER_POSTGRES` and `SERVICE_PASSWORD_POSTGRES`. The compose file constructs the full URL from these:
64
-
65
- ```yaml
66
- FORGE_DB_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-forgecad}
67
- ```
68
-
69
- The hostname `postgresql` is the Docker Compose service name — Docker's internal DNS resolves it to the postgres container. You never need to set `FORGE_DB_URL` directly in Coolify; it assembles itself from Coolify's auto-generated service credentials.
70
-
71
- **In the self-hosted compose file**, the pattern is simpler:
72
-
73
- ```yaml
74
- FORGE_DB_URL=postgresql://forgecad:${POSTGRES_PASSWORD}@postgres:5432/forgecad
75
- ```
76
-
77
- Here you set `POSTGRES_PASSWORD` in a `.env` file and the same value is shared with the postgres container.
78
-
79
- ### Authentication
80
-
81
- Authentication uses JWT access tokens (short-lived, 15 min) and refresh tokens (7 days, stored in DB with rotation and replay detection).
82
-
83
- | Variable | Required | Default | Purpose |
84
- |----------|----------|---------|---------|
85
- | `FORGE_JWT_SECRET` | **yes** | — | HMAC key for signing JWT tokens. Generate with `openssl rand -base64 32` |
86
- | `FORGE_JWT_ACCESS_EXPIRES` | no | `15m` | Access token lifetime |
87
- | `FORGE_JWT_REFRESH_EXPIRES` | no | `7d` | Refresh token lifetime |
88
-
89
- **The JWT secret is critical.** Without it, login and registration complete the database operations but crash when issuing tokens — the user gets a 500 error. The server starts without it (the value is lazily read), but all auth endpoints fail.
90
-
91
- ### CORS & Public URL
92
-
93
- These tell the server which origins to trust and how to construct user-facing URLs (e.g., in emails).
94
-
95
- | Variable | Required | Default | Purpose |
96
- |----------|----------|---------|---------|
97
- | `FORGE_ALLOWED_ORIGINS` | no | `http://localhost:5173` | Comma-separated list of allowed CORS origins |
98
- | `FORGE_APP_URL` | no | `http://localhost:5173` | Public base URL for the app. Used in email links |
99
-
100
- For production, set `FORGE_ALLOWED_ORIGINS=https://forgecad.io` and `FORGE_APP_URL=https://forgecad.io`.
101
-
102
- ### OAuth Providers
103
-
104
- Optional. If not set, the corresponding "Sign in with X" button won't appear on the login page.
105
-
106
- | Variable | Required | Default | Purpose |
107
- |----------|----------|---------|---------|
108
- | `GITHUB_CLIENT_ID` | no | — | GitHub OAuth app client ID |
109
- | `GITHUB_CLIENT_SECRET` | no | — | GitHub OAuth app client secret |
110
- | `GOOGLE_CLIENT_ID` | no | — | Google OAuth client ID |
111
- | `GOOGLE_CLIENT_SECRET` | no | — | Google OAuth client secret |
112
-
113
- To set up GitHub OAuth: create an OAuth App at github.com/settings/developers with callback URL `https://forgecad.io/auth/callback/github`.
114
-
115
- ### Email Delivery
116
-
117
- Email is used for account verification and password reset. Without `RESEND_API_KEY`, emails are logged to the container's stdout instead of being sent — useful for development, but users won't receive them.
118
-
119
- | Variable | Required | Default | Purpose |
120
- |----------|----------|---------|---------|
121
- | `RESEND_API_KEY` | no | — | API key from [resend.com](https://resend.com). Enables real email delivery |
122
- | `FORGE_EMAIL_FROM` | no | `ForgeCAD <noreply@forgecad.io>` | Sender address for outgoing emails |
123
-
124
- To enable email: sign up at Resend, verify `forgecad.io` as a sending domain (add their DNS records), get an API key, and set it in Coolify.
125
-
126
- ### File Storage
127
-
128
- User project files (`.forge.js`, meshes) are stored on disk, not in the database.
129
-
130
- | Variable | Required | Default | Purpose |
131
- |----------|----------|---------|---------|
132
- | `FORGE_STORAGE_ROOT` | no | `/data/projects` | Root directory for project file storage |
133
-
134
- In Docker, this is backed by the `project-data` volume, which persists across container rebuilds.
135
-
136
- ---
137
-
138
- ## Coolify-Specific Variables
139
-
140
- These are managed by Coolify itself — you don't set them manually, but the compose file references them:
141
-
142
- | Variable | Source | Purpose |
143
- |----------|--------|---------|
144
- | `SERVICE_USER_POSTGRES` | Coolify auto-generated | PostgreSQL username |
145
- | `SERVICE_PASSWORD_POSTGRES` | Coolify auto-generated | PostgreSQL password |
146
- | `POSTGRES_DB` | Coolify (defaults to `forgecad`) | Database name |
147
-
148
- ---
149
-
150
- ## What You Actually Need to Set in Coolify
151
-
152
- Only these variables need manual configuration in Coolify's environment settings:
153
-
154
- 1. **`FORGE_JWT_SECRET`** — `openssl rand -base64 32`. Without this, auth is broken.
155
- 2. **`FORGE_ALLOWED_ORIGINS`** — `https://forgecad.io`
156
- 3. **`RESEND_API_KEY`** — from resend.com (optional, but needed for email)
157
- 4. **`GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET`** — if you want GitHub login
158
- 5. **`GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET`** — if you want Google login
159
-
160
- Everything else has working defaults or is auto-generated by Coolify.
161
-
162
- ---
163
-
164
- ## Database Migrations
165
-
166
- Migrations run automatically on server startup (`server/db/migrate.ts`). The migration system:
167
-
168
- 1. Creates a `_migrations` table to track which migrations have been applied
169
- 2. Runs any unapplied migrations in order
170
- 3. Logs each migration to stdout
171
-
172
- No manual database setup is needed. The PostgreSQL container starts with an empty database, and the ForgeCAD server creates all tables on first boot.
173
-
174
- ---
175
-
176
- ## Debugging Production
177
-
178
- SSH access: `ssh hetzner` (see `~/.ssh/config`).
179
-
180
- ```bash
181
- # Find containers
182
- docker ps --format "{{.Names}}" | grep forge
183
-
184
- # App logs
185
- docker logs --tail 200 <forgecad-container>
186
-
187
- # DB access (get credentials from app env first)
188
- docker exec <forgecad-container> env | grep POSTGRES
189
- docker exec <postgres-container> psql -U <USER> -d forgecad
190
-
191
- # System health
192
- df -h && free -h
193
- ```
194
-
195
- See the `/hetzner-logs` skill for the full workflow.
196
-
197
- ### Email not delivered (user didn't receive verification/reset email)
198
-
199
- **Symptom:** User registers or requests password reset, no email arrives. Logs show:
200
- ```
201
- [email] To: user@example.com | Subject: Verify your ForgeCAD email
202
- ```
203
-
204
- **Cause:** `RESEND_API_KEY` is empty or missing. The `[email]` log line is the dev fallback — it means the email was *logged* to stdout, not sent.
205
-
206
- **Check:**
207
- ```bash
208
- docker exec <forgecad-container> env | grep RESEND_API_KEY
209
- # → RESEND_API_KEY= ← empty = emails not sent
210
- ```
211
-
212
- **Fix:** Set `RESEND_API_KEY` in Coolify environment variables → redeploy.
213
-
214
- ### Connecting a DB client (e.g. Beekeeper Studio) to prod
215
-
216
- The PostgreSQL container has no host port mapping — `localhost:5432` is not reachable from outside the server. Instead use an SSH tunnel to the container's Docker network IP.
217
-
218
- 1. Find the container IP (run once, it's stable across restarts within the same Coolify stack):
219
- ```bash
220
- ssh hetzner "docker inspect \$(docker ps -qf name=postgresql) | grep '\"IPAddress\"'"
221
- # → 10.0.2.3 (or similar)
222
- ```
223
-
224
- 2. In Beekeeper Studio, configure the SSH tunnel:
225
- - SSH Host: `65.108.210.215`, User: `kostard`, use your private key
226
- - DB Host: `10.0.2.3`, Port: `5432`
227
- - Credentials: from Coolify's auto-generated `SERVICE_USER_POSTGRES` / `SERVICE_PASSWORD_POSTGRES`
228
- - Database: `forgecad`
229
-
230
- > `AllowTcpForwarding yes` must be set in `/etc/ssh/sshd_config` on the server for the tunnel to work.
231
-
232
- ---
233
-
234
- ## Local Development
235
-
236
- ### Quick start (editor only, no auth)
237
-
238
- For working on the CAD editor, geometry, sketches, or viewer:
239
-
240
- ```bash
241
- npm run dev
242
- ```
243
-
244
- Opens the editor with local example files. No login, no database. Fastest workflow for anything that doesn't touch auth or multi-user features. Vite proxies `/api` to port 5174 but the backend is optional — the editor works without it.
245
-
246
- ### Production build locally (test real server behavior)
247
-
248
- For testing WASM serving, bundle sizes, caching headers — the full production Fastify server on your machine:
249
-
250
- ```bash
251
- npm run dev:db # start PostgreSQL (once)
252
- npm run dev:prod # tsc + vite build + run Fastify server
253
- ```
254
-
255
- Open `http://localhost:5173` — same server code as production, serving the Vite production build. ~25s turnaround.
256
-
257
- ### Full stack (auth, database, landing page, docs, blog)
258
-
259
- For working on the hosted application:
260
-
261
- ```bash
262
- # Terminal 1: start PostgreSQL (once)
263
- npm run dev:db
264
-
265
- # Terminal 2: start Fastify API server (port 5174)
266
- npm run dev:server
267
-
268
- # Terminal 3: start Vite dev server (port 5173, proxies /api to 5174)
269
- npm run dev:studio
270
- ```
271
-
272
- Open `http://localhost:5173` — landing page, login, docs, blog, admin, the full thing.
273
-
274
- To stop the database: `npm run dev:db:stop`
275
-
276
- **Dev credentials** (hardcoded in `dev:server`, never used in production):
277
- - Database: `forgecad:forgecad@localhost:5432/forgecad`
278
- - JWT secret: `dev-secret-do-not-use-in-production`
279
- - Allowed origin: `http://localhost:5173`
280
-
281
- Migrations run automatically on server startup.