types: clear remaining tsc errors across 41 files (76→14, behavior-preserving)

Per-file type-only fixes surfaced after the Supabase client was correctly
typed. All fixes preserve runtime behavior; no any/ts-ignore/ts-expect-error.

- lib/supabase/client.ts: annotate the browser client as SupabaseClient<Database>
  (same ssr/js drift as server.ts; fixes it centrally for all callers).
- Supabase embedded-select joins whose FK metadata is missing from the
  generated types are bridged with `as unknown as <target>` + a TODO to remove
  after regenerating types/database.ts.
- setState optimistic-update variance and raw <select> enum values cast to the
  precise element/union type; .insert payload fields (Json, enums) given the
  precise column type via satisfies/field casts.
- Added narrowing guards where a value was legitimately nullable (comms channel,
  public form page) without changing the intended path.

The 14 remaining errors are confined to the four files fixed in Phase B (real
bugs + the tautological actions.test rewrite). 639 tests still green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Moheeb Zara
2026-08-01 18:56:11 -07:00
co-authored by Claude Opus 4.8
parent 1766780bca
commit b1edb5c460
41 changed files with 148 additions and 59 deletions
+11 -5
View File
@@ -9,7 +9,7 @@ import { revealSecret, deleteSecret } from '@/lib/actions/secrets'
import { OpsAclEditor } from '@/components/ops/ops-acl-editor'
import { createClient } from '@/lib/supabase/client'
import { toast } from 'sonner'
import type { Tables, TablesInsert } from '@/types/database'
import type { Tables, TablesInsert, TablesUpdate, Enums } from '@/types/database'
import { PageTitle } from '@/components/ui/page-title'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { useConfirm } from '@/components/ui/confirm'
@@ -135,7 +135,7 @@ function KbModal({
<label className="font-sans text-xs font-medium text-muted-foreground block mb-1.5">Visibility</label>
<select
value={visibility}
onChange={e => setVisibility(e.target.value)}
onChange={e => setVisibility(e.target.value as Enums<'kb_visibility'>)}
className="w-full bg-background border border-border rounded px-3 py-2 font-sans text-sm text-foreground focus:outline-none focus:border-primary transition"
>
<option value="all_members">All Members</option>
@@ -212,7 +212,11 @@ function AddSecretModal({
label: title.trim(),
area: area.trim() || null,
value: value.trim(),
}).select('id, title, area, created_at').single()
// `satisfies` keeps the payload type-checked; the trailing `as never`
// only bridges the typed browser client whose .insert() generic collapses
// to `never`.
// TODO(types): remove after regenerating types/database.ts (missing FK relationship metadata)
} satisfies TablesInsert<'secrets'> as never).select('id, title, area, created_at').single()
setSaving(false)
if (error) { toast.error(error.message); return }
toast.success('Secret saved')
@@ -298,14 +302,16 @@ function AreaLeadModal({
area_name: areaName.trim(),
lead_handle: memberName.trim(),
description: contactInfo.trim() || null,
}).eq('id', lead.id).select('*').single()
// TODO(types): remove `as never` after regenerating types/database.ts (missing FK relationship metadata)
} satisfies TablesUpdate<'area_leads'> as never).eq('id', lead.id).select('*').single()
} else {
result = await supabase.from('area_leads').insert({
space_id: spaceId,
area_name: areaName.trim(),
lead_handle: memberName.trim(),
description: contactInfo.trim() || null,
}).select('*').single()
// TODO(types): remove `as never` after regenerating types/database.ts (missing FK relationship metadata)
} satisfies TablesInsert<'area_leads'> as never).select('*').single()
}
setSaving(false)
if (result.error) { toast.error(result.error.message); return }