# Deploy backend til Vercel

Efter lektion 17 kører jeres system på jeres egen maskine: siden, Express og
gruppens database i Neon. Til D2 skal det ligge på én URL, så andre kan prøve
den centrale brugerhandling. Det er samme Vercel-projekt som i lektion 9 —
nu med en server.

Vejledningen tager ca. 45 minutter. Del 1 laver I sammen i repoet. Del 2 gør
**ejeren** af Vercel-projektet, fordi Hobby-planen kun deployer ejerens push.

## Hvad ændrer sig

| | Lokalt i lektion 17 | På Vercel |
|---|---|---|
| Siden | HTML-filen åbnes direkte | Vercel serverer filerne i `public/` |
| `fetch` | `http://localhost:3000/api/…` | `/api/…` — samme adresse som siden |
| Express | `node --env-file=.env server.js` | Vercel kører `server.js` som en funktion |
| Connection-string | `.env` på jeres maskine | Miljøvariabel i Vercel-projektet |

Siden og API'et kommer fra samme adresse. Derfor skal `fetch` ikke længere
have `http://localhost:3000` foran — og der er ikke længere brug for CORS.
`cors()` må gerne blive stående.

## Del 1 — Gør repoet klar (hele gruppen)

1. Lav en mappe `public/` ved siden af `server.js`. Flyt alle HTML-, CSS- og
   JavaScript-filer til frontend derind. `server.js`, repository-filerne og
   `package.json` bliver, hvor de er.

```text
server.js
patients.js
maalinger.js
package.json
.gitignore
public/
  index.html
  login.html
  …
  style.css
  app.js
```

2. Ret alle `fetch`-URL'er i frontend, så de starter med `/api/`:

```js
// før
const res = await fetch("http://localhost:3000/api/patients");
// efter
const res = await fetch("/api/patients");
```

3. I `server.js`: lad Express servere `public/`, når I kører lokalt. Linjen
   skal stå efter `express.json()` og før jeres routes:

```js
app.use(express.static("public"));
```

   Det er static files: filer Express udleverer, fordi de ligger i mappen,
   uden en route pr. fil. I lektion 13 åbner I HTML'en ved siden af API'et.
   Her får siden og API'et samme adresse.

   På Vercel gør `express.static` ingenting — dér serverer Vercel selv
   `public/`. Lokalt er det linjen, der gør, at `http://localhost:3000`
   viser jeres forside.

   Tilføj også en route til `/`, lige under. Vercel serverer filerne i
   `public/` — men selve `/` sender den videre til Express, og så skal
   Express selv sende forsiden:

```js
const path = require("path"); // øverst i filen

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "public", "index.html"));
});
```

   `__dirname` er mappen, `server.js` ligger i. Hedder jeres forside noget
   andet end `index.html`, så skriv det navn.

4. Start serveren, og åbn **`http://localhost:3000`** — ikke HTML-filen
   direkte. Klik rundt, og udfør den centrale handling. Alt skal virke som
   før.
5. Tjek at `.env` ikke kommer med:

```bash
git status
```

6. Commit og push. Det deployer ikke endnu som server — det gør ejeren i
   del 2.

## Del 2 — Vercel (ejeren)

Ejeren af gruppens Vercel-projekt fra lektion 9 gør resten. I skal **ikke**
oprette et nyt projekt. I skifter typen på det, I har, og URL'en bliver den
samme.

Rækkefølgen er vigtig: først indstillingerne, så et push. Vercel bygger med de
indstillinger, der gælder, når der kommer et push.

7. Log ind på [vercel.com](https://vercel.com). Under **Projects**: tryk
   **⋯** på gruppens projekt, og vælg **Settings**.
   ![Projektets menu på oversigten med Settings](screenshots/01-projekt-settings.png)

   **Project Settings** åbner på **General**. Gå til **Build and
   Deployment** i menuen til venstre.
   ![Project Settings med menuen General, Build and Deployment, Environments …](screenshots/02-settings-menu.png)
   - Under **Framework Settings**: vælg **Express** i dropdown'en
     **Framework Preset** (den står på *Other* fra lektion 9). Alle
     **Override**-knapper skal være slået fra. Tryk **Save**.
     ![Framework Settings med Framework Preset, Override-knapperne og Save](screenshots/03-framework-settings.png)

     Når **Express** er valgt, står Build Command på *None* og Output
     Directory på *N/A*:
     ![Framework Preset sat til Express](screenshots/04-framework-express.png)
   - Længere nede, **Root Directory**: mappen, hvor `server.js` og
     `package.json` ligger. Ligger de i roden af repoet, skal feltet være
     tomt. Tryk **Save**, hvis du har ændret det.

<!-- screenshot: Build and Deployment med Framework Preset Express og Root Directory -->

8. **Settings** → **Environment Variables**. Tilføj:
   - **Key**: `DATABASE_URL`
   - **Value**: gruppens connection-string — samme som i `.env`, med
     `sslmode=verify-full`. Værdien vises som prikker.
   - **Environments**: lad *Production and Preview* stå.
   - Gem.

   I kan også trykke **Import .env** eller indsætte hele linjen fra `.env` i
   **Key**-feltet — så deler Vercel den selv i navn og værdi.
   ![Environment Variables med DATABASE_URL og skjult værdi](screenshots/05-environment-variables.png)

9. Ejeren puller og pusher fra sin egen konto. Er der ikke noget nyt at
   committe, så lav et tomt commit — samme trick som i D1:

```bash
git pull
git commit --allow-empty -m "redeploy"
git push
```

10. Når deployet er **Ready**, så åbn URL'en:
    - `https://…vercel.app/api/patients` skal vise JSON fra Neon.
    - `https://…vercel.app/` skal vise forsiden.
    - Udfør den centrale handling på siden. Ejeren finder rækken i Neons
      SQL-editor.
11. Åbn URL'en på en telefon eller hos en anden i gruppen. Det skal virke
    dér også — det er hele pointen.

<!-- screenshot: den deployede side med data fra Neon -->

## Tjekliste

- [ ] Frontend ligger i `public/`, og `fetch` bruger `/api/…`
- [ ] `http://localhost:3000` virker lokalt med `express.static("public")`
- [ ] `.env` er ikke i repoet. Connection-stringen står i Vercel
- [ ] `/api/patients` på den live URL viser data fra Neon
- [ ] Den centrale handling virker på den live URL, også fra en anden enhed

## Hvis I sidder fast

- **`500` og `serverfejl` på den live URL:** åbn projektet i Vercel →
  **Logs**. Står der `ECONNREFUSED`, mangler `DATABASE_URL`, eller ejeren har
  ikke pushet efter at have sat den. Står der `password authentication
  failed`, er værdien forkert. Ret den, og push et tomt commit igen —
  miljøvariabler gælder først fra næste deploy.
- **`{"error":"not found"}` på `https://…vercel.app/`, men
  `/index.html` virker:** routen `app.get("/", …)` med `res.sendFile`
  mangler.
- **`404` på `/index.html`:** filerne ligger ikke i `public/`, eller **Root
  Directory** peger på den forkerte mappe.
- **Gul advarsel i Build Logs: `npm warn Unknown env config "cache-dir"`:**
  den kommer fra Vercel selv og er ufarlig.
- **API'et giver `404`, men forsiden virker:** Vercel har ikke fundet
  serveren. Tjek, at `server.js` og `package.json` ligger i **Root
  Directory**, at `express` står i `package.json`, og at **Override** er
  slået fra ved Build Command og Output Directory.
- **Siden virker, men tabellen er tom, og Console viser en fejl om
  `localhost`:** en `fetch` peger stadig på `http://localhost:3000`. Ret den
  til `/api/…`.
- **Et push kommer ikke på den live URL:** det var ikke ejeren, der
  pushede. Ejeren puller og pusher igen.
- **Lokalt viser `http://localhost:3000` `{"error":"not found"}`:**
  `express.static("public")` mangler, eller den står under 404-handleren.

## Eksempel

[Et komplet eksempel med patienter](../deploy-eksempel/README.md) —
`server.js`, `patients.js`, `public/index.html` og `public/app.js` — viser
hele strukturen. Det er koden fra slidesne, klar til deploy.
