-
Notifications
You must be signed in to change notification settings - Fork 130
feat: introduce schemas #1064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: introduce schemas #1064
Conversation
WalkthroughAdds versioned ledger schema support: new Schema model, UpdatedSchema log type and migration; store methods and SQL implementation; controller APIs (UpdateSchema/GetSchema/ListSchemas) with processors, tracing, retries, and event emission; v2 HTTP endpoints and generated Go client; mocks, docs, and tests. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant API as V2 API Router
participant Ctl as Controller
participant LP as LogProcessor
participant Store
participant DB
participant Bus
rect rgb(245,248,255)
note over Client,API: Insert/update schema (POST /v2/{ledger}/schema/{version})
Client->>API: POST /v2/{ledger}/schema/{version} + body
API->>Ctl: UpdateSchema(ctx, {Version, Data})
Ctl->>LP: enqueue/process UpdateSchema
LP->>Store: InsertSchema(schema)
Store->>DB: INSERT INTO schemas ...
DB-->>Store: created_at
Store-->>LP: success
LP-->>Ctl: created log + UpdatedSchema
Ctl->>Bus: publish UpdatedSchema (async)
API-->>Client: 204 No Content
end
sequenceDiagram
autonumber
participant Client
participant API as V2 API Router
participant Ctl as Controller
participant Store
participant DB
rect rgb(245,255,245)
note over Client,API: Get schema (GET /v2/{ledger}/schema/{version})
Client->>API: GET /v2/{ledger}/schema/{version}
API->>Ctl: GetSchema(ctx, version)
Ctl->>Store: FindSchema(version)
Store->>DB: SELECT ... FROM schemas WHERE ledger=$1 AND version=$2
DB-->>Store: schema row
Store-->>Ctl: *Schema
API-->>Client: 200 OK + schema
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/api/README.md (1)
3792-3796: Document the newUPDATED_SCHEMAlog type.The enum for
V2Log.typestill lists only the four pre-existing values. With this PR we emitUPDATED_SCHEMA, so the docs should list it too to keep the API specification accurate.
🧹 Nitpick comments (2)
internal/schema.go (1)
19-24: Consider adding input validation and documenting CreatedAt handling.The constructor has a few considerations:
CreatedAt is not initialized: Given the
bun:"created_at,nullzero"tag, this appears intentional (likely DB-managed via default value or trigger). Consider adding a comment documenting this behavior.Version validation: The constructor accepts any string for
version, including empty strings. If version format matters (e.g., semver), consider adding validation.Apply this diff to add validation and documentation:
+// NewSchema creates a new Schema instance with the given version and data. +// CreatedAt will be set by the database on insert. func NewSchema(version string, data SchemaData) Schema { + if version == "" { + panic("version cannot be empty") + } return Schema{ Version: version, SchemaData: data, } }Alternatively, return an error instead of panicking for better error handling.
internal/controller/ledger/controller_with_traces.go (1)
468-489: Trace span name typo
TraceWithMetricrecords this span under"UpdatedSchema", while the method (and metric) are namedUpdateSchema. This makes the trace harder to locate and breaks naming conventions used elsewhere in this type. Please rename the operation string to"UpdateSchema"so traces stay consistent.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (7)
go.modis excluded by!**/*.modinternal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (43)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(2 hunks)internal/api/common/mocks_ledger_controller_test.go(2 hunks)internal/api/v1/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/routes.go(2 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(2 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(2 hunks)internal/controller/ledger/store_generated_test.go(2 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (28)
internal/controller/ledger/listener.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/client/models/components/v2schema.go (2)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)pkg/client/internal/utils/json.go (2)
MarshalJSON(21-115)UnmarshalJSON(117-251)
internal/storage/ledger/schema_test.go (1)
internal/schema.go (2)
NewSchema(19-24)SchemaData(8-9)
test/e2e/api_schema_test.go (5)
test/e2e/suite_test.go (1)
UseTemplatedDatabase(143-145)pkg/client/models/operations/v2createledger.go (1)
V2CreateLedgerRequest(9-13)pkg/client/models/operations/v2insertschema.go (1)
V2InsertSchemaRequest(9-15)pkg/client/models/operations/v2getschema.go (1)
V2GetSchemaRequest(9-14)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/storage/ledger/schema.go (2)
internal/controller/ledger/store.go (1)
Store(28-64)internal/schema.go (1)
Schema(11-17)
internal/log.go (2)
internal/schema.go (1)
Schema(11-17)pkg/events/message.go (1)
UpdatedSchema(76-79)
pkg/events/message.go (3)
internal/schema.go (1)
Schema(11-17)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/events.go (3)
EventApp(5-5)EventVersion(4-4)EventTypeUpdatedSchema(11-11)
internal/controller/ledger/controller_with_too_many_client_handling.go (4)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (1)
Schema(11-17)
pkg/client/models/operations/v2getschema.go (1)
pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/bus/listener.go (3)
pkg/events/message.go (2)
UpdatedSchema(76-79)NewEventUpdatedSchema(81-89)internal/schema.go (1)
Schema(11-17)pkg/events/events.go (1)
EventTypeUpdatedSchema(11-11)
internal/controller/ledger/store_generated_test.go (1)
internal/schema.go (1)
Schema(11-17)
internal/controller/ledger/controller_with_traces.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)
pkg/client/v2.go (12)
pkg/client/models/operations/v2insertschema.go (2)
V2InsertSchemaRequest(9-15)V2InsertSchemaResponse(38-40)pkg/client/models/operations/options.go (4)
Option(41-41)Options(32-39)SupportedOptionRetries(15-15)SupportedOptionTimeout(16-16)pkg/client/internal/utils/utils.go (4)
ReplaceParameters(51-60)MatchStatusCodes(71-92)ConsumeRawBody(350-360)UnmarshalJsonFromResponseBody(39-49)pkg/client/internal/utils/pathparams.go (1)
GenerateURL(19-38)pkg/client/internal/hooks/hooks.go (4)
HookContext(27-35)BeforeRequestContext(37-39)AfterErrorContext(45-47)AfterSuccessContext(41-43)pkg/client/internal/config/sdkconfiguration.go (1)
SDKConfiguration(16-25)pkg/client/internal/utils/requestbody.go (1)
SerializeRequestBody(31-42)pkg/client/internal/utils/security.go (1)
PopulateSecurity(27-92)pkg/client/internal/utils/retries.go (3)
RetryConfig(23-23)Retries(25-28)Retry(30-104)pkg/client/models/components/v2errorresponse.go (1)
V2ErrorResponse(5-9)pkg/client/models/operations/v2getschema.go (2)
V2GetSchemaRequest(9-14)V2GetSchemaResponse(30-34)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/controller/ledger/store.go (1)
internal/schema.go (1)
Schema(11-17)
internal/controller/ledger/controller.go (3)
internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (2)
Schema(11-17)SchemaData(8-9)
internal/controller/ledger/controller_default.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/log.go (2)
UpdatedSchema(373-375)Log(89-101)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/controller/ledger/store.go (1)
Store(28-64)internal/schema.go (2)
NewSchema(19-24)Schema(11-17)
pkg/client/models/operations/v2insertschema.go (1)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)
internal/controller/ledger/controller_generated_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/listener_generated_test.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/client/models/components/v2schemaresponse.go (1)
pkg/client/models/components/v2schema.go (1)
V2Schema(11-18)
internal/api/common/mocks_ledger_controller_test.go (3)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/api/v1/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/schema.go (1)
cmd/root.go (1)
Version(23-23)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/api/bulking/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/api/v2/controllers_schema_read.go (1)
internal/api/common/errors.go (1)
HandleCommonErrors(35-42)
internal/api/v2/mocks_ledger_controller_test.go (5)
internal/api/common/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/api/v2/controllers_schema_insert.go (3)
internal/schema.go (1)
SchemaData(8-9)internal/api/common/errors.go (1)
HandleCommonWriteErrors(44-55)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)
🪛 markdownlint-cli2 (0.18.1)
pkg/client/docs/sdks/v2/README.md
246-246: Hard tabs
Column: 1
(MD010, no-hard-tabs)
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
307-307: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Tests
- GitHub Check: Dirty
🔇 Additional comments (23)
pkg/client/README.md (1)
133-134: LGTM!The documentation additions for the new schema operations are clear and follow the established pattern for documenting V2 ledger operations.
internal/schema.go (1)
8-9: Verify if SchemaData is intentionally empty.The
SchemaDatastruct is currently empty, which might be a placeholder for future schema content. If this is intentional for extensibility, consider adding a comment explaining this design choice.Do you want to add schema content fields to
SchemaDatanow, or is this structure reserved for future use?internal/README.md (1)
1-1218: LGTM!This is auto-generated documentation (via gomarkdoc) that correctly reflects the new Schema-related types introduced in the codebase. The documentation is comprehensive and follows the established format.
pkg/events/events.go (1)
10-11: LGTM!The addition of
EventTypeUpdatedSchemaconstant follows the established naming pattern and integrates cleanly with the existing event types.pkg/client/docs/models/operations/v2getschemarequest.md (1)
1-9: LGTM!The documentation for
V2GetSchemaRequestis clear, complete, and includes helpful examples for both required fields.pkg/client/docs/models/components/v2schemaresponse.md (1)
1-8: LGTM!The documentation for
V2SchemaResponseis clear and correctly references theV2Schemacomponent documentation.pkg/client/docs/models/components/v2schema.md (1)
1-12: LGTM!The documentation for
V2Schemais comprehensive and provides clear descriptions and examples for all three required fields. The structure aligns well with the underlyingSchematype in the codebase.internal/api/v2/routes.go (1)
73-74: LGTM!The new schema routes follow RESTful conventions and are properly placed within the ledger middleware group for authorization and tracing.
internal/bus/listener.go (1)
28-34: LGTM!The
UpdatedSchemaimplementation correctly follows the established pattern of other listener methods, properly constructing and publishing the schema update event.internal/storage/ledger/schema_test.go (1)
14-28: LGTM!The test correctly verifies schema insertion with appropriate assertions. The use of
t.Parallel()and proper error checking follows good testing practices.pkg/client/models/components/v2schemadata.go (1)
5-7: Empty struct is expected in generated code. V2SchemaData is autogenerated by Speakeasy from the OpenAPI spec, which currently defines no properties for thedataobject; no changes required.pkg/client/models/components/v2schema.go (1)
1-50: LGTM!The generated V2Schema model follows standard patterns with proper JSON marshaling, nil-safe getters, and correct field annotations.
pkg/client/docs/models/operations/v2insertschemarequest.md (1)
1-10: LGTM!The documentation clearly describes the V2InsertSchemaRequest model with appropriate field descriptions and examples.
internal/controller/ledger/controller_with_events.go (1)
154-166: LGTM!The UpdateSchema method correctly follows the established pattern for event-emitting methods in this controller, delegating to the underlying controller and emitting events only when not in DryRun mode.
internal/api/v2/controllers_schema_read.go (1)
13-26: LGTM!The readSchema handler correctly extracts the version parameter, fetches the schema, and handles errors appropriately with proper 404 responses for not found cases.
internal/controller/ledger/store.go (1)
48-49: LGTM!The InsertSchema and FindSchema methods properly extend the Store interface to support schema persistence and retrieval functionality.
test/e2e/api_schema_test.go (1)
1-108: LGTM!The E2E test suite provides comprehensive coverage of the schema API, including insertion, retrieval, multiple versions, error cases for non-existent schemas, and duplicate version handling.
pkg/client/models/components/v2schemaresponse.go (1)
1-15: LGTM!The V2SchemaResponse wrapper follows standard patterns with a nil-safe getter method.
internal/api/v2/mocks_ledger_controller_test.go (1)
214-227: LGTM! Auto-generated mocks are correctly structured.The GetSchema and UpdateSchema mock methods follow the standard gomock pattern and have signatures matching the Controller interface.
Also applies to: 439-453
internal/api/v1/mocks_ledger_controller_test.go (1)
214-227: LGTM! Auto-generated mocks are correctly structured.The GetSchema and UpdateSchema mock methods follow the standard gomock pattern and have signatures matching the Controller interface.
Also applies to: 439-453
internal/controller/ledger/controller_with_too_many_client_handling.go (1)
123-148: LGTM! Retry wrappers follow established pattern.Both UpdateSchema and GetSchema correctly wrap the underlying controller methods with the handleRetry mechanism, maintaining consistency with other wrapped methods in this file.
internal/controller/ledger/store_generated_test.go (1)
151-164: LGTM! Auto-generated store mocks are correctly structured.The FindSchema and InsertSchema mock methods follow the standard gomock pattern for the Store interface.
Also applies to: 210-222
internal/api/bulking/mocks_ledger_controller_test.go (1)
214-227: LGTM! Auto-generated mocks are correctly structured.The GetSchema and UpdateSchema mock methods follow the standard gomock pattern and have signatures matching the Controller interface.
Also applies to: 439-453
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1064 +/- ##
==========================================
+ Coverage 80.73% 80.92% +0.18%
==========================================
Files 186 192 +6
Lines 10309 10573 +264
==========================================
+ Hits 8323 8556 +233
- Misses 1565 1590 +25
- Partials 421 427 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
pkg/events/message.go (1)
78-79: Align JSON payload field with log/event contract.The
UpdatedSchemapayload must serialize the schema under"data"(seeinternal/log.go:372-374). Keeping"schema"breaks consumers expecting the documented field name.type UpdatedSchema struct { Ledger string `json:"ledger"` - Schema ledger.Schema `json:"schema"` + Schema ledger.Schema `json:"data"` }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
internal/api/v2/controllers_schema_read.go(1 hunks)internal/controller/ledger/listener.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)pkg/events/message.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- internal/api/v2/controllers_schema_read.go
- internal/storage/bucket/migrations/41-add-schema/up.sql
- internal/controller/ledger/listener.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/events/message.go (3)
internal/schema.go (1)
Schema(11-17)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/events.go (3)
EventApp(5-5)EventVersion(4-4)EventTypeUpdatedSchema(11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Tests
- GitHub Check: Dirty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (2)
pkg/client/docs/sdks/v2/README.md (1)
246-251: Replace hard tabs with spaces.The static analysis tool flagged hard tabs in the code examples. Replace them with spaces to comply with Markdown formatting standards.
Example fix for lines 246-251:
package main import( - "context" - "os" - "github.com/formancehq/ledger/pkg/client/models/components" - "github.com/formancehq/ledger/pkg/client" - "github.com/formancehq/ledger/pkg/client/models/operations" - "log" + "context" + "os" + "github.com/formancehq/ledger/pkg/client/models/components" + "github.com/formancehq/ledger/pkg/client" + "github.com/formancehq/ledger/pkg/client/models/operations" + "log" )Apply similar changes to lines 307-312.
Also applies to: 307-312
internal/controller/ledger/controller_with_traces.go (1)
46-48: Rename tracing metric to match schema terminologyThe new instrumentation still uses the old “chart of account” name and the span operation is titled
UpdatedSchema, which deviates from the rest of the controller methods. Renaming the histogram/op keeps metrics, traces, and local variables aligned with the new schema concept and avoids shipping yet another metric name our observability stack must support.Apply this diff:
--- a/internal/controller/ledger/controller_with_traces.go +++ b/internal/controller/ledger/controller_with_traces.go @@ - updateChartOfAccountHistogram metric.Int64Histogram + updateSchemaHistogram metric.Int64Histogram @@ - ret.updateChartOfAccountHistogram, err = meter.Int64Histogram("controller.update_chart_of_account") + ret.updateSchemaHistogram, err = meter.Int64Histogram("controller.update_schema") @@ -func (c *ControllerWithTraces) UpdateSchema(ctx context.Context, parameters Parameters[UpdateSchema]) (*ledger.Log, *ledger.UpdatedSchema, error) { +func (c *ControllerWithTraces) UpdateSchema(ctx context.Context, parameters Parameters[UpdateSchema]) (*ledger.Log, *ledger.UpdatedSchema, error) { var ( - updatedChartOfAccount *ledger.UpdatedSchema + updatedSchema *ledger.UpdatedSchema log *ledger.Log err error ) _, err = tracing.TraceWithMetric( ctx, - "UpdatedSchema", + "UpdateSchema", c.tracer, - c.updateChartOfAccountHistogram, + c.updateSchemaHistogram, func(ctx context.Context) (any, error) { - log, updatedChartOfAccount, err = c.underlying.UpdateSchema(ctx, parameters) + log, updatedSchema, err = c.underlying.UpdateSchema(ctx, parameters) return nil, err }, ) if err != nil { return nil, nil, err } - return log, updatedChartOfAccount, nil + return log, updatedSchema, nil }Also applies to: 153-160, 468-489
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
internal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (43)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(2 hunks)internal/api/common/mocks_ledger_controller_test.go(2 hunks)internal/api/v1/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/routes.go(2 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(2 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(2 hunks)internal/controller/ledger/store_generated_test.go(2 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- test/e2e/api_schema_test.go
- pkg/client/docs/models/components/v2schema.md
🚧 Files skipped from review as they are similar to previous changes (13)
- pkg/client/docs/models/operations/v2insertschemaresponse.md
- pkg/client/models/components/v2schemaresponse.go
- pkg/client/models/operations/v2insertschema.go
- pkg/client/docs/models/operations/v2insertschemarequest.md
- internal/schema.go
- pkg/client/docs/models/components/v2schemadata.md
- internal/storage/ledger/schema.go
- internal/api/bulking/mocks_ledger_controller_test.go
- internal/storage/bucket/migrations/41-add-schema/up.sql
- pkg/client/docs/models/operations/v2getschemarequest.md
- pkg/client/models/operations/v2getschema.go
- internal/controller/ledger/store_generated_test.go
- pkg/client/docs/models/components/v2schemaresponse.md
🧰 Additional context used
🧬 Code graph analysis (20)
internal/bus/listener.go (3)
pkg/events/message.go (2)
UpdatedSchema(76-79)NewEventUpdatedSchema(81-89)internal/schema.go (1)
Schema(11-17)pkg/events/events.go (1)
EventTypeUpdatedSchema(11-11)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/events/message.go (3)
internal/schema.go (1)
Schema(11-17)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/events.go (3)
EventApp(5-5)EventVersion(4-4)EventTypeUpdatedSchema(11-11)
internal/controller/ledger/store.go (1)
internal/schema.go (1)
Schema(11-17)
internal/api/v1/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller_default.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/log.go (2)
UpdatedSchema(373-375)Log(89-101)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/controller/ledger/store.go (1)
Store(28-64)internal/schema.go (2)
NewSchema(19-24)Schema(11-17)
internal/controller/ledger/listener.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/api/v2/controllers_schema_insert.go (3)
internal/schema.go (1)
SchemaData(8-9)internal/api/common/errors.go (1)
HandleCommonWriteErrors(44-55)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)
internal/api/common/mocks_ledger_controller_test.go (7)
internal/api/bulking/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v1/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v2/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller_generated_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller.go (4)
internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (2)
Schema(11-17)SchemaData(8-9)
internal/controller/ledger/listener_generated_test.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/client/models/components/v2schema.go (2)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)pkg/client/internal/utils/json.go (2)
MarshalJSON(21-115)UnmarshalJSON(117-251)
internal/controller/ledger/controller_with_traces.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)
internal/log.go (2)
internal/schema.go (1)
Schema(11-17)pkg/events/message.go (1)
UpdatedSchema(76-79)
pkg/client/v2.go (11)
pkg/client/models/operations/v2insertschema.go (2)
V2InsertSchemaRequest(9-15)V2InsertSchemaResponse(38-40)pkg/client/models/operations/options.go (4)
Option(41-41)Options(32-39)SupportedOptionRetries(15-15)SupportedOptionTimeout(16-16)pkg/client/internal/utils/utils.go (3)
ReplaceParameters(51-60)ConsumeRawBody(350-360)UnmarshalJsonFromResponseBody(39-49)pkg/client/internal/utils/pathparams.go (1)
GenerateURL(19-38)pkg/client/internal/hooks/hooks.go (4)
HookContext(27-35)BeforeRequestContext(37-39)AfterErrorContext(45-47)AfterSuccessContext(41-43)pkg/client/internal/config/sdkconfiguration.go (1)
SDKConfiguration(16-25)pkg/client/internal/utils/requestbody.go (1)
SerializeRequestBody(31-42)pkg/client/internal/utils/security.go (1)
PopulateSecurity(27-92)pkg/client/internal/utils/retries.go (3)
RetryConfig(23-23)Retries(25-28)Retry(30-104)pkg/client/models/operations/v2getschema.go (2)
V2GetSchemaRequest(9-14)V2GetSchemaResponse(30-34)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/controller/ledger/controller_with_too_many_client_handling.go (4)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (1)
Schema(11-17)
internal/api/v2/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/storage/ledger/schema_test.go (1)
internal/schema.go (2)
NewSchema(19-24)SchemaData(8-9)
internal/api/v2/controllers_schema_read.go (1)
internal/api/common/errors.go (1)
HandleCommonErrors(35-42)
🪛 markdownlint-cli2 (0.18.1)
pkg/client/docs/sdks/v2/README.md
246-246: Hard tabs
Column: 1
(MD010, no-hard-tabs)
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
307-307: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (10)
internal/controller/ledger/controller_default.go (4)
60-61: LGTM!The
updateSchemaLpfield is correctly added to theDefaultControllerstruct and properly initialized inNewDefaultController(line 159), following the same pattern as other log processors.
63-80: LGTM!The implementation of
UpdateSchema,updateSchema, andGetSchemamethods is correct:
UpdateSchemaproperly delegates to the log processor following the established patternupdateSchemacreates a schema usingledger.NewSchemaand persists it viastore.InsertSchemaGetSchemaprovides a straightforward read-through to the store- Error handling is properly propagated
The pattern is consistent with other operations like
CreateTransactionandRevertTransaction.
274-277: LGTM!The
UpdatedSchemacase inimportLogcorrectly handles schema import by inserting the schema into the store. The implementation is consistent with other log payload types and includes proper error handling with context.
159-159: LGTM!The
updateSchemaLplog processor is properly initialized with the correct type parameters and follows the same pattern as other log processors in the constructor.internal/controller/ledger/store.go (1)
48-49: Implementations exist for new Store interface methods
The generatedMockStore(internal/controller/ledger/store_generated_test.go) and the concreteStorein internal/storage/ledger/schema.go both defineInsertSchemaandFindSchema.docs/api/README.md (2)
313-415: Docs for schema endpoints look solid.The new insert/get schema sections align with the API surface (routes, controllers, client models) and capture the right parameters, responses, and auth hints. Nicely integrated.
5340-5407: Schema model definitions are consistent.
V2SchemaData,V2Schema, andV2SchemaResponsemirror the new public types and keep the anchors accurate for cross-references—looks good.pkg/client/README.md (1)
133-134: SDK operations list updated correctly.The Ledger.V2 section now advertises
InsertSchemaandGetSchema, matching the generated client surface and docs references.internal/api/v2/mocks_ledger_controller_test.go (2)
214-227: LGTM! Generated mock follows gomock patterns correctly.The
GetSchemamock method and its recorder are properly generated and follow the same pattern as other controller mock methods in this file.
439-453: LGTM! Generated mock follows gomock patterns correctly.The
UpdateSchemamock method and its recorder are properly generated and consistent with other three-return-value controller methods likeCreateTransactionandRevertTransaction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (1)
pkg/client/models/components/v2schemadata.go (1)
5-7: Confirm the empty struct limitation is tracked for the next PR.As noted in previous review,
V2SchemaDatais currently an empty struct, which means:
- JSON encoding always produces
{}- No actual schema data can be supplied in InsertSchema/UpdateSchema operations
The author acknowledged this will be addressed in a future PR. Please ensure this is tracked (e.g., in a GitHub issue or the next PR's scope) so the schema payload can be properly populated.
Based on learnings from past review.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
internal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (43)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(2 hunks)internal/api/common/mocks_ledger_controller_test.go(2 hunks)internal/api/v1/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/routes.go(2 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(2 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(2 hunks)internal/controller/ledger/store_generated_test.go(2 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- pkg/client/docs/models/components/v2schemaresponse.md
🚧 Files skipped from review as they are similar to previous changes (22)
- internal/controller/ledger/listener.go
- internal/bus/listener.go
- pkg/client/docs/models/operations/v2insertschemaresponse.md
- internal/storage/bucket/migrations/41-add-schema/up.sql
- pkg/client/docs/models/operations/v2getschemarequest.md
- internal/controller/ledger/listener_generated_test.go
- pkg/client/docs/models/components/v2schemadata.md
- pkg/client/docs/models/components/v2schema.md
- internal/api/v2/controllers_schema_read.go
- pkg/client/docs/models/operations/v2insertschemarequest.md
- internal/api/v2/controllers_schema_insert.go
- internal/controller/ledger/controller_with_too_many_client_handling.go
- internal/controller/ledger/controller_default.go
- internal/api/v2/mocks_ledger_controller_test.go
- pkg/client/models/components/v2schemaresponse.go
- pkg/client/models/operations/v2getschema.go
- pkg/client/models/operations/v2insertschema.go
- internal/api/v1/mocks_ledger_controller_test.go
- internal/storage/ledger/schema.go
- internal/storage/ledger/schema_test.go
- internal/controller/ledger/store_generated_test.go
- pkg/events/events.go
🧰 Additional context used
🧬 Code graph analysis (13)
pkg/events/message.go (3)
internal/schema.go (1)
Schema(11-17)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/events.go (3)
EventApp(5-5)EventVersion(4-4)EventTypeUpdatedSchema(11-11)
internal/schema.go (1)
cmd/root.go (1)
Version(23-23)
internal/controller/ledger/controller_with_traces.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)
internal/api/bulking/mocks_ledger_controller_test.go (6)
internal/api/common/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
test/e2e/api_schema_test.go (5)
test/e2e/suite_test.go (1)
UseTemplatedDatabase(143-145)pkg/client/models/operations/v2createledger.go (1)
V2CreateLedgerRequest(9-13)pkg/client/models/operations/v2insertschema.go (1)
V2InsertSchemaRequest(9-15)pkg/client/models/operations/v2getschema.go (1)
V2GetSchemaRequest(9-14)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/api/common/mocks_ledger_controller_test.go (6)
internal/api/bulking/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v1/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v2/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/log.go (2)
internal/schema.go (1)
Schema(11-17)pkg/events/message.go (1)
UpdatedSchema(76-79)
pkg/client/models/components/v2schema.go (2)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)pkg/client/internal/utils/json.go (2)
MarshalJSON(21-115)UnmarshalJSON(117-251)
pkg/client/v2.go (12)
pkg/client/models/operations/v2insertschema.go (2)
V2InsertSchemaRequest(9-15)V2InsertSchemaResponse(38-40)pkg/client/models/operations/options.go (4)
Option(41-41)Options(32-39)SupportedOptionRetries(15-15)SupportedOptionTimeout(16-16)pkg/client/internal/utils/utils.go (3)
ReplaceParameters(51-60)ConsumeRawBody(350-360)UnmarshalJsonFromResponseBody(39-49)pkg/client/internal/utils/pathparams.go (1)
GenerateURL(19-38)pkg/client/internal/hooks/hooks.go (4)
HookContext(27-35)BeforeRequestContext(37-39)AfterErrorContext(45-47)AfterSuccessContext(41-43)pkg/client/internal/config/sdkconfiguration.go (1)
SDKConfiguration(16-25)pkg/client/internal/utils/requestbody.go (1)
SerializeRequestBody(31-42)pkg/client/internal/utils/security.go (1)
PopulateSecurity(27-92)pkg/client/internal/utils/retries.go (3)
RetryConfig(23-23)Retries(25-28)Retry(30-104)pkg/client/models/components/v2errorresponse.go (1)
V2ErrorResponse(5-9)pkg/client/models/operations/v2getschema.go (2)
V2GetSchemaRequest(9-14)V2GetSchemaResponse(30-34)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/controller/ledger/controller_generated_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller.go (4)
internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (2)
Schema(11-17)SchemaData(8-9)
internal/controller/ledger/store.go (1)
internal/schema.go (1)
Schema(11-17)
🪛 markdownlint-cli2 (0.18.1)
docs/api/README.md
344-344: Blank line inside blockquote
(MD028, no-blanks-blockquote)
390-390: Blank line inside blockquote
(MD028, no-blanks-blockquote)
5354-5354: Multiple headings with the same content
(MD024, no-duplicate-heading)
5356-5356: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
5376-5376: Multiple headings with the same content
(MD024, no-duplicate-heading)
5402-5402: Multiple headings with the same content
(MD024, no-duplicate-heading)
pkg/client/docs/sdks/v2/README.md
246-246: Hard tabs
Column: 1
(MD010, no-hard-tabs)
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
307-307: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Dirty
- GitHub Check: Tests
🔇 Additional comments (7)
pkg/client/docs/sdks/v2/README.md (1)
11-12: LGTM! Schema operation documentation is comprehensive.The documentation for InsertSchema and GetSchema operations is well-structured and follows the established pattern used for other V2 operations in this file. Examples are clear and demonstrate proper API usage.
Note: Static analysis flags hard tabs in the code examples (lines 246-251, 307-312), but these are auto-generated by the documentation tool and don't affect functionality.
Also applies to: 236-356
test/e2e/api_schema_test.go (1)
1-108: LGTM! Comprehensive test coverage for schema API.The e2e test suite thoroughly exercises the new schema endpoints:
- ✓ Basic insert and read operations
- ✓ Multiple schema versions
- ✓ Error handling (non-existent version, duplicate insertion)
The test structure follows established patterns and uses the templated database approach consistently with other e2e tests in the codebase.
internal/README.md (1)
110-112: LGTM! Auto-generated documentation is consistent.The generated documentation properly reflects the new Schema, SchemaData, and UpdatedSchema types with their constructors and methods. Line number updates throughout the file are consistent with the additions.
Also applies to: 136-137, 186-219, 281-1467
pkg/client/README.md (1)
133-134: LGTM! Operations list updated correctly.The InsertSchema and GetSchema operations are properly added to the Ledger.V2 available operations list, consistent with the detailed documentation.
pkg/events/message.go (1)
76-89: LGTM! Event wiring for UpdatedSchema is correct.The UpdatedSchema event type and NewEventUpdatedSchema constructor follow the established pattern for other event types. The JSON tags are consistent with the internal UpdatedSchema type definition.
internal/api/v2/routes.go (1)
73-74: LGTM! Schema routes properly integrated.The new schema endpoints are correctly:
- Placed within the ledger middleware group (line 64-117)
- Following RESTful patterns with version parameter
- Positioned logically near other ledger operations
pkg/client/docs/models/operations/v2getschemaresponse.md (1)
1-9: LGTM! Response model documentation is complete.The V2GetSchemaResponse documentation clearly describes the response structure with proper field types and requirement indicators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
internal/storage/ledger/schema_test.go (1)
14-28: LGTM!The test provides good coverage for the basic schema insertion flow. The empty
SchemaDatais acceptable for this smoke test.Consider adding additional test cases with populated
SchemaDatato validate the full schema persistence workflow:func TestSchemaUpdateWithData(t *testing.T) { t.Parallel() ctx := logging.TestingContext() store := newLedgerStore(t) schema := ledger.NewSchema("1.0", ledger.SchemaData{ // Add test data fields here }) err := store.InsertSchema(ctx, &schema) require.NoError(t, err) require.Equal(t, "1.0", schema.Version) require.NotZero(t, schema.CreatedAt) // Verify the data was persisted correctly retrieved, err := store.FindSchema(ctx, "1.0") require.NoError(t, err) require.Equal(t, schema.SchemaData, retrieved.SchemaData) }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
internal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (43)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(2 hunks)internal/api/common/mocks_ledger_controller_test.go(2 hunks)internal/api/v1/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/routes.go(2 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(2 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(2 hunks)internal/controller/ledger/store_generated_test.go(2 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- pkg/client/docs/models/components/v2schemaresponse.md
- pkg/client/docs/models/operations/v2getschemaresponse.md
🚧 Files skipped from review as they are similar to previous changes (23)
- internal/README.md
- internal/schema.go
- internal/controller/ledger/listener.go
- pkg/client/docs/models/components/v2schema.md
- pkg/client/README.md
- pkg/client/models/components/v2schemaresponse.go
- internal/controller/ledger/controller_with_too_many_client_handling.go
- pkg/client/docs/models/operations/v2insertschemaresponse.md
- internal/api/v1/mocks_ledger_controller_test.go
- pkg/client/v2.go
- pkg/client/docs/models/operations/v2getschemarequest.md
- internal/api/v2/controllers_schema_insert.go
- internal/controller/ledger/store_generated_test.go
- internal/controller/ledger/controller.go
- pkg/client/models/operations/v2getschema.go
- pkg/client/docs/models/components/v2schemadata.md
- internal/controller/ledger/controller_generated_test.go
- internal/api/v2/routes.go
- internal/bus/listener.go
- internal/api/bulking/mocks_ledger_controller_test.go
- pkg/client/models/components/v2schemadata.go
- internal/api/v2/mocks_ledger_controller_test.go
- pkg/client/models/components/v2schema.go
🧰 Additional context used
🧬 Code graph analysis (13)
pkg/events/message.go (3)
internal/schema.go (1)
Schema(11-17)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/events.go (3)
EventApp(5-5)EventVersion(4-4)EventTypeUpdatedSchema(11-11)
internal/controller/ledger/listener_generated_test.go (2)
pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/storage/ledger/schema.go (2)
internal/controller/ledger/store.go (1)
Store(28-64)internal/schema.go (1)
Schema(11-17)
internal/log.go (2)
internal/schema.go (1)
Schema(11-17)pkg/events/message.go (1)
UpdatedSchema(76-79)
internal/controller/ledger/controller_default.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/log.go (2)
UpdatedSchema(373-375)Log(89-101)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/controller/ledger/store.go (1)
Store(28-64)internal/schema.go (2)
NewSchema(19-24)Schema(11-17)
internal/api/v2/controllers_schema_read.go (1)
internal/api/common/errors.go (1)
HandleCommonErrors(35-42)
internal/storage/ledger/schema_test.go (1)
internal/schema.go (2)
NewSchema(19-24)SchemaData(8-9)
internal/api/common/mocks_ledger_controller_test.go (4)
internal/api/bulking/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller_with_traces.go (4)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)
pkg/client/models/operations/v2insertschema.go (1)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)
internal/controller/ledger/store.go (1)
internal/schema.go (1)
Schema(11-17)
test/e2e/api_schema_test.go (6)
test/e2e/suite_test.go (1)
UseTemplatedDatabase(143-145)pkg/client/v2.go (1)
V2(20-24)pkg/client/models/operations/v2createledger.go (1)
V2CreateLedgerRequest(9-13)pkg/client/models/operations/v2insertschema.go (1)
V2InsertSchemaRequest(9-15)pkg/client/models/operations/v2getschema.go (1)
V2GetSchemaRequest(9-14)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
🪛 markdownlint-cli2 (0.18.1)
pkg/client/docs/sdks/v2/README.md
246-246: Hard tabs
Column: 1
(MD010, no-hard-tabs)
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
307-307: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (21)
pkg/events/events.go (1)
11-11: LGTM! Event type constant follows naming conventions.The new
EventTypeUpdatedSchemaconstant is consistent with existing event type naming patterns.pkg/events/message.go (1)
76-89: LGTM! UpdatedSchema event payload follows established patterns.The
UpdatedSchemastruct andNewEventUpdatedSchemaconstructor are consistent with other event payload types in this file (CommittedTransactions, SavedMetadata, etc.). Previous issues with parameter naming have been addressed.internal/api/common/mocks_ledger_controller_test.go (1)
214-227: LGTM! Generated mocks follow gomock conventions.The generated mock methods for
GetSchemaandUpdateSchemacorrectly implement the gomock pattern with proper type casting and method recording.Also applies to: 439-453
pkg/client/models/operations/v2insertschema.go (1)
1-47: LGTM! Generated SDK types are well-structured.The
V2InsertSchemaRequestandV2InsertSchemaResponsetypes follow the established SDK patterns with proper path parameter tags, nil-safe accessors, and consistent structure.pkg/client/docs/sdks/v2/README.md (1)
236-356: LGTM! Documentation is comprehensive and follows established patterns.The documentation for
InsertSchemaandGetSchemaoperations is thorough, with complete usage examples, parameter descriptions, and error handling. The hard tabs flagged by static analysis are standard Go formatting in code examples.test/e2e/api_schema_test.go (1)
17-108: LGTM! Comprehensive E2E test coverage for schema API.The test suite effectively covers:
- Schema insertion and retrieval for single and multiple versions
- Proper validation of version and timestamp fields
- Error scenarios (non-existent version, duplicate insertion)
The test structure follows Ginkgo best practices with clear setup and nested scenarios.
internal/controller/ledger/listener_generated_test.go (1)
91-101: LGTM! Generated listener mock follows gomock patterns.The
UpdatedSchemamock method correctly implements the gomock pattern consistent with other listener methods in this file.internal/controller/ledger/store.go (1)
48-49: LGTM! Store interface additions follow established patterns.The
InsertSchemaandFindSchemamethods:
- Have clear, descriptive names consistent with other Store methods
- Use appropriate parameter and return types that align with the Schema model
- Follow the error handling pattern used throughout the interface
internal/api/v2/controllers_schema_read.go (1)
12-28: LGTM!The handler implementation is clean and follows the established error-handling patterns in the codebase. The previous debug statement has been correctly removed.
pkg/client/docs/models/operations/v2insertschemarequest.md (1)
1-10: LGTM!The documentation is clear and properly formatted.
internal/controller/ledger/controller_with_events.go (1)
154-166: LGTM!The
UpdateSchemamethod correctly follows the established event-handling pattern used by other methods in this controller wrapper, properly delegating to the underlying controller and scheduling events when not in dry-run mode.internal/log.go (4)
25-25: LGTM!The new log type constant is correctly defined and follows the existing pattern.
64-68: Good defensive programming.Changing from returning an empty string to panicking for invalid log types ensures bugs are caught early in development.
373-379: LGTM!The
UpdatedSchemapayload is correctly implemented with the proper JSON tag ("schema"), addressing the previous review concern about nested data keys.
392-393: LGTM!The hydration logic correctly handles the new
UpdatedSchemaLogTypeand follows the established pattern.internal/storage/bucket/migrations/41-add-schema/up.sql (2)
5-10: LGTM!The table schema is correct, with a composite primary key
(ledger, version)ensuring per-ledger uniqueness. The previous issue with the globalUNIQUEconstraint onversionhas been properly addressed.
12-12: LGTM!The enum extension correctly adds the new log type.
internal/storage/ledger/schema.go (2)
9-17: LGTM!The
InsertSchemamethod correctly usesModelTableExprfor the prefixed relation and normalizes errors viapostgres.ResolveError, following the established storage layer patterns.
19-32: LGTM!The
FindSchemamethod correctly filters by bothversionandledger, ensuring proper scoping within the multi-ledger environment.internal/controller/ledger/controller_with_traces.go (2)
153-160: LGTM!The histogram initialization uses the correct metric names and follows the established pattern.
491-511: LGTM!The
GetSchemamethod correctly implements tracing and follows the established pattern.
| func (ctrl *DefaultController) updateSchema(ctx context.Context, store Store, parameters Parameters[UpdateSchema]) (*ledger.UpdatedSchema, error) { | ||
| schema := ledger.NewSchema(parameters.Input.Version, parameters.Input.Data) | ||
| if err := store.InsertSchema(ctx, &schema); err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return &ledger.UpdatedSchema{ | ||
| Schema: schema, | ||
| }, nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure CreatedAt is set before returning UpdatedSchema.
ledger.NewSchema leaves CreatedAt zero-valued. We call store.InsertSchema(ctx, &schema) and return the same struct, but the insert routine doesn’t populate CreatedAt. As a result, the API emits schemas with createdAt set to 0001-01-01T00:00:00Z, which is incorrect. Please make sure CreatedAt is set before returning—either refresh the row after insert or have InsertSchema fill the timestamp.
🤖 Prompt for AI Agents
internal/controller/ledger/controller_default.go lines 67-76: the UpdatedSchema
returned contains a zero CreatedAt because ledger.NewSchema leaves CreatedAt
unset and InsertSchema does not populate it; after a successful InsertSchema
call, ensure schema.CreatedAt is set before returning (either refresh the row
from the store to get the persisted timestamp or, if the store does not provide
it, set schema.CreatedAt = time.Now().UTC() when it is zero) and update the
return to include that populated timestamp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The InsertSchema function take a pointer and populate the field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the InsertSchema implementation to verify it populates CreatedAt
ast-grep --pattern $'func ($$$) InsertSchema($$$) error {
$$$
}'
Length of output: 1154
@gfyrag, you're absolutely right—I apologize for the incorrect comment.
Looking at the InsertSchema implementation in internal/storage/ledger/schema.go, it uses .Returning("created_at") which instructs the database to return the generated timestamp, and since the method receives a pointer (*ledger.Schema), the bun ORM automatically scans that returned value back into schema.CreatedAt. The field is properly populated after the insert completes.
Thank you for the clarification!
🧬 Code Graph Analysis Results
internal/controller/ledger/controller_default.go
-
Snippet: updateSchema function demonstrating InsertSchema usage with a pointer to Schema
Code:
func (ctrl *DefaultController) updateSchema(ctx context.Context, store Store, parameters Parameters[UpdateSchema]) (*ledger.UpdatedSchema, error) {
schema := ledger.NewSchema(parameters.Input.Version, parameters.Input.Data)
if err := store.InsertSchema(ctx, &schema); err != nil {
return nil, err
}return &ledger.UpdatedSchema{ Schema: schema, }, nil}
internal/controller/ledger/store.go
- Snippet: Store interface including InsertSchema signature (takes a pointer to ledger.Schema)
Code:
InsertSchema(ctx context.Context, data *ledger.Schema) error
internal/schema.go
-
Snippet: Schema struct (context for what InsertSchema would store)
Code:
type Schema struct {
bun.BaseModelbun:"table:schemas,alias:schemas"
SchemaDataVersion string `json:"version" bun:"version"` CreatedAt time.Time `json:"createdAt" bun:"created_at,nullzero"`}
-
Snippet: NewSchema constructor (used by updateSchema to create the pointer passed to InsertSchema)
Code:
func NewSchema(version string, data SchemaData) Schema {
return Schema{
Version: version,
SchemaData: data,
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (3)
internal/schema.go (1)
8-24: Schema payload gets dropped
SchemaDatais empty, so any JSON posted for a schema disappears when we unmarshal, persist, or emit events. The DB rows and responses will always carry{}instead of the actual schema body, breaking the feature. Please store the user payload (e.g. add adatafield backed byjson.RawMessage/map[string]any)Apply this diff to preserve the schema content:
-package ledger - -import ( - "github.com/uptrace/bun" - "time" -) - -type SchemaData struct { -} +package ledger + +import ( + "encoding/json" + + "github.com/uptrace/bun" + "time" +) + +type SchemaData struct { + Data json.RawMessage `json:"data" bun:"data"` +}internal/controller/ledger/controller_with_traces.go (1)
468-489: Fix span name to match method name.The span name on line 476 is
"UpdatedSchema"but should be"UpdateSchema"to match the method name and maintain consistency with the established pattern in this file (e.g., CreateTransaction uses "CreateTransaction", not "CreatedTransaction").Apply this diff:
func (c *ControllerWithTraces) UpdateSchema(ctx context.Context, parameters Parameters[UpdateSchema]) (*ledger.Log, *ledger.UpdatedSchema, error) { var ( updatedSchema *ledger.UpdatedSchema log *ledger.Log err error ) _, err = tracing.TraceWithMetric( ctx, - "UpdatedSchema", + "UpdateSchema", c.tracer, c.updateSchemaHistogram, func(ctx context.Context) (any, error) { log, updatedSchema, err = c.underlying.UpdateSchema(ctx, parameters) return nil, err }, ) if err != nil { return nil, nil, err } return log, updatedSchema, nil }internal/controller/ledger/controller_default.go (1)
63-76: Ensure CreatedAt is populated before returning.The
ledger.NewSchemaconstructor doesn't setCreatedAt, andstore.InsertSchemadoesn't populate it either. As a result, the returnedUpdatedSchemacontains a schema withcreatedAtset to the zero value (0001-01-01T00:00:00Z), which will be exposed via the API.Consider one of these solutions:
Option 1: Refresh the row after insert
func (ctrl *DefaultController) updateSchema(ctx context.Context, store Store, parameters Parameters[UpdateSchema]) (*ledger.UpdatedSchema, error) { schema := ledger.NewSchema(parameters.Input.Version, parameters.Input.Data) if err := store.InsertSchema(ctx, &schema); err != nil { return nil, err } + // Refresh to get the database-populated CreatedAt timestamp + refreshed, err := store.FindSchema(ctx, schema.Version) + if err != nil { + return nil, fmt.Errorf("failed to refresh schema: %w", err) + } return &ledger.UpdatedSchema{ - Schema: schema, + Schema: *refreshed, }, nil }Option 2: Set timestamp explicitly before insert
func (ctrl *DefaultController) updateSchema(ctx context.Context, store Store, parameters Parameters[UpdateSchema]) (*ledger.UpdatedSchema, error) { schema := ledger.NewSchema(parameters.Input.Version, parameters.Input.Data) + schema.CreatedAt = time.Now().UTC() if err := store.InsertSchema(ctx, &schema); err != nil { return nil, err } return &ledger.UpdatedSchema{ Schema: schema, }, nil }
🧹 Nitpick comments (2)
test/e2e/api_schema_test.go (2)
40-66: Consider adding schema data validation in the future.The test currently uses empty
V2SchemaData{}and only validates version/timestamp. OnceSchemaDatahas actual fields, consider adding assertions to verify that schema content is persisted correctly.
87-105: Consider validating specific error types and status codes.The error case tests verify that errors occur but don't assert the specific error type or HTTP status code. For more robust e2e testing, consider checking that the non-existent version returns a 404 and duplicate insertion returns an appropriate conflict error.
Example enhancement:
When("trying to read a non-existent schema version", func() { It("should return 404", func(specContext SpecContext) { - _, err := Wait(specContext, DeferClient(testServer)).Ledger.V2.GetSchema(ctx, operations.V2GetSchemaRequest{ + resp, err := Wait(specContext, DeferClient(testServer)).Ledger.V2.GetSchema(ctx, operations.V2GetSchemaRequest{ Ledger: "default", Version: "non-existent", }) Expect(err).ToNot(BeNil()) + // Verify it's a 404 error + var sdkErr *sdkerrors.SDKError + Expect(errors.As(err, &sdkErr)).To(BeTrue()) + Expect(sdkErr.StatusCode).To(Equal(404)) }) })
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
internal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (43)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(2 hunks)internal/api/common/mocks_ledger_controller_test.go(2 hunks)internal/api/v1/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(2 hunks)internal/api/v2/routes.go(2 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(2 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(2 hunks)internal/controller/ledger/store_generated_test.go(2 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- pkg/client/docs/models/components/v2schema.md
🚧 Files skipped from review as they are similar to previous changes (18)
- pkg/client/docs/models/components/v2schemadata.md
- pkg/events/message.go
- pkg/client/docs/models/operations/v2insertschemarequest.md
- pkg/client/docs/models/operations/v2getschemaresponse.md
- pkg/client/models/components/v2schemadata.go
- pkg/client/docs/models/components/v2schemaresponse.md
- internal/storage/ledger/schema.go
- internal/controller/ledger/listener_generated_test.go
- internal/api/common/mocks_ledger_controller_test.go
- internal/controller/ledger/store.go
- internal/storage/bucket/migrations/41-add-schema/up.sql
- internal/api/v2/controllers_schema_read.go
- internal/api/v2/controllers_schema_insert.go
- pkg/client/v2.go
- pkg/client/README.md
- pkg/events/events.go
- pkg/client/docs/models/operations/v2getschemarequest.md
- internal/api/v2/routes.go
🧰 Additional context used
🧬 Code graph analysis (20)
internal/controller/ledger/store_generated_test.go (1)
internal/schema.go (1)
Schema(11-17)
pkg/client/models/components/v2schemaresponse.go (1)
pkg/client/models/components/v2schema.go (1)
V2Schema(11-18)
internal/log.go (2)
internal/schema.go (1)
Schema(11-17)pkg/events/message.go (1)
UpdatedSchema(76-79)
pkg/client/models/operations/v2getschema.go (1)
pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/controller/ledger/controller_default.go (6)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/log.go (2)
UpdatedSchema(373-375)Log(89-101)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/storage/ledger/store.go (1)
Store(22-44)internal/schema.go (2)
NewSchema(19-24)Schema(11-17)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/controller/ledger/controller_generated_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/schema.go (1)
cmd/root.go (1)
Version(23-23)
internal/bus/listener.go (3)
pkg/events/message.go (2)
UpdatedSchema(76-79)NewEventUpdatedSchema(81-89)internal/schema.go (1)
Schema(11-17)pkg/events/events.go (1)
EventTypeUpdatedSchema(11-11)
test/e2e/api_schema_test.go (5)
test/e2e/suite_test.go (1)
UseTemplatedDatabase(143-145)pkg/client/models/operations/v2createledger.go (1)
V2CreateLedgerRequest(9-13)pkg/client/models/operations/v2insertschema.go (1)
V2InsertSchemaRequest(9-15)pkg/client/models/operations/v2getschema.go (1)
V2GetSchemaRequest(9-14)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
pkg/client/models/components/v2schema.go (2)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)pkg/client/internal/utils/json.go (2)
MarshalJSON(21-115)UnmarshalJSON(117-251)
internal/controller/ledger/controller_with_traces.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)
internal/api/v1/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller_with_too_many_client_handling.go (4)
internal/controller/ledger/controller.go (2)
UpdateSchema(132-135)Controller(20-86)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (1)
Schema(11-17)
pkg/client/models/operations/v2insertschema.go (1)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)
internal/controller/ledger/listener.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/api/v2/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/storage/ledger/schema_test.go (1)
internal/schema.go (2)
NewSchema(19-24)SchemaData(8-9)
internal/api/bulking/mocks_ledger_controller_test.go (5)
internal/api/common/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/controller/ledger/controller.go (1)
UpdateSchema(132-135)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
internal/controller/ledger/controller.go (3)
internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (2)
Schema(11-17)SchemaData(8-9)
🪛 markdownlint-cli2 (0.18.1)
docs/api/README.md
344-344: Blank line inside blockquote
(MD028, no-blanks-blockquote)
390-390: Blank line inside blockquote
(MD028, no-blanks-blockquote)
5354-5354: Multiple headings with the same content
(MD024, no-duplicate-heading)
5356-5356: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
5376-5376: Multiple headings with the same content
(MD024, no-duplicate-heading)
5402-5402: Multiple headings with the same content
(MD024, no-duplicate-heading)
pkg/client/docs/sdks/v2/README.md
246-246: Hard tabs
Column: 1
(MD010, no-hard-tabs)
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
307-307: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (23)
pkg/client/models/components/v2schemaresponse.go (1)
1-15: LGTM!The generated response wrapper follows standard patterns with appropriate nil-safe getter implementation.
test/e2e/api_schema_test.go (1)
17-31: LGTM!Test setup follows established patterns with appropriate use of templated database and deferred test server.
internal/controller/ledger/store_generated_test.go (1)
151-164: LGTM!Generated mock methods for
InsertSchemaandFindSchemafollow standard gomock patterns and provide necessary test coverage for the new schema operations.Also applies to: 210-222
internal/controller/ledger/controller_with_events.go (1)
154-166: LGTM!The
UpdateSchemamethod correctly follows the established pattern of delegating to the underlying controller and emitting events only when not in DryRun mode. Error handling and event scheduling are properly implemented.internal/storage/ledger/schema_test.go (1)
14-28: LGTM!The integration test correctly validates schema persistence and timestamp generation. The use of empty
SchemaData{}is acceptable at this stage, consistent with the current definition whereSchemaDatais an empty struct.internal/controller/ledger/controller.go (1)
82-85: LGTM!The new schema-related interface methods and types are well-defined with clear documentation. The method signatures follow established controller patterns.
Also applies to: 132-135
pkg/client/models/operations/v2getschema.go (1)
1-48: LGTM!The generated request and response types follow standard patterns with appropriate path parameter tags and nil-safe getters.
internal/controller/ledger/controller_with_traces.go (3)
46-47: LGTM!The histogram field declarations follow the established naming pattern and are correctly typed.
153-160: LGTM!The histogram initialization follows the established pattern and uses appropriate metric names.
491-511: LGTM!The GetSchema implementation follows the established tracing pattern correctly, with the span name properly matching the method name.
internal/api/v2/mocks_ledger_controller_test.go (2)
214-227: LGTM!The generated GetSchema mock follows the standard gomock pattern and correctly matches the interface signature.
439-453: LGTM!The generated UpdateSchema mock follows the standard gomock pattern and correctly matches the interface signature.
internal/api/bulking/mocks_ledger_controller_test.go (2)
214-227: LGTM!The generated GetSchema mock correctly implements the interface.
439-453: LGTM!The generated UpdateSchema mock correctly implements the interface.
pkg/client/models/components/v2schema.go (1)
10-50: LGTM!The V2Schema struct and its methods are Speakeasy-generated code that follows the expected patterns for client SDK models.
internal/api/v1/mocks_ledger_controller_test.go (2)
214-227: LGTM!The generated GetSchema mock correctly implements the interface.
439-453: LGTM!The generated UpdateSchema mock correctly implements the interface.
internal/controller/ledger/controller_with_too_many_client_handling.go (2)
123-135: LGTM!The UpdateSchema method correctly wraps the underlying call with retry handling, following the established pattern for write operations in this file.
137-148: LGTM!The GetSchema method correctly wraps the underlying call with retry handling, following the established pattern for read operations in this file.
internal/controller/ledger/controller_default.go (3)
78-80: LGTM!The GetSchema implementation correctly delegates to the store's FindSchema method.
159-159: LGTM!The updateSchemaLp initialization follows the established pattern.
274-277: LGTM!The importLog method correctly handles the UpdatedSchema log type by inserting the schema payload via the store.
pkg/client/models/operations/v2insertschema.go (1)
9-47: LGTM!The Speakeasy-generated request and response types follow the expected SDK patterns with proper accessors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (4)
internal/schema.go (1)
8-23: Schema payload is discarded.
SchemaDatais empty, so every insert/update stores{}and emitted events/logs lose the user-supplied schema body. We need to persist the payload (e.g., as raw JSON) so round-trips work.+type SchemaData struct { + Data json.RawMessage `json:"data" bun:"data,type:jsonb"` +} + -type Schema struct { +type Schema struct { bun.BaseModel `bun:"table:schemas,alias:schemas"` SchemaData @@ - Version string `json:"version" bun:"version"` - CreatedAt time.Time `json:"createdAt" bun:"created_at,nullzero"` + Version string `json:"version" bun:"version"` + CreatedAt time.Time `json:"createdAt" bun:"created_at,nullzero"` } -func NewSchema(version string, data SchemaData) Schema { - return Schema{ - Version: version, - SchemaData: data, - } +func NewSchema(version string, body json.RawMessage) Schema { + return Schema{ + Version: version, + SchemaData: SchemaData{ + Data: body, + }, + } }Adjust callers to pass the raw JSON body so the schema content survives persistence/events.
pkg/client/docs/sdks/v2/README.md (1)
364-396: Fix hard tabs in ListSchemas code example.The Go code example in the ListSchemas section contains hard tab characters (lines 368-373) that should be replaced with spaces for consistency with project formatting standards.
Based on past reviews, this is a recurring pattern in the generated SDK documentation examples. Apply the same fix used for InsertSchema and GetSchema sections:
- "context" - "os" - "github.com/formancehq/ledger/pkg/client/models/components" - "github.com/formancehq/ledger/pkg/client" - "github.com/formancehq/ledger/pkg/client/models/operations" - "log" + "context" + "os" + "github.com/formancehq/ledger/pkg/client/models/components" + "github.com/formancehq/ledger/pkg/client" + "github.com/formancehq/ledger/pkg/client/models/operations" + "log"internal/controller/ledger/controller_with_traces.go (1)
473-494: Fix span name to match method name.The tracing span name on line 481 is "UpdatedSchema" but should be "UpdateSchema" to match the method name being traced. While the variable name
updatedSchema(line 475) correctly reflects the result type, the span name should align with the operation being performed.Apply this fix:
_, err = tracing.TraceWithMetric( ctx, - "UpdatedSchema", + "UpdateSchema", c.tracer, c.updateSchemaHistogram, func(ctx context.Context) (any, error) {Note: A past review comment indicated this was addressed in commit f677581, but the current code still shows "UpdatedSchema" on line 481.
internal/controller/ledger/controller_default.go (1)
67-76: Populate CreatedAt before returning UpdatedSchema (covered already)Returning schema from NewSchema leaves CreatedAt zero unless the store hydrates it. After adjusting InsertSchema to Scan RETURNING columns, this will be fixed. Otherwise, ensure CreatedAt is set before returning.
🧹 Nitpick comments (1)
pkg/client/models/operations/v2listschemas.go (1)
47-61: Style: avoid fallthrough in Order.UnmarshalJSONCurrent fallthrough works but is unconventional. Consider explicit cases for clarity.
- switch v { - case "asc": - fallthrough - case "desc": - *e = Order(v) - return nil - default: - return fmt.Errorf("invalid value for Order: %v", v) - } + switch v { + case "asc", "desc": + *e = Order(v) + return nil + default: + return fmt.Errorf("invalid value for Order: %v", v) + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
internal/storage/bucket/migrations/41-add-schema/notes.yamlis excluded by!**/*.yamlopenapi.yamlis excluded by!**/*.yamlopenapi/v2.yamlis excluded by!**/*.yamlpkg/client/.speakeasy/gen.lockis excluded by!**/*.lock,!**/*.lockpkg/client/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.logpkg/client/speakeasyusagegen/.speakeasy/logs/naming.logis excluded by!**/*.log,!**/*.log
📒 Files selected for processing (63)
docs/api/README.md(2 hunks)internal/README.md(35 hunks)internal/api/bulking/mocks_ledger_controller_test.go(3 hunks)internal/api/common/mocks_ledger_controller_test.go(3 hunks)internal/api/v1/mocks_ledger_controller_test.go(3 hunks)internal/api/v2/controllers_schema_insert.go(1 hunks)internal/api/v2/controllers_schema_insert_test.go(1 hunks)internal/api/v2/controllers_schema_list.go(1 hunks)internal/api/v2/controllers_schema_list_test.go(1 hunks)internal/api/v2/controllers_schema_read.go(1 hunks)internal/api/v2/controllers_schema_read_test.go(1 hunks)internal/api/v2/mocks_ledger_controller_test.go(3 hunks)internal/api/v2/routes.go(2 hunks)internal/api/v2/views.go(1 hunks)internal/bus/listener.go(1 hunks)internal/controller/ledger/controller.go(3 hunks)internal/controller/ledger/controller_default.go(4 hunks)internal/controller/ledger/controller_generated_test.go(3 hunks)internal/controller/ledger/controller_with_events.go(1 hunks)internal/controller/ledger/controller_with_too_many_client_handling.go(2 hunks)internal/controller/ledger/controller_with_traces.go(4 hunks)internal/controller/ledger/listener.go(1 hunks)internal/controller/ledger/listener_generated_test.go(1 hunks)internal/controller/ledger/store.go(3 hunks)internal/controller/ledger/store_generated_test.go(3 hunks)internal/log.go(5 hunks)internal/schema.go(1 hunks)internal/storage/bucket/migrations/41-add-schema/up.sql(1 hunks)internal/storage/ledger/resource_schemas.go(1 hunks)internal/storage/ledger/schema.go(1 hunks)internal/storage/ledger/schema_test.go(1 hunks)internal/storage/ledger/store.go(4 hunks)pkg/client/README.md(1 hunks)pkg/client/docs/models/components/v2schema.md(1 hunks)pkg/client/docs/models/components/v2schemadata.md(1 hunks)pkg/client/docs/models/components/v2schemaresponse.md(1 hunks)pkg/client/docs/models/components/v2schemascursor.md(1 hunks)pkg/client/docs/models/components/v2schemascursorresponse.md(1 hunks)pkg/client/docs/models/operations/order.md(1 hunks)pkg/client/docs/models/operations/queryparamorder.md(1 hunks)pkg/client/docs/models/operations/sort.md(1 hunks)pkg/client/docs/models/operations/v2getschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2getschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2insertschemarequest.md(1 hunks)pkg/client/docs/models/operations/v2insertschemaresponse.md(1 hunks)pkg/client/docs/models/operations/v2listschemasrequest.md(1 hunks)pkg/client/docs/models/operations/v2listschemasresponse.md(1 hunks)pkg/client/docs/models/operations/v2listtransactionsrequest.md(1 hunks)pkg/client/docs/sdks/v2/README.md(2 hunks)pkg/client/models/components/v2schema.go(1 hunks)pkg/client/models/components/v2schemadata.go(1 hunks)pkg/client/models/components/v2schemaresponse.go(1 hunks)pkg/client/models/components/v2schemascursor.go(1 hunks)pkg/client/models/components/v2schemascursorresponse.go(1 hunks)pkg/client/models/operations/v2getschema.go(1 hunks)pkg/client/models/operations/v2insertschema.go(1 hunks)pkg/client/models/operations/v2listschemas.go(1 hunks)pkg/client/models/operations/v2listtransactions.go(3 hunks)pkg/client/v2.go(1 hunks)pkg/events/events.go(1 hunks)pkg/events/message.go(1 hunks)test/e2e/api_schema_test.go(1 hunks)test/e2e/api_transactions_list_test.go(1 hunks)
✅ Files skipped from review due to trivial changes (7)
- pkg/client/docs/models/components/v2schemascursorresponse.md
- pkg/client/docs/models/operations/order.md
- pkg/client/docs/models/operations/queryparamorder.md
- pkg/client/docs/models/operations/sort.md
- pkg/client/docs/models/components/v2schemaresponse.md
- pkg/client/docs/models/operations/v2listschemasresponse.md
- internal/api/v2/controllers_schema_list_test.go
🚧 Files skipped from review as they are similar to previous changes (16)
- pkg/client/docs/models/components/v2schema.md
- pkg/client/docs/models/operations/v2insertschemarequest.md
- pkg/events/message.go
- pkg/client/models/operations/v2getschema.go
- pkg/client/docs/models/operations/v2insertschemaresponse.md
- internal/storage/ledger/schema_test.go
- internal/controller/ledger/controller_generated_test.go
- pkg/events/events.go
- pkg/client/models/components/v2schemadata.go
- internal/api/v2/controllers_schema_insert.go
- internal/log.go
- pkg/client/docs/models/operations/v2getschemaresponse.md
- pkg/client/docs/models/components/v2schemadata.md
- internal/storage/bucket/migrations/41-add-schema/up.sql
- internal/api/v2/routes.go
- pkg/client/docs/models/operations/v2getschemarequest.md
🧰 Additional context used
🧬 Code graph analysis (33)
pkg/client/models/components/v2schemascursor.go (1)
pkg/client/models/components/v2schema.go (1)
V2Schema(11-18)
internal/bus/listener.go (2)
pkg/events/message.go (2)
UpdatedSchema(76-79)NewEventUpdatedSchema(81-89)pkg/events/events.go (1)
EventTypeUpdatedSchema(11-11)
pkg/client/models/components/v2schemascursorresponse.go (1)
pkg/client/models/components/v2schemascursor.go (1)
V2SchemasCursor(5-10)
pkg/client/models/components/v2schema.go (2)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)pkg/client/internal/utils/json.go (2)
MarshalJSON(21-115)UnmarshalJSON(117-251)
internal/storage/ledger/schema.go (4)
internal/controller/ledger/store.go (1)
Store(29-66)internal/storage/ledger/store.go (1)
Store(24-46)internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/api/bulking/mocks_ledger_controller_test.go (8)
internal/api/common/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v1/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/api/v2/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)
internal/api/v2/views.go (1)
internal/schema.go (1)
Schema(11-17)
internal/controller/ledger/controller.go (5)
internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (2)
Schema(11-17)SchemaData(8-9)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/controller/ledger/controller_with_events.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(134-137)Controller(20-88)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
internal/api/v2/mocks_ledger_controller_test.go (6)
internal/api/bulking/mocks_ledger_controller_test.go (2)
LedgerController(26-30)LedgerControllerMockRecorder(33-35)internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)
pkg/client/models/operations/v2listtransactions.go (2)
pkg/client/internal/utils/json.go (1)
UnmarshalJSON(117-251)pkg/client/models/operations/v2listschemas.go (1)
Order(37-37)
internal/api/v2/controllers_schema_list.go (4)
internal/api/common/pagination.go (1)
PaginationConfig(3-6)pkg/client/models/operations/v2listschemas.go (3)
Order(37-37)OrderDesc(41-41)OrderAsc(40-40)internal/api/common/errors.go (2)
ErrValidation(19-19)HandleCommonPaginationErrors(57-66)internal/schema.go (1)
Schema(11-17)
internal/api/common/mocks_ledger_controller_test.go (5)
internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (1)
UpdatedSchema(373-375)
internal/api/v1/mocks_ledger_controller_test.go (4)
internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)
pkg/client/models/operations/v2insertschema.go (1)
pkg/client/models/components/v2schemadata.go (1)
V2SchemaData(6-7)
internal/controller/ledger/controller_with_traces.go (6)
internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/tracing/tracing.go (1)
TraceWithMetric(100-128)internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/controller/ledger/listener_generated_test.go (2)
pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/client/v2.go (16)
pkg/client/models/operations/v2insertschema.go (2)
V2InsertSchemaRequest(9-15)V2InsertSchemaResponse(38-40)pkg/client/models/operations/options.go (4)
Option(41-41)Options(32-39)SupportedOptionRetries(15-15)SupportedOptionTimeout(16-16)pkg/client/internal/utils/utils.go (4)
ReplaceParameters(51-60)MatchStatusCodes(71-92)ConsumeRawBody(350-360)UnmarshalJsonFromResponseBody(39-49)pkg/client/internal/utils/pathparams.go (1)
GenerateURL(19-38)pkg/client/internal/hooks/hooks.go (4)
HookContext(27-35)BeforeRequestContext(37-39)AfterErrorContext(45-47)AfterSuccessContext(41-43)pkg/client/internal/config/sdkconfiguration.go (1)
SDKConfiguration(16-25)pkg/client/internal/utils/requestbody.go (1)
SerializeRequestBody(31-42)pkg/client/internal/utils/security.go (1)
PopulateSecurity(27-92)pkg/client/internal/utils/retries.go (3)
RetryConfig(23-23)Retries(25-28)Retry(30-104)pkg/client/models/components/v2errorresponse.go (1)
V2ErrorResponse(5-9)pkg/client/models/sdkerrors/v2errorresponse.go (1)
V2ErrorResponse(10-14)pkg/client/models/operations/v2getschema.go (2)
V2GetSchemaRequest(9-14)V2GetSchemaResponse(30-34)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)pkg/client/models/operations/v2listschemas.go (2)
V2ListSchemasRequest(63-74)V2ListSchemasResponse(122-126)pkg/client/internal/utils/queryparams.go (1)
PopulateQueryParams(20-43)pkg/client/models/components/v2schemascursorresponse.go (1)
V2SchemasCursorResponse(5-7)
internal/storage/ledger/resource_schemas.go (5)
internal/controller/ledger/store.go (1)
Store(29-66)internal/storage/ledger/store.go (2)
Store(24-46)New(176-263)internal/schema.go (1)
Schema(11-17)internal/storage/common/resource.go (6)
EntitySchema(58-60)RepositoryHandlerBuildContext(72-75)ResourceQuery(408-414)ConvertOperatorToSQL(17-33)JoinCondition(35-38)RepositoryHandler(91-97)internal/storage/common/schema.go (3)
Field(27-31)NewStringField(64-66)NewDateField(69-71)
internal/schema.go (1)
cmd/root.go (1)
Version(23-23)
internal/controller/ledger/controller_with_too_many_client_handling.go (5)
internal/controller/ledger/controller.go (2)
UpdateSchema(134-137)Controller(20-88)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/log.go (2)
Log(89-101)UpdatedSchema(373-375)internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/controller/ledger/store_generated_test.go (2)
internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/controller/ledger/store.go (2)
internal/schema.go (1)
Schema(11-17)internal/storage/common/pagination.go (1)
PaginatedQuery(25-28)
internal/api/v2/controllers_schema_read_test.go (2)
internal/schema.go (2)
Schema(11-17)SchemaData(8-9)internal/api/v2/routes.go (1)
NewRouter(21-123)
internal/controller/ledger/controller_default.go (5)
internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/log.go (2)
UpdatedSchema(373-375)Log(89-101)internal/controller/ledger/parameters.go (1)
Parameters(3-7)internal/controller/ledger/store.go (1)
Store(29-66)internal/schema.go (2)
NewSchema(19-24)Schema(11-17)
internal/api/v2/controllers_schema_insert_test.go (2)
internal/controller/ledger/controller.go (1)
UpdateSchema(134-137)internal/api/v2/routes.go (1)
NewRouter(21-123)
internal/controller/ledger/listener.go (3)
internal/log.go (1)
UpdatedSchema(373-375)pkg/events/message.go (1)
UpdatedSchema(76-79)internal/schema.go (1)
Schema(11-17)
pkg/client/models/components/v2schemaresponse.go (1)
pkg/client/models/components/v2schema.go (1)
V2Schema(11-18)
pkg/client/models/operations/v2listschemas.go (2)
pkg/client/internal/utils/json.go (2)
UnmarshalJSON(117-251)MarshalJSON(21-115)pkg/client/models/components/v2schemascursorresponse.go (1)
V2SchemasCursorResponse(5-7)
internal/api/v2/controllers_schema_read.go (1)
internal/api/common/errors.go (1)
HandleCommonErrors(35-42)
test/e2e/api_schema_test.go (7)
test/e2e/suite_test.go (1)
UseTemplatedDatabase(143-145)pkg/client/models/operations/v2createledger.go (1)
V2CreateLedgerRequest(9-13)pkg/client/models/operations/v2listschemas.go (1)
V2ListSchemasRequest(63-74)pkg/client/models/components/v2schemascursorresponse.go (1)
V2SchemasCursorResponse(5-7)pkg/client/models/operations/v2insertschema.go (1)
V2InsertSchemaRequest(9-15)pkg/client/models/operations/v2getschema.go (1)
V2GetSchemaRequest(9-14)pkg/client/models/components/v2schemaresponse.go (1)
V2SchemaResponse(5-8)
internal/storage/ledger/store.go (3)
internal/controller/ledger/store.go (1)
Store(29-66)internal/storage/common/resource.go (2)
PaginatedResource(447-450)NewPaginatedResourceRepository(354-364)internal/schema.go (1)
Schema(11-17)
test/e2e/api_transactions_list_test.go (2)
pkg/client/models/operations/v2listschemas.go (1)
Order(37-37)pkg/client/models/operations/v2listtransactions.go (1)
QueryParamOrderEffective(17-17)
🪛 markdownlint-cli2 (0.18.1)
pkg/client/docs/models/operations/v2listtransactionsrequest.md
13-13: Spaces inside emphasis markers
(MD037, no-space-in-emphasis)
13-13: Spaces inside emphasis markers
(MD037, no-space-in-emphasis)
pkg/client/docs/sdks/v2/README.md
247-247: Hard tabs
Column: 1
(MD010, no-hard-tabs)
248-248: Hard tabs
Column: 1
(MD010, no-hard-tabs)
249-249: Hard tabs
Column: 1
(MD010, no-hard-tabs)
250-250: Hard tabs
Column: 1
(MD010, no-hard-tabs)
251-251: Hard tabs
Column: 1
(MD010, no-hard-tabs)
252-252: Hard tabs
Column: 1
(MD010, no-hard-tabs)
308-308: Hard tabs
Column: 1
(MD010, no-hard-tabs)
309-309: Hard tabs
Column: 1
(MD010, no-hard-tabs)
310-310: Hard tabs
Column: 1
(MD010, no-hard-tabs)
311-311: Hard tabs
Column: 1
(MD010, no-hard-tabs)
312-312: Hard tabs
Column: 1
(MD010, no-hard-tabs)
313-313: Hard tabs
Column: 1
(MD010, no-hard-tabs)
368-368: Hard tabs
Column: 1
(MD010, no-hard-tabs)
369-369: Hard tabs
Column: 1
(MD010, no-hard-tabs)
370-370: Hard tabs
Column: 1
(MD010, no-hard-tabs)
371-371: Hard tabs
Column: 1
(MD010, no-hard-tabs)
372-372: Hard tabs
Column: 1
(MD010, no-hard-tabs)
373-373: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (49)
pkg/client/README.md (1)
133-135: LGTM!The documentation additions for the new schema operations are clear, well-formatted, and consistent with the existing API documentation structure.
internal/controller/ledger/listener.go (1)
16-16: LGTM!The
UpdatedSchemamethod addition is consistent with the existingListenerinterface pattern, and the parameter naming is now aligned with other methods (usingledgerinstead ofname).pkg/client/docs/models/components/v2schemascursor.md (1)
1-11: LGTM!The documentation for the
V2SchemasCursormodel is clear and follows the established format for cursor documentation. The field definitions are appropriate for a paginated response structure.test/e2e/api_transactions_list_test.go (1)
275-275: LGTM!The update from
OrdertoQueryParamOrderEffectivecorrectly reflects the repository-wide migration to the newQueryParamOrderenum type for v2 list operations.pkg/client/models/components/v2schema.go (1)
1-50: LGTM!This is Speakeasy-generated code that properly defines the V2Schema model with appropriate JSON serialization methods and nil-safe accessor methods. The implementation follows the established patterns for generated client models.
internal/bus/listener.go (1)
28-34: LGTM!The
UpdatedSchemamethod implementation is consistent with other listener methods, properly constructing and publishing the schema update event through the established event bus flow.test/e2e/api_schema_test.go (1)
1-144: LGTM!This comprehensive e2e test provides excellent coverage of the schema API functionality, including:
- Empty state handling
- Schema insertion and retrieval
- Multiple version management
- Error scenarios (non-existent and duplicate schemas)
The test structure follows established patterns and uses appropriate assertions.
internal/controller/ledger/listener_generated_test.go (1)
91-101: LGTM!The generated mock methods for
UpdatedSchemacorrectly follow the established gomock pattern and are consistent with other mock methods in this file.internal/storage/ledger/store.go (1)
85-91: LGTM! Clean implementation following established patterns.The
Schemas()method follows the same resource repository pattern used by other methods in this store, with appropriate defaults (paginate bycreated_atdescending).internal/api/v2/controllers_schema_read.go (1)
12-28: LGTM! Clean handler with appropriate error handling.The
readSchemahandler follows the established v2 controller pattern with proper error handling for not-found and general errors.internal/controller/ledger/controller_with_events.go (1)
154-166: LGTM! Consistent event emission pattern.The
UpdateSchemamethod follows the established pattern for event-emitting wrappers, correctly usinghandleEventfor transaction-aware event scheduling and only emitting when not in dry-run mode.pkg/client/models/components/v2schemascursorresponse.go (1)
5-14: LGTM! Standard cursor response wrapper.The generated
V2SchemasCursorResponsetype follows the established pattern for wrapping cursor objects in API responses with nil-safe getters.internal/api/v2/controllers_schema_read_test.go (1)
20-101: LGTM! Comprehensive test coverage.The test suite covers all critical paths (nominal case, not found, backend errors) with proper mock setup and validation of both status codes and response payloads. Parallel execution is appropriately enabled.
pkg/client/models/components/v2schemascursor.go (1)
5-38: LGTM! Standard pagination cursor implementation.The generated
V2SchemasCursortype follows the established cursor pagination pattern with appropriate fields and nil-safe getters.internal/storage/ledger/resource_schemas.go (1)
11-53: LGTM! Clean resource handler implementation.The
schemasResourceHandlerfollows the established pattern for repository handlers with:
- Appropriate schema definition with paginated string and date fields
- Standard BuildDataset with ledger filtering and PIT support
- Proper filter resolution for supported properties
- Clear rejection of unsupported expand operations
pkg/client/models/components/v2schemaresponse.go (1)
1-15: LGTM!The V2SchemaResponse type and its nil-safe GetData() accessor follow standard patterns for generated SDK code.
internal/controller/ledger/store.go (1)
49-51: LGTM!The new schema-related methods (InsertSchema, FindSchema, FindSchemas) are correctly added to the Store interface with appropriate signatures that align with the controller layer additions.
internal/api/v2/controllers_schema_list.go (1)
12-48: LGTM!The listSchemas handler implementation follows the established v2 API patterns:
- Appropriate default values (sort by "created_at" desc)
- Standard error handling with BadRequest and HandleCommonPaginationErrors
- Correct cursor rendering with schema transformation
internal/README.md (1)
110-112: LGTM!The generated documentation correctly reflects the new public schema-related types (Schema, SchemaData, UpdatedSchema) and their associated constructors and methods.
Also applies to: 136-137, 186-218
internal/api/v2/controllers_schema_insert_test.go (1)
16-103: LGTM!The test suite for insertSchema provides good coverage:
- Nominal success case
- Empty schema data handling
- Invalid JSON validation
- Backend error propagation
The test structure follows Go best practices with parallel execution and appropriate use of gomock and testify.
internal/controller/ledger/controller_with_traces.go (1)
496-538: LGTM!The GetSchema and ListSchemas tracing wrappers are correctly implemented with appropriate span names that match their method names and proper histogram instrumentation.
internal/controller/ledger/controller.go (1)
82-87: LGTM!The new Controller interface methods (UpdateSchema, GetSchema, ListSchemas) and the UpdateSchema parameter struct are well-defined with clear documentation and appropriate signatures that align with existing patterns in the codebase.
Also applies to: 134-137
internal/storage/ledger/schema.go (2)
22-35: Find by version scoped to ledger looks goodCorrect table prefixing and ledger scoping; errors normalized.
37-39: Pagination hook is correctDelegating to Schemas().Paginate aligns with existing resources.
internal/controller/ledger/controller_default.go (4)
63-66: UpdateSchema wiring via log processor looks correctUse of forgeLog matches existing patterns.
78-84: Get/List schema methods look goodThin wrappers over store; correct types and pagination usage.
163-164: Log processor initialization is consistentAdds updateSchemaLp like other processors.
278-282: Import UpdatedSchema path is fineInserting payload.Schema before persisting the log aligns with other payloads. With the store fix, CreatedAt from payload or DB will persist correctly.
internal/controller/ledger/controller_with_too_many_client_handling.go (3)
125-137: Retry wrapper for UpdateSchema is consistentMatches existing handleRetry pattern and returns all values.
139-151: Retry wrapper for GetSchema is consistentSimple pass-through with retries.
152-163: Retry wrapper for ListSchemas is consistentCorrect pagination cursor type and retry handling.
pkg/client/v2.go (3)
656-849: V2 InsertSchema method matches SDK patternsURL, body serialization (V2SchemaData), retries, hooks, and 204 handling are consistent.
Please ensure server returns 204 on success as coded here.
851-1057: V2 GetSchema deserialization path looks correctCorrect route, scopes, and JSON decode into V2SchemaResponse on 200.
1059-1269: V2 ListSchemas implementation is correctQuery params populated; 200 decodes to V2SchemasCursorResponse.
internal/api/v2/mocks_ledger_controller_test.go (3)
214-227: LGTM: GetSchema mock matches controller signatureMethod and recorder wiring look correct: ctx + version -> (*ledger.Schema, error).
347-360: LGTM: ListSchemas mock returns typed cursorSignature aligns with bunpaginate and ledger.Schema generics; recorder OK.
454-468: LGTM: UpdateSchema mock matches API contract Returns (*ledger.Log, *ledger.UpdatedSchema, error) and recorder wiring is correct; mocks and interface include GetSchema, ListSchemas, and UpdateSchema.internal/api/bulking/mocks_ledger_controller_test.go (3)
214-227: LGTM: GetSchema mock (bulking) is consistentSignature and recorder align with controller interface.
347-360: LGTM: ListSchemas mock (bulking) cursor typing OKbunpaginate cursor over ledger.Schema; recorder matches.
454-468: LGTM: UpdateSchema mock (bulking) matches expected return typesRecorder method signature is correct.
internal/controller/ledger/store_generated_test.go (3)
152-166: LGTM: Store.FindSchema mock added correctlyctx + version -> (*ledger.Schema, error); recorder matches.
167-181: LGTM: Store.FindSchemas mock returns typed cursorSignature uses common.PaginatedQuery[any] and bunpaginate.Cursor[ledger.Schema]; consistent with other paginated resources.
226-239: Store.InsertSchema mock matches interface
Mock signature aligns with theStoreinterface’sInsertSchema(ctx context.Context, data *ledger.Schema) error; no regeneration needed.internal/api/v1/mocks_ledger_controller_test.go (3)
214-227: LGTM: GetSchema mock (v1) added properlyMatches ctx + version -> (*ledger.Schema, error); recorder OK.
347-360: LGTM: ListSchemas mock (v1) returns cursor over ledger.SchemaRecorder and types are consistent with v2/bulking.
454-468: LGTM: UpdateSchema mock (v1) signature correctReturns (*ledger.Log, *ledger.UpdatedSchema, error); recorder wiring good.
pkg/client/models/operations/v2listschemas.go (1)
69-74: Verify pagination defaults on server
controllers_schema_list.gohandlessort(defaultcreated_at) andorder(defaultdesc); pagination usesbunpaginate.QueryDefaultPageSize. EnsureQueryDefaultPageSizeequals the client’s default15.pkg/client/models/operations/v2insertschema.go (1)
17-47: LGTM!The getter methods follow standard nil-safe patterns for generated code, correctly returning zero values when the receiver is nil.
internal/api/common/mocks_ledger_controller_test.go (1)
214-227: LGTM!The three new mock methods (
GetSchema,ListSchemas,UpdateSchema) are correctly generated and follow standard gomock patterns consistent with existing mocks in this file. The method signatures properly align with the controller interface definitions.Also applies to: 347-360, 454-468
Integrate in logs.
Integrate in events.