mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
183fe0a93c
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
153 lines
5.9 KiB
PL/PgSQL
153 lines
5.9 KiB
PL/PgSQL
|
|
-- Tenant info request flow (mirrors vendor_profile_requests pattern)
|
|
|
|
CREATE TABLE public.tenant_info_requests (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
owner_id uuid NOT NULL REFERENCES public.owners(id) ON DELETE CASCADE,
|
|
unit_id uuid REFERENCES public.units(id) ON DELETE SET NULL,
|
|
association_id uuid NOT NULL,
|
|
token text NOT NULL UNIQUE DEFAULT encode(extensions.gen_random_bytes(24), 'hex'),
|
|
sent_to_email text,
|
|
custom_message text,
|
|
sent_at timestamptz NOT NULL DEFAULT now(),
|
|
submitted_at timestamptz,
|
|
expires_at timestamptz NOT NULL DEFAULT (now() + interval '30 days'),
|
|
created_by uuid,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX idx_tenant_info_requests_token ON public.tenant_info_requests(token);
|
|
CREATE INDEX idx_tenant_info_requests_owner ON public.tenant_info_requests(owner_id);
|
|
CREATE INDEX idx_tenant_info_requests_unit ON public.tenant_info_requests(unit_id);
|
|
|
|
ALTER TABLE public.tenant_info_requests ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "Staff manage tenant info requests" ON public.tenant_info_requests
|
|
TO authenticated
|
|
USING (has_role(auth.uid(),'admin'::app_role) OR has_role(auth.uid(),'manager'::app_role))
|
|
WITH CHECK (has_role(auth.uid(),'admin'::app_role) OR has_role(auth.uid(),'manager'::app_role));
|
|
|
|
-- Submission rows store full tenant data per request
|
|
CREATE TABLE public.tenant_info_submissions (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
request_id uuid NOT NULL REFERENCES public.tenant_info_requests(id) ON DELETE CASCADE,
|
|
owner_id uuid NOT NULL,
|
|
unit_id uuid,
|
|
association_id uuid NOT NULL,
|
|
-- Basic
|
|
tenant_first_name text NOT NULL,
|
|
tenant_last_name text NOT NULL,
|
|
occupants jsonb DEFAULT '[]'::jsonb,
|
|
-- Contact
|
|
email text,
|
|
phone text,
|
|
emergency_contact_name text,
|
|
emergency_contact_phone text,
|
|
-- Lease
|
|
lease_start date,
|
|
lease_end date,
|
|
lease_length_months integer,
|
|
lease_document_url text,
|
|
-- Vehicles & pets (free-form arrays)
|
|
vehicles jsonb DEFAULT '[]'::jsonb,
|
|
pets jsonb DEFAULT '[]'::jsonb,
|
|
notes text,
|
|
submitted_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX idx_tenant_info_submissions_owner ON public.tenant_info_submissions(owner_id);
|
|
CREATE INDEX idx_tenant_info_submissions_unit ON public.tenant_info_submissions(unit_id);
|
|
|
|
ALTER TABLE public.tenant_info_submissions ENABLE ROW LEVEL SECURITY;
|
|
CREATE POLICY "Staff manage tenant info submissions" ON public.tenant_info_submissions
|
|
TO authenticated
|
|
USING (has_role(auth.uid(),'admin'::app_role) OR has_role(auth.uid(),'manager'::app_role))
|
|
WITH CHECK (has_role(auth.uid(),'admin'::app_role) OR has_role(auth.uid(),'manager'::app_role));
|
|
|
|
-- Lookup RPC (public, security definer — token is the secret)
|
|
CREATE OR REPLACE FUNCTION public.lookup_tenant_info_request(p_token text)
|
|
RETURNS TABLE (
|
|
request_id uuid,
|
|
owner_id uuid,
|
|
unit_id uuid,
|
|
association_id uuid,
|
|
owner_name text,
|
|
property_address text,
|
|
association_name text,
|
|
custom_message text,
|
|
expires_at timestamptz,
|
|
submitted_at timestamptz
|
|
)
|
|
LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$
|
|
SELECT r.id, r.owner_id, r.unit_id, r.association_id,
|
|
trim(coalesce(o.first_name,'') || ' ' || coalesce(o.last_name,'')) AS owner_name,
|
|
coalesce(u.address, o.property_address) AS property_address,
|
|
a.name AS association_name,
|
|
r.custom_message,
|
|
r.expires_at, r.submitted_at
|
|
FROM public.tenant_info_requests r
|
|
JOIN public.owners o ON o.id = r.owner_id
|
|
LEFT JOIN public.units u ON u.id = r.unit_id
|
|
LEFT JOIN public.associations a ON a.id = r.association_id
|
|
WHERE r.token = p_token
|
|
LIMIT 1;
|
|
$$;
|
|
GRANT EXECUTE ON FUNCTION public.lookup_tenant_info_request(text) TO anon, authenticated;
|
|
|
|
-- Submit RPC
|
|
CREATE OR REPLACE FUNCTION public.submit_tenant_info(
|
|
p_token text,
|
|
p_tenant_first_name text,
|
|
p_tenant_last_name text,
|
|
p_email text DEFAULT NULL,
|
|
p_phone text DEFAULT NULL,
|
|
p_emergency_contact_name text DEFAULT NULL,
|
|
p_emergency_contact_phone text DEFAULT NULL,
|
|
p_lease_start date DEFAULT NULL,
|
|
p_lease_end date DEFAULT NULL,
|
|
p_lease_length_months integer DEFAULT NULL,
|
|
p_lease_document_url text DEFAULT NULL,
|
|
p_vehicles jsonb DEFAULT '[]'::jsonb,
|
|
p_pets jsonb DEFAULT '[]'::jsonb,
|
|
p_occupants jsonb DEFAULT '[]'::jsonb,
|
|
p_notes text DEFAULT NULL
|
|
)
|
|
RETURNS boolean
|
|
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$
|
|
DECLARE
|
|
r record;
|
|
BEGIN
|
|
SELECT * INTO r FROM public.tenant_info_requests WHERE token = p_token;
|
|
IF r IS NULL THEN RETURN false; END IF;
|
|
IF r.submitted_at IS NOT NULL THEN RETURN false; END IF;
|
|
IF r.expires_at < now() THEN RETURN false; END IF;
|
|
|
|
INSERT INTO public.tenant_info_submissions (
|
|
request_id, owner_id, unit_id, association_id,
|
|
tenant_first_name, tenant_last_name, occupants,
|
|
email, phone, emergency_contact_name, emergency_contact_phone,
|
|
lease_start, lease_end, lease_length_months, lease_document_url,
|
|
vehicles, pets, notes
|
|
) VALUES (
|
|
r.id, r.owner_id, r.unit_id, r.association_id,
|
|
p_tenant_first_name, p_tenant_last_name, coalesce(p_occupants,'[]'::jsonb),
|
|
p_email, p_phone, p_emergency_contact_name, p_emergency_contact_phone,
|
|
p_lease_start, p_lease_end, p_lease_length_months, p_lease_document_url,
|
|
coalesce(p_vehicles,'[]'::jsonb), coalesce(p_pets,'[]'::jsonb), p_notes
|
|
);
|
|
|
|
-- Upsert a basic record into unit_tenants for roster visibility
|
|
IF r.unit_id IS NOT NULL THEN
|
|
INSERT INTO public.unit_tenants (unit_id, name, email, phone, lease_start, lease_end, status)
|
|
VALUES (
|
|
r.unit_id,
|
|
trim(p_tenant_first_name || ' ' || p_tenant_last_name),
|
|
p_email, p_phone, p_lease_start, p_lease_end, 'active'
|
|
);
|
|
END IF;
|
|
|
|
UPDATE public.tenant_info_requests SET submitted_at = now() WHERE id = r.id;
|
|
RETURN true;
|
|
END;
|
|
$$;
|
|
GRANT EXECUTE ON FUNCTION public.submit_tenant_info(
|
|
text,text,text,text,text,text,text,date,date,integer,text,jsonb,jsonb,jsonb,text
|
|
) TO anon, authenticated;
|