package dialectsfcrm

import (
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
)

// owningPackName is the CRM pack identity this dialect belongs to. A greenfield org
// without this pack active causes the binder to SKIP the mount. This L1 module is
// the single source for the salesforce-v63 dialect identity while it is staged in
// this monorepo; the final ownership move is to the app-pack/distribution side.
const owningPackName = "salesforce-crm-standard"

// CompositeTreePartition is the gin-free salesforce-v63 dialect partition. The
// constructor name is kept during the drain to avoid a noisy composition-root
// rename; it is now the single mounted CRM v63 door.
type CompositeTreePartition struct {
	recordDecorator        recordReadDecorator
	recordAttachmentLookup contract.RecordAttachmentSourceLookup
}

type CompositeTreePartitionOption func(*CompositeTreePartition)

// NewCompositeTreePartition returns the gin-free salesforce-v63 route partition.
func NewCompositeTreePartition(options ...CompositeTreePartitionOption) CompositeTreePartition {
	p := CompositeTreePartition{}
	for _, option := range options {
		if option != nil {
			option(&p)
		}
	}
	return p
}

// WithContentDistributionRecordReadDecoration installs the CRM-owned legacy
// ContentDistribution read decorator. The shared seam exposes only neutral file
// authorization; the Salesforce source vocabulary and href rewrite policy stay
// in this L1 partition.
func WithContentDistributionRecordReadDecoration(fieldsForObject ContentDistributionHrefFieldsFunc, lookup contract.RecordAttachmentSourceLookup) CompositeTreePartitionOption {
	return func(p *CompositeTreePartition) {
		p.recordDecorator = NewContentDistributionRecordReadDecorator(fieldsForObject)
		p.recordAttachmentLookup = lookup
	}
}

func (CompositeTreePartition) Name() string       { return "salesforce-v63" }
func (CompositeTreePartition) OwningPack() string { return owningPackName }
func (CompositeTreePartition) BasePath() string   { return "/services/data" }

func (CompositeTreePartition) Versions() []string {
	return []string{"v59.0", "v60.0", "v61.0", "v62.0", "v63.0"}
}

func (CompositeTreePartition) VersionLabels() map[string]string {
	return map[string]string{
		"v59.0": "Winter '24",
		"v60.0": "Spring '24",
		"v61.0": "Summer '24",
		"v62.0": "Winter '25",
		"v63.0": "Spring '25",
	}
}

// ErrorProjector is mandatory and non-nil; the handler returns its v63 envelopes as
// Responses directly, so this fires only if a neutral DomainWireError escapes the
// handler or the binder injects a transport-level wire error.
func (CompositeTreePartition) ErrorProjector() dialect.Projector {
	return V63CompositeTreeErrorProjector
}

// InternalErrorProjector is the partition's dialect-owned generic 500 envelope.
// The backend binder calls it only for fail-closed transport/handler invariants;
// the v63 JSON shape stays here in L1, not in the shared seam or L0 binder.
func (CompositeTreePartition) InternalErrorProjector() dialect.InternalErrorProjector {
	return V63InternalErrorProjector
}

// Manifest declares the routes already relocated to the gin-free door. No per-route
// Gate beyond the host's base data-API stack (the SDK routes carried no extra
// permission either). The describe read spine now includes the layout family:
// /describe/layouts, /describe/layouts/:recordTypeId, the dedicated static
// _System_File layouts clone. The related-list candidate picker is owned by
// the independent sfcrm AppService, outside this legacy manifest.
func (p CompositeTreePartition) Manifest() []dialect.Route {
	routes := []dialect.Route{
		{
			Method:  "GET",
			Path:    "/id/:orgId/:userId",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: IdentityNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/connect/notifications",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ConnectNotificationsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/actions/standard",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListStandardActionsNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/actions/standard/:name",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DispatchStandardActionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/actions/standard/:name/preview",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: PreviewStandardActionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/actions/standard/:name/output-preview",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: OutputPreviewStandardActionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/quickActions",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListGlobalQuickActionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/quickActions",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListObjectQuickActionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/quickActions/:actionName/describe",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeQuickActionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/quickActions/:actionName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ExecuteQuickActionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/actions/custom/flow",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunFlow}},
			Handler: ListInvocableFlowsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/actions/custom/flow/:name",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunFlow}},
			Handler: GetFlowSchemaNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/actions/custom/flow/:name",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunFlow}},
			Handler: ExecuteCustomFlowNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/actions/custom/resumeFlow",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunFlow}},
			Handler: ResumeCustomFlowNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/FlowInterview",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListFlowInterviewsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/FlowInterview/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: GetFlowInterviewNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/sobjects/FlowInterview/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DeleteFlowInterviewNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/process/approvals",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ProcessApprovalsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/approvals/pending",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ApprovalPendingNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/approvals/records/:recordId/instance",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ApprovalLatestProcessInstanceNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/approvals/records/:recordId/step-display",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ApprovalStepDisplayMetadataNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/rules",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: WorkflowRulesNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/rules/:sObject",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: WorkflowRulesForObjectNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/process/approvals/notification-flows",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: ApprovalNotificationFlowsNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/process/approvals/clone",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: ApprovalCloneNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/jobs/query",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CreateBulkQueryJobNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/jobs/query/:jobId",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: GetBulkQueryJobNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/jobs/query/:jobId/results",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: GetBulkQueryResultsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/dashboards",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: ListDashboardsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/dashboards/:dashboardId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: GetDashboardNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/dashboards",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: CreateDashboardNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/analytics/dashboards/:dashboardId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: UpdateDashboardNeutralHandler,
		},
		{
			Method:  "PUT",
			Path:    "/analytics/dashboards/:dashboardId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: RefreshDashboardPUTNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/analytics/dashboards/:dashboardId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: DeleteDashboardNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/dashboards/:dashboardId/refresh",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: RefreshDashboardNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/dashboards/:dashboardId/status",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: GetDashboardStatusNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/reports",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: ListReportsNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/reports",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: CreateReportNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/report-execution",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: RunReportExecutionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/reports/execute",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: ExecuteReportDefinitionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/reports/:reportId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: RunReportNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/analytics/reports/:reportId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: RunReportNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/analytics/reports/:reportId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: UpdateReportNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/analytics/reports/:reportId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: DeleteReportNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/analytics/reports/:reportId/describe",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: DescribeReportNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/folders",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: ListFoldersNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/folders",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: CreateFolderNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/folders/transfer-ownership",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermManageUsers}},
			Handler: TransferFolderOwnershipNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/folders/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: GetFolderNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/folders/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: UpdateFolderNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/folders/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: DeleteFolderNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/folders/:id/children",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: GetFolderChildrenNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/folders/:id/shares",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: ListFolderSharesNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/folders/:id/shares",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: AddFolderSharesNeutralHandler,
		},
		{
			Method:  "PUT",
			Path:    "/folders/:id/shares",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: ReplaceFolderSharesNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/folders/:id/shares/:shareId",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermRunReports}},
			Handler: GetFolderShareNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/folders/:id/shares/:shareId",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: UpdateFolderShareNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/folders/:id/shares/:shareId",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermManageReportsInPubFolders, constants.PermManageDashbdsInPubFolders}},
			Handler: DeleteFolderShareNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/permissions/effective",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: EffectivePermissionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/objects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: MetadataObjectsListNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/objects/:apiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: MetadataObjectGetNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/fieldtypes",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: MetadataFieldTypesNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/validation-rules",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: MetadataValidationRulesListNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/search/scope-order",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: MetadataSearchScopeOrderNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/formula-views/:objectName/status",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: FormulaViewStatusNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/formula-views/:objectName/ddl",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: FormulaViewDDLNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/metadata/deployRequest/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataDeployStatusNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/objects",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataObjectCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/metadata/objects/:apiName",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataObjectUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/metadata/objects/:apiName",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataObjectDeleteNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/objects/:apiName/fields",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataFieldCreateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/objects/:apiName/fields/batch",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataFieldBatchCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/metadata/objects/:apiName/fields/:fieldApiName",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataFieldUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/metadata/objects/:apiName/fields/:fieldApiName",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataFieldDeleteNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/refresh-cache",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataRefreshCacheNeutralHandler,
		},
		{
			Method:         "POST",
			Path:           "/metadata/deployRequest",
			Gate:           dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			BodyMode:       dialect.BodyStream,
			BodyLimitBytes: maxMetadataDeploySizeBytes,
			Handler:        MetadataDeployRequestNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/formula-views/:objectName/rebuild",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: FormulaViewRebuildNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/formula-views/rebuild-all",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: FormulaViewRebuildAllNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/formula-views/:objectName/validate",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: FormulaViewValidateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/admin/autonumber/refresh-metadata",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: AdminAutoNumberRefreshMetadataNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/admin/connector/sync-status",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: AdminConnectorSyncStatusNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/connector-webhooks/secrets",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermViewSetup}},
			Handler: ConnectorWebhookSecretsListNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/connector-webhooks/secrets/:id/rotate",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermManageNamedCredentials}},
			Handler: ConnectorWebhookSecretsRotateNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/admin/audit/log",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermViewFieldAuditTrail}},
			Handler: AdminAuditLogNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/admin/recalculate-rollups/:object",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyAllData}},
			Handler: AdminRollupRecalculateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/metadata/validation-rules",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataValidationRuleCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/metadata/validation-rules/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataValidationRuleUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/metadata/validation-rules/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermModifyMetadata}},
			Handler: MetadataValidationRuleDeleteNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/CustomObject",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomObjectCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/tooling/sobjects/CustomObject/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomObjectUpdateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/CustomField",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomFieldCreateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/ValidationRule",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingValidationRuleCreateNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/QuickActionDefinition",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingQuickActionDefinitionCreateNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/query",
			Gate:    dialect.Gate{Mode: dialect.GateAny, Permissions: []constants.Permission{constants.PermViewSetup, constants.PermCustomizeApplication}},
			Handler: ToolingQueryNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/FlowDefinition",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ListFlowDefinitionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/FlowDefinition/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: GetFlowDefinitionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/FlowDefinition",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: CreateFlowDefinitionNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/tooling/sobjects/FlowDefinition/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: UpdateFlowDefinitionNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/tooling/sobjects/FlowDefinition/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: DeleteFlowDefinitionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/Flow",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ListFlowVersionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/Flow/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: GetFlowVersionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/Flow",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: CreateFlowVersionNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/tooling/sobjects/Flow/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: UpdateFlowVersionNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/tooling/sobjects/Flow/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: DeleteFlowVersionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/Flow/:id/activate",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ActivateFlowVersionNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/Flow/:id/deactivate",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: DeactivateFlowVersionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/record-ui/:recordIds",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: p.UIAPIRecordUINeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/ui-api/record-access",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIBatchRecordAccessNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/object-info/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIObjectInfoNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/layout/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPILayoutNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/layouts/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIListLayoutsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/approval-layouts/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIListApprovalLayoutsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/record-defaults/create/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIRecordDefaultsCreateNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/record-defaults/clone/:recordId",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIRecordDefaultsCloneNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/list-info/:objectApiName/:listViewApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIListInfoNeutralHandler,
		},

		{
			Method:  "GET",
			Path:    "/ui-api/layout-assignments/:objectApiName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UIAPIListAssignmentsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/ui-api/apps",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListUIApplicationsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/CustomApplication",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomApplicationListNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/tooling/sobjects/CustomApplication/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomApplicationGetNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/tooling/sobjects/CustomApplication",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomApplicationCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/tooling/sobjects/CustomApplication/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomApplicationUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/tooling/sobjects/CustomApplication/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingCustomApplicationDeleteNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/tooling/sobjects/ValidationRule/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingValidationRuleUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/tooling/sobjects/ValidationRule/:id",
			Gate:    dialect.Gate{Mode: dialect.GateAll, Permissions: []constants.Permission{constants.PermCustomizeApplication}},
			Handler: ToolingValidationRuleDeleteNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeGlobalNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/_System_File/describe",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeSystemFileNeutralHandler,
		},
		// Dedicated static literal route for _System_File layouts. It MUST be a
		// distinct Route from the generic "/sobjects/:sobject/describe/layouts"
		// below so Gin's radix tree does not stop at the
		// /sobjects/_System_File/:id param node (download/delete file static
		// branches on this dialect) and shadow the generic layouts route — the
		// #2037 radix-shadow lesson, here applied to the layout sub-tree.
		{
			Method:  "GET",
			Path:    "/sobjects/_System_File/describe/layouts",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeSystemFileLayoutsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/describe",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeObjectNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/describe/layouts",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeLayoutsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/describe/layouts/:recordTypeId",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DescribeLayoutByRecordTypeNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/listviews",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListViewsNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/sobjects/:sobject/listviews",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CreatePrivateListViewNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/sobjects/:sobject/listviews/:listViewId",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DeletePrivateListViewNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/listviews/:listViewId/describe",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ListViewDescribeNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/relevantItems",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: RelevantItemsNeutralHandler,
		},
		{
			Method:         "POST",
			Path:           "/files",
			Gate:           dialect.Gate{Mode: dialect.GateNone},
			BodyMode:       dialect.BodyStream,
			BodyLimitBytes: maxV63FileUploadSizeBytes,
			Handler:        UploadRecordFileNeutralHandler,
		},
		{
			Method:         "POST",
			Path:           "/record-files",
			Gate:           dialect.Gate{Mode: dialect.GateNone},
			BodyMode:       dialect.BodyStream,
			BodyLimitBytes: maxV63FileUploadSizeBytes,
			Handler:        UploadRecordFileNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/files/:id/download",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DownloadRecordFileNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/files/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DeleteRecordFileNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/_System_File/:id/download",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DownloadRecordFileNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/sobjects/_System_File/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DeleteRecordFileNeutralHandler,
		},
		{
			Method:         "POST",
			Path:           "/sobjects/ContentVersion",
			Gate:           dialect.Gate{Mode: dialect.GateNone},
			BodyMode:       dialect.BodyStream,
			BodyLimitBytes: maxV63FileUploadSizeBytes,
			Handler:        UploadLegacyContentVersionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/ContentVersion/:fileId/VersionData",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DownloadLegacyContentVersionNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: p.GetRecordNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/sobjects/:sobject",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CreateRecordNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/sobjects/:sobject/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UpdateRecordNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/sobjects/:sobject/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: DeleteRecordNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/sobjects/:sobject/:id/:fieldValue",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: UpsertByExternalIDNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/sobjects/:sobject/:id/:fieldValue",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: GetByExternalIDNeutralHandler,
		},
	}
	routes = append(routes, runtimeQueryRoutes()...)
	routes = append(routes, []dialect.Route{
		{
			Method:  "POST",
			Path:    "/ui-api/related-list-counts",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: RelatedListCountsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/search",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: SearchNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/parameterizedSearch",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ParameterizedSearchNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/parameterizedSearch",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: ParameterizedSearchPostNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/search/layout",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: SearchLayoutNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/search/suggestions",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: SearchSuggestionsNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/search/scopeOrder",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: SearchScopeOrderNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/recyclebin",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: RecycleBinListNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/recyclebin/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: RecycleBinPurgeNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/recyclebin/restore/:id",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: RecycleBinRestoreNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/composite",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/composite/batch",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeBatchNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/composite/tree/:objectName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeTreeNeutralHandler,
		},
		{
			Method:  "GET",
			Path:    "/composite/sobjects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeCollectionsRetrieveNeutralHandler,
		},
		{
			Method:  "POST",
			Path:    "/composite/sobjects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeCollectionsCreateNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/composite/sobjects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeCollectionsUpdateNeutralHandler,
		},
		{
			Method:  "DELETE",
			Path:    "/composite/sobjects",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeCollectionsDeleteNeutralHandler,
		},
		{
			Method:  "PATCH",
			Path:    "/composite/sobjects/:sObjectName/:externalIdFieldName",
			Gate:    dialect.Gate{Mode: dialect.GateNone},
			Handler: CompositeCollectionsUpsertNeutralHandler,
		},
	}...)
	return routes
}
