# VCC Pre-Build Checklist

Run through the VCC (Verified Correct Code) checklist before the first Edit/Write of any build, fix, or improvement session. Skim the sections that apply to today's work and apply prevention rules before writing code.

---

## A. PostgREST RPCs
- [ ] Verified actual response shape? RPC may return TABLE (array) or composite (object) — never assume from function name.
- [ ] For `verify_pin`: response is `[{id, name, role}]` array — check `Array.isArray(res) ? res.length > 0 : res?.id`. NOT `res?.success`.
- [ ] Checked existing callers of the same RPC for shape examples?

## B. DB Objects (tables / views / columns / functions)
- [ ] Migration SQL written AND applied BEFORE writing code that depends on it?
- [ ] Verified object exists: `docker exec -i postgres psql -U lmadmin -d lm360 -c "SELECT to_regclass('schema.object')"` returns non-null?
- [ ] `NOTIFY pgrst, 'reload schema'` included in migration if new table/column added?
- [ ] **Grants verified via web_anon HTTP path** — NOT `psql -U lmadmin` (superuser bypasses grants; anon path is the real test). Probe with `curl .../db/<obj>` + correct `Accept-Profile`/`Content-Profile` headers.
- [ ] Function reads a table in another schema or one web_anon can't SELECT? → `SECURITY DEFINER` + `SET search_path = ...`, or grant the read. Verify via web_anon.

## C. JS ↔ DB Value Comparison
- [ ] Timestamps normalized on BOTH sides via `new Date(v).toISOString()` before comparing? (DB: `+00:00`, JS: `.000Z` — string equality fails)
- [ ] Numbers using `parseFloat()` on both sides, not string equality?

## D. Derived / Dependent Columns
- [ ] Does any other column derive from the field being edited? (e.g. `trip_date` must sync when `start_time` changes)
- [ ] Any aggregate/summary columns in other tables that should update?

## E. SW Cache Version
- [ ] Updated `const CACHE = '...-vNN'` in `sw.js`?
- [ ] Updated the SW version assertion in `tests/[pwa].spec.js` to match?

## F. DOM ↔ JS References
- [ ] Every `$('element-id')` verified against current HTML (grep after any structural change)?
- [ ] Null-guarded before calling methods: `const el = $('x'); if (!el) return;`?

## G. CSS Visibility Defaults
- [ ] Elements that must start hidden: `display:none` set in HTML attribute, not only via JS?
- [ ] Any existing global CSS rule that could override the intended default state?

## H. PostgREST PATCH / POST / DELETE
- [ ] `resp.ok` guard on every fetch call? (`fetch()` resolves on 4xx/5xx — only rejects on network error)
- [ ] Non-2xx responses won't be silently ignored?

## I. Column Names in JS Queries
- [ ] Column names verified against actual schema? (PostgREST returns empty array, not error, for wrong column names)
- [ ] `docker exec -i postgres psql -U lmadmin -d lm360 -c "\d schema.table"` consulted?
- [ ] Schema-qualified queries use the correct schema header?

## J. Playwright Specs
- [ ] New form fields or screens added → spec updated to assert their presence?
- [ ] Test helper functions updated if form flow changed?

## K. Cross-PWA Safety
- [ ] Does this change touch shared infra (PostgREST grants, hub session format, SW cache keys, shared DB schemas, proxy network, Traefik labels)? If yes: **ask user before proceeding.**

## L. Timezone Display
- [ ] Any timestamp shown to user? → IST conversion required. Use `toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' })`.

## M. Source-of-Truth Migration
- [ ] Replacing a file/array with a DB table? Keep write path updating BOTH until old source is fully deprecated.
- [ ] Offline JS fallback kept in sync with the primary source write path?

## N. OpenClaw (OC)
- [ ] OC OAuth token checked for expiry? (`cat /opt/openclaw/*.json | grep expiry`)
- [ ] JID format confirmed: groups → `@g.us`, individuals → `@s.whatsapp.net`
- [ ] `requireMention` state known for any group being messaged?
- [ ] OC logs checked after first test send: `docker logs openclaw --tail 30`?
- [ ] Obsidian vault path exists: `ls /opt/obsidian/vault/`?

## O. Gmail MCP
- [ ] Raw MCP response logged before acting — confirmed non-null?
- [ ] Correct Gmail account active (Haris-Gmail vs YEMO-Gmail)?
- [ ] Draft vs send confirmed? (Sends are irreversible)
- [ ] Label/thread operations checked against actual label IDs, not assumed from name?

---

_Bug class details, instances, and UX decisions → `vcc_library.md` in memory._
