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
29 changes: 29 additions & 0 deletions openespi-common/.claude/commands/commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
description: Generate and create commit from staged changes
allowed-tools: Bash(git add:*), Bash(git diff:*), Bash(git log:*), Bash(git status:*), Bash(git commit:*)
model: haiku
---

## Context
- Current branch: !`git branch --show-current`
- Commits on this branch: !`git log main..HEAD --oneline`
- Full diff from main: !`git diff main...HEAD --stat`
## Task
Generate a pull request description that includes:
1. **Summary** - One paragraph explaining what this PR does
2. **Changes** - Bullet list of key changes based on commits
3. **Testing** - How to verify these changes work
Use the commit messages to understand intent. Keep the description concise but complete.
After generating, ask if I want to create the PR with `gh pr create`.

## Context
- Current git status: !`git status`
- Staged changes: !`git diff --cached`
- Unstaged changes: !`git diff`
- Recent commits for style: !`git log --oneline -10`
## Task
Based on the staged changes, generate a conventional commit message.
Format: `type(scope): description`
Types: feat, fix, docs, style, refactor, test, chore
Match the commit style used in this repository's recent history.
After generating the message, ask if I want to commit with it.
19 changes: 19 additions & 0 deletions openespi-common/.claude/commands/fix-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: Analyze failed CI pipeline and suggest fixes
allowed-tools: Bash(gh:*), Read, Write, Edit, Grep
model: sonnet
---

## Context
- Recent workflow runs: !`gh run list --limit 5`
## Task
Analyze the most recent failed CI run and fix the issue.
**Critical: You MUST read the actual error logs before proposing any fix.**
Steps:
1. Get the failed run ID from the list above
2. Run `gh run view <run-id> --log-failed` to see actual errors
3. Analyze the root cause - not just the symptom
4. Search the codebase for relevant files
5. Implement a fix
6. Explain what failed and why your fix addresses it
Do not guess at solutions. The logs contain the answer.
5 changes: 5 additions & 0 deletions openespi-common/.claude/commands/pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
description: Generate PR description from branch commits
allowed-tools: Bash(git:*), Bash(gh:*)
model: haiku
---
19 changes: 19 additions & 0 deletions openespi-common/.claude/commands/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: Prepare a new release with version bump and changelog
allowed-tools: Bash(git:*), Bash(gh:*), Bash(npm:*), Read, Write, Edit
model: haiku
---

## Context
- Current version (package.json): !`cat package.json | grep '"version"' | head -1`
- Commits since last tag: !`git log $(git describe --tags --abbrev=0)..HEAD --oneline`
- Existing tags: !`git tag --sort=-v:refname | head -5`
## Task
Prepare a release. Ask me what version bump type: major, minor, or patch.
Then:
1. Update version in package.json
2. Generate changelog entry from commits since last tag
3. Group changes by type (Features, Fixes, Other)
4. Stage the changes
5. Ask if I want to create the git tag
Do not push or publish - just prepare locally for my review.
23 changes: 23 additions & 0 deletions openespi-common/.claude/commands/security-scan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
description: Security scan of staged changes before commit
allowed-tools: Bash(git diff:*), Read, Grep
model: sonnet
---
## Context
- Staged changes: !`git diff --cached`
- Changed files: !`git diff --cached --name-only`
## Task
Review the staged changes for security issues.
Check for:
- Hardcoded secrets, API keys, or credentials
- SQL injection vulnerabilities
- XSS attack vectors
- Insecure dependencies being added
- Authentication/authorization bypasses
- Sensitive data exposure
For each issue found:
1. File and line number
2. What the vulnerability is
3. How to fix it
If no issues found, confirm the changes are safe to commit.
Be thorough but avoid false positives on obvious non-issues.
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.JdbcTypeCode;
import org.greenbuttonalliance.espi.common.domain.common.DateTimeInterval;
import org.greenbuttonalliance.espi.common.domain.common.SummaryMeasurement;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.SqlTypes;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Objects;
import java.util.UUID;

/**
* Pure JPA/Hibernate entity for LineItem without JAXB concerns.
Expand All @@ -61,12 +60,12 @@ public class LineItemEntity {

/**
* Primary key identifier.
* LineItem extends Object (not IdentifiedObject) per ESPI 4.0 XSD (espi.xsd:1449).
*/
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@JdbcTypeCode(SqlTypes.CHAR)
@Column(length = 36, columnDefinition = "char(36)", updatable = false, nullable = false)
private UUID id;
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Long id;

/**
* Amount for this line item in currency minor units (e.g., cents).
Expand Down Expand Up @@ -100,6 +99,47 @@ public class LineItemEntity {
@Size(max = 256, message = "Note cannot exceed 256 characters")
private String note;

/**
* Relevant measurement for line item (optional).
* Per ESPI 4.0 XSD (espi.xsd:1471), extension field.
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "powerOfTenMultiplier", column = @Column(name = "measurement_multiplier")),
@AttributeOverride(name = "timeStamp", column = @Column(name = "measurement_timestamp")),
@AttributeOverride(name = "uom", column = @Column(name = "measurement_uom")),
@AttributeOverride(name = "value", column = @Column(name = "measurement_value")),
@AttributeOverride(name = "readingTypeRef", column = @Column(name = "measurement_reading_type_ref", length = 512))
})
private SummaryMeasurement measurement;

/**
* Classification of line item (required).
* Per ESPI 4.0 XSD (espi.xsd:1476), extension field.
* ItemKind enumeration values (e.g., 1=Energy Generation Fee, 2=Energy Delivery Fee, etc.)
*/
@Column(name = "item_kind", nullable = false)
@NotNull(message = "Item kind cannot be null")
private Integer itemKind;

/**
* Per unit cost (optional).
* Per ESPI 4.0 XSD (espi.xsd:1481), extension field.
*/
@Column(name = "unit_cost")
private Long unitCost;

/**
* Time period covered by the line item (optional).
* Per ESPI 4.0 XSD (espi.xsd:1486), extension field to support pricing changes mid-billing period.
*/
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "start", column = @Column(name = "item_period_start")),
@AttributeOverride(name = "duration", column = @Column(name = "item_period_duration"))
})
private DateTimeInterval itemPeriod;

// ElectricPowerUsageSummary relationship removed - deprecated resource

/**
Expand All @@ -111,33 +151,94 @@ public class LineItemEntity {
private UsageSummaryEntity usageSummary;

/**
* Constructor with basic line item information.
*
* Constructor with basic line item information (legacy, pre-ESPI 4.0 compliance).
* @deprecated Use constructor with itemKind parameter for ESPI 4.0 compliance.
*
* @param amount the amount in currency minor units
* @param dateTime the timestamp
* @param note the descriptive note
*/
@Deprecated
public LineItemEntity(Long amount, Long dateTime, String note) {
this.amount = amount;
this.dateTime = dateTime;
this.note = note;
}

/**
* Constructor with full line item information.
*
* Constructor with basic line item information and required itemKind.
*
* @param amount the amount in currency minor units
* @param dateTime the timestamp
* @param note the descriptive note
* @param itemKind the classification of the line item (required)
*/
public LineItemEntity(Long amount, Long dateTime, String note, Integer itemKind) {
this.amount = amount;
this.dateTime = dateTime;
this.note = note;
this.itemKind = itemKind;
}

/**
* Constructor with full line item information (legacy, pre-ESPI 4.0 compliance).
* @deprecated Use constructor with itemKind parameter for ESPI 4.0 compliance.
*
* @param amount the amount in currency minor units
* @param rounding the rounding adjustment
* @param dateTime the timestamp
* @param note the descriptive note
*/
@Deprecated
public LineItemEntity(Long amount, Long rounding, Long dateTime, String note) {
this.amount = amount;
this.rounding = rounding;
this.dateTime = dateTime;
this.note = note;
}

/**
* Constructor with full line item information including required itemKind.
*
* @param amount the amount in currency minor units
* @param rounding the rounding adjustment
* @param dateTime the timestamp
* @param note the descriptive note
* @param itemKind the classification of the line item (required)
*/
public LineItemEntity(Long amount, Long rounding, Long dateTime, String note, Integer itemKind) {
this.amount = amount;
this.rounding = rounding;
this.dateTime = dateTime;
this.note = note;
this.itemKind = itemKind;
}

/**
* Constructor with complete line item information including all optional fields.
*
* @param amount the amount in currency minor units
* @param rounding the rounding adjustment
* @param dateTime the timestamp
* @param note the descriptive note
* @param measurement relevant measurement for line item
* @param itemKind the classification of the line item (required)
* @param unitCost per unit cost
* @param itemPeriod time period covered by the line item
*/
public LineItemEntity(Long amount, Long rounding, Long dateTime, String note,
SummaryMeasurement measurement, Integer itemKind,
Long unitCost, DateTimeInterval itemPeriod) {
this.amount = amount;
this.rounding = rounding;
this.dateTime = dateTime;
this.note = note;
this.measurement = measurement;
this.itemKind = itemKind;
this.unitCost = unitCost;
this.itemPeriod = itemPeriod;
}

// ElectricPowerUsageSummary setter removed - deprecated resource

/**
Expand Down
Loading
Loading