# QA Review MC #9783 — reviewing MC #8386

# Proveo QA Review — MC #9783 reviewing MC #8386

**Source task:** MC #8386 — `URGENT: alai.no contact form is DEAD STUB — wire to real backend`  
**Review task:** MC #9783 — `QA review: #8386`  
**Reviewer:** John / Proveo mode  
**Review date:** 2026-07-28  
**BookStack:** https://docs.alai.no/books/testing-qa/page/qa-review-mc-9783-reviewing-mc-8386  
**Verdict:** APPROVED_WITH_COMMENTS

## Scope

Reviewed whether the live `alai.no` contact form is still wired to a real backend, whether the old dead-stub behavior is absent from the active page, and whether a synthetic submission reaches email.

## Files and live assets reviewed

- `/Users/makinja/system/docs/runbooks/contact-form-intake.md`
- `/Users/makinja/business/ALAI-Holding-AS/web/BUILD-BLUEPRINT.md`
- `/Users/makinja/business/ALAI-Holding-AS/web/public/index.html`
- `/Users/makinja/business/ALAI-Holding-AS/web/functions/api/contact.js`
- Live pages: `https://alai.no/`, `https://alai.no/no/`, `https://alai.no/bs/`
- Updated endpoint registry: `/Users/makinja/system/config/known-api-endpoints.json`

## Evidence summary

Evidence directory: `/Users/makinja/system/evidence/9783-qa-review-8386/`

| Check | Result | Evidence |
|---|---:|---|
| Live root loads | PASS — HTTP 200 | `curl-get-status.txt`, `alai-no.headers` |
| Active live source uses backend call | PASS — `fetch('/api/contact')` present | `live-source-contact-grep.txt` |
| Active live source has no old stub text | PASS — no `Form submission logic would go here` / old alert in root, `/no/`, `/bs/` | `live-language-pages-contact-check.txt` |
| `/api/contact` endpoint exists and has CORS preflight | PASS — OPTIONS HTTP 204 | `options-status.txt`, `options.headers` |
| Server-side validation exists | PASS — POST `{}` returns HTTP 400 `{"error":"Name is required"}` | `invalid-post-status.txt`, `invalid-post.body` |
| Browser E2E form submit | PASS — Playwright submitted live form, POST `/api/contact` HTTP 200, response `{"ok":true}`, success UI visible | `playwright-result.json`, `playwright-contact-success.png` |
| Email delivery | PASS — IMAP search/read found token email UID 737 in `john`/`alai` account search | `mail-native-search.txt`, `mail-native-read-john-uid737.txt` |
| Endpoint registry | PASS — `alai.no` and `api.basicconsulting.no` documented and JSON re-read validated | `/Users/makinja/system/config/known-api-endpoints.json` |

Synthetic token used: `MC9783-20260728T175248Z-30993`.

Email evidence excerpt from IMAP UID 737:

```text
From: "ALAI Website" <info@alai.no>
To: info@alai.no
Subject: [alai.no] Contact: QA MC9783-20260728T175248Z-30993
Message: Automated Proveo QA review for MC #9783 / source task #8386. Token: MC9783-20260728T175248Z-30993
```

## Findings

### Blocking findings

None.

### Should fix

1. **Public `.bak` files are still served by Cloudflare Pages.**
   - Evidence: `public-backup-files-head.txt` shows HTTP 200 for:
     - `https://alai.no/index.html.bak`
     - `https://alai.no/index.html.bak-20260216-151821`
     - `https://alai.no/index.html.bak-live-20260212`
   - Local grep confirms at least `public/index.html.bak` still contains the original stub text.
   - Impact: not a failure of the active `https://alai.no/` contact form, but stale public backup files can confuse audits/crawlers and expose obsolete behavior.
   - Recommendation: remove `*.bak*` HTML files from `public/` or block them with Cloudflare Pages routing rules.

### Optional hardening

1. Add rate limiting / abuse protection for `/api/contact` if not already enforced upstream.
2. Keep `/api/contact` in the endpoint registry current if the backend migrates away from `api.basicconsulting.no` to UFS.

## QA conclusion

MC #8386 acceptance is satisfied for the active production contact form: the dead stub is not present on live active pages, the form submits to a real backend through `/api/contact`, the endpoint validates bad input, Playwright confirms a successful live browser submission, and the synthetic submission landed in email.

Final status: **APPROVED_WITH_COMMENTS** due to publicly served stale backup files under `public/`.