Add new url fields to vendors

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-05-27 20:07:15 -07:00
parent a4a279c5de
commit 6eb3332103
15 changed files with 837 additions and 359 deletions

View File

@@ -0,0 +1,86 @@
ALTER TABLE vendors
ADD COLUMN business_associate_agreement_url TEXT,
ADD COLUMN subprocessors_list_url TEXT;
UPDATE vendors SET
business_associate_agreement_url = CASE name
WHEN 'Notion' THEN 'https://www.notion.so/notion/Business-Associate-Agreement-909d9f4ccca041b1a23d0fe6e56fa111'
WHEN 'OpenAI' THEN 'https://openai.com/policies/business-terms/'
WHEN 'Amazon Web Services (AWS)' THEN 'https://aws.amazon.com/compliance/hipaa-compliance/'
WHEN 'Google Cloud Platform' THEN 'https://cloud.google.com/terms/hipaa-baa'
WHEN 'Microsoft Azure' THEN 'https://learn.microsoft.com/en-us/compliance/regulatory/offering-hipaa-hitech'
WHEN 'Cal.com' THEN 'https://app.cal.com/apps/baa-for-hipaa'
WHEN 'Fly.io' THEN 'https://fly.io/documents'
WHEN 'New Relic' THEN 'https://newrelic.com/termsandconditions/hipaabaafaq'
WHEN 'Gusto' THEN 'https://support.gusto.com/article/152166121100000/The-Health-Insurance-Portability-and-Accountability-Act-of-1996-HIPAA'
WHEN 'Microsoft 365' THEN 'https://learn.microsoft.com/en-us/compliance/regulatory/offering-hipaa-hitech'
WHEN 'Monday.com' THEN 'https://monday.com/l/privacy/hipaa-baa'
WHEN 'Atlassian' THEN 'https://www.atlassian.com/legal/business-associate-agreement'
WHEN 'Resend' THEN 'https://newrelic.com/termsandconditions/hipaabaafaq'
END,
subprocessors_list_url = CASE name
WHEN 'Github' THEN 'https://docs.github.com/en/site-policy/privacy-policies/github-subprocessors'
WHEN 'Notion' THEN 'https://www.notion.so/notion/Notion-s-List-of-Subprocessors-268fa5bcfa0f46b6bc29436b21676734'
WHEN 'Mintlify' THEN 'https://security.mintlify.com'
WHEN 'Segment' THEN 'https://www.twilio.com/en-us/legal/sub-processors'
WHEN 'Heroku' THEN 'https://www.salesforce.com/en-us/wp-content/uploads/sites/4/documents/legal/misc/salesforce-infrastructure-and-subprocessors.pdf'
WHEN 'Linear' THEN 'https://linear.app/dpa'
WHEN 'Hubspot' THEN 'https://legal.hubspot.com/sub-processors-page'
WHEN 'Google Workspace' THEN 'https://workspace.google.com/terms/subprocessors/'
WHEN 'Algolia' THEN 'https://www.algolia.com/policies/infrastructure-and-sub-processors'
WHEN 'PostHog' THEN 'https://posthog.com/dpa'
WHEN 'Airtable' THEN 'https://www.airtable.com/company/subprocessors'
WHEN 'OpenAI' THEN 'https://openai.com/policies/sub-processor-list/'
WHEN 'Anthropic' THEN 'https://trust.anthropic.com/subprocessors'
WHEN 'Amazon Web Services (AWS)' THEN 'https://aws.amazon.com/compliance/sub-processors/'
WHEN 'Calendly' THEN 'https://help.calendly.com/hc/en-us/articles/360047345493-Calendly-sub-processors-GDPR-CCPA'
WHEN 'jsDelivr' THEN 'https://www.jsdelivr.com/terms/sub-processors'
WHEN 'Clerk' THEN 'https://clerk.com/legal/subprocessors'
WHEN 'Plausible Analytics' THEN 'https://plausible.io/privacy'
WHEN 'Docker' THEN 'https://www.docker.com/trust/privacy/sub-processors/'
WHEN 'Brex' THEN 'https://trust-portal.brex.com'
WHEN 'Ramp' THEN 'https://trust.ramp.com/'
WHEN 'ClickHouse' THEN 'https://clickhouse.com/legal/agreements/subprocessors'
WHEN 'Tailscale' THEN 'https://tailscale.com/dpa-subprocessors'
WHEN 'Probo' THEN 'https://www.getprobo.com/subprocessors'
WHEN 'folk' THEN 'https://www.folk.app/privacy-policy#3-list-of-sub-processors'
WHEN 'Claap' THEN 'https://www.claap.io/legal/privacy-policy#sub-processors'
WHEN 'Pitch' THEN 'https://pitch.com/dpa#annex-7-2'
WHEN 'Spendesk' THEN 'https://www.spendesk.com/legals/subprocessors/'
WHEN 'Lever' THEN 'https://www.lever.co/subprocessors-archive-june-2023/'
WHEN 'Google Cloud Platform' THEN 'https://cloud.google.com/terms/subprocessors'
WHEN 'Microsoft Azure' THEN 'https://www.microsoft.com/en-us/download/details.aspx?id=50426'
WHEN 'Fly.io' THEN 'https://fly.io/legal/sub-processors/'
WHEN 'Upstash' THEN 'https://trust.upstash.com/subprocessors'
WHEN 'bunny.net' THEN 'https://bunny.net/gdpr/sub-processors/'
WHEN 'ClickUp' THEN 'https://clickup.com/terms/dpa/subprocessors'
WHEN 'New Relic' THEN 'https://newrelic.com/sub-processors'
WHEN 'Pylon' THEN 'https://usepylon.com/subprocessors'
WHEN 'Loops' THEN 'https://loops.so/subprocessors'
WHEN 'Perplexity' THEN 'https://trust.perplexity.ai/'
WHEN 'Mailchimp' THEN 'https://mailchimp.com/legal/subprocessors/'
WHEN 'Otter.ai' THEN 'https://otter.ai/subprocessors'
WHEN 'Resend' THEN 'https://newrelic.com/sub-processors'
WHEN 'OVHcloud global' THEN 'https://www.ovh.ie/support/termsofservice/OVH%20IE%20Sub%20processors.pdf'
WHEN 'OVHcloud US' THEN 'https://storage.gra.cloud.ovh.net/v1/AUTH_325716a587c64897acbef9a4a4726e38/contracts/30c4ab8-OVH_Sub_processors-IE-2.0.pdf'
WHEN 'Pipedrive' THEN 'https://www.pipedrive.com/en/subprocessors'
WHEN 'Plesk' THEN 'https://www.plesk.com/wp-content/uploads/legal/gdpr3.pdf'
WHEN 'Brevo' THEN 'https://www.brevo.com/legal/termsofuse/#sub-processors'
WHEN 'Better Stack' THEN 'https://betterstack.com/dpa/schedules'
WHEN 'PlanetScale' THEN 'https://planetscale.com/legal/subprocessors'
WHEN 'Microsoft 365' THEN 'https://www.microsoft.com/en-us/download/details.aspx?id=50426'
WHEN 'Bitwarden' THEN 'https://bitwarden.com/help/subprocessors/'
WHEN 'Framer' THEN 'https://www.framer.com/legal/sub-processors/'
WHEN 'Cal.com' THEN 'https://security.cal.com/?itemUid=e3fae2ca-94a9-416b-b577-5c90e382df57'
WHEN 'monday.com' THEN 'https://monday.com/l/privacy/sub-processors-subsidiaries-support'
WHEN 'Carta' THEN 'https://carta.com/legal/carta-europe/data-processor-agreement/'
WHEN 'Apollo.io' THEN 'https://trust.apollo.io/'
WHEN 'Atlassian' THEN 'https://www.atlassian.com/legal/sub-processors'
WHEN 'Webflow' THEN 'https://uploads-ssl.webflow.com/5d80c03f1edd7bd68fcdb623/657c411c020d1ee5f047f6ab_20231207%20-%20List%20of%20approved%20Sub-processors.pdf'
WHEN '1Password' THEN 'https://1passwordstatic.com/files/legal-center/notice-of-updates-to-the-1password-subprocessor-list.pdf'
WHEN 'Checkr' THEN 'https://checkr.com/sub-processor-list'
WHEN 'Rippling' THEN 'https://app.rippling.com/legal/subprocessors'
WHEN 'Twilio' THEN 'https://www.twilio.com/en-us/legal/sub-processors'
WHEN 'Cursor' THEN 'https://trust.cursor.com/subprocessors'
WHEN 'Pulley' THEN 'https://large-walk-bd5.notion.site/6449d3ecd2854af0a313b6e8679b5795?v=d61abc36355842bb939d49544f18dc95'
END;

View File

@@ -28,26 +28,28 @@ import (
type (
Vendor struct {
ID gid.GID `db:"id"`
OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"`
Description *string `db:"description"`
Category VendorCategory `db:"category"`
HeadquarterAddress *string `db:"headquarter_address"`
LegalName *string `db:"legal_name"`
WebsiteURL *string `db:"website_url"`
PrivacyPolicyURL *string `db:"privacy_policy_url"`
ServiceLevelAgreementURL *string `db:"service_level_agreement_url"`
DataProcessingAgreementURL *string `db:"data_processing_agreement_url"`
Certifications []string `db:"certifications"`
BusinessOwnerID *gid.GID `db:"business_owner_id"`
SecurityOwnerID *gid.GID `db:"security_owner_id"`
StatusPageURL *string `db:"status_page_url"`
TermsOfServiceURL *string `db:"terms_of_service_url"`
SecurityPageURL *string `db:"security_page_url"`
TrustPageURL *string `db:"trust_page_url"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
ID gid.GID `db:"id"`
OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"`
Description *string `db:"description"`
Category VendorCategory `db:"category"`
HeadquarterAddress *string `db:"headquarter_address"`
LegalName *string `db:"legal_name"`
WebsiteURL *string `db:"website_url"`
PrivacyPolicyURL *string `db:"privacy_policy_url"`
ServiceLevelAgreementURL *string `db:"service_level_agreement_url"`
DataProcessingAgreementURL *string `db:"data_processing_agreement_url"`
BusinessAssociateAgreementURL *string `db:"business_associate_agreement_url"`
SubprocessorsListURL *string `db:"subprocessors_list_url"`
Certifications []string `db:"certifications"`
BusinessOwnerID *gid.GID `db:"business_owner_id"`
SecurityOwnerID *gid.GID `db:"security_owner_id"`
StatusPageURL *string `db:"status_page_url"`
TermsOfServiceURL *string `db:"terms_of_service_url"`
SecurityPageURL *string `db:"security_page_url"`
TrustPageURL *string `db:"trust_page_url"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
Vendors []*Vendor
@@ -83,6 +85,8 @@ SELECT
privacy_policy_url,
service_level_agreement_url,
data_processing_agreement_url,
business_associate_agreement_url,
subprocessors_list_url,
certifications,
business_owner_id,
security_owner_id,
@@ -141,6 +145,8 @@ INSERT INTO
privacy_policy_url,
service_level_agreement_url,
data_processing_agreement_url,
business_associate_agreement_url,
subprocessors_list_url,
certifications,
business_owner_id,
security_owner_id,
@@ -164,6 +170,8 @@ VALUES (
@privacy_policy_url,
@service_level_agreement_url,
@data_processing_agreement_url,
@business_associate_agreement_url,
@subprocessors_list_url,
@certifications,
@business_owner_id,
@security_owner_id,
@@ -177,27 +185,29 @@ VALUES (
`
args := pgx.StrictNamedArgs{
"tenant_id": scope.GetTenantID(),
"vendor_id": v.ID,
"organization_id": v.OrganizationID,
"name": v.Name,
"description": v.Description,
"category": v.Category,
"headquarter_address": v.HeadquarterAddress,
"legal_name": v.LegalName,
"website_url": v.WebsiteURL,
"privacy_policy_url": v.PrivacyPolicyURL,
"service_level_agreement_url": v.ServiceLevelAgreementURL,
"data_processing_agreement_url": v.DataProcessingAgreementURL,
"certifications": v.Certifications,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
"status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL,
"trust_page_url": v.TrustPageURL,
"created_at": v.CreatedAt,
"updated_at": v.UpdatedAt,
"tenant_id": scope.GetTenantID(),
"vendor_id": v.ID,
"organization_id": v.OrganizationID,
"name": v.Name,
"description": v.Description,
"category": v.Category,
"headquarter_address": v.HeadquarterAddress,
"legal_name": v.LegalName,
"website_url": v.WebsiteURL,
"privacy_policy_url": v.PrivacyPolicyURL,
"service_level_agreement_url": v.ServiceLevelAgreementURL,
"data_processing_agreement_url": v.DataProcessingAgreementURL,
"business_associate_agreement_url": v.BusinessAssociateAgreementURL,
"subprocessors_list_url": v.SubprocessorsListURL,
"certifications": v.Certifications,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
"status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL,
"trust_page_url": v.TrustPageURL,
"created_at": v.CreatedAt,
"updated_at": v.UpdatedAt,
}
_, err := conn.Exec(ctx, q, args)
return err
@@ -241,6 +251,8 @@ SELECT
privacy_policy_url,
service_level_agreement_url,
data_processing_agreement_url,
business_associate_agreement_url,
subprocessors_list_url,
certifications,
business_owner_id,
security_owner_id,
@@ -295,6 +307,8 @@ SET
privacy_policy_url = @privacy_policy_url,
service_level_agreement_url = @service_level_agreement_url,
data_processing_agreement_url = @data_processing_agreement_url,
business_associate_agreement_url = @business_associate_agreement_url,
subprocessors_list_url = @subprocessors_list_url,
certifications = @certifications,
status_page_url = @status_page_url,
terms_of_service_url = @terms_of_service_url,
@@ -309,24 +323,26 @@ WHERE %s
q = fmt.Sprintf(q, scope.SQLFragment())
args := pgx.StrictNamedArgs{
"vendor_id": v.ID,
"updated_at": time.Now(),
"name": v.Name,
"description": v.Description,
"category": v.Category,
"headquarter_address": v.HeadquarterAddress,
"legal_name": v.LegalName,
"website_url": v.WebsiteURL,
"privacy_policy_url": v.PrivacyPolicyURL,
"service_level_agreement_url": v.ServiceLevelAgreementURL,
"data_processing_agreement_url": v.DataProcessingAgreementURL,
"certifications": v.Certifications,
"status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL,
"trust_page_url": v.TrustPageURL,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
"vendor_id": v.ID,
"updated_at": time.Now(),
"name": v.Name,
"description": v.Description,
"category": v.Category,
"headquarter_address": v.HeadquarterAddress,
"legal_name": v.LegalName,
"website_url": v.WebsiteURL,
"privacy_policy_url": v.PrivacyPolicyURL,
"service_level_agreement_url": v.ServiceLevelAgreementURL,
"data_processing_agreement_url": v.DataProcessingAgreementURL,
"business_associate_agreement_url": v.BusinessAssociateAgreementURL,
"subprocessors_list_url": v.SubprocessorsListURL,
"certifications": v.Certifications,
"status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL,
"trust_page_url": v.TrustPageURL,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
}
maps.Copy(args, scope.SQLArguments())
@@ -344,7 +360,7 @@ func (v Vendor) ExpireNonExpiredRiskAssessments(
q := `
UPDATE vendor_risk_assessments
SET
SET
expires_at = @now,
updated_at = @now
WHERE