Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
605a7ad
docs: document the three deployment/hosting layers
LucasSantana-Dev Sep 6, 2026
e44b406
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
9b4a511
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
52e07fe
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
f9e1013
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
6d9f12b
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
024a1cb
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
e8fa818
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
ff814d4
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
dfb4732
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
26935ff
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
cec276f
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
372015a
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 6, 2026
839c697
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
09640b0
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
1b4661f
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
b250fbb
docs: qualify nginx.conf proxying rule with explicit exceptions
LucasSantana-Dev Sep 7, 2026
73cbbfc
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
ec74c1f
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
c33d418
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
f2b8be2
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
a1fff72
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
eb6ed10
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
49e0774
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
1272015
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
828c085
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
729349a
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
1d5add0
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 7, 2026
4b401a0
Merge branch 'main' into docs/deployment-hosting-layers
LucasSantana-Dev Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,27 @@ The nginx container listens on port 80 and proxies to backend and frontend. In d

Config: `nginx/nginx.conf`.

## Deployment & hosting

Production serves through **three independent layers**, each with its own config file. Editing the wrong one is a common mistake (fixing the `/invite` redirect took three PRs - #1889, #1893, #1895 - before landing in the file that actually served that host).

| host | served by | config |
| ----------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `lucky.lucassantana.tech` | **Cloudflare Pages**, project `lucky-webapp` (`.github/workflows/deploy-frontend-cf.yml`) | `packages/frontend/public/_redirects`, `_headers` |
| `lucky-api.lucassantana.tech` | Cloudflare Tunnel → homelab nginx | `nginx/nginx.conf` |
| self-hosted `docker compose` | the same nginx image, serving frontend + API together | `nginx/nginx.conf` |
| preview deploys | Vercel (legacy; production migrated off on 2026-06-25) | `vercel.json` |

**How to tell which layer answered a request.** Compare the CSP: `_headers` allows `https://static.cloudflareinsights.com` in `script-src` (Cloudflare injects that beacon); the other two do not.

```bash
curl -sD - -o /dev/null https://lucky.lucassantana.tech/ | grep -i content-security-policy
```

**`nginx.conf` only proxies `/api` as a rule** (plus the explicit `/invite`, `/webhook/`, `/webhooks/` location blocks). Anything else falls through to the SPA - a new public path served by the backend needs its own `location` block.

**`_redirects` is evaluated top to bottom**, and the `/* /index.html 200` catch-all swallows any rule placed below it.

## Docker Services

| Service | Role |
Expand Down Expand Up @@ -87,12 +108,12 @@ Each package can be developed independently:

### Package layouts

| Package | Layout | Where to add |
| ------------ | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **shared** | `src/config/`, `src/services/`, `src/types/`, `src/utils/` | New config in config/; new services in services/; shared types in types/; composables and helpers in utils/. |
| Package | Layout | Where to add |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **shared** | `src/config/`, `src/services/`, `src/types/`, `src/utils/` | New config in config/; new services in services/; shared types in types/; composables and helpers in utils/. |
| **bot** | `src/functions/{automod,general,management,moderation,music}/commands/`, `src/handlers/`, `src/utils/`, `src/services/`, `src/events/` | New slash command: add file under `functions/<category>/commands/` or folder + re-export (see command loading below). Handlers, utils, and services by domain. |
| **backend** | `src/routes/`, `src/services/`, `src/middleware/` | New API: route in routes/, logic in services/. |
| **frontend** | `src/components/`, `src/pages/`, `src/hooks/`, `src/stores/`, `src/services/` | New page in pages/; shared UI in components/; API client in services/. |
| **backend** | `src/routes/`, `src/services/`, `src/middleware/` | New API: route in routes/, logic in services/. |
| **frontend** | `src/components/`, `src/pages/`, `src/hooks/`, `src/stores/`, `src/services/` | New page in pages/; shared UI in components/; API client in services/. |

### Command loading (bot)

Expand Down
4 changes: 4 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Serves lucky-api.lucassantana.tech and the self-hosted docker-compose
# deployment. lucky.lucassantana.tech is served separately by Cloudflare
# Pages (packages/frontend/public/_redirects, _headers); legacy Vercel
# preview deploys use vercel.json. See docs/ARCHITECTURE.md#deployment--hosting.
resolver 127.0.0.11 valid=10s ipv6=off;

map $http_x_forwarded_proto $proxy_x_forwarded_proto {
Expand Down
5 changes: 3 additions & 2 deletions packages/frontend/public/_redirects
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Cloudflare Pages serves lucky.lucassantana.tech (project lucky-webapp), so
# this file — not vercel.json and not nginx/nginx.conf — is what governs the
# public site. Rules are evaluated top to bottom, so /invite must come before
# the SPA catch-all or the catch-all swallows it (#1888).
# public site. See docs/ARCHITECTURE.md#deployment--hosting for how the three
# hosting layers split up. Rules are evaluated top to bottom, so /invite must
# come before the SPA catch-all or the catch-all swallows it (#1888).
#
# Proxied to the backend rather than sent straight to Discord: the backend
# handler logs the utm_* parameters before redirecting, which is what
Expand Down
Loading