# Build Config Skill

## Purpose
Create the initial Falcon connector YAML configuration with complete authentication setup and one test action.

## YAML Schema Documentation

This skill uses comprehensive Falcon schema skills for building correct configurations:

### Available Schema Skills

**Core & Structure:**
- `connector-patterns` - Base YAML structure, file organization, partials approach; `connector-patterns/references/naming-conventions.md` for naming rules (N1–N12)

**Authentication:**
- `auth-oauth2` - OAuth 2.0 configuration (authorization_code, client_credentials, refresh tokens)
- `auth-custom` - API Key, Basic Auth, Bearer token configuration
- `auth-soap` - SOAP/WS-Security authentication patterns
- `connector-patterns/references/authentication.md` - all authorization shapes, setupFields/configFields, scope definitions

**Actions & Steps:**
- `references/action-config.md` - Action configuration (actionId, effects, label, result pattern)
- `references/input-config.md` - Complete input configuration reference (all types, fields)
- `references/args-config.md` - Complete args configuration (all properties, array handling, conditions)
- `references/step-function-request.md` - HTTP request functions (request, paginated_request)
- `references/step-function-upload-download.md` - File operations (upload_file, upload_binary, download_file)
- `connector-patterns/references/tricky-handling.md` - SOAP, GraphQL, file chains and event actions

**Expressions:**
- `connector-patterns/references/schema-vs-corpus.md` - JSONPath, String Interpolation, JEXL — the three expression formats

### How to Use Schema Skills

When building configurations, invoke relevant skills based on provider's API type:

**For REST APIs:**
```
Use connector-patterns skill for base structure
Use auth-oauth2 OR auth-custom skill for authentication
read `references/action-config.md` for action definitions
read `references/step-function-request.md` for request configuration
Use connector-patterns/references/schema-vs-corpus.md for dynamic values
```

**For GraphQL APIs:**
```
Use connector-patterns skill for base structure
Use auth-oauth2 OR auth-custom skill for authentication
read `references/action-config.md` for action definitions
read `references/step-function-request.md` for GraphQL queries/mutations
Use connector-patterns/references/schema-vs-corpus.md for variable mapping
```

**For SOAP APIs:**
```
Use connector-patterns skill for base structure
read `references/auth-soap.md` for authentication
read `references/action-config.md` for action definitions
Use connector-patterns/references/tricky-handling.md for SOAP operations
Use string interpolation for SOAP values
```

## Building Configuration Process

When building the connector configuration, use the appropriate schema skills:

### Step 1: Use connector-patterns Skill

```
Use the connector-patterns skill to understand base YAML structure
```

This provides:
- File structure and partials approach
- Main connector file schema
- Naming conventions (`references/naming-conventions.md`)
- Required and optional fields

### Step 2: Use Authentication Skills

Based on the stored authentication data (`.connector-dev/{{provider}}/research/auth/auth_config.yaml`):

**For OAuth 2.0:**
```
read `references/auth-oauth2.md` to configure OAuth authentication
```

**For API Key / Basic Auth:**
```
read `references/auth-custom.md` to configure custom authentication
```

**For SOAP:**
```
read `references/auth-soap.md` to configure SOAP authentication
```

### Step 3: Use action-config and input-config Skills

```
read `references/action-config.md` to understand action configuration
read `references/input-config.md` to understand complete input mapping
```

This provides:
- Unified vs non-unified action patterns
- Action field requirements
- **Complete input configuration for ALL parameters**
- Result mapping patterns

**⚠️ CRITICAL**: When adding the test action, include ALL parameters from provider API (required + optional)

### Step 4: Use Step Function Skills

Based on API type from stored data:

**For REST APIs:**
```
read `references/step-function-request.md` for HTTP request configuration
```

**For GraphQL APIs:**
```
read `references/step-function-request.md` for GraphQL queries/mutations
```

**For SOAP APIs:**
```
Use connector-patterns/references/tricky-handling.md for SOAP operations
```

### Step 5: read `references/input-config.md`

```
read `references/input-config.md` for complete parameter mapping
```

This provides:
- All input types (string, number, object, array, enum)
- Input field properties (label, placeholder, tooltip)
- Mapping to args in step functions
- Complete parameter coverage guidelines

### Step 6: Use the Expression Formats Reference

```
Read connector-patterns/references/schema-vs-corpus.md for dynamic value references
```

This provides:
- JSONPath for direct references
- String interpolation for URLs
- JEXL for conditions and transformations

### Step 7: Configure OAuth Scopes (If OAuth 2.0)

```
Read connector-patterns/references/authentication.md for scope definitions
```

## Configuration Tasks

### 1. Create Connector Structure

Read `connector_path` from `.connector-dev/{{provider}}/build-state.yaml` (field `build.connector_path`). Create the YAML file at `{{connector_path}}/{{provider}}.connector.s1.yaml`.

> **Filenames: lowercase letters, digits and dots only — never a hyphen, underscore, space,
> comma or capital.** A multi-word provider runs together as one token:
> `azureblobstorage`, never `azure-blob-storage` or `azure_blob_storage`. The filename is
> parsed — a partial's resource is read out of it and must match a `$ref` — so a hyphen
> produces a resource nothing refers to and fails wiring later without naming the filename
> as the cause.


```yaml
# {{connector_path}}/{{provider}}.connector.s1.yaml
StackOne: 1.0.0
info:
  title: {{Provider}}
  key: {{provider}}
  version: 0.1.0
  assets:
    icon: https://stackone-logos.com/api/{{provider}}/filled/svg
  description: {{description}}
  changelog:
    summary: Initial release covering {{resources}}.   # 1-2 customer-facing lines, overwritten each bump
    labels: [new-actions]   # optional; each one of: auth, downstream-change, bug-fix, new-actions

baseUrl: {{base_url}}
releaseStage: preview
```

**New connectors always start at `0.1.0`** with `releaseStage: preview`. **Every published
version records what changed** — the initial one included: `info.changelog` carries a 1–2
line customer-facing `summary` (overwritten on each bump, never appended) and optional
`labels`, each one of `auth`, `downstream-change`, `bug-fix`, `new-actions`. Validate's
V10 checks this. GA promotion bumps to `1.0.0` — `releaseStage: ga` below that is a
blocking contradiction.

### 2. Configure Authentication
Pull from stored auth data to configure:
- OAuth 2.0 configurations
- API Key setup
- Basic auth if applicable
- Custom authentication
- Scope definitions
- Test actions for validation

### 2b. testActions and environments — always, both

Every auth block declares `testActions` (the resource's read-only LIST action) and an
`environments` block with the `production` key. Both are scored by exact key/id match in
the quality benchmark, and two measured providers sat at 50% on this sub-metric purely
because one of the two was absent. They cost two lines each.

### 2a. Region / Server Location / Data Center Fields

**RULE: Region values are configFields, NOT environments.**

`environments` = deployment stages only: `production`, `sandbox`, `staging`
`configFields` = user-specific values: region, serverLocation, dataCenter, tenant, subdomain

**NEVER put region/location/datacenter as an environment entry.**

Check research data for these signals:
- Provider has multiple API hosts per geographic region (e.g. `us.api.provider.com`, `eu.api.provider.com`)
- Provider docs mention "data center", "server location", "region", "pod"
- URLs differ by region
- Provider has select-your-region during signup/setup

When detected, add as `configField` or `setupField` (based on research data — check who sets the region):
- **`setupFields`** — if region is set once by T1/admin during OAuth app or integration setup (e.g. provider ties region to app registration)
- **`configFields`** — if region is chosen by T2/end user per connection (e.g. user selects their data center when connecting)

Use `type: select` with provider's exact terminology:

**Pattern A — Region in baseUrl (most common):**
```yaml
baseUrl: https://${credentials.region}.api.provider.com

# Under auth block:
configFields:
  - key: region
    label: Data Region               # use provider's exact terminology
    type: select
    required: true
    secret: false
    description: Select your data region as shown in your account settings
    options:
      - label: United States
        value: us
      - label: Europe
        value: eu
      - label: Australia
        value: au
```

**Pattern B — Region in request headers (some providers):**
```yaml
baseUrl: https://api.provider.com    # static, no interpolation

# Under auth block:
configFields:
  - key: serverLocation
    label: Server Location           # use provider's exact terminology
    type: select
    required: true
    secret: false
    options:
      - label: US
        value: us1
      - label: EU
        value: eu1

# In each action's step args:
args:
  - name: X-Server-Location
    value: $.credentials.serverLocation
    in: headers
```

**WRONG — never do this:**
```yaml
# WRONG — region values mixed into environments
environments:
  - key: production
    name: Production
  - key: us
    name: US Region
    baseUrl: https://us.api.provider.com
  - key: eu
    name: EU Region
    baseUrl: https://eu.api.provider.com
```

### 3. Add Single Test Action

**Do not ask about a test account.** This flow never connects one — nothing is executed
against a live API, so there is no account whose contents could be in question.

Pick from the research artifact instead: a LIST endpoint on the highest-ranked in-scope
resource, falling back to CREATE only when the resource has no LIST. The test action exists
so the connector has one wired action to validate structurally; it is not run here.
```yaml
actions:
  $ref: {{provider}}.test

# In partial file:
- actionId: list_users
  categories: [unified/users]
  actionType: custom
  label: List Users
  description: Retrieve a list of users
  details: Get all users from the system
  steps:
    - stepId: fetch_users
      description: Fetch users from API
      stepFunction:
        functionName: request
        parameters:
          url: /users
          method: get
  result:
    data: $.steps.fetch_users.output.data
```

### 4. Validate Configuration

Run validation:
```bash
# Resolve $CONNECTOR_PATH from state (see docs/PATHS.md §Connector-path resolution)
CONNECTOR_PATH=$(yq -r '.build.connector_path // ""' ".connector-dev/{{provider}}/build-state.yaml" 2>/dev/null)
[ -z "$CONNECTOR_PATH" ] && CONNECTOR_PATH=$([ -d "src/configs" ] && echo "src/configs/{{provider}}/" || echo "{{provider}}/")

stackone validate "$CONNECTOR_PATH"
```

**What it checks:**
- YAML syntax (indentation, quotes, structure)
- Required fields (info, baseUrl, authentication)
- Field types (string vs text, array format)
- $ref references (partial files exist)
- Action schema (actionId, steps, result)
- Authentication config (setupFields vs configFields)

**Common errors:**
- Missing required fields → Add them
- Invalid $ref → Check file exists
- Wrong field type → Fix type (text not string)
- Invalid YAML → Check indentation/quotes

**Note:** May show warnings like "Unknown field 'guides'" - these are safe to ignore.

## Output Files

1. **Main Connector File**
   - `{{connector_path}}/{{provider}}.connector.s1.yaml`
   - Contains info, auth, and $ref

2. **Test Action Partial**
   - `{{connector_path}}/{{provider}}.test.s1.partial.yaml`
   - Single action for testing

3. **Validation Report**
   - Confirmation that YAML is valid
   - Ready for guide addition

## Success Criteria
- [ ] Valid YAML structure
- [ ] All auth methods configured
- [ ] One working test action
- [ ] Passes StackOne validation
- [ ] Ready for the build gate

## Skill Invocation Workflow

**When this skill is invoked, follow this pattern:**

1. **Start**: Use `connector-patterns` skill (+ `references/naming-conventions.md`)
2. **Authentication**: Use `auth-oauth2` OR `auth-custom` OR `auth-soap.md` (based on API type)
3. **Actions**: Use `references/action-config.md` skill
4. **Inputs**: Use `references/input-config.md` skill for complete parameter mapping
5. **Args**: Use `references/args-config.md` skill for mapping inputs to step function args
6. **Steps**: Use `references/step-function-request.md` (REST/GraphQL) or `connector-patterns/references/tricky-handling.md` (SOAP)
7. **Expressions**: Read `connector-patterns/references/schema-vs-corpus.md`
8. **Scopes**: Read `connector-patterns/references/authentication.md` (if OAuth 2.0)
9. **Validate**: Run `stackone validate` command

**This ensures the configuration follows all Falcon schema standards and best practices.**

## Source of Truth for Configuration

**⚠️ CRITICAL: Skills are the primary source of truth — always follow skill documentation first.**

### Rule: Skill First, Connectors Second

When writing any YAML configuration:

1. **Always consult the relevant skill first** (`auth-oauth2`, `connector-patterns`, `step-function-request`, etc.)
   - The skill defines the correct field names, structure, and patterns
   - The skill examples are the canonical reference

2. **Only look at existing connectors when:**
   - The skill documentation is ambiguous or incomplete for a specific case
   - You need to verify that a field passes `stackone validate` in a real connector
   - You encounter a validation error and need to cross-check the schema in practice

3. **Do NOT use existing connectors as a template** — copy from the skill, not from other connectors. Existing connectors may use outdated patterns or workarounds that the skill docs have since superseded.

**Example**: If `auth-oauth2.md` shows `grantType: authorization_code` as a top-level field on the `oauth2` block, use that — don't copy `tokenParams.grant_type` from another connector's `authorization` block just because you found it there.

## Next Steps
After this skill:
1. Run the auth gate loop until it exits 0:
   `node ${CLAUDE_PLUGIN_ROOT}/scripts/gates/auth.js --provider {{provider}} --connector-path <dir>`
2. Begin adding more actions (via `build-actions.md`)

## Context Compacting

**Preserve:** Current step, files created, validation status
**Resume from:** Check created files and continue

---
