-
-
Notifications
You must be signed in to change notification settings - Fork 1
api usage
unggul edited this page Mar 25, 2026
·
2 revisions
Documentation Authority: SYSTEM_MODEL.md Section 1 (Tech Stack) and Section 2 (Data Integrity)
Document how AWCMS uses the Supabase client APIs for data, auth, storage, and edge-facing integrations.
- Admin and public portal developers
- Integrators building extensions
- SYSTEM_MODEL.md - Primary authority for API patterns and Supabase integration
- AGENTS.md - Implementation patterns and Context7 references
docs/tenancy/supabase.mddocs/architecture/database.md
import { supabase } from '@/lib/customSupabaseClient';Context7 note: Supabase clients should be initialized with PKCE flow, session persistence, and global headers.
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY, {
auth: {
flowType: 'pkce',
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
db: {
schema: 'public',
},
global: {
headers: { 'x-application-name': 'awcms' },
},
});import { createScopedClient } from '../lib/supabase';
const supabase = createScopedClient({ 'x-tenant-id': tenantId }, runtimeEnv);Vite Env Reminder: Only
VITE_-prefixed variables are exposed to client code. UseloadEnvinvite.configwhen config values must read non-prefixed keys.
const { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'securepassword'
});const { data, error } = await supabase
.from('blogs')
.select('*, author:users(id, full_name)')
.eq('status', 'published')
.is('deleted_at', null)
.order('created_at', { ascending: false });const { error } = await supabase
.from('blogs')
.update({ deleted_at: new Date().toISOString() })
.eq('id', blogId);const edgeUrl = import.meta.env.VITE_EDGE_URL || import.meta.env.VITE_LOCAL_EDGE_URL;
const response = await fetch(`${edgeUrl}/api/media/upload`, {
method: 'POST',
headers: {
Authorization: `Bearer ${session.access_token}`,
},
body: formData,
});
const data = await response.json();const { data: { session } } = await supabase.auth.getSession();
const edgeUrl = import.meta.env.VITE_EDGE_URL || import.meta.env.VITE_LOCAL_EDGE_URL;
const response = await fetch(`${edgeUrl}/api/mailketing`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${session.access_token}`,
},
body: JSON.stringify({ action: 'send', recipient: 'user@example.com' })
});
const data = await response.json();- Always filter
deleted_at IS NULLfor reads. - Tenant-scoped tables must be filtered by tenant and RLS enforced.
- Secret keys may be used only in Cloudflare Workers, migrations, and trusted operational scripts.
- Admin client injects
x-tenant-idautomatically viacustomSupabaseClient. - Supabase Storage is disabled; object storage must use Cloudflare R2.
- For local dev, prefer the locally configured Worker URL (
VITE_LOCAL_EDGE_URL) when the flow depends onwrangler devroutes.
docs/tenancy/supabase.mddocs/security/rls.mddocs/architecture/database.md