-- 006: platform-admin-only tenant provisioning, authenticated using existing signed context
BEGIN;
SET LOCAL search_path TO pg_catalog,optikrapor;
CREATE FUNCTION optikrapor.is_platform_administrator()
RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER SET search_path=pg_catalog,optikrapor AS $$
 SELECT EXISTS (SELECT 1 FROM optikrapor.auth_claims() a JOIN optikrapor.users u ON u.id=a.user_id WHERE u.is_active AND u.is_platform_admin)
$$;
REVOKE ALL ON FUNCTION optikrapor.is_platform_administrator() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION optikrapor.is_platform_administrator() TO oprapr;
CREATE FUNCTION optikrapor.platform_create_company(p_code text,p_name text,p_phone text,p_email text)
RETURNS bigint LANGUAGE plpgsql SECURITY DEFINER
SET search_path=pg_catalog,optikrapor AS $$
DECLARE claims record; new_id bigint; admin_role smallint;
BEGIN
 SELECT * INTO claims FROM optikrapor.auth_claims() LIMIT 1;
 IF claims.user_id IS NULL OR NOT EXISTS (
  SELECT 1 FROM optikrapor.users u WHERE u.id=claims.user_id AND u.is_active AND u.is_platform_admin
 ) THEN RAISE EXCEPTION 'Platform administrator required' USING ERRCODE='42501'; END IF;
 IF length(trim(coalesce(p_code,''))) NOT BETWEEN 2 AND 40
 OR trim(p_code) !~ '^[A-Za-z0-9_-]+$'
 OR length(trim(coalesce(p_name,''))) NOT BETWEEN 2 AND 200
 OR length(coalesce(p_phone,''))>35 OR length(coalesce(p_email,''))>254
 THEN RAISE EXCEPTION 'Invalid company fields' USING ERRCODE='22023'; END IF;
 SELECT id INTO admin_role FROM optikrapor.roles WHERE code='company_admin';
 IF admin_role IS NULL THEN RAISE EXCEPTION 'Missing company_admin role'; END IF;
 INSERT INTO optikrapor.companies(code,name,phone,email)
 VALUES(upper(trim(p_code)),trim(p_name),nullif(trim(p_phone),''),nullif(trim(p_email),''))
 RETURNING id INTO new_id;
 INSERT INTO optikrapor.user_memberships(user_id,company_id,branch_id,role_id,is_active)
 VALUES(claims.user_id,new_id,NULL,admin_role,true);
 INSERT INTO optikrapor.audit_logs(company_id,user_id,event,entity_type,entity_id,details)
 VALUES(new_id,claims.user_id,'company.created','company',new_id,jsonb_build_object('code',upper(trim(p_code))));
 RETURN new_id;
END $$;
REVOKE ALL ON FUNCTION optikrapor.platform_create_company(text,text,text,text) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION optikrapor.platform_create_company(text,text,text,text) TO oprapr;
INSERT INTO optikrapor.schema_migrations(version,description) VALUES('006','Platform-admin-only company provisioning');
COMMIT;
