Repository navigation
Merge develop into main: pricing engine, PII pipeline, web3 wallets, categories & inventory - #837
Merged
Merged
Conversation
…ermission engine (#372) (#819) * wip: salvage at quota wall 2026-10-12 * fix(authz): authorize ownership transfer before the existence check — unauthorized actors must not learn whether a resource has a recorded owner * fix(authz): owner-override fail-closed hardening — padded mode names never parse into a widening mode; owner fixture carries IsOwner; wildcard case exercised through the ownership designation only * test(authz): override the audit mock after CreateSut — Moq keeps the last matching setup, so the earlier override was silently discarded * fix(security): annotate owner-expiry audit log with CodeQL suppression Matches the established cs/cleartext-storage annotation pattern used for Guid audit logging throughout EffectivePermissionResolverService. * fix(authz): confine the system-account sensitive-equality taint step to a private predicate CodeQL reported 4 high cs/cleartext-storage-of-sensitive-information alerts at the owner-override audit logs. The taint source is the equality at the Layer-1 wildcard check (context.UserId == Authorization:SystemAccountId): the query's sensitive-equality step taints the context.UserId value, and may-alias propagation then reaches every audit log that reads context.UserId — which is why the line-adjacent codeql[] annotations could not suppress them (the alerts are on the read of a value tainted upstream, not on the annotated argument lines; the five still-open alerts 917-937 from earlier PRs show the same signature). Moving the comparison into IsSystemAccountUser(Guid) confines the tainted value to the predicate parameter, which never reaches a log sink. Both values are non- sensitive Guids; behavior is unchanged (pure predicate extraction). * fix(authz): drop user identifiers from owner-override engine logs (CodeQL cleartext-storage) Follows the fleet remedy proven in 1c9d054: the resolver's context.UserId is constrained by the Authorization:SystemAccountId equality (Layer-1 wildcard check), and CodeQL's clear-text-storage taint flags every log statement that stores it — suppression annotations cannot reach a value tainted upstream, and moving the comparison into a predicate did not break the path (verified on CI at 97a604d: same four alerts). The four owner-override log statements now omit the user identifier the way the #358 logs did; tenant/resource/mode data is retained, and the single test asserting on the 'Owner override applied' debug entry still matches. --------- Co-authored-by: Alexandre Tolstenko <tolstenko@gmail.com>
#823) * fix(authz): bulk permission cache expiry envelope (fail-closed) Cached bulk permission-check decisions previously stored raw booleans with the configured cache TTL and no grant-expiry boundary, so a cached allow could keep serving after its grant's ExpiresAt passed (no mutation, no security-version bump, no invalidation) until TTL eviction. - Cached bulk values are now CachedPermissionDecision records carrying EffectiveUntilUtc: the earliest ExpiresAt among grants that conveyed or denied the requested permission for that decision (min across participating grants). - Writes clamp each entry's TTL to the floored remaining grant lifetime via a new per-entry-TTL SetManyValuesAsync overload; the cache layers cap explicit TTLs at the configured TTLs so they only ever shorten. - Reads treat an entry whose envelope boundary has passed as a miss (fail closed) and re-evaluate from the authoritative grants; a decision whose floored remaining lifetime is already zero is returned but never cached. - HybridPermissionCache.SetAsyncCore now enforces the documented never-extends contract at L1 as well (previously only L2). - Bulk cache key bumped bulk:v1 -> bulk:v2 so pre-envelope boolean entries are never read again. - Docs: authorization-cache-configuration.md gains the bulk cache expiry envelope semantics and why load evidence stays in the BenchmarkDotNet performance projects. References #309 * wip: salvage at quota wall 2026-10-12
…ing, introspection control (#827) * feat(api): GraphQL authorization framework — @authorize directive, schema filtering, introspection control (#335) - General repeatable @authorize directive mapped to the typed permission model (permissions All/Any, policy, roles, maskUnauthorized, resource scoping) published from Identity.Authorization.GraphQL and usable by any domain module (attribute form). - Centralized deny-by-default field middleware (API host): policy/role checks via ASP.NET Core authorization services; permission checks via the effective-permission engine — resource-scoped rules activate owner override (#372) and expiration-aware precedence (#363); request-scoped permission-resolution and role-attribution caching; durable allow/deny evaluation logging (#359); fail-closed on anonymous callers, missing actor context, unknown permission keys, unresolvable resource ids and evaluation errors (bounded AUTHORIZATION_UNAVAILABLE / AUTHORIZATION_ DENIED errors; masking resolves denied fields to null). - Schema filtering + introspection control: permission-aware schema visibility fails closed (callers that cannot see every protected field are denied introspection; resource-scoped rules are never provable without a resource), config-gated Production restriction to schema admins (GraphQL:SchemaAuthorization), HotChocolate's coarse introspection firewall disabled in favor of the permission-aware gate. - SetupGraphQL registers the directive, applies middleware to all fields (introspection roots included) and drops HotChocolate's AddAuthorization in favor of the general contract; Projects adopts @authorize for the admin deleted-projects policy requirement. - Developer documentation (apps/api/docs/graphql-authorization.md) and enforcement-matrix/introspection/configuration test suites. References #335 * fix(api): drop unused resolver dependency from schema visibility evaluator (warning-clean) * fix(api): assert probe schema typename in GraphQL introspection test (CI)
…nciliation, metrics (#406) (#821) * feat(payments): wallet operations — multi-currency, adjustments, reconciliation, metrics Implements the issue #406 verifier spec for the billing wallet: - Multi-currency schema: unique index relaxed from UserId to (UserId, Currency) with an EF migration; CreateWallet enforces one wallet per user per currency (self-service returns 409 on duplicates); currency-aware credit/debit/transfer resolution with deterministic primary-wallet fallback. - POST wallets/{id}:adjust and POST wallets:transfer admin endpoints wiring the existing AddFunds/DeductFunds/TransferFunds commands, with privileged-action audit events and ReferenceId idempotency (replays return the original transaction without double-applying). - Report-only reconciliation query: Balance vs latest BalanceAfter vs Σ(Credit+TransferIn−Debit−TransferOut over Completed) per wallet, exposed at GET wallets/reconciliation. - Webhook-driven credit: durable BillingInvoicePaidV1 consumer credits the paying user's wallet through AddFundsCommand as the system actor, idempotent per provider event id (opt-out via Wallets:WebhookCreditEnabled). - Low-balance threshold notifications: WalletsOptions (threshold + interval + enable), WalletBalanceAlertMonitor background pass, WalletBalanceBelowThreshold Billing notification type with catalog classification and re-arm after recovery. - GET wallets/metrics: total balances by currency, active/frozen counts, completed transaction volume by type and day. References #406 * chore(openapi): regenerate typed client — wallet adjust/transfer/reconciliation/metrics endpoints (#406) * test(economy): seed the legacy treasury snapshot through the legacy schema (raw SQL over 2026-08-25 columns) — the current EF model already carries post-legacy wallet columns like LowBalanceAlertedAt, so an EF insert at the legacy point is not a legacy row * test(economy): read the surviving legacy row through the legacy schema after the downgrade too — the current EF model selects post-legacy wallet columns * fix(context): BeginActorContextScope repairs the original AsyncLocal holder on dispose — a plain Set/restore pair clears the caller's holder by design, leaving upstack observers with an anonymous context; the webhook wallet-credit handler now swaps the system actor through the scope so the dispatch pipeline's ambient context survives * test(wallets): keep DataProtection keys ephemeral in the in-memory integration factory — the certificate-protected EF key repository opens explicit transactions (rejected by the in-memory store) and its key-creation retry double-inserts into the request-scoped context, which 500s the adjust/transfer/reconciliation requests * fix(tests): implement BeginActorContextScope on the two remaining hand-written IActorContextAccessor stubs The Economy Release Gate solution build failed CS0535: BlogCommentTests.StubAccessor and DataMaskingPostgreSqlIntegrationTests.DataMaskingTestActorContextAccessor were the only hand-implemented accessors (everything else Moqs the interface) that did not grow the BeginActorContextScope member introduced for the webhook wallet-credit system-actor swap. Blog's stub keeps its no-op Set semantics with a no-op scope; the data-masking stub gets a faithful restore scope (set, then restore previous on dispose), matching PaymentRetryQueueWorkerTests.MutableActorContextAccessor. * fix(payments): register wallet ledger transactions explicitly — EntityBase pre-generates its Guid key, so change-tracking graph discovery infers new WalletTransaction rows as updates to existing rows and the save throws DbUpdateConcurrencyException (the 500s behind wallet adjust/transfer/reconciliation and the 8 WalletOperationsServiceTests failures); AddFunds/DeductFunds now return the created transaction and WalletService routes it through IWalletRepository.AddTransaction before saving (#406) * fix(payments): wallet integration reads use the API JSON contract (string enums) and transfers surface recipient currency mismatches instead of silently minting a destination wallet (#406)
…825) * feat(audit): query DSL with saved views and role-based access - Typed audit query DSL (field conditions, AND/OR/NOT nesting, eq/ne/gt/ gte/lt/lte/in/contains/startswith/wildcard) over the unified audit stores (AuthenticationAttempt, PermissionAuditLog, AuditLog) - Fail-closed parser accepting structured JSON and a light text syntax (actor:alice AND action:granted AFTER 2026-01-01); unknown fields, operators, and value types are rejected with precise errors - Bounded executor: AND-context window/source pushdown, per-source row caps, wall-clock timeout, tenant scope clamping, aggregates over the full matched set, redaction through IDataMaskingService (withheld on masking failure), and audit-trail attribution for every execution - Saved views: SavedAuditQuery is now a real persisted aggregate with CRUD, shared-vs-private access (owner or shared+audit-read), execute-by-id, revision history via SavedAuditQueryRevision, EF migration AddSavedAuditQueryViews, and DI wiring - Built-in role-based investigation templates (validated at startup) - Endpoints under v{v}/audit-queries: :execute, :results (GET paged), :validate, templates, and saved-view CRUD + {id}:execute; SystemAdmin policy per sibling Compliance.Audit controllers; mutations through ISender commands with use-case event contracts - Tests: parser matrix, evaluator semantics, executor (filters, paging, pushdown, limits, timeout, masking passthrough/failure, tenant clamping), saved-view CRUD/access matrix, authorization matrix References #160 * fix(audit): bare AFTER/BEFORE suffix binds as an implicit AND term in the text DSL; operator-name coverage respects the per-field matrix (ordered ops on timestamp); SavedAuditQueryServiceTests moves to the Services namespace; regenerate typed client for the audit query endpoints (#160)
#830) * wip: salvage at PC reset 2026-10-12 * fix(tests): implement IActorContextAccessor.BeginActorContextScope in the GraphQL authorize/schema test doubles — the develop-side interface change (billing wallet-credit handler) landed without updating these two doubles, breaking affected-API compilation
…ime reconstruction (#832) * feat(authz): governance audit wiring — inheritance cascades, policy snapshots, multi-stage approvals, point-in-time reconstruction (refs #188, refs #189) * test(authz): governance audit + reconstruction suites; migration for governance tables (refs #188, refs #189) * test(api)+docs+dbml: EF-hook capture tests for governance entities, permission-change-tracking doc, regenerated schema.dbml (refs #188, refs #189) * fix(authz): resolve governance audit hook lazily to break the DbContext DI cycle; implement BeginActorContextScope on GraphQL test fakes (refs #188, refs #189) * chore(client): regenerate typed client from captured OpenAPI (permission history + approvals endpoints) (refs #188, refs #189) * test(authz): fix strict-mock setups in approval/snapshot tests (grant setup on final approval; sequence default return)
…n web build (#834) The Devtron web image build fails at the deps stage: ENOENT: no such file or directory, open '/repo/patches/braces@3.0.3.patch' exit code: 254 .dockerignore is deny-all (`**/*` plus an allowlist) and never allowed patches/. `turbo prune --docker` therefore runs without the patch files, so it omits them from out/json, and the subsequent `pnpm install --frozen-lockfile` cannot resolve the patchedDependencies declared in pnpm-workspace.yaml. Allowlist patches/ and lock the invariant with a CI test that fails if any declared or lockfile-referenced patch path is excluded from the build context.
The Devtron API image fails at the publish step with 56 Sonar analyzer errors (S3928, S3267, S1066, S125, S1694, ...). The root .editorconfig — the only place those rules are reviewed and waived to severity=none — was absent from the Docker build context (deny-all .dockerignore) and never copied by apps/api/Dockerfile, so the image compiled against Sonar defaults while SharedKernel sets TreatWarningsAsErrors=true. Allowlist .editorconfig in .dockerignore and COPY it into the api build stage workdir (/src), where Roslyn discovers it as an ancestor of Source/**. Lock the invariant with a CI test mirroring the pnpm-patches guard. Verified with full docker builds of the `build` stage: - original files: 56 analyzer errors, exit 1 (matches the Devtron log) - with fix: publish succeeds, exit 0
…ts, cycle-change proration, validation (#391 #392) (#829) * wip: salvage at PC reset 2026-10-12 * feat(subscriptions): interval-aware pricing — per-interval price points with derived fallbacks, cycle-change proration via the shared billing calculator, EF migration, command wiring and unit coverage; register the SetSubscriptionPlanIntervalPrice use-case event contract (#391 #392) * fix(subscriptions): XML doc comments must not use the × HTML entity (CS1570 under warnings-as-errors) * fix(subscriptions): register IBillingCalculator and ISubscriptionIntervalPricingService (the lifecycle service took them without a registration — host validation aborted startup); implement BeginActorContextScope in the GraphQL test doubles (develop-side interface change) * fix(subscriptions): the plan-comparison benchmark fake implements the interval-price repository members (whole-solution economy gate compiles the performance project)
…ty and bundle recommendations (#401) (#826) * feat(commerce): hierarchical categories, inventory availability, bundle recommendations (issue #401) - ProductCategory entity (single-parent tree, tenant-unique slug, jsonb attributes, depth cap 5, cycle-preventing validator) + admin CRUD endpoints guarded by products:manage, optimistic concurrency and Compliance.Audit logging - Product->category assignment via create/update/patch product commands; categoryId catalog filter includes descendant categories - ProductInventory entity (stock/reserved/track flag, untracked-by-default) with reserve-on-add-to-order, decrement-on-complete, release-on-cancel, restore-on-refund hooks; GET products/{id}/availability; PUT products/{id}/inventory; inStock filter - Rule-based recommendations: frequently-bought-together from completed-order co-occurrence (cached, sized entries), bundle sum-of-parts savings hints, complete-the-bundle optional items; ML personalization documented as deferred References #401 * feat(commerce): EF migration ProductCatalogCategoriesInventory + build fixes (issue #401) * test(commerce): unit coverage for categories, inventory hooks, bundle savings, recommendations (issue #401) * wip: salvage at quota wall 2026-10-12b * fix(commerce): recommendation fixture builds a real bundle anchor (CompleteTheBundle needs it) and keeps Draft published for the tie ranking; refund fixture uses the refundable Completed status; cancel-handler tests mock the line-items load path; regenerate typed client for categories/inventory/recommendations endpoints (#401) * fix(commerce): category/inventory unit fixtures — the depth test builds two independent chains (moving a root under its own descendant is a cycle, not depth); untracked inventory never accumulates stock; Configure guards shrinking below reserved so the commit-fail state is seeded via a concurrent-writer simulation; the guards test reserves from restocked units; the catalog test DbContext mirrors the production Version auto-increment so SoftDelete accepts persisted rows (#401)
…rs, SIWE hooks, sign-in UI (#291 #16 #38 #39) (#831) * wip: salvage at PC reset 2026-10-12 * fix(web3): export COMMON_CHAINS from the testing harness, classify SIWE failures as verification_failed and surface the unauthorized taxonomy when authenticating before connect; lockfile updated for the package's new dev dependencies * fix(web): declare the @game-guild/web3 workspace dependency — eslint resolved the import as any without it (unsafe-call/member-access family) * fix(web3): package typechecks clean (MapIterator spread, readonly error code via Object.assign, no jest-dom matcher dependency) and the wallet buttons access the context through its object (unbound-method) with the WalletError parameter scoped correctly; tsconfig aligned to the auth-components library shape * fix(web3): drop the unused React import in the provider test (react-jsx runtime) * fix(web3): drop the remaining unused chain-switch import * fix(web): pin the wallet context to a narrow local contract so lint type-checks connect/account even where the package's context generics do not resolve in the host project * fix(web3): remove adjacent wildcards from the chain-error match The 'chain.*not.*(added|found)' branch is a polynomial (ReDoS-prone) regex flagged by CodeQL on wallet-controlled error messages. Equivalent literal separator match keeps the same accepted messages without the nested wildcards. --------- Co-authored-by: Alexandre Tolstenko <tolstenko@gmail.com>
…ddons/usage/promos/proration/tax/credits (#417) (#824) * feat(commerce): unified pricing engine core with tax wiring, previews, and ledger quotes - IPricingEngine in Payments: one calculation path for base plan/custom amount, independently priced add-ons, progressive usage tiers, promo discounts, proration, tax, wallet credits, currency conversion, and pricing-decision ledger recording (#809 ledger, Version-2 breakdown with replay arithmetic) - Wire the landed building blocks: TaxCalculationService (was never called from pricing), BillingCalculator.CalculateProration via IPlanProrationCalculator, Products promo engine (#795) via IPromoDiscountCalculator, SharedKernel FX core (#790) with fail-closed conversion and plan-price caching - Retire the divergent calculi: Payments CalculatePricingQueryHandler stub (SAVE20 string parsing, zeroed add-ons/tax) now delegates to the engine; dead ISubscriptionDomainService and the duplicate Subscriptions PricingCalculationResult/AppliedDiscount/DiscountType models removed; one PricingCalculationResult model remains (Payments) - Endpoints: POST /api/v1/pricing/:calculate, POST /api/v1/pricing/:preview, GET /api/v1/pricing/calculations/{id}, POST /api/v1/pricing/validate/{id}, GET /api/v1/subscriptions/{id}/breakdown, POST /api/v1/subscriptions/{id}/pricing:preview - Engine self-validation invariants + ledger-backed validate query with replay - Tests: engine unit suite (tiers, stacking scope, tax-after-discount, inclusive/exclusive, B2B, credits caps/consume, FX, ledger replay, caching, preview) and CI-enforced <100ms p99 latency gate References #417 * feat(commerce): surface rejected promo codes in pricing results * wip: salvage at quota wall 2026-10-12b * chore(openapi): regenerate typed client — unified pricing engine endpoints (pricing-calculate, previews, ledger quotes, validation) (#417) * fix(pricing): honor the persisted DiscountType contract and guard null calculation requests — FreeMonths stays 2 / Credits moves to 3 (numeric values 0-2 are the persisted Payments contract; the unified enum had them swapped) and CalculatePricingQueryHandler now throws ArgumentNullException instead of NullReferenceException on a null request (#417) * chore(openapi): regenerate client — DiscountType member order follows the persisted Payments contract (FreeMonths=2, Credits=3) (#417) * test(payments): align wallet mock signatures with the currency parameter DeductFundsAsync gained an optional currency argument in the unified pricing engine; the two PricingEngineTests mocks still bound the CancellationToken to parameter 5 and failed to compile. --------- Co-authored-by: Alexandre Tolstenko <tolstenko@gmail.com>
…red logs and the audit sink (#192) (#828) * feat(compliance): PII redaction and tokenization pipeline (issue #192) * fix(migrations): drop stray conflict-label remnant in the model snapshot hand-union * fix(compliance): the PII log sink's dependency graph must stay ILogger-free — resolving the logger factory from inside the Serilog configuration lambda re-enters factory creation and deadlocks startup in a DI StackGuard recursion (thread-dump-verified); sink diagnostics move to Serilog SelfLog and provider/tokenizer diagnostics to Trace; regenerate typed client for the redaction pipeline endpoints (#192) * fix(compliance): resolve committed merge markers in AuditModelConfiguration Keep both sides of the conflicted hunk: the PII pipeline entities (this branch) and the saved-audit-query views (develop) — both already have migrations and snapshot entries. * fix(migrations): rebuild model snapshot — develop base + PII pipeline entities The branch snapshot carried interleaved merge markers. Take develop's clean snapshot (includes saved-query views, permission history, interval prices) and transplant the three PII entities from the original PII commit (0fdf842). * fix(migrations): rebuild snapshot on current develop + sync merged develop Take develop's snapshot (governance history, interval prices, refunds) and transplant the three PII entities from the original PII commit. EF confirms no pending model changes. * fix(api): compose the PII interceptor chain in AddDatabase AddDatabase resolves AuditLogPiiRedactionInterceptor for the DbContext unconditionally, but its registrations lived only in the audit module — minimal service collections (unit tests) could not build the options. TryAdd the interceptor and its dependency chain next to the sibling interceptor registrations; the audit module stays authoritative when composed. * fix(compliance): make the redaction engine order rules by precedence itself (field-name before global, then ascending priority — defense in depth over the provider ordering); reject any supplied non-compilable regex regardless of rule pattern type; persist staged vault/operation rows in the pipeline service tests before querying (InMemory queries do not see pending Adds); add PiiRedactionRuleRefreshServiceTests with an injectable refresh interval (#192) * fix(compliance): stage one vault row per tokenized match — the engine outcome now carries per-match token/original pairs so the vault maps each deterministic token back to exactly the PII value it replaced instead of the whole surrounding field text (#192) * fix(compliance): extract the tokenized-list assignment (Sonar S1121) The inline `(tokenized ??= []).Add(...)` assignment inside the replace lambda fails the Release build's analyzer gates. --------- Co-authored-by: Alexandre Tolstenko <tolstenko@gmail.com>
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| BestPractice | 85 medium 2 minor |
| ErrorProne | 2 high |
| CodeStyle | 11 minor |
🟢 Metrics 3068 complexity · 142 duplication
Metric Results Complexity 3068 Duplication 142
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved authorization, PII leakage, wallet idempotency, and billing correctness defects could affect security and financial integrity.
8 open findings
Prevent exception handling from emitting unredacted log events · New Enforce atomic uniqueness for wallet reference idempotency · New Align proration and billing periods with effective transitions · New Redact fallback IP addresses and session IDs · New Require authentication for CreateProject · New Reject unpublished anchor products from anonymous recommendations · New Record audit entries for system-initiated wallet mutations · New Group interval reports by currency · New
What changed in this PR
This release merge integrates major commerce, privacy, authorization, audit, and Web3 capabilities across the platform.
Changes:
- Adds unified pricing, multi-currency wallets, interval billing, product categories, inventory, and recommendations.
- Adds PII redaction, audit-query governance, permission history, and owner overrides.
- Adds Web3 wallet authentication, generated clients, migrations, tests, and container-build safeguards.
| File group | Description |
|---|---|
.dockerignore, apps/api/Dockerfile, .github/workflows/pr-verify.yml, scripts/ci/tests/* |
Fixes and verifies Docker build inputs. |
packages/features/web3/** |
Implements wallet adapters, SIWE state/provider APIs, tests, and documentation. |
apps/web/src/auth.ts, apps/web/src/lib/auth/web3-credentials.ts, apps/web/src/components/wallet-sign-in-buttons.tsx, apps/web/src/app/api/auth/web3/challenge/route.ts |
Integrates Web3 authentication into the web application. |
packages/infrastructure/client/src/generated/** |
Regenerates clients and types for the expanded APIs. |
apps/api/Source/Modules/GameGuild.Commerce.Payments/** |
Adds pricing-engine and multi-currency wallet operations, reconciliation, alerts, and metrics. |
apps/api/Source/Modules/GameGuild.Commerce.Subscriptions/** |
Adds interval-specific prices and billing-cycle proration. |
apps/api/Source/Modules/GameGuild.Commerce.Products/** |
Adds hierarchical categories, inventory, bundle savings, and catalog enrichment. |
apps/api/Source/Modules/GameGuild.Commerce.Orders/** |
Connects inventory lifecycle hooks and public recommendations. |
apps/api/Source/Modules/GameGuild.Compliance.Audit/** |
Adds PII protection, saved audit queries, and compliance evidence processing. |
apps/api/Source/Modules/GameGuild.Identity.Authorization/** |
Adds permission history, approvals, ownership transfer, and GraphQL authorization infrastructure. |
apps/api/Source/Modules/GameGuild.Projects/GraphQL/**, apps/api/Source/GameGuild.API/Core/GraphQL/** |
Migrates project resolvers to custom field authorization. |
apps/api/Source/GameGuild.API/Database/Migrations/**, ApplicationDbContext.cs |
Persists the new commerce, audit, and governance models. |
apps/api/tests/** |
Expands unit, integration, performance, architecture, and security coverage. |
docs/**, apps/api/docs/** |
Documents schema, billing, PII, and authorization behavior. |
pnpm-lock.yaml, package/project manifests |
Updates frontend and backend dependencies. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Release train (follows #696)
Highlights
.dockerignorenow shipspatches/and.editorconfiginto build contexts (+ CI regression guards)Verify
Same review policy as #696: needs 2 approvals + last-push approval.