# Projects

## List all onboarded projects

> Returns a list of all projects that have been onboarded to the system. Projects are returned in no particular order. This endpoint is useful for discovering available projects before performing operations on them.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"ProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Repository identifier"},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository (user-specified)","enum":["github","gitlab","bitbucket","azure-devops","other"]},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"},"version":{"type":"number","description":"Document version for optimistic concurrency control"},"configuration":{"type":"object","description":"Project configuration object for extensibility.\n\nIncludes optional fields for:\n- **workItems**: Issue tracker integration (Jira, GitHub, Azure DevOps)\n- **metricsAlertConfig**: Custom alert thresholds for dashboard metrics\n- **branches**: Tracked branches\n- **settings**: Build and deployment settings"},"integrations":{"type":"array","description":"Integration references linked to this project"}},"required":["identifier","remoteUrl","platform","createdAt","updatedAt","version"]}}},"paths":{"/sfp/api/projects":{"get":{"operationId":"ProjectsController_listProjects","summary":"List all onboarded projects","description":"Returns a list of all projects that have been onboarded to the system. Projects are returned in no particular order. This endpoint is useful for discovering available projects before performing operations on them.","parameters":[],"responses":{"200":{"description":"List of projects retrieved successfully.","schema":{},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectDto"}}}}},"403":{"description":"Forbidden - Requires role: member, application"},"500":{"description":"Internal server error"}},"tags":["Projects"]}}}}
```

## Onboard a new repository

> Creates a new project entry for repository onboarding. Fails if the project already exists to prevent accidental updates through POST requests. Use this endpoint to register repositories with the SFP server for future operations. Only users with the "owner" role can create projects.

````json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"CreateProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Repository identifier (e.g., \"org/repo\" for GitHub, \"org/project/repo\" for Azure DevOps). Must be lowercase. If omitted, auto-derived from remoteUrl."},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository. If not provided, will be inferred from URL (deprecated behavior)","enum":["github","gitlab","bitbucket","azure-devops","other"]},"configuration":{"description":"Project configuration including workItems settings","allOf":[{"$ref":"#/components/schemas/ProjectConfigurationDto"}]}},"required":["remoteUrl"]},"ProjectConfigurationDto":{"type":"object","properties":{"platform":{"type":"string","description":"Platform identifier"},"workItems":{"description":"Work items / issue tracker configuration","allOf":[{"$ref":"#/components/schemas/WorkItemsConfigDto"}]},"branches":{"description":"Tracked branches for this project. Used to determine which branches trigger `build-on-merge` on push webhooks and which branches are analyzed by scheduled code analysis.\n\nDefaults to `[\"main\"]` if not specified.","type":"array","items":{"type":"string"}},"integrations":{"type":"array","description":"Integration configurations"},"metricsAlertConfig":{"type":"object","description":"Custom alert thresholds for dashboard metrics. Override default thresholds for specific metrics.\n\n**Valid metric keys:**\n- Success rates (0-1 scale, warning > alert): `validation.successRate`, `deploy.successRate`, `build.successRate`, `release.successRate`, `install.successRate`\n- Durations (minutes, warning < alert): `pr.turnaroundTime`, `validation.duration`, `build.avgCreationTime`, `release.avgDuration`, `install.avgDuration`, `deploy.avgDuration`, `workflow.validation.avgDuration`, `workflow.build.avgDuration`, `workflow.release.avgDuration`\n- Coverage (percentage, warning > alert): `apexTests.avgCoverage`\n\n**Default thresholds (see alert-thresholds.config.ts for complete list):**\n| Metric | Warning | Alert | Direction |\n|--------|---------|-------|-----------|\n| validation.successRate | 0.90 | 0.75 | below |\n| deploy.successRate | 0.95 | 0.85 | below |\n| build.successRate | 0.90 | 0.75 | below |\n| pr.turnaroundTime | 2880 (48h) | 4320 (72h) | above |\n| validation.duration | 30 min | 45 min | above |\n| build.avgCreationTime | 20 min | 40 min | above |\n| apexTests.avgCoverage | 85% | 75% | below |","additionalProperties":{"$ref":"#/components/schemas/MetricThresholdDto"}},"disabledFlows":{"description":"List of disabled flow type IDs. Disabled flows will not be triggered by webhooks or API calls.","type":"array","items":{"type":"string"}},"flowOverrides":{"type":"object","description":"Per-project flow type overrides. Maps original flow type IDs to replacement flow type IDs. When a webhook or API triggers \"build-on-merge\", if an override exists it will route to the replacement instead."},"version":{"type":"number","description":"Configuration version for migrations"},"aiProvider":{"type":"string","description":"AI provider for architecture analysis. The credentials must be stored via `POST /integrations`.\n\n**Available providers:**\n- `ai_anthropic` - Anthropic Claude models (recommended)\n- `ai_openai` - OpenAI GPT models\n- `ai_google` - Google Gemini models\n- `ai_github_copilot` - GitHub Copilot\n- `ai_amazon_bedrock` - Amazon Bedrock\n- `none` - Explicitly opt out of AI features for this project\n\n**Setup:**\n1. Store credentials: `POST /integrations` with `provider: \"ai_anthropic\"`, `credentials: { api_key: \"sk-ant-...\" }`\n2. Configure project: `PATCH /projects/{id}` with `configuration.aiProvider: \"ai_anthropic\"`\n\n**Default resolution:** If no AI provider is configured for a project, the system falls back to the default integration (if one is marked `isDefault`). Set `aiProvider: \"none\"` to explicitly disable AI for a project.","enum":["ai_anthropic","ai_openai","ai_google","ai_github_copilot","ai_amazon_bedrock","none"]},"webhookFilters":{"description":"Webhook filter exclusion rules. When a webhook matches eventType + branchPattern, the matching flows are NOT triggered.\n\n**Branch matching:** Uses wildcard patterns (e.g., `release/*`, `release-*`, `main`).\n- For `push` events: matches the pushed branch\n- For `pull_request` events: matches the target (base) branch\n\n**Flow filtering:** If `flowIds` is specified, only those flows are excluded. If omitted, ALL flows for that event+branch are excluded.\n\n**Example:** Skip build-on-merge for release branches, and skip pr-analyze for PRs targeting main:\n```json\n[\n  { \"eventType\": \"push\", \"branchPattern\": \"release/*\" },\n  { \"eventType\": \"push\", \"branchPattern\": \"release-*\" },\n  { \"eventType\": \"pull_request\", \"branchPattern\": \"main\", \"flowIds\": [\"pr-analyze\"] }\n]\n```","type":"array","items":{"$ref":"#/components/schemas/WebhookFilterRuleDto"}},"analyzeConfig":{"description":"Configuration for automated PR analysis (`sfp analyze`).\n\n**All linters are ON by default.** Use this to turn specific linters off or configure which should cause check failures.\n\n**Branch rules:** Matched against the **target branch** (baseBranch) of the PR. First matching rule wins.\n\n**Valid linter types:** `duplicates`, `compliance`, `architecture`, `code-analyzer`\n\n**Example:** Fail on compliance globally, but for release branches also fail on code-analyzer and skip architecture:\n```json\n{\n  \"failOn\": [\"compliance\"],\n  \"branchRules\": [\n    {\n      \"pattern\": \"release/*\",\n      \"excludeLinters\": [\"architecture\"],\n      \"failOn\": [\"compliance\", \"code-analyzer\"]\n    }\n  ]\n}\n```","allOf":[{"$ref":"#/components/schemas/AnalyzeConfigDto"}]},"validateConfig":{"description":"Configuration for automated PR validation (`sfp validate org`).\n\n**Top-level fields are defaults.** Branch rules override specific settings for matching target branches.\nFirst matching rule wins; if none match, top-level defaults apply.\n\n**Validation modes:** `thorough` (full deploy, default) or `individual` (per-package)\n\n**Example:** Skip testing by default, but enable it for release branches with individual mode:\n```json\n{\n  \"validationMode\": \"thorough\",\n  \"skipTesting\": true,\n  \"diffCheck\": true,\n  \"installDeps\": true,\n  \"coveragePercent\": 75,\n  \"branchRules\": [\n    {\n      \"pattern\": \"release/*\",\n      \"validationMode\": \"individual\",\n      \"skipTesting\": false,\n      \"disableArtifactUpdate\": true\n    }\n  ]\n}\n```","allOf":[{"$ref":"#/components/schemas/ValidateConfigDto"}]},"jiraWriteBack":{"description":"Jira write-back configuration for deployment and release events","allOf":[{"$ref":"#/components/schemas/JiraWriteBackConfigDto"}]},"preflight":{"description":"Preflight status for this project. Automatically updated by the `project-preflight` workflow.\n\n**Statuses:**\n- `valid`: Project is correctly configured for sfp (ready to use)\n- `configured`: Changes were made but not yet merged\n- `pr-created`: A PR was created with configuration changes — user must merge and re-run\n- `error`: Preflight check failed","allOf":[{"$ref":"#/components/schemas/PreflightStatusDto"}]}}},"WorkItemsConfigDto":{"type":"object","properties":{"provider":{"type":"string","description":"Issue tracker provider","enum":["jira","github","azure-devops"]},"jiraProjects":{"description":"**Jira only**: Project keys to filter work items (e.g., [\"DP\", \"PROJ\"])","type":"array","items":{"type":"string"}},"baseUrl":{"type":"string","description":"**Jira only**: Base URL for work item links"},"workItemRegexFilter":{"type":"string","description":"**Jira only**: Regex pattern to match work item IDs in commit messages"},"project":{"type":"string","description":"**Azure DevOps only**: Project name within the organization (required for ADO)"},"organizationUrl":{"type":"string","description":"**Azure DevOps only**: Organization URL"},"areaPaths":{"description":"**Azure DevOps only**: Area paths to filter work items (e.g., [\"sf-core\\\\Team1\", \"sf-core\\\\Team2\"])","type":"array","items":{"type":"string"}}}},"MetricThresholdDto":{"type":"object","properties":{"warning":{"type":"number","description":"Warning threshold value. For success rates/coverage, this should be > alert. For durations, this should be < alert.","minimum":0},"alert":{"type":"number","description":"Alert threshold value (more severe than warning). For success rates/coverage, this should be < warning. For durations, this should be > warning.","minimum":0}}},"WebhookFilterRuleDto":{"type":"object","properties":{"eventType":{"type":"string","description":"Webhook event category to filter","enum":["push","pull_request"]},"branchPattern":{"type":"string","description":"Wildcard pattern for branch name. For push: the pushed branch. For pull_request: the target (base) branch."},"flowIds":{"description":"Specific flow IDs to exclude. If omitted, ALL flows for this event+branch are excluded.","type":"array","items":{"type":"string"}}},"required":["eventType","branchPattern"]},"AnalyzeConfigDto":{"type":"object","properties":{"excludeLinters":{"description":"Linters to turn OFF globally (default: none — all linters run)","type":"array","items":{"type":"string"}},"failOn":{"description":"Linters whose issues should cause the check to fail (default: none — informational only)","type":"array","items":{"type":"string"}},"changeSignificanceEnabled":{"type":"boolean","description":"Enable change significance check for architecture linter — skip AI for small/trivial changes (default: false — AI runs for all changes). Same key as changeSignificance.enabled in ai-architecture.yaml."},"branchRules":{"description":"Target-branch-specific overrides. First matching pattern wins.","type":"array","items":{"$ref":"#/components/schemas/AnalyzeBranchRuleDto"}}}},"AnalyzeBranchRuleDto":{"type":"object","properties":{"pattern":{"type":"string","description":"Glob pattern for target branch (e.g., \"release/*\", \"hotfix/*\", \"main\")"},"excludeLinters":{"description":"Linters to turn OFF for PRs targeting this branch pattern","type":"array","items":{"type":"string"}},"failOn":{"description":"Linters whose issues should cause the check to fail for PRs targeting this branch pattern","type":"array","items":{"type":"string"}},"changeSignificanceEnabled":{"type":"boolean","description":"Enable change significance check for architecture linter — skip AI for small/trivial changes (default: false — AI runs for all changes). Same key as changeSignificance.enabled in ai-architecture.yaml."}}},"ValidateConfigDto":{"type":"object","properties":{"validationMode":{"type":"string","description":"Default validation mode","enum":["thorough","individual"]},"skipTesting":{"type":"boolean","description":"Skip Apex test execution during validation (default)"},"coveragePercent":{"type":"number","description":"Required code coverage percentage (default, 0-100)","minimum":0,"maximum":100},"disableParallelTesting":{"type":"boolean","description":"Disable parallel test execution (default)"},"installDeps":{"type":"boolean","description":"Install dependent packages before validation (default)"},"disableArtifactUpdate":{"type":"boolean","description":"Disable artifact update after validation (default)"},"diffCheck":{"type":"boolean","description":"Enable diff-based change detection (default)"},"branchRules":{"description":"Target-branch-specific overrides. First matching pattern wins.","type":"array","items":{"$ref":"#/components/schemas/ValidateBranchRuleDto"}}}},"ValidateBranchRuleDto":{"type":"object","properties":{"pattern":{"type":"string","description":"Wildcard pattern for target branch (e.g., \"release/*\", \"main\")"},"validationMode":{"type":"string","description":"Validation mode: thorough (full deploy) or individual (per package)","enum":["thorough","individual"]},"skipTesting":{"type":"boolean","description":"Skip Apex test execution during validation"},"coveragePercent":{"type":"number","description":"Required code coverage percentage (0-100)","minimum":0,"maximum":100},"disableParallelTesting":{"type":"boolean","description":"Disable parallel test execution"},"installDeps":{"type":"boolean","description":"Install dependent packages before validation"},"disableArtifactUpdate":{"type":"boolean","description":"Disable artifact update after validation"},"diffCheck":{"type":"boolean","description":"Enable diff-based change detection"}},"required":["pattern"]},"JiraWriteBackConfigDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Enable Jira write-back. Not configured = not enabled."}}},"PreflightStatusDto":{"type":"object","properties":{"status":{"type":"string","description":"Preflight result status","enum":["already-configured","configured","not-configured","pr-created","error"]},"lastCheckedAt":{"type":"string","description":"ISO 8601 timestamp of the last preflight check"},"prUrl":{"type":"string","description":"URL of the PR created by preflight (if status is pr-created)"},"prNumber":{"type":"number","description":"PR number created by preflight"}}},"ProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Repository identifier"},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository (user-specified)","enum":["github","gitlab","bitbucket","azure-devops","other"]},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"},"version":{"type":"number","description":"Document version for optimistic concurrency control"},"configuration":{"type":"object","description":"Project configuration object for extensibility.\n\nIncludes optional fields for:\n- **workItems**: Issue tracker integration (Jira, GitHub, Azure DevOps)\n- **metricsAlertConfig**: Custom alert thresholds for dashboard metrics\n- **branches**: Tracked branches\n- **settings**: Build and deployment settings"},"integrations":{"type":"array","description":"Integration references linked to this project"}},"required":["identifier","remoteUrl","platform","createdAt","updatedAt","version"]}}},"paths":{"/sfp/api/projects":{"post":{"operationId":"ProjectsController_createProject","summary":"Onboard a new repository","description":"Creates a new project entry for repository onboarding. Fails if the project already exists to prevent accidental updates through POST requests. Use this endpoint to register repositories with the SFP server for future operations. Only users with the \"owner\" role can create projects.","parameters":[],"requestBody":{"required":true,"description":"Project details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectDto"}}}},"responses":{"201":{"description":"The project has been successfully created.","schema":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDto"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{}}}},"403":{"description":"Forbidden - Requires role: owner, application"},"409":{"description":"The project already exists.","content":{"application/json":{"schema":{}}}}},"tags":["Projects"]}}}}
````

## Get a specific project by identifier

> Retrieves a project by its repository identifier (e.g., "org/repo"). The identifier must match exactly what was used during project creation. This endpoint supports identifiers with slashes for GitHub-style repositories.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"ProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Repository identifier"},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository (user-specified)","enum":["github","gitlab","bitbucket","azure-devops","other"]},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"},"version":{"type":"number","description":"Document version for optimistic concurrency control"},"configuration":{"type":"object","description":"Project configuration object for extensibility.\n\nIncludes optional fields for:\n- **workItems**: Issue tracker integration (Jira, GitHub, Azure DevOps)\n- **metricsAlertConfig**: Custom alert thresholds for dashboard metrics\n- **branches**: Tracked branches\n- **settings**: Build and deployment settings"},"integrations":{"type":"array","description":"Integration references linked to this project"}},"required":["identifier","remoteUrl","platform","createdAt","updatedAt","version"]}}},"paths":{"/sfp/api/projects/{identifier}":{"get":{"operationId":"ProjectsController_getProject","summary":"Get a specific project by identifier","description":"Retrieves a project by its repository identifier (e.g., \"org/repo\"). The identifier must match exactly what was used during project creation. This endpoint supports identifiers with slashes for GitHub-style repositories.","parameters":[{"name":"identifier","required":true,"in":"path","description":"Repository identifier (e.g., \"org/repo\")","schema":{"type":"string"}}],"responses":{"200":{"description":"Project retrieved successfully.","schema":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDto"}}}},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"Project not found.","content":{"application/json":{"schema":{}}}},"500":{"description":"Internal server error"}},"tags":["Projects"]}}}}
```

## Delete a project

> Permanently deletes a project and its stored configuration. Only owners can delete projects. This does not delete external resources (webhooks, environments, etc.).

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/projects/{identifier}":{"delete":{"operationId":"ProjectsController_deleteProject","summary":"Delete a project","description":"Permanently deletes a project and its stored configuration. Only owners can delete projects. This does not delete external resources (webhooks, environments, etc.).","parameters":[{"name":"identifier","required":true,"in":"path","description":"Repository identifier (e.g., \"org/repo\")","schema":{"type":"string"}}],"responses":{"204":{"description":"Project deleted successfully."},"403":{"description":"Forbidden - Requires role: owner, application"},"404":{"description":"Project not found.","content":{"application/json":{"schema":{}}}},"500":{"description":"Internal server error"}},"tags":["Projects"]}}}}
```

## Update project configuration

> Updates an existing project's configuration. Supports partial updates via PATCH semantics. Only owners can update projects. Includes optimistic concurrency control through version checking to prevent concurrent update conflicts.\
> \
> \*\*Renaming:\*\* Pass \`identifier\` in the body to rename the project. The old identifier is deleted and a new one is created with all existing data.

````json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"UpdateProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"New repository identifier. Renames the project key in the store. Must be lowercase in format org/repo or org/project/repo."},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository","enum":["github","gitlab","bitbucket","azure-devops","other"]},"configuration":{"description":"Project configuration object.\n\n**Examples by provider:**\n- **Jira**: `{ workItems: { provider: \"jira\", jiraProjects: [\"DP\", \"PROJ\"], baseUrl: \"https://company.atlassian.net/browse\" } }`\n- **GitHub**: `{ workItems: { provider: \"github\" } }` (uses project identifier directly)\n- **Azure DevOps**: `{ workItems: { provider: \"azure-devops\", project: \"sf-core\", organizationUrl: \"https://dev.azure.com/org\", areaPaths: [\"sf-core\\\\Team1\"] } }`","allOf":[{"$ref":"#/components/schemas/ProjectConfigurationDto"}]},"version":{"type":"number","description":"Document version for optimistic concurrency control"}}},"ProjectConfigurationDto":{"type":"object","properties":{"platform":{"type":"string","description":"Platform identifier"},"workItems":{"description":"Work items / issue tracker configuration","allOf":[{"$ref":"#/components/schemas/WorkItemsConfigDto"}]},"branches":{"description":"Tracked branches for this project. Used to determine which branches trigger `build-on-merge` on push webhooks and which branches are analyzed by scheduled code analysis.\n\nDefaults to `[\"main\"]` if not specified.","type":"array","items":{"type":"string"}},"integrations":{"type":"array","description":"Integration configurations"},"metricsAlertConfig":{"type":"object","description":"Custom alert thresholds for dashboard metrics. Override default thresholds for specific metrics.\n\n**Valid metric keys:**\n- Success rates (0-1 scale, warning > alert): `validation.successRate`, `deploy.successRate`, `build.successRate`, `release.successRate`, `install.successRate`\n- Durations (minutes, warning < alert): `pr.turnaroundTime`, `validation.duration`, `build.avgCreationTime`, `release.avgDuration`, `install.avgDuration`, `deploy.avgDuration`, `workflow.validation.avgDuration`, `workflow.build.avgDuration`, `workflow.release.avgDuration`\n- Coverage (percentage, warning > alert): `apexTests.avgCoverage`\n\n**Default thresholds (see alert-thresholds.config.ts for complete list):**\n| Metric | Warning | Alert | Direction |\n|--------|---------|-------|-----------|\n| validation.successRate | 0.90 | 0.75 | below |\n| deploy.successRate | 0.95 | 0.85 | below |\n| build.successRate | 0.90 | 0.75 | below |\n| pr.turnaroundTime | 2880 (48h) | 4320 (72h) | above |\n| validation.duration | 30 min | 45 min | above |\n| build.avgCreationTime | 20 min | 40 min | above |\n| apexTests.avgCoverage | 85% | 75% | below |","additionalProperties":{"$ref":"#/components/schemas/MetricThresholdDto"}},"disabledFlows":{"description":"List of disabled flow type IDs. Disabled flows will not be triggered by webhooks or API calls.","type":"array","items":{"type":"string"}},"flowOverrides":{"type":"object","description":"Per-project flow type overrides. Maps original flow type IDs to replacement flow type IDs. When a webhook or API triggers \"build-on-merge\", if an override exists it will route to the replacement instead."},"version":{"type":"number","description":"Configuration version for migrations"},"aiProvider":{"type":"string","description":"AI provider for architecture analysis. The credentials must be stored via `POST /integrations`.\n\n**Available providers:**\n- `ai_anthropic` - Anthropic Claude models (recommended)\n- `ai_openai` - OpenAI GPT models\n- `ai_google` - Google Gemini models\n- `ai_github_copilot` - GitHub Copilot\n- `ai_amazon_bedrock` - Amazon Bedrock\n- `none` - Explicitly opt out of AI features for this project\n\n**Setup:**\n1. Store credentials: `POST /integrations` with `provider: \"ai_anthropic\"`, `credentials: { api_key: \"sk-ant-...\" }`\n2. Configure project: `PATCH /projects/{id}` with `configuration.aiProvider: \"ai_anthropic\"`\n\n**Default resolution:** If no AI provider is configured for a project, the system falls back to the default integration (if one is marked `isDefault`). Set `aiProvider: \"none\"` to explicitly disable AI for a project.","enum":["ai_anthropic","ai_openai","ai_google","ai_github_copilot","ai_amazon_bedrock","none"]},"webhookFilters":{"description":"Webhook filter exclusion rules. When a webhook matches eventType + branchPattern, the matching flows are NOT triggered.\n\n**Branch matching:** Uses wildcard patterns (e.g., `release/*`, `release-*`, `main`).\n- For `push` events: matches the pushed branch\n- For `pull_request` events: matches the target (base) branch\n\n**Flow filtering:** If `flowIds` is specified, only those flows are excluded. If omitted, ALL flows for that event+branch are excluded.\n\n**Example:** Skip build-on-merge for release branches, and skip pr-analyze for PRs targeting main:\n```json\n[\n  { \"eventType\": \"push\", \"branchPattern\": \"release/*\" },\n  { \"eventType\": \"push\", \"branchPattern\": \"release-*\" },\n  { \"eventType\": \"pull_request\", \"branchPattern\": \"main\", \"flowIds\": [\"pr-analyze\"] }\n]\n```","type":"array","items":{"$ref":"#/components/schemas/WebhookFilterRuleDto"}},"analyzeConfig":{"description":"Configuration for automated PR analysis (`sfp analyze`).\n\n**All linters are ON by default.** Use this to turn specific linters off or configure which should cause check failures.\n\n**Branch rules:** Matched against the **target branch** (baseBranch) of the PR. First matching rule wins.\n\n**Valid linter types:** `duplicates`, `compliance`, `architecture`, `code-analyzer`\n\n**Example:** Fail on compliance globally, but for release branches also fail on code-analyzer and skip architecture:\n```json\n{\n  \"failOn\": [\"compliance\"],\n  \"branchRules\": [\n    {\n      \"pattern\": \"release/*\",\n      \"excludeLinters\": [\"architecture\"],\n      \"failOn\": [\"compliance\", \"code-analyzer\"]\n    }\n  ]\n}\n```","allOf":[{"$ref":"#/components/schemas/AnalyzeConfigDto"}]},"validateConfig":{"description":"Configuration for automated PR validation (`sfp validate org`).\n\n**Top-level fields are defaults.** Branch rules override specific settings for matching target branches.\nFirst matching rule wins; if none match, top-level defaults apply.\n\n**Validation modes:** `thorough` (full deploy, default) or `individual` (per-package)\n\n**Example:** Skip testing by default, but enable it for release branches with individual mode:\n```json\n{\n  \"validationMode\": \"thorough\",\n  \"skipTesting\": true,\n  \"diffCheck\": true,\n  \"installDeps\": true,\n  \"coveragePercent\": 75,\n  \"branchRules\": [\n    {\n      \"pattern\": \"release/*\",\n      \"validationMode\": \"individual\",\n      \"skipTesting\": false,\n      \"disableArtifactUpdate\": true\n    }\n  ]\n}\n```","allOf":[{"$ref":"#/components/schemas/ValidateConfigDto"}]},"jiraWriteBack":{"description":"Jira write-back configuration for deployment and release events","allOf":[{"$ref":"#/components/schemas/JiraWriteBackConfigDto"}]},"preflight":{"description":"Preflight status for this project. Automatically updated by the `project-preflight` workflow.\n\n**Statuses:**\n- `valid`: Project is correctly configured for sfp (ready to use)\n- `configured`: Changes were made but not yet merged\n- `pr-created`: A PR was created with configuration changes — user must merge and re-run\n- `error`: Preflight check failed","allOf":[{"$ref":"#/components/schemas/PreflightStatusDto"}]}}},"WorkItemsConfigDto":{"type":"object","properties":{"provider":{"type":"string","description":"Issue tracker provider","enum":["jira","github","azure-devops"]},"jiraProjects":{"description":"**Jira only**: Project keys to filter work items (e.g., [\"DP\", \"PROJ\"])","type":"array","items":{"type":"string"}},"baseUrl":{"type":"string","description":"**Jira only**: Base URL for work item links"},"workItemRegexFilter":{"type":"string","description":"**Jira only**: Regex pattern to match work item IDs in commit messages"},"project":{"type":"string","description":"**Azure DevOps only**: Project name within the organization (required for ADO)"},"organizationUrl":{"type":"string","description":"**Azure DevOps only**: Organization URL"},"areaPaths":{"description":"**Azure DevOps only**: Area paths to filter work items (e.g., [\"sf-core\\\\Team1\", \"sf-core\\\\Team2\"])","type":"array","items":{"type":"string"}}}},"MetricThresholdDto":{"type":"object","properties":{"warning":{"type":"number","description":"Warning threshold value. For success rates/coverage, this should be > alert. For durations, this should be < alert.","minimum":0},"alert":{"type":"number","description":"Alert threshold value (more severe than warning). For success rates/coverage, this should be < warning. For durations, this should be > warning.","minimum":0}}},"WebhookFilterRuleDto":{"type":"object","properties":{"eventType":{"type":"string","description":"Webhook event category to filter","enum":["push","pull_request"]},"branchPattern":{"type":"string","description":"Wildcard pattern for branch name. For push: the pushed branch. For pull_request: the target (base) branch."},"flowIds":{"description":"Specific flow IDs to exclude. If omitted, ALL flows for this event+branch are excluded.","type":"array","items":{"type":"string"}}},"required":["eventType","branchPattern"]},"AnalyzeConfigDto":{"type":"object","properties":{"excludeLinters":{"description":"Linters to turn OFF globally (default: none — all linters run)","type":"array","items":{"type":"string"}},"failOn":{"description":"Linters whose issues should cause the check to fail (default: none — informational only)","type":"array","items":{"type":"string"}},"changeSignificanceEnabled":{"type":"boolean","description":"Enable change significance check for architecture linter — skip AI for small/trivial changes (default: false — AI runs for all changes). Same key as changeSignificance.enabled in ai-architecture.yaml."},"branchRules":{"description":"Target-branch-specific overrides. First matching pattern wins.","type":"array","items":{"$ref":"#/components/schemas/AnalyzeBranchRuleDto"}}}},"AnalyzeBranchRuleDto":{"type":"object","properties":{"pattern":{"type":"string","description":"Glob pattern for target branch (e.g., \"release/*\", \"hotfix/*\", \"main\")"},"excludeLinters":{"description":"Linters to turn OFF for PRs targeting this branch pattern","type":"array","items":{"type":"string"}},"failOn":{"description":"Linters whose issues should cause the check to fail for PRs targeting this branch pattern","type":"array","items":{"type":"string"}},"changeSignificanceEnabled":{"type":"boolean","description":"Enable change significance check for architecture linter — skip AI for small/trivial changes (default: false — AI runs for all changes). Same key as changeSignificance.enabled in ai-architecture.yaml."}}},"ValidateConfigDto":{"type":"object","properties":{"validationMode":{"type":"string","description":"Default validation mode","enum":["thorough","individual"]},"skipTesting":{"type":"boolean","description":"Skip Apex test execution during validation (default)"},"coveragePercent":{"type":"number","description":"Required code coverage percentage (default, 0-100)","minimum":0,"maximum":100},"disableParallelTesting":{"type":"boolean","description":"Disable parallel test execution (default)"},"installDeps":{"type":"boolean","description":"Install dependent packages before validation (default)"},"disableArtifactUpdate":{"type":"boolean","description":"Disable artifact update after validation (default)"},"diffCheck":{"type":"boolean","description":"Enable diff-based change detection (default)"},"branchRules":{"description":"Target-branch-specific overrides. First matching pattern wins.","type":"array","items":{"$ref":"#/components/schemas/ValidateBranchRuleDto"}}}},"ValidateBranchRuleDto":{"type":"object","properties":{"pattern":{"type":"string","description":"Wildcard pattern for target branch (e.g., \"release/*\", \"main\")"},"validationMode":{"type":"string","description":"Validation mode: thorough (full deploy) or individual (per package)","enum":["thorough","individual"]},"skipTesting":{"type":"boolean","description":"Skip Apex test execution during validation"},"coveragePercent":{"type":"number","description":"Required code coverage percentage (0-100)","minimum":0,"maximum":100},"disableParallelTesting":{"type":"boolean","description":"Disable parallel test execution"},"installDeps":{"type":"boolean","description":"Install dependent packages before validation"},"disableArtifactUpdate":{"type":"boolean","description":"Disable artifact update after validation"},"diffCheck":{"type":"boolean","description":"Enable diff-based change detection"}},"required":["pattern"]},"JiraWriteBackConfigDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Enable Jira write-back. Not configured = not enabled."}}},"PreflightStatusDto":{"type":"object","properties":{"status":{"type":"string","description":"Preflight result status","enum":["already-configured","configured","not-configured","pr-created","error"]},"lastCheckedAt":{"type":"string","description":"ISO 8601 timestamp of the last preflight check"},"prUrl":{"type":"string","description":"URL of the PR created by preflight (if status is pr-created)"},"prNumber":{"type":"number","description":"PR number created by preflight"}}},"ProjectDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Repository identifier"},"remoteUrl":{"type":"string","description":"Remote repository URL"},"platform":{"type":"string","description":"Platform for the repository (user-specified)","enum":["github","gitlab","bitbucket","azure-devops","other"]},"createdAt":{"type":"string","description":"Creation timestamp"},"updatedAt":{"type":"string","description":"Last update timestamp"},"version":{"type":"number","description":"Document version for optimistic concurrency control"},"configuration":{"type":"object","description":"Project configuration object for extensibility.\n\nIncludes optional fields for:\n- **workItems**: Issue tracker integration (Jira, GitHub, Azure DevOps)\n- **metricsAlertConfig**: Custom alert thresholds for dashboard metrics\n- **branches**: Tracked branches\n- **settings**: Build and deployment settings"},"integrations":{"type":"array","description":"Integration references linked to this project"}},"required":["identifier","remoteUrl","platform","createdAt","updatedAt","version"]}}},"paths":{"/sfp/api/projects/{identifier}":{"patch":{"operationId":"ProjectsController_updateProject","summary":"Update project configuration","description":"Updates an existing project's configuration. Supports partial updates via PATCH semantics. Only owners can update projects. Includes optimistic concurrency control through version checking to prevent concurrent update conflicts.\n\n**Renaming:** Pass `identifier` in the body to rename the project. The old identifier is deleted and a new one is created with all existing data.","parameters":[{"name":"identifier","required":true,"in":"path","description":"Repository identifier (e.g., \"org/repo\")","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Fields to update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectDto"}}}},"responses":{"200":{"description":"Project updated successfully.","schema":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDto"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{}}}},"403":{"description":"Forbidden - Requires role: owner, application"},"404":{"description":"Project not found.","content":{"application/json":{"schema":{}}}},"409":{"description":"Version conflict - the project has been modified by another process.","content":{"application/json":{"schema":{}}}},"500":{"description":"Internal server error"}},"tags":["Projects"]}}}}
````
