Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Claude Instructions for openapi-starter

## Branch Management

**IMPORTANT:** Always create a new branch before making any changes to the codebase.

### Branch Naming Convention
- Feature branches: `feature/<description>`
- Bug fixes: `fix/<description>`
- Documentation: `docs/<description>`
- CI/CD changes: `ci/<description>`

### Workflow
1. **Before making changes:** Create a new branch from main
```bash
git checkout main
git pull
git checkout -b <branch-type>/<description>
```

2. **After changes:** Commit and push to the feature branch
```bash
git add <files>
git commit -m "type: description"
git push -u origin <branch-name>
```

3. **Create PR:** Use `gh pr create` with descriptive title and body

4. **After merge:** Delete the feature branch
```bash
git checkout main
git pull
git branch -d <branch-name>
```

## OpenAPI Development

### File Organization
- Main spec: `openapi/openapi.yaml`
- Schemas: `openapi/components/schemas/`
- Paths: `openapi/paths/`
- Parameters: `openapi/components/parameters/`
- Responses: `openapi/components/responses/`

### Testing Changes
Always run these commands before committing:
```bash
npm test # Lint the OpenAPI spec
npm run build # Build HTML documentation
npm start # Preview docs locally
```

### Examples
- Use resource-specific examples inline in path files
- Base examples on real ESPI sample data when available
- Use `data.greenbuttonconnect.org` as the host for all example URLs
- Follow ESPI/Atom XML formatting conventions from ~/.claude/CLAUDE.md

## Commit Message Format

Follow conventional commits:
- `feat:` New features
- `fix:` Bug fixes
- `docs:` Documentation changes
- `ci:` CI/CD changes
- `chore:` Maintenance tasks

Always include:
```
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
```

## Deployment

- CI/CD automatically runs on all PRs and pushes to main
- GitHub Pages deploys automatically on main branch pushes
- Documentation URL: https://greenbuttonalliance.github.io/openapi-starter/
57 changes: 57 additions & 0 deletions openapi/components/responses/AtomEntry_ApplicationInformation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
description: >-
OK - Returns an Atom entry wrapping a single ApplicationInformation resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
ApplicationInformationEntry:
summary: An ApplicationInformation entry for a registered Third Party Application
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:af6e8b01-3c52-5d19-84a3-7f2e9d4b6c08</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ApplicationInformation/247931" type="espi-entry/ApplicationInformation"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ApplicationInformation" type="espi-feed/ApplicationInformation"/>
<published>2023-10-20T17:32:35.448812Z</published>
<updated>2023-10-20T17:33:23.054424Z</updated>
<title>ApplicationInformation</title>
<content>
<ApplicationInformation xmlns="http://naesb.org/espi">
<dataCustodianId>DATA_CUSTODIAN_001</dataCustodianId>
<dataCustodianApplicationStatus>3</dataCustodianApplicationStatus>
<thirdPartyApplicationDescription>Energy analytics platform for residential customers</thirdPartyApplicationDescription>
<thirdPartyApplicationStatus>3</thirdPartyApplicationStatus>
<thirdPartyApplicationType>1</thirdPartyApplicationType>
<thirdPartyApplicationUse>1</thirdPartyApplicationUse>
<thirdPartyPhone>555-123-4567</thirdPartyPhone>
<authorizationServerUri>https://data.greenbuttonconnect.org/DataCustodian</authorizationServerUri>
<thirdPartyNotifyUri>https://thirdparty.example.com/espi/1_1/Notification</thirdPartyNotifyUri>
<authorizationServerAuthorizationEndpoint>https://data.greenbuttonconnect.org/DataCustodian/oauth/authorize</authorizationServerAuthorizationEndpoint>
<authorizationServerRegistrationEndpoint>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/register</authorizationServerRegistrationEndpoint>
<authorizationServerTokenEndpoint>https://data.greenbuttonconnect.org/DataCustodian/oauth/token</authorizationServerTokenEndpoint>
<dataCustodianBulkRequestURI>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Batch/Bulk</dataCustodianBulkRequestURI>
<dataCustodianResourceEndpoint>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource</dataCustodianResourceEndpoint>
<client_secret>secret_abcdef123456</client_secret>
<logo_uri>https://thirdparty.example.com/logo.png</logo_uri>
<client_name>GreenEnergy Analytics</client_name>
<client_uri>https://thirdparty.example.com</client_uri>
<redirect_uri>https://thirdparty.example.com/espi/1_1/OAuthCallBack</redirect_uri>
<client_id>third_party_247931</client_id>
<tos_uri>https://thirdparty.example.com/tos</tos_uri>
<policy_uri>https://thirdparty.example.com/privacy</policy_uri>
<software_id>GreenEnergy_Analytics</software_id>
<software_version>2.1.0</software_version>
<client_id_issued_at>1697823155</client_id_issued_at>
<client_secret_expires_at>0</client_secret_expires_at>
<contacts>admin@thirdparty.example.com</contacts>
<token_endpoint_auth_method>client_secret_basic</token_endpoint_auth_method>
<scope>FB=1_3_4_5_8_13_14_15_18_19_31_32_33_34_35_37_39;IntervalDuration=900;BlockDuration=monthly;HistoryLength=13</scope>
<grant_types>authorization_code</grant_types>
<grant_types>client_credentials</grant_types>
<grant_types>refresh_token</grant_types>
<response_types>code</response_types>
<registration_client_uri>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ApplicationInformation/247931</registration_client_uri>
<registration_access_token>reg_token_d4e5f6a7b8c9</registration_access_token>
</ApplicationInformation>
</content>
</entry>
38 changes: 38 additions & 0 deletions openapi/components/responses/AtomEntry_Authorization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
description: >-
OK - Returns an Atom entry wrapping a single Authorization resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
AuthorizationEntry:
summary: An Authorization entry with active OAuth 2.0 authorization details
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:b3c7d1e5-4a98-5f26-8b03-1d5e7f9a2c46</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Authorization/407593" type="espi-entry/Authorization"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Authorization" type="espi-feed/Authorization"/>
<published>2023-10-20T17:32:35.448812Z</published>
<updated>2023-10-20T17:33:23.054424Z</updated>
<title>Authorization</title>
<content>
<Authorization xmlns="http://naesb.org/espi">
<authorizedPeriod>
<duration>31536000</duration>
<start>1697823155</start>
</authorizedPeriod>
<publishedPeriod>
<duration>31536000</duration>
<start>1697823155</start>
</publishedPeriod>
<status>1</status>
<expires_at>1729359155</expires_at>
<grant_type>authorization_code</grant_type>
<scope>FB=1_3_4_5_8_13_14_15_18_19_31_32_33_34_35_37_39;IntervalDuration=900;BlockDuration=monthly;HistoryLength=13</scope>
<token_type>Bearer</token_type>
<resourceURI>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593</resourceURI>
<authorizationURI>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Authorization/407593</authorizationURI>
<customerResourceURI>https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Batch/RetailCustomer/618934/UsagePoint</customerResourceURI>
</Authorization>
</content>
</entry>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
description: >-
OK - Returns an Atom entry wrapping a single ElectricPowerQualitySummary
resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
ElectricPowerQualitySummaryEntry:
summary: An ElectricPowerQualitySummary entry with power quality event data for a billing period
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:d4e5f6a7-b8c9-5d01-e2f3-a4b5c6d7e8f9</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/ElectricPowerQualitySummary/328475" type="espi-entry/ElectricPowerQualitySummary"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/ElectricPowerQualitySummary" type="espi-feed/ElectricPowerQualitySummary"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246" type="espi-entry/UsagePoint"/>
<published>2023-10-20T17:32:35.448812Z</published>
<updated>2023-10-20T17:33:23.054424Z</updated>
<title>ElectricPowerQualitySummary</title>
<content>
<ElectricPowerQualitySummary xmlns="http://naesb.org/espi">
<flickerPlt>1</flickerPlt>
<flickerPst>2</flickerPst>
<harmonicVoltage>3</harmonicVoltage>
<longInterruptions>0</longInterruptions>
<mainsVoltage>240100</mainsVoltage>
<measurementProtocol>2</measurementProtocol>
<powerFrequency>600</powerFrequency>
<rapidVoltageChanges>0</rapidVoltageChanges>
<shortInterruptions>2</shortInterruptions>
<summaryInterval>
<duration>2592000</duration>
<start>1693540800</start>
</summaryInterval>
<supplyVoltageDips>1</supplyVoltageDips>
<supplyVoltageImbalance>0</supplyVoltageImbalance>
<supplyVoltageVariations>3</supplyVoltageVariations>
<tempOvervoltage>0</tempOvervoltage>
</ElectricPowerQualitySummary>
</content>
</entry>
35 changes: 35 additions & 0 deletions openapi/components/responses/AtomEntry_IntervalBlock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
description: >-
OK - Returns an Atom entry wrapping a single IntervalBlock resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
IntervalBlockEntry:
summary: An IntervalBlock entry with a single IntervalReading
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:1e530409-5dbe-572f-aad8-fa06f6a68cfc</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading/Ba020673_kwh_1/IntervalBlock/000001" type="espi-entry/IntervalBlock"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading/Ba020673_kwh_1/IntervalBlock" type="espi-feed/IntervalBlock"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading/Ba020673_kwh_1" type="espi-feed/MeterReading"/>
<published>2023-10-20T17:32:44.801089Z</published>
<updated>2023-10-20T17:32:44.801089Z</updated>
<title>IntervalBlock</title>
<content>
<IntervalBlock xmlns="http://naesb.org/espi">
<interval>
<duration>2332800</duration>
<start>1663992000</start>
</interval>
<IntervalReading>
<cost>115780000</cost>
<timePeriod>
<duration>2332800</duration>
<start>1663992000</start>
</timePeriod>
<value>1330890000</value>
</IntervalReading>
</IntervalBlock>
</content>
</entry>
26 changes: 26 additions & 0 deletions openapi/components/responses/AtomEntry_LocalTimeParameters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
description: >-
OK - Returns an Atom entry wrapping a single LocalTimeParameters resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
LocalTimeParametersEntry:
summary: A LocalTimeParameters entry with US Eastern timezone DST rules
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:305129b8-503c-5b50-b293-333cd7fb6adf</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/LocalTimeParameters/TIMEZONE_407593_1455246" type="espi-entry/LocalTimeParameters"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/LocalTimeParameters" type="espi-feed/LocalTimeParameters"/>
<published>2023-10-20T17:32:35.448812Z</published>
<updated>2023-10-20T17:33:23.054424Z</updated>
<title>LocalTimeParameters</title>
<content>
<LocalTimeParameters xmlns="http://naesb.org/espi">
<dstEndRule>B40E2000</dstEndRule>
<dstOffset>3600</dstOffset>
<dstStartRule>360E2000</dstStartRule>
<tzOffset>-18000</tzOffset>
</LocalTimeParameters>
</content>
</entry>
24 changes: 24 additions & 0 deletions openapi/components/responses/AtomEntry_MeterReading.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
description: >-
OK - Returns an Atom entry wrapping a single MeterReading resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
MeterReadingEntry:
summary: A MeterReading entry with empty content and related links
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:6052217b-aadf-5cca-b803-c611f9fcf89e</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading/Ba020673_kwh_1" type="espi-entry/MeterReading"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading" type="espi-feed/MeterReading"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246" type="espi-entry/UsagePoint"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading/Ba020673_kwh_1/IntervalBlock" type="espi-feed/IntervalBlock"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ReadingType/407593_1455246_Ba020673_kwh_1" type="espi-entry/ReadingType"/>
<published>2023-10-20T17:32:44.801089Z</published>
<updated>2023-10-20T17:32:44.801089Z</updated>
<title>MeterReading</title>
<content>
<MeterReading xmlns="http://naesb.org/espi"/>
</content>
</entry>
31 changes: 31 additions & 0 deletions openapi/components/responses/AtomEntry_ReadingType.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
description: >-
OK - Returns an Atom entry wrapping a single ReadingType resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
ReadingTypeEntry:
summary: A ReadingType entry for monthly kWh electricity consumption
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:06ff0942-04fc-5f91-bc35-ca5e51b49dbb</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ReadingType/407593_1455246_Ba020673_kwh_1" type="espi-entry/ReadingType"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/ReadingType" type="espi-feed/ReadingType"/>
<published>2023-10-20T17:32:44.801089Z</published>
<updated>2023-10-20T17:32:44.801089Z</updated>
<title>ReadingType</title>
<content>
<ReadingType xmlns="http://naesb.org/espi">
<accumulationBehaviour>1</accumulationBehaviour>
<commodity>1</commodity>
<currency>840</currency>
<flowDirection>1</flowDirection>
<intervalLength>2332800</intervalLength>
<kind>12</kind>
<phase>0</phase>
<powerOfTenMultiplier>-3</powerOfTenMultiplier>
<uom>72</uom>
</ReadingType>
</content>
</entry>
29 changes: 29 additions & 0 deletions openapi/components/responses/AtomEntry_UsagePoint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
description: >-
OK - Returns an Atom entry wrapping a single UsagePoint resource.
content:
application/atom+xml:
schema:
$ref: '../schemas/AtomEntry.yaml'
examples:
UsagePointEntry:
summary: A UsagePoint entry for an electricity service
value: |
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:e6896122-a094-5d30-be14-e44544247e14</id>
<link rel="self" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246" type="espi-entry/UsagePoint"/>
<link rel="up" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint" type="espi-feed/UsagePoint"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/MeterReading" type="espi-feed/MeterReading"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/UsageSummary" type="espi-feed/UsageSummary"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/Subscription/407593/UsagePoint/1455246/ElectricPowerQualitySummary" type="espi-feed/ElectricPowerQualitySummary"/>
<link rel="related" href="https://data.greenbuttonconnect.org/DataCustodian/espi/1_1/resource/LocalTimeParameters/TIMEZONE_407593_1455246" type="espi-entry/LocalTimeParameters"/>
<published>2023-10-20T17:32:35.448812Z</published>
<updated>2023-10-20T17:33:23.054424Z</updated>
<title>UsagePoint</title>
<content>
<UsagePoint xmlns="http://naesb.org/espi">
<ServiceCategory>
<kind>0</kind>
</ServiceCategory>
</UsagePoint>
</content>
</entry>
Loading