Skip to content

Example: SOAP service contract document

contracts/<contract-slug>.md documents one WCF service class and every operation it exposes. Doc gen produces one per service contract at docs/services/<service-slug>/contracts/<contract-slug>.md: an identity table for the class, then one H2 section per operation naming its SOAP action, input and output messages, faults, authorization, side effects, and an example message, closed by a coverage checklist.

What reviewers should check

  • A SOAP operation is named by its contract. No HTTP verb, route template, query string, or status code appears in any section; the SOAP action URI is the operation's address.
  • The identity table's Declared contract row matches the index page's Contract assembly row. Here the interface is in the repository, so contract names and SOAP actions are observable. When the interface is external, those cells read "Not observable - contract assembly is external", undeclared members carry the dagger marker, and no [OperationContract(Name = ...)] override or [FaultContract] is invented.
  • SOAP action URIs follow from the contract: service namespace, contract name, and operation name. A namespace left at the template default (http://tempuri.org/) is a tech-debt finding, not an identity.
  • Every public member of the class appears in the coverage checklist, in declaration order. A section with no row, or a row with no section, fails the coverage gate. A public member that is not part of the contract, such as the constructor here, still gets a row with the reason in place of the link.
  • The Pattern row says "One-way" only for IsOneWay = true, and a one-way operation has no response envelope and no output members. Faults for a one-way operation are not surfaced to the caller, and the page says so.
  • "No fault contract is declared for this operation" is a real, expected finding. A typed fault, as on SubmitClaim, is listed only because [FaultContract] is declared on the interface member.
  • Authorization is the check actually in the code. GetClaimStatus records "None in code" even though the binding authenticates the caller.
  • Every business rule is cited as a link, never a bare BR- identifier, and the Process cell links the operation page or reads -.
  • Example envelopes are composed from the observed namespace, the parameter names, and the data contract members in the order the serializer emits them.
  • Links to root pages carry the ../ prefix because the page lives in contracts/, and ## Related documentation lists root pages only.

Example

The document below is a complete, correct service-contract-document.md for a fictional WCF service class.

View rendered example — the same document as a real page, so you can compare rendering as well as source.

---
title: ClaimIntake
summary: Operations exposed by the ClaimIntake WCF service class for claim submission, intake status, and review flagging.
status: draft
owner: Claims Systems Team
last_reviewed: 2026-09-10
---

# ClaimIntake

`ClaimIntake` is the WCF service class that lets SAIF's internal applications submit a first report of injury, read the intake status of a submitted claim, and flag a submitted claim for manual review. It is called by the claims portal and by the `SAIF.Claims.Intake.Client` proxy package.

| Field | Value |
| --- | --- |
| **Service class** | `ClaimIntake` |
| **Declared contract** | `IClaimIntake` - In repository (`src/SAIF.Claims.Intake.Service/IClaimIntake.cs`) |
| **Route** | `ClaimIntake.svc` |
| **Source** | `src/SAIF.Claims.Intake.Service/ClaimIntake.svc.cs` |
| **Service attributes** | `[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]`, `[LogErrorBehavior]` |
| **Instancing / concurrency** | `InstanceContextMode.PerCall` / `ConcurrencyMode.Single` |
| **Binding** | `basicHttpBinding` (`ClaimIntakeBasic`) |
| **Class-level authorization** | None in code |
| **Error handling** | `ClaimIntakeErrorHandler` installed by `[LogErrorBehavior]` - see [Faults and error pipeline](../faults.md) |
| **Operations** | 3 |
| **Also hosted in** | - |

---

## SubmitClaim

Records a first report of injury and returns a receipt carrying the assigned claim number.

| Field | Value |
| --- | --- |
| **Operation name** | `SubmitClaim` |
| **Contract name** | `SubmitClaim` |
| **SOAP action** | `http://services.saif.example/claims/intake/v1/ClaimIntake/SubmitClaim` |
| **Implementing member** | `ClaimIntake.SubmitClaim` (`src/SAIF.Claims.Intake.Service/ClaimIntake.svc.cs:44`) |
| **Pattern** | Request/response |
| **Binding** | `basicHttpBinding` (`ClaimIntakeBasic`) |
| **Authorization** | [`SAIF\ClaimsIntakeSubmitters` role](../authentication-authorization.md#submitter-role-requirement) |
| **Process** | [OP-001](../operations/submit-claim.md) |

### Input message

| Part | Type | Required | Default | Purpose |
| --- | --- | --- | --- | --- |
| `submission` | `ClaimSubmission` | Yes | - | The first report of injury being submitted |

#### Complex input types

| Type | Kind | Members | Declared in |
| --- | --- | --- | --- |
| `ClaimSubmission` | Data contract | `BodyPartCode`, `ClaimantContact`, `ClaimantFirstName`, `ClaimantLastName`, `EmployerPolicyNumber`, `InjuryDate`, `InjuryDescription` | `src/SAIF.Claims.Intake.Service/DataContracts/ClaimSubmission.cs` |
| `ClaimantContact` | Data contract | `Email`, `Phone` | `src/SAIF.Claims.Intake.Service/DataContracts/ClaimantContact.cs` |

### Output message

| Field | Value |
| --- | --- |
| **Return type** | `ClaimReceipt` |
| **Meaning** | Confirmation that intake accepted the report, carrying the assigned claim number |
| **Empty-result behavior** | Never empty: on success the receipt is always populated, and on failure the operation throws instead of returning null |

| Member | Type | Nullable | Purpose |
| --- | --- | --- | --- |
| `ClaimNumber` | `string` | No | The claim number assigned by intake, or the existing number when the submission is a duplicate |
| `IsDuplicate` | `bool` | No | True when an earlier submission matched and no new record was written ([BR-CLM-003](../business-rules.md#br-clm-003-duplicate-submission-returns-original-receipt)) |
| `ReceivedUtc` | `DateTime` | No | When intake accepted the original submission |
| `Status` | `string` | No | The intake status at the time of the call, always `Received` on a first submission |

### Faults

| Fault | Declared | Raised when | Surfaced as | Detail crosses the boundary |
| --- | --- | --- | --- | --- |
| `ClaimValidationFault` | `[FaultContract(typeof(ClaimValidationFault))]` | The injury date is in the future ([BR-CLM-001](../business-rules.md#br-clm-001-injury-date-not-in-future)) or the employer policy is not active on the injury date ([BR-CLM-002](../business-rules.md#br-clm-002-policy-active-on-injury-date)) | Typed SOAP fault | Yes |
| `OracleException` | Not declared | The `PKG_CLAIM_INTAKE.INSERT_CLAIM` call fails | Generic SOAP fault produced by WCF through the error pipeline | No |

### Authorization

`SubmitClaim` carries `[PrincipalPermission(SecurityAction.Demand, Role = @"SAIF\ClaimsIntakeSubmitters")]`, so a caller outside that Windows group is rejected before the method body runs. See the [Submitter role requirement](../authentication-authorization.md#submitter-role-requirement) section of [Authentication and authorization](../authentication-authorization.md).

### Side effects

| Aspect | Finding |
| --- | --- |
| Records written | `CLM.CLAIM_INTAKE` ([data model](../data-model.md#clm.claim_intake)) |
| Downstream calls | `PKG_CLAIM_INTAKE.INSERT_CLAIM` (Oracle stored procedure) |
| Files or messages produced | None |
| Shared state touched | None |
| Repeat-call behavior | A second submission with the same policy number, claimant name, and injury date within 24 hours returns the original receipt with `IsDuplicate` set to true and writes no second record ([BR-CLM-003](../business-rules.md#br-clm-003-duplicate-submission-returns-original-receipt)) |

### Example message

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <SubmitClaim xmlns="http://services.saif.example/claims/intake/v1">
      <submission xmlns:d="http://schemas.datacontract.org/2004/07/SAIF.Claims.Intake.Service.DataContracts">
        <d:BodyPartCode>HND</d:BodyPartCode>
        <d:ClaimantContact>
          <d:Email>alex.rivera@example.com</d:Email>
          <d:Phone>503-555-0142</d:Phone>
        </d:ClaimantContact>
        <d:ClaimantFirstName>Alex</d:ClaimantFirstName>
        <d:ClaimantLastName>Rivera</d:ClaimantLastName>
        <d:EmployerPolicyNumber>PL-0048213</d:EmployerPolicyNumber>
        <d:InjuryDate>2026-09-03T00:00:00</d:InjuryDate>
        <d:InjuryDescription>Laceration to left hand while clearing a jammed conveyor.</d:InjuryDescription>
      </submission>
    </SubmitClaim>
  </soap:Body>
</soap:Envelope>
```

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <SubmitClaimResponse xmlns="http://services.saif.example/claims/intake/v1">
      <SubmitClaimResult xmlns:d="http://schemas.datacontract.org/2004/07/SAIF.Claims.Intake.Service.DataContracts">
        <d:ClaimNumber>2026-0041872</d:ClaimNumber>
        <d:IsDuplicate>false</d:IsDuplicate>
        <d:ReceivedUtc>2026-09-10T16:42:08Z</d:ReceivedUtc>
        <d:Status>Received</d:Status>
      </SubmitClaimResult>
    </SubmitClaimResponse>
  </soap:Body>
</soap:Envelope>
```

---

## GetClaimStatus

Returns the current intake status of a previously submitted claim.

| Field | Value |
| --- | --- |
| **Operation name** | `GetClaimStatus` |
| **Contract name** | `GetClaimStatus` |
| **SOAP action** | `http://services.saif.example/claims/intake/v1/ClaimIntake/GetClaimStatus` |
| **Implementing member** | `ClaimIntake.GetClaimStatus` (`src/SAIF.Claims.Intake.Service/ClaimIntake.svc.cs:88`) |
| **Pattern** | Request/response |
| **Binding** | `basicHttpBinding` (`ClaimIntakeBasic`) |
| **Authorization** | None in code |
| **Process** | - |

### Input message

| Part | Type | Required | Default | Purpose |
| --- | --- | --- | --- | --- |
| `claimNumber` | `string` | Yes | - | The claim number returned by `SubmitClaim` |

### Output message

| Field | Value |
| --- | --- |
| **Return type** | `ClaimStatusResult` |
| **Meaning** | The intake status recorded for the claim and when it last changed |
| **Empty-result behavior** | Returns null when no claim matches the claim number, and also when the lookup fails (see Swallowed failures in [Faults and error pipeline](../faults.md)) |

| Member | Type | Nullable | Purpose |
| --- | --- | --- | --- |
| `ClaimNumber` | `string` | No | The claim number that was requested |
| `LastUpdatedUtc` | `DateTime` | No | When the status last changed |
| `Status` | `string` | No | One of `Received`, `InReview`, `Accepted`, or `Denied` |
| `StatusReason` | `string` | Yes | Free-text reason recorded with the status, absent when none was entered |

### Faults

| Fault | Declared | Raised when | Surfaced as | Detail crosses the boundary |
| --- | --- | --- | --- | --- |
| `Exception` | Not declared | Any failure inside the method, including a database error | Not surfaced - the exception is caught and the operation returns null | No |

No fault contract is declared for this operation. See [Faults and error pipeline](../faults.md) for what the caller actually receives.

### Authorization

None in code. The `ClaimIntakeBasic` binding requires Windows transport authentication, so the caller is identified, but no role or permission check is made inside the method. See [Authentication and authorization](../authentication-authorization.md).

### Side effects

| Aspect | Finding |
| --- | --- |
| Records written | None |
| Downstream calls | `PKG_CLAIM_INTAKE.GET_STATUS` (Oracle stored procedure) |
| Files or messages produced | None |
| Shared state touched | None |
| Repeat-call behavior | Returns the current status each time; no state changes |

### Example message

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetClaimStatus xmlns="http://services.saif.example/claims/intake/v1">
      <claimNumber>2026-0041872</claimNumber>
    </GetClaimStatus>
  </soap:Body>
</soap:Envelope>
```

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetClaimStatusResponse xmlns="http://services.saif.example/claims/intake/v1">
      <GetClaimStatusResult xmlns:d="http://schemas.datacontract.org/2004/07/SAIF.Claims.Intake.Service.DataContracts">
        <d:ClaimNumber>2026-0041872</d:ClaimNumber>
        <d:LastUpdatedUtc>2026-09-10T16:42:08Z</d:LastUpdatedUtc>
        <d:Status>Received</d:Status>
        <d:StatusReason i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      </GetClaimStatusResult>
    </GetClaimStatusResponse>
  </soap:Body>
</soap:Envelope>
```

---

## FlagClaimForReview

Marks a submitted claim for manual review and records the reason, without returning anything to the caller.

| Field | Value |
| --- | --- |
| **Operation name** | `FlagClaimForReview` |
| **Contract name** | `FlagClaimForReview` |
| **SOAP action** | `http://services.saif.example/claims/intake/v1/ClaimIntake/FlagClaimForReview` |
| **Implementing member** | `ClaimIntake.FlagClaimForReview` (`src/SAIF.Claims.Intake.Service/ClaimIntake.svc.cs:121`) |
| **Pattern** | One-way (`IsOneWay = true`) |
| **Binding** | `basicHttpBinding` (`ClaimIntakeBasic`) |
| **Authorization** | [`SAIF\ClaimsIntakeSubmitters` role](../authentication-authorization.md#submitter-role-requirement) |
| **Process** | [OP-002](../operations/flag-claim-for-review.md) |

### Input message

| Part | Type | Required | Default | Purpose |
| --- | --- | --- | --- | --- |
| `claimNumber` | `string` | Yes | - | The claim to flag |
| `reason` | `string` | Yes | - | Why the claim needs manual review; an empty value is rejected ([BR-CLM-004](../business-rules.md#br-clm-004-review-flag-requires-reason)) |

### Output message

| Field | Value |
| --- | --- |
| **Return type** | void |
| **Meaning** | A successful send means only that the request was accepted for processing; the caller cannot learn whether the flag was recorded |
| **Empty-result behavior** | Not applicable - a one-way operation returns no message |

### Faults

| Fault | Declared | Raised when | Surfaced as | Detail crosses the boundary |
| --- | --- | --- | --- | --- |
| `OracleException` | Not declared | The `PKG_CLAIM_INTAKE.ADD_REVIEW_FLAG` call fails | Not surfaced - a one-way operation returns no message, so the failure is only logged by the error pipeline | No |

No fault contract is declared for this operation. See [Faults and error pipeline](../faults.md) for what the caller actually receives.

### Authorization

`FlagClaimForReview` carries `[PrincipalPermission(SecurityAction.Demand, Role = @"SAIF\ClaimsIntakeSubmitters")]`, the same requirement as `SubmitClaim`. See the [Submitter role requirement](../authentication-authorization.md#submitter-role-requirement) section of [Authentication and authorization](../authentication-authorization.md).

### Side effects

| Aspect | Finding |
| --- | --- |
| Records written | `CLM.CLAIM_INTAKE_NOTE` ([data model](../data-model.md#clm.claim_intake_note)) |
| Downstream calls | `PKG_CLAIM_INTAKE.ADD_REVIEW_FLAG` (Oracle stored procedure) |
| Files or messages produced | None |
| Shared state touched | None |
| Repeat-call behavior | Each call inserts another note row; duplicate flags are not detected |

### Example message

```xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <FlagClaimForReview xmlns="http://services.saif.example/claims/intake/v1">
      <claimNumber>2026-0041872</claimNumber>
      <reason>Injury description conflicts with the employer's report.</reason>
    </FlagClaimForReview>
  </soap:Body>
</soap:Envelope>
```

This operation is one-way, so there is no response envelope.

---

## Coverage checklist

| Public member | Documented section | Pattern |
| --- | --- | --- |
| `ClaimReceipt SubmitClaim(ClaimSubmission submission)` | [`SubmitClaim`](#submitclaim) | Request/response |
| `ClaimStatusResult GetClaimStatus(string claimNumber)` | [`GetClaimStatus`](#getclaimstatus) | Request/response |
| `void FlagClaimForReview(string claimNumber, string reason)` | [`FlagClaimForReview`](#flagclaimforreview) | One-way |
| `ClaimIntake()` | Not an operation - parameterless constructor, not declared on `IClaimIntake` | - |

## Related documentation
- [Index](../index.md)
- [Overview](../overview.md)
- [Architecture](../architecture.md)
- [Activation and hosting](../activation-hosting.md)
- [Operations](../operations.md)
- [Faults and error pipeline](../faults.md)
- [Authentication and authorization](../authentication-authorization.md)
- [Dependencies](../dependencies.md)
- [Configuration](../configuration.md)
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Data model](../data-model.md)
- [Operational runbook](../operational-runbook.md)
- [Tech debt](../tech-debt.md)

## Sources
- `src/SAIF.Claims.Intake.Service/ClaimIntake.svc.cs`
- `src/SAIF.Claims.Intake.Service/IClaimIntake.cs`
- `src/SAIF.Claims.Intake.Service/DataContracts/ClaimSubmission.cs`
- `src/SAIF.Claims.Intake.Service/DataContracts/ClaimantContact.cs`
- `src/SAIF.Claims.Intake.Service/DataContracts/ClaimReceipt.cs`
- `src/SAIF.Claims.Intake.Service/DataContracts/ClaimStatusResult.cs`
- `src/SAIF.Claims.Intake.Service/DataContracts/ClaimValidationFault.cs`
- `src/SAIF.Claims.Intake.Service/Web.config`