You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/charges/SKILL.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,6 +65,10 @@ The generic rule is:
65
65
- type-specific service subpackages may own reusable realization mechanics when the parent service becomes too broad; keep state-machine decisions in the lifecycle files and move only mechanical operations such as rating snapshots, realization persistence, credit allocation/correction, and realization lineage persistence into these helpers
66
66
- invoice-backed charges must not reach the meta `final` state until their payment lifecycle is fully settled; if a charge is waiting on invoice payment authorization or settlement, keep it in an `active.*` detailed status instead of collapsing to `final`
67
67
68
+
Adapter rules:
69
+
70
+
- Keep Ent access transaction-aware in `openmeter/billing/charges/.../adapter`, including shared helper functions. Prefer helpers to accept the adapter/repo handle rather than a raw `*entdb.Client`, so `entutils.TransactingRepo(...)` or `entutils.TransactingRepoWithNoValue(...)` can pass the transaction-bound handle from `ctx`. If a helper must accept a raw client, only call it with the swapped handle's client, such as `tx.db` inside the transacting callback.
71
+
68
72
Important types:
69
73
70
74
-`charges.AdvanceChargesInput` identifies the customer whose charges should advance
Copy file name to clipboardExpand all lines: .agents/skills/samber-lo/SKILL.md
+27-3Lines changed: 27 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,23 +1,45 @@
1
1
---
2
2
name: samber-lo
3
-
description: Use when writing or refactoring Go code in OpenMeter that can use github.com/samber/lo helpers, especially trivial slice-to-map, map keys/values, mapping, filtering, grouping, uniqueness, set-like conversions, and map entry transformations.
3
+
description: Use when writing or refactoring Go collection/pointer helper code in OpenMeter, especially when choosing between standard library slices/maps helpers and github.com/samber/lo for cloning, copying, equality, sorting, pointer literals, slice-to-map transforms, map keys/values, mapping, filtering, grouping, uniqueness, set-like conversions, and map entry transformations.
4
4
user-invocable: true
5
5
argument-hint: "[collection transformation or lo helper question]"
Use `github.com/samber/lo` for small, local collection transformations when it makes the intent clearer than a hand-written loop. OpenMeter pins `github.com/samber/lo v1.53.0` in `go.mod`.
11
+
Use standard library collection helpers first when they express the operation directly, and use `github.com/samber/lo` for small, local collection transformations when it makes the intent clearer than a hand-written loop. OpenMeter pins `github.com/samber/lo v1.53.0` in `go.mod`.
12
12
13
-
## Default Import
13
+
## Imports
14
14
15
15
```go
16
+
import"maps"
17
+
import"slices"
16
18
import"github.com/samber/lo"
17
19
```
18
20
19
21
Do not use dot imports. Do not reach for `lo/parallel`, `lo/mutable`, or `lo/it` unless the surrounding package already uses that subpackage or the task explicitly needs it.
20
22
23
+
## Standard Library First
24
+
25
+
Prefer `slices` for operations the standard library already names clearly:
26
+
27
+
-`slices.Clone(s)` for defensive slice copies instead of `append([]T(nil), s...)`.
28
+
-`slices.Contains(s, v)` for membership checks on short or already-available slices.
29
+
-`slices.Sort`, `slices.SortFunc`, and `slices.SortStableFunc` before comparing, logging, serializing, or asserting on order.
30
+
-`slices.Equal` and `slices.EqualFunc` for equality checks.
31
+
-`slices.Concat(a, b, c)` for concatenating known slices.
32
+
-`slices.Compact` after sorting when normalizing a slice.
33
+
34
+
Prefer `maps` for direct map operations:
35
+
36
+
-`maps.Clone(m)` for defensive copies.
37
+
-`maps.Copy(dst, src)` when merging maps.
38
+
-`maps.Equal` and `maps.EqualFunc` for equality checks.
39
+
-`maps.Keys(m)` and `maps.Values(m)` when the iterator result is acceptable; collect or sort when a slice is required or order matters.
40
+
41
+
Prefer `lo.ToPtr(...)`, `lo.FromPtr(...)`, and `lo.FromPtrOr(...)` for pointer literals and pointer defaults. Avoid local wrappers such as `ptr`, `loPtr`, `must`, or `loMust`.
42
+
21
43
## Common Helpers
22
44
23
45
For slice transforms:
@@ -49,6 +71,8 @@ For map work:
49
71
50
72
Use `*Err` variants such as `MapErr`, `KeyByErr`, `GroupByMapErr`, `MapValuesErr`, or `MapToSliceErr` when the callback can fail and the first error should stop the transform.
51
73
74
+
For slice-wide invariants where the exact offending element is not important, prefer collecting distinct values with `lo.Map` plus `lo.Uniq` and validating cardinality over stateful "first seen value" loops.
75
+
52
76
## Correctness Notes
53
77
54
78
- Duplicate keys in `KeyBy`, `SliceToMap`, `MapKeys`, and `MapEntries` overwrite earlier entries; the last value wins.
Copy file name to clipboardExpand all lines: .coderabbit.yaml
+6-1Lines changed: 6 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -58,8 +58,13 @@ reviews:
58
58
instructions: |
59
59
Make sure the tests are comprehensive and cover the changes. Keep a strong focus on unit tests and in-code integration tests.
60
60
When appropriate, recommend e2e tests for critical changes.
61
-
61
+
62
62
Do not request additional tests only because a helper or fixture could also cover an override/base-layer variant. Suggest missing tests only when the PR introduces behavior without meaningful coverage, or when the current tests would pass despite a concrete regression in the changed code.
63
+
- path: ".agents/skills/**/SKILL.md"
64
+
instructions: |
65
+
Review skills for clarity, durable guidance, and domain correctness.
66
+
Do not request additions for issues that the compiler or normal toolchain will detect, such as Go generic type constraints or missing imports, unless the skill text is actively misleading in a way compilation would not catch.
67
+
Prefer comments only when the skill would teach the wrong durable practice or omit non-obvious project-specific context.
63
68
- path: "**/*.md"
64
69
instructions: |
65
70
"Assess the documentation for misspellings, grammatical errors, missing documentation and correctness"
Copy file name to clipboardExpand all lines: AGENTS.md
+21-24Lines changed: 21 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,8 +17,11 @@ The committed `.nvmrc` is the GitHub Actions source of truth for Node-based jobs
17
17
## AGENTS.md maintenance
18
18
19
19
- Treat this file as long-lived project guidance for all agents and contributors.
20
+
- Treat AGENTS.md as the repo-local source of truth. Do not bypass coding style, workflow, testing, or documentation guidance in this file. If a requested change appears to conflict with AGENTS.md, ask the human developer/reviewer to confirm the exception before proceeding, and make the exception explicit in the handoff.
20
21
- Prefer durable wording over time-based wording (avoid labels like "recent", "latest", "today").
21
22
- Keep entries actionable and specific (what to do, where, and why), not conversational history.
23
+
- Capture universal truths and cross-cutting coding conventions here when they become repeated practice or reviewer expectation. Do not leave them only in chat or pull request comments.
24
+
- Capture subsystem-specific guidance in the closest applicable nested `AGENTS.md` when the guidance should always apply to a subtree, such as `api/spec/AGENTS.md` for TypeSpec and SDK guidance. Use skills for reusable workflows or domain procedures that agents opt into for a task. Skills must stay usable by both Claude and Codex: write them as plain repo guidance, keep `.agents/skills` as the source of truth, and avoid assistant-specific assumptions unless a workflow truly requires them.
22
25
- When adding new guidance, fold it into the most relevant section and remove/merge stale or duplicate notes.
23
26
24
27
## Testing
@@ -94,8 +97,6 @@ The TypeSpec JS client emitted from `api/spec/packages/aip` now lands in `api/sp
94
97
95
98
The emitted `api/spec/packages/aip-client-javascript/src/openMeterClient.ts` exposes aggregated sub-client getters on `OpenMeterClient` (e.g. `meters`, `customers`, `features`, `productCatalog`, `subscriptions`, `billing`, `entitlements`). Access operations through those getters, e.g. `sdk.meters.list()`, `sdk.customers.create(...)`, `sdk.productCatalog.createPlan(...)`. Note that resources are grouped by tag, so some operations live under a grouped client rather than a same-named top-level getter (for example plan operations are `sdk.productCatalog.createPlan`, not `sdk.plans.create`).
96
99
97
-
When adding query decorators (for example `@query`) to a TypeSpec file that does not already use HTTP decorators, import `@typespec/http` and add `using TypeSpec.Http;` in that file; otherwise compilation fails with `Unknown decorator @query`.
98
-
99
100
**Workflow for changing Go types/DI:**
100
101
101
102
1. Edit the source files (ent schema, wire.go, converter interfaces)
@@ -212,33 +213,29 @@ All builds use `GO_BUILD_FLAGS=-tags=dynamic`.
212
213
213
214
See the `/service` skill for service/adapter patterns, constructors, input types, errors, transactions, hooks, logging, multi-tenancy, and DI wiring. See the `/api` skill for HTTP handler patterns and ValidationIssue. See the `/ent` skill for Ent ORM patterns and Postgres type gotchas. See the `/ledger` skill for ledger package architecture, wiring, and testing. See the `/subscription` skill for subscription domain model, sync algorithm, patch system, workflow layer, and addon sub-system. See the `/notification` skill for notification event pipeline, Kafka consumers, Svix webhook delivery, reconciliation loop, and payload versioning.
214
215
215
-
Do not extract helper functions only to hide a couple of simple operations or short guard checks. If the helper would only wrap 2-4 lines and its name does not add meaningful domain or business intent, keep the code inline even when there is some duplication. Readers can inspect the function body to see what the code does; prefer function names that explain the domain reason for the call over names that merely restate the implementation steps. When you encounter a leftover pass-through wrapper that only calls another function without adding behavior, remove it and call the underlying function directly, even if it is outside the immediate change area.
216
-
217
-
For `Validate() error` methods, prefer collecting all validation issues into `var errs []error` and returning `models.NewNillableGenericValidationError(errors.Join(errs...))` instead of returning on the first invalid field. Preserve field context with wrapped errors like `fmt.Errorf("field: %w", err)` and use plain `errors.New(...)` for simple local checks.
218
-
219
-
In `openmeter/billing/charges/.../adapter`, keep Ent access transaction-aware even in shared helper functions. If a helper accepts a raw `*entdb.Client`, still wrap its body with `entutils.TransactingRepo(...)` / `TransactingRepoWithNoValue(...)` so it rebinds to the transaction already carried in `ctx` instead of depending on the caller to pass a tx-specific client.
220
-
221
-
Do not introduce `context.Background()` or `context.TODO()` to sidestep missing context propagation in application code. Either propagate the caller's context through the full call path, or remove the unused `context.Context` parameter from the API if the operation is purely local and does not need cancellation, deadlines, or request-scoped values.
222
-
223
-
Never use `panic` in non-test code paths. If a new failure mode is possible, change the function signature to return an error and propagate it explicitly.
224
-
225
-
In production constructors and initialization, do not use `slog.Default()` as a fallback dependency. Require a `*slog.Logger` in config/provider inputs and inject it explicitly.
226
-
227
-
Prefer standard library helpers and existing dependencies over local wrappers: use `slices.Clone(s)` for defensive slice copies instead of `append([]T(nil), s...)`; use `lo.ToPtr(...)` for pointer literals; and use `lo.Must(...)` only for `(value, err)` flows where panic-on-failure is intentional in test setup. Do not add local wrappers such as `ptr`, `loPtr`, `must`, or `loMust` when `github.com/samber/lo` already covers the need.
228
-
229
-
Keep helper functions honest and narrow. If a production helper is only called once and is just a short guard or a few straightforward lines, inline it unless the name carries meaningful domain semantics. Do not add helpers for trivial single-use struct literals, do not hide aggregate mutation inside construction helpers, and return the domain value a helper actually builds rather than a broader wrapper needed by one caller.
216
+
For TypeSpec-specific coding constraints, update `api/spec/AGENTS.md` instead of adding them here.
230
217
231
-
Prefer explicit input structs for helpers that combine an aggregate with derived lifecycle values, such as period or timestamp overrides. This makes it clear which fields are construction inputs and which fields are persisted aggregate state.
218
+
### Documentation Constraints
232
219
233
-
For files and functions that convert between domain, API, and DB representations, use the `/go-types-conversion` skill. In prose, prefer `map` / `mapped` terminology for domain representation translation and avoid `project` / `projected` for that meaning; function names must still follow the skill's `FromAPI...`, `ToAPI...`, `FromDB...`, and `ToDB...` conventions.
220
+
- When adding comments or docstrings, document intent and domain constraints that are only available from human author context, not facts a reader can infer by reading the codebase. Avoid comments that merely translate obvious conditions, such as saying that a branch runs when `servicePeriod > 0`. A good comment should be understandable without the author's chat context and should explain why the code deliberately includes or excludes a case.
221
+
- Add a docstring to domain helpers when the name compresses important business semantics that are easy to misread at call sites. Explain the observable business contract and why excluded cases are excluded, not the implementation mechanics.
222
+
- When refactoring or reverting code, preserve existing explanatory comments by default. Remove or rewrite a comment only when the code change makes it false, stale, or misleading.
234
223
235
-
Add a docstring to domain helpers when the name compresses important business semantics that are easy to misread at call sites. Explain the observable business contract and why excluded cases are excluded, not the implementation mechanics.
224
+
### Go Style Constraints
236
225
237
-
When refactoring or reverting code, preserve existing explanatory comments by default. Remove or rewrite a comment only when the code change makes it false, stale, or misleading.
226
+
- For Go string enum constants, name values as `<Type><Value>` so the constant carries its enum type at the use site, for example `InvoiceStatusDraft` instead of `Draft`.
227
+
- Do not extract helper functions only to hide a couple of simple operations or short guard checks. If the helper would only wrap 2-4 lines and its name does not add meaningful domain or business intent, keep the code inline even when there is some duplication. Readers can inspect the function body to see what the code does; prefer function names that explain the domain reason for the call over names that merely restate the implementation steps. When you encounter a leftover pass-through wrapper that only calls another function without adding behavior, remove it and call the underlying function directly, even if it is outside the immediate change area.
228
+
- For `Validate() error` methods, prefer collecting all validation issues into `var errs []error` and returning `models.NewNillableGenericValidationError(errors.Join(errs...))` instead of returning on the first invalid field. Preserve field context with wrapped errors like `fmt.Errorf("field: %w", err)` and use plain `errors.New(...)` for simple local checks.
229
+
- Do not introduce `context.Background()` or `context.TODO()` to sidestep missing context propagation in application code. Either propagate the caller's context through the full call path, or remove the unused `context.Context` parameter from the API if the operation is purely local and does not need cancellation, deadlines, or request-scoped values.
230
+
- Never use `panic` in non-test code paths. If a new failure mode is possible, change the function signature to return an error and propagate it explicitly.
231
+
- In production constructors and initialization, do not use `slog.Default()` as a fallback dependency. Require a `*slog.Logger` in config/provider inputs and inject it explicitly.
232
+
- Prefer standard library `slices` and `maps` helpers for common collection operations, and use `github.com/samber/lo` when it makes pointer literals or collection transformations clearer than local wrappers or hand-written loops. See the `/samber-lo` skill for common OpenMeter use cases and caveats. Do not add local wrappers such as `ptr`, `loPtr`, `must`, or `loMust` when standard helpers or `lo` already cover the need.
233
+
- Keep helper functions honest and narrow. If a production helper is only called once and is just a short guard or a few straightforward lines, inline it unless the name carries meaningful domain semantics. Do not add helpers for trivial single-use struct literals, do not hide aggregate mutation inside construction helpers, and return the domain value a helper actually builds rather than a broader wrapper needed by one caller.
234
+
- For files and functions that convert between domain, API, and DB representations, use the `/go-types-conversion` skill. In prose, prefer `map` / `mapped` terminology for domain representation translation and avoid `project` / `projected` for that meaning; function names must still follow the skill's `FromAPI...`, `ToAPI...`, `FromDB...`, and `ToDB...` conventions.
238
235
239
-
For slice-wide invariants where the exact offending element is not important, prefer collecting distinct values with `lo.Map` + `lo.Uniq` and validating cardinality over stateful "first seen value" loops.
236
+
### Generation And Dependency Constraints
240
237
241
-
When `make generate` or `atlas migrate --env local diff ...` adds incidental `go.sum` entries, such as `tablewriter`, drop those `go.sum` changes unless the task explicitly requires a dependency change.
238
+
-When `make generate` or `atlas migrate --env local diff ...` adds incidental `go.sum` entries, such as `tablewriter`, drop those `go.sum` changes unless the task explicitly requires a dependency change.
242
239
243
240
## Key Dependencies
244
241
@@ -313,4 +310,4 @@ Initialize it with `codegraph init -i` before doing code exploration. It indexes
313
310
314
311
## Skills
315
312
316
-
Skills are created inside [.agents/skills](.agents/skills/) by default and then symlinked to [.claude/skills](.claude/skills). Make sure you always treat `.agents/skills` as the source of truth.
313
+
Skills are created inside [.agents/skills](.agents/skills/) by default and then symlinked to [.claude/skills](.claude/skills). Make sure you always treat `.agents/skills` as the source of truth. Keep skill guidance compatible with both Claude and Codex; avoid instructions that assume only one agent runtime unless the skill is explicitly about that runtime.
0 commit comments