refactor(ipns): drop folder/file record_type discriminator#562
Conversation
The record_type ('folder' vs 'file') discriminator was write-only metadata
the client volunteered to a zero-knowledge server. Nothing functional (TS or
Rust) branched on it and the server never returned it — it fed only a single
Prometheus gauge label and two log strings. Rather than teach the client to tag
every record, remove the field entirely across the stack. The functional
expectedSequenceNumber CAS field is untouched.
Layers touched:
- Client / SDK: drop recordType from sdk-core registration builders and the
ipns/shared-write batch payloads, and from apps/web ipns.service.
- API: remove recordType from the PublishIpnsEntryDto, the publishRecord /
upsertFolderIpns signatures and object literals, and strip the type prefix
from the two republish-enrollment log strings.
- DB: drop the folder_ipns.record_type column (entity + a new migration
DropFolderIpnsRecordType inverting AddRecordTypeToFolderIpns).
- Metrics: collapse the cipherbox_ipns_entries_total gauge from a
record_type-labelled, group-by-and-seed collection to a single untyped
folder_ipns row count.
- Grafana: drop the record_type-broken-down "IPNS Entries by Type" panel (a
"Total IPNS Entries" panel already exists) and convert "IPNS Entry Growth"
to a single sum() series; update docker/MONITORING.md.
- Regenerated @cipherbox/api-client (removed the orphaned
publishIpnsEntryDtoRecordType model + barrel export, refreshed openapi.json).
Tests updated to drop recordType fixtures/assertions; the metrics regression
test now asserts a single untyped gauge value.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDNQVLoAw4DbPrPvtQPobh
|
Warning Review limit reached
More reviews will be available in 34 minutes and 53 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughIPNS publish contracts, storage, SDK payloads, and dashboards stop using ChangesIPNS recordType removal
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Release Preview
Cascade Details
|
Greptile SummaryThis PR removes the
Confidence Score: 5/5The change is safe to merge: it removes write-only metadata that nothing functional depended on, with consistent updates across every layer (DB migration, entity, DTO, service, SDK, generated client, metrics, Grafana) and passing targeted test suites. The field being dropped was confirmed write-only (no server return path, no branching logic). The migration is guarded with IF EXISTS / IF NOT EXISTS, all call sites were updated in the same PR, and the metrics simplification is mechanically correct. No orphaned references remain in the checked files. No files require special attention. The most sensitive file — the TypeORM migration — is straightforward and properly invertible. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client as Client / SDK
participant API as API (publishRecord)
participant DB as folder_ipns table
participant Metrics as MetricsService
Note over Client,Metrics: Before — recordType threaded through every layer
Client->>API: "{ ipnsName, record, metadataCid, recordType: 'file'|'folder', ... }"
API->>DB: upsertFolderIpns(..., recordType)
DB-->>API: saved row (record_type column updated)
Metrics->>DB: GROUP BY record_type
DB-->>Metrics: "[{recordType:'folder',count:'N'},{recordType:'file',count:'M'}]"
Metrics->>Metrics: gauge.labels('folder').set(N) / gauge.labels('file').set(M)
Note over Client,Metrics: After — recordType removed end-to-end
Client->>API: "{ ipnsName, record, metadataCid, ... }"
API->>DB: upsertFolderIpns(...)
DB-->>API: saved row (record_type column dropped)
Metrics->>DB: repository.count()
DB-->>Metrics: total row count
Metrics->>Metrics: gauge.set(total)
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client as Client / SDK
participant API as API (publishRecord)
participant DB as folder_ipns table
participant Metrics as MetricsService
Note over Client,Metrics: Before — recordType threaded through every layer
Client->>API: "{ ipnsName, record, metadataCid, recordType: 'file'|'folder', ... }"
API->>DB: upsertFolderIpns(..., recordType)
DB-->>API: saved row (record_type column updated)
Metrics->>DB: GROUP BY record_type
DB-->>Metrics: "[{recordType:'folder',count:'N'},{recordType:'file',count:'M'}]"
Metrics->>Metrics: gauge.labels('folder').set(N) / gauge.labels('file').set(M)
Note over Client,Metrics: After — recordType removed end-to-end
Client->>API: "{ ipnsName, record, metadataCid, ... }"
API->>DB: upsertFolderIpns(...)
DB-->>API: saved row (record_type column dropped)
Metrics->>DB: repository.count()
DB-->>Metrics: total row count
Metrics->>Metrics: gauge.set(total)
Reviews (2): Last reviewed commit: "fix: address PR review comments" | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/api/src/ipns/ipns.service.ts (1)
349-360: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winNormalize the enrollment rejection before logging it.
Lines 360 and 397 assume
enrollFolder()always rejects with anError. If it rejects with a string,null, or another non-Errorvalue,err.messagethrows inside this detached.catch(), which drops the warning and can surface as an unhandled rejection. Please format these the same way as the delegated-routing error handling above.Suggested fix
- .catch((err) => - this.logger.warn(`Failed to enroll ${ipnsName} for republishing: ${err.message}`) - ); + .catch((err) => + this.logger.warn( + `Failed to enroll ${ipnsName} for republishing: ${err instanceof Error ? err.message : String(err)}` + ) + );Also applies to: 386-397
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/ipns/ipns.service.ts` around lines 349 - 360, Normalize the `enrollFolder()` rejection before logging in `ipns.service.ts`, since the detached `.catch()` in the republish flow assumes an `Error` and can throw again if the rejection is a string, null, or other value. Update the warning handling in the `republishService.enrollFolder(...)` branches to match the delegated-routing error normalization pattern already used nearby, and log a safe message derived from the normalized error instead of directly accessing `err.message`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/metrics/metrics.service.spec.ts`:
- Around line 149-152: Tighten the assertions in metrics.service.spec.ts around
the metric rendering for metric names like cipherbox_ipns_entries_total so the
test fails if collectGauges() emits legacy record_type-labeled series again.
Update the existing expectations near the single-metric checks to verify the
rendered output contains exactly one sample line for the aggregate metric and
explicitly does not include any record_type= labels, rather than only matching a
0 or 5 value. Use the existing service.registry.getSingleMetricAsString and
metric variable assertions to locate the affected tests.
In `@apps/api/src/migrations/1749400000000-DropFolderIpnsRecordType.ts`:
- Around line 16-34: The migration in DropFolderIpnsRecordType is not truly
reversible because up() drops the only stored record_type values and down()
repopulates every row with a fabricated default. Fix this by either preserving
the existing discriminator values before ALTER TABLE in up() so down() can
restore them correctly, or by making the down() path explicitly irreversible
instead of recreating the column with a blanket 'folder' value. Keep the fix
centered on the QueryRunner migration methods up() and down() and ensure
rollback does not silently relabel file entries.
In `@docker/grafana/dashboards/cipherbox-staging.json`:
- Around line 772-773: The Grafana panel query for cipherbox_ipns_entries_total
is overcounting because it uses a summing aggregate across replicas; update the
dashboard expression in the IPNS entries panel to use a deduping single-series
aggregate such as max() instead of sum(), so it reflects the actual DB total
from MetricsService.collectGauges() and the folder_ipns row count exported by
each API instance.
In `@release-please-config.json`:
- Line 69: The current release-as targets for the contract removals are patch
versions, which under-version these breaking pre-1.0 changes. Update the
release-please configuration entries tied to the public API DTO and sdk-core
surface removals so they use minor release-as targets instead of 0.44.1 /
0.39.1, keeping the change aligned with the relevant release config symbols in
release-please-config.json.
---
Outside diff comments:
In `@apps/api/src/ipns/ipns.service.ts`:
- Around line 349-360: Normalize the `enrollFolder()` rejection before logging
in `ipns.service.ts`, since the detached `.catch()` in the republish flow
assumes an `Error` and can throw again if the rejection is a string, null, or
other value. Update the warning handling in the
`republishService.enrollFolder(...)` branches to match the delegated-routing
error normalization pattern already used nearby, and log a safe message derived
from the normalized error instead of directly accessing `err.message`.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e0426664-ab16-4dcd-8405-b0a557d0c214
⛔ Files ignored due to path filters (131)
packages/api-client/openapi.jsonis excluded by!packages/api-client/**packages/api-client/src/generated/auth/auth.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/device-approval/device-approval.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/health/health.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/identity/identity.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/invites/invites.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/ipfs/ipfs.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/ipns/ipns.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/root/root.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/share-invites/share-invites.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/shares/shares.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/tee/tee.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/generated/vault/vault.tsis excluded by!**/generated/**,!**/generated/**,!packages/api-client/**packages/api-client/src/models/addShareKeysDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/authMethodResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/authMethodResponseDtoType.tsis excluded by!packages/api-client/**packages/api-client/src/models/batchPublishIpnsDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/batchPublishIpnsResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/batchUnenrollIpnsDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/batchUnenrollIpnsResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/childKeyDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/childKeyDtoKeyType.tsis excluded by!packages/api-client/**packages/api-client/src/models/claimChildKeyDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/claimChildKeyDtoKeyType.tsis excluded by!packages/api-client/**packages/api-client/src/models/claimInviteDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/claimInviteResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/connectionTestRequestDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/connectionTestResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/connectionTestResponseDtoProtocol.tsis excluded by!packages/api-client/**packages/api-client/src/models/createApprovalDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/createInviteDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/createInviteDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareDtoPermission.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/createShareResponseDtoPermission.tsis excluded by!packages/api-client/**packages/api-client/src/models/deleteAccountDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/deleteAccountResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/desktopRefreshDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/deviceApprovalControllerCreateRequest201.tsis excluded by!packages/api-client/**packages/api-client/src/models/deviceApprovalControllerGetPending200Item.tsis excluded by!packages/api-client/**packages/api-client/src/models/deviceApprovalControllerGetStatus200.tsis excluded by!packages/api-client/**packages/api-client/src/models/deviceApprovalControllerGetStatus200Status.tsis excluded by!packages/api-client/**packages/api-client/src/models/googleLoginDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/googleLoginDtoIntent.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200Details.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200DetailsDatabase.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200Error.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200Info.tsis excluded by!packages/api-client/**packages/api-client/src/models/healthControllerCheck200InfoDatabase.tsis excluded by!packages/api-client/**packages/api-client/src/models/identityControllerGetJwks200.tsis excluded by!packages/api-client/**packages/api-client/src/models/identityControllerGetJwks200KeysItem.tsis excluded by!packages/api-client/**packages/api-client/src/models/identityControllerGetWalletNonce200.tsis excluded by!packages/api-client/**packages/api-client/src/models/identityTokenResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/index.tsis excluded by!packages/api-client/**packages/api-client/src/models/initVaultDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteChildKeyDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteChildKeyDtoKeyType.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteDataResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteDataResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteDataResponseDtoStatus.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteResponseDtoStatus.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteStatusResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/inviteStatusResponseDtoStatus.tsis excluded by!packages/api-client/**packages/api-client/src/models/ipfsControllerUploadBody.tsis excluded by!packages/api-client/**packages/api-client/src/models/ipnsControllerResolveRecordParams.tsis excluded by!packages/api-client/**packages/api-client/src/models/linkMethodDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/linkMethodDtoLoginType.tsis excluded by!packages/api-client/**packages/api-client/src/models/loginDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/loginDtoLoginType.tsis excluded by!packages/api-client/**packages/api-client/src/models/loginResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/logoutResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/lookupUserResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/paginatedReceivedSharesDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/paginatedSentSharesDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/pendingRotationResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/pendingRotationResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/publishIpnsDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/publishIpnsEntryDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/publishIpnsEntryDtoRecordType.tsis excluded by!packages/api-client/**packages/api-client/src/models/publishIpnsResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/quotaResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/receivedShareResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/receivedShareResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/receivedShareResponseDtoPermission.tsis excluded by!packages/api-client/**packages/api-client/src/models/registerCidDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/registerCidResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/resolveIpnsResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/respondApprovalDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/respondApprovalDtoAction.tsis excluded by!packages/api-client/**packages/api-client/src/models/sendOtpDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/sendOtpResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/sentShareResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/sentShareResponseDtoItemType.tsis excluded by!packages/api-client/**packages/api-client/src/models/sentShareResponseDtoPermission.tsis excluded by!packages/api-client/**packages/api-client/src/models/setByoStatusDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/setByoStatusResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/shareInvitesControllerListInvitesParams.tsis excluded by!packages/api-client/**packages/api-client/src/models/shareKeyEntryDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/shareKeyEntryDtoKeyType.tsis excluded by!packages/api-client/**packages/api-client/src/models/shareKeyResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/shareKeyResponseDtoKeyType.tsis excluded by!packages/api-client/**packages/api-client/src/models/sharesControllerGetReceivedSharesParams.tsis excluded by!packages/api-client/**packages/api-client/src/models/sharesControllerGetSentSharesParams.tsis excluded by!packages/api-client/**packages/api-client/src/models/sharesControllerLookupUserParams.tsis excluded by!packages/api-client/**packages/api-client/src/models/teeKeysDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/testLoginDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/testLoginResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/tokenResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/unlinkMethodDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/unlinkMethodResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/unpinDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/unpinResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/updateEncryptedKeyDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/updateItemNameDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/updatePermissionDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/updatePermissionDtoPermission.tsis excluded by!packages/api-client/**packages/api-client/src/models/uploadResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/vaultConfigResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/vaultExportDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/vaultResponseDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/vaultResponseDtoTeeKeys.tsis excluded by!packages/api-client/**packages/api-client/src/models/verifyOtpDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/verifyOtpDtoIntent.tsis excluded by!packages/api-client/**packages/api-client/src/models/walletVerifyDto.tsis excluded by!packages/api-client/**packages/api-client/src/models/walletVerifyDtoIntent.tsis excluded by!packages/api-client/**
📒 Files selected for processing (16)
apps/api/src/ipns/dto/publish.dto.tsapps/api/src/ipns/entities/folder-ipns.entity.tsapps/api/src/ipns/ipns-verify-cache.spec.tsapps/api/src/ipns/ipns.service.spec.tsapps/api/src/ipns/ipns.service.tsapps/api/src/metrics/metrics.service.spec.tsapps/api/src/metrics/metrics.service.tsapps/api/src/migrations/1749400000000-DropFolderIpnsRecordType.tsapps/web/src/services/ipns.service.tsdocker/MONITORING.mddocker/grafana/dashboards/cipherbox-staging.jsonpackages/sdk-core/src/__tests__/folder.test.tspackages/sdk-core/src/folder/registration.tspackages/sdk-core/src/ipns/index.tspackages/sdk/src/share/shared-write.tsrelease-please-config.json
💤 Files with no reviewable changes (6)
- apps/api/src/ipns/entities/folder-ipns.entity.ts
- packages/sdk/src/share/shared-write.ts
- packages/sdk-core/src/ipns/index.ts
- apps/api/src/ipns/ipns-verify-cache.spec.ts
- apps/web/src/services/ipns.service.ts
- apps/api/src/ipns/ipns.service.spec.ts
- ipns.service: normalize enroll-failure errors before logging (instanceof Error guard) - metrics spec: assert single ipns_entries_total sample, no record_type label - folder.test: positive ipnsName identity assertions for file/folder records - grafana: use max() not sum() for cipherbox_ipns_entries_total (multi-replica dedup) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SDNQVLoAw4DbPrPvtQPobh
|
Resolved CodeRabbit / greptile review feedback in Fixed:
Declined / deferred (replied inline on the threads):
Verification: targeted jest suites ( |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (66.66%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #562 +/- ##
==========================================
- Coverage 65.96% 65.93% -0.03%
==========================================
Files 149 149
Lines 11503 11494 -9
Branches 1305 1305
==========================================
- Hits 7588 7579 -9
- Misses 3673 3674 +1
+ Partials 242 241 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Summary
Completely removes the
record_type/recordTypediscriminator ('folder'vs'file') for IPNS records across the whole monorepo.It was write-only metadata the client volunteered to a zero-knowledge server: nothing functional (TS or Rust) branched on it, the server never returned it, and it was consumed only by a single Prometheus gauge label plus two log strings. Rather than teach the client to tag every record, the field is deleted end to end. The functional
expectedSequenceNumberCAS field is left untouched.Layers touched
recordTypefrom the sdk-core registration builders and theipns/shared-writebatch payloads, and from theapps/webipns.service.recordTypefromPublishIpnsEntryDto, from thepublishRecord/upsertFolderIpnssignatures and object literals, and strip the${recordType}prefix from the two republish-enrollment log strings.folder_ipns.record_typecolumn (entity + new migrationDropFolderIpnsRecordTypethat invertsAddRecordTypeToFolderIpns).cipherbox_ipns_entries_totalfrom arecord_type-labelled, group-by-and-seed collection to a single untypedfolder_ipnsrow count.record_type-broken-down "IPNS Entries by Type" panel (a "Total IPNS Entries" panel already exists) and convert "IPNS Entry Growth" to a singlesum(cipherbox_ipns_entries_total)series; updatedocker/MONITORING.md. No panel references therecord_typelabel anymore and the JSON still parses.@cipherbox/api-client(removed the orphanedpublishIpnsEntryDtoRecordTypemodel + barrel export, refreshedopenapi.json).Tests
Updated to drop
recordTypefixtures/assertions:packages/sdk-core/src/__tests__/folder.test.ts— assert viaexpectedSequenceNumberinstead ofrecordType.apps/api/src/ipns/ipns.service.spec.tsandapps/api/src/ipns/ipns-verify-cache.spec.ts— droppedrecordTypefixtures.apps/api/src/metrics/metrics.service.spec.ts— regression block now asserts a single untyped gauge value;mockFolderIpnsRepoexposescount().Verification
api(nest build),sdk-core,sdk,web(tsc -b) — all clean.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes