[PM-39925] feat: scaffold the Bit.Subscription.* and Bit.Invoicing libraries for invoice preview - #8208
[PM-39925] feat: scaffold the Bit.Subscription.* and Bit.Invoicing libraries for invoice preview#8208kdenney wants to merge 24 commits into
Conversation
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Re-reviewed at the current head. The only change since the last pass is Code Review DetailsNo new findings this pass. Re-verified since the previous review:
Dependency review: no manifest version changes. The new |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8208 +/- ##
==========================================
+ Coverage 63.29% 63.31% +0.01%
==========================================
Files 2401 2406 +5
Lines 104043 104091 +48
Branches 9426 9429 +3
==========================================
+ Hits 65857 65904 +47
- Misses 35930 35931 +1
Partials 2256 2256 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
c0c45fd to
3922c6e
Compare
3922c6e to
dfbff32
Compare
SaintPatrck
left a comment
There was a problem hiding this comment.
⛏️ PR description mentions new CLAUDE.md files in every library, but I don't see any new CLAUDE.md files, or modifications to existing ones.
|
|
||
| # Library comment discipline | ||
|
|
||
| Public API gets `///` doc comments — terse, but they state the contract LIBRARY.md requires: |
There was a problem hiding this comment.
⛏️ ❓ Pointing Claude to LIBRARY.md here is going to pull the entire file into context every time a matching path is touched, even if it's only reading a file in the path. LIBRARY.md contains more than comment-specific details, so the rule name is misleading.
This rule reads like it's relevant when Claude is writing-server-code, where LIBRARY.md is already referenced. Did you observe behavior that warranted duplicating the instructions and reference outside of writing-server-code?
There was a problem hiding this comment.
Yeah originally I had per-library CLAUDE.md files and each had this comment discipline rule inside but a claude reviewer suggested I remove the duplication and add it to a rule file that covers all of billing team's libraries.
The comment rule was essentially our team's attempt at forcing claude to stop writing verbose comments all throughout code that is already self-explanatory. I don't see any mentions of code comments in writing-server-code but I'm happy to relocate this or rethink how best to achieve this if you have any suggestions. Thanks for the feedback!
There was a problem hiding this comment.
writing-server-code is probably a better place for this. Library Shape is already referenced in the skill. If Claude isn't invoking writing-server-code, not reading LIBRARY.md, or not producing the expected results when it is invoked, we should try remediating that first.
There was a problem hiding this comment.
writing-server-code doesn't really say much about the library shape itself; it links out to LIBRARY.md for that. Buuuuut you could make the argument that all server code should follow this sort of comment discipline rule, not just library code. 😄 To that end, I'll add a comment discipline section to writing-server-code that is not library specific, but let me know if you think I should take a different approach. Thanks!
# Conflicts: # src/Core/Constants.cs
Includes the automatic packages.lock.json updates for Api and Api.Test reflecting the new project-reference graph.
… handling to group chain
…ng reference swap
…ionHandling reference swap
…illing/subscription/premium
…grade The rebase onto the stripe-upgrade branch brought in a newer main where Core swapped its direct Serilog.Extensions.Logging.File dependency for the new SerilogFileLogging project and the internal project version moved from 2026.7.2 to 2026.8.0. The lock files that this branch had regenerated at the old base were left stale, so `dotnet restore --locked-mode` (the CI gate) failed with NU1004. Regenerate the ten affected lock files to record the SerilogFileLogging project edge and the 2026.8.0 versions.
…nd add test placeholder
Minimal API endpoint groups don't get ApiExplorerGroupConvention, so without an explicit group name their future endpoints would emit into the published Public API spec (api.public.json). Set WithGroupName("internal") on both subscription groups to match the legacy PreviewInvoiceController, and assert it in the metadata tests.
Also add the placeholder test the repo convention expects so the otherwise-empty Invoicing.Test assembly doesn't fail the test run.
…in CODEOWNERS
The substring globs (**/*subscription*, **/*invoice*) don't match the
capitalized library paths, so the new src/Libraries/Invoicing and
src/Libraries/Subscriptions.{Organization,User} directories (and their
tests) were ownerless. Add explicit entries, following the
src/Libraries/OrganizationAuthorization precedent.
… a rule The three new libraries each carried a byte-identical "Comment discipline" section in their own CLAUDE.md, so the rule lived in triplicate with nothing keeping the copies in sync and a fresh copy due for every future library. Replace them with a single .claude/rules/billing-library-comment-discipline.md scoped via `paths:` to exactly the three new libraries (Invoicing, Subscriptions.Organization, Subscriptions.User) — matching the existing auth-tokenables and database-* rules — and delete the per-library CLAUDE.md files. The wording now states the contract LIBRARY.md requires so "terse" cannot be read as "skip the contract." Addresses the AI validation note on #8208.
…in Bit.Invoicing Address review feedback on PR #8208: the feature libraries no longer take a Core dependency for the feature flag key. - Add InvoicingFeatureFlags ([FlagKeyCollection]) in Bit.Invoicing holding PM36631_PreviewDrivenCart, and register it as a known flag from AddInvoicing via AddKnownFeatureFlags. - Reference Bit.Invoicing's key from both subscription endpoint groups and remove the constant from Core's FeatureFlagKeys. - Reference the Bitwarden.Server.Sdk meta-SDK in Bit.Invoicing so the [FlagKeyCollection] source generator runs; this also aligns the library lock files' platform package versions up to Core's baseline. - Trim the FeatureFlagKeys row from the subscription library README debt tables (Policies.Application remains) and note the ownership in Invoicing. - Replace the Invoicing.Test placeholder with a test asserting AddInvoicing registers the flag as a known feature flag.
…tionally in the API host Address review feedback on PR #8208: guarding service registration behind !SelfHosted risks a generic DI resolution failure. Register AddUserSubscriptions/AddOrganizationSubscriptions unconditionally (they are TryAdd singletons) and keep only the endpoint mapping and OpenAPI data source cloud-only, so the environment decision lives at routing.
…kill Replace the billing-scoped .claude/rules/billing-library-comment-discipline.md with a general "Comment discipline" subsection in the writing-server-code skill. The standalone rule fired on every touch of a matching library path, including reads, and duplicated guidance the skill already covers. Folding it into the skill removes the duplication and the misleading rule name, and applies the guidance to all server code rather than only the billing libraries. Addresses review feedback on #8208.
a47db11
225030d to
a47db11
Compare
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-39925
📔 Objective
Sets up the library skeleton for the preview-driven cart work. There is no user-facing behavior yet: the endpoint groups map no routes, and everything sits behind a feature flag that defaults off.
PM36631_PreviewDrivenCartfeature flag.src/Libraries/:Bit.Invoicing(platform tier, which will own the invoice-preview projection) plus two feature-tier endpoint-group shells,Bit.Subscriptions.UserandBit.Subscriptions.Organization.!globalSettings.SelfHostedblock). The host owns the route prefixes: the user group mounts at/account/billing/subscription/premiumand the organization group at/organizations/{organizationId:guid}/billing/subscription.Applicationauthorization policy, exception handling, and thePM36631_PreviewDrivenCartgate) to an empty group but maps no endpoints yet; those arrive in later slices. Only an authenticated caller is required at the group level, and each future handler will perform its own organization billing authorization check.Subscriptions.Userdirectory that the stock*.usergitignore pattern was silently hiding.All three libraries reference
Coreas a documented deviation from the target billing-library contract (pendingBit.Integrations.Billing, per ADR-0032); each library's README records what it takes from Core.This branch is stacked on the Stripe SDK upgrade work (PM-36225), which is its base and should merge first.
Stack created with GitHub Stacks CLI • Give Feedback 💬