feat(worker): Phase 3c — port heavy writes (freeze/mint/analyze/generate/trust/ledger/seed)#41
Conversation
…ate/trust/ledger/seed) Ports 8 write routes with external service calls (ChittyMint, ChittyLedger, OpenAI gpt-4o) and the dev-only seed-demo endpoint: POST /api/assets/:id/freeze server/routes.ts:125 POST /api/assets/:id/mint server/routes.ts:166 POST /api/evidence/:evidenceId/analyze server/routes.ts:379 POST /api/legal/generate-document server/routes.ts:557 POST /api/assets/:assetId/calculate-trust-score server/routes.ts:596 POST /api/evidence-ledger/submit server/routes.ts:51 POST /api/evidence-ledger/:chittyId/verify server/routes.ts:92 POST /api/seed-demo server/routes.ts:39 (dev-only) External clients (3s per-call timeout, no retries; mirror Phase 2c pattern): - worker/src/clients/openai.ts (new — chat completions via fetch) - worker/src/clients/chittymint.ts (new — freeze + mint) - worker/src/clients/chittyledger.ts (extended — submit + verify) Notes: - OPENAI_API_KEY added to Env as optional Worker secret; handlers return 503 service_unavailable when unset (no crash). - /mint gates on chittyChainStatus === 'frozen' (matches Express; the "7-day elapsed" check is aspirational and not present in Express today). - trust_score column is numeric(3,1) — OpenAI output clamped to [0, 99.9]. - /api/seed-demo returns 403 unless ENVIRONMENT === "development". - Phase 3a chitty_id=NULL deferral is NOT resolved by this PR. /mint mints an evidence TOKEN, not the ChittyID. ChittyID generation at create-time remains a separate phase. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a06d1fa8de
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| chittyChainStatus: "frozen", | ||
| ipfsHash: freezeResult.ipfsHash ?? null, |
There was a problem hiding this comment.
Reject freeze requests for non-draft assets
Add a state guard before mutating the asset here; this handler unconditionally sets chittyChainStatus to "frozen", so callers can refreeze assets that are already minted/settled/disputed. That breaks the documented lifecycle ordering and allows invalid backward transitions (and potentially repeated mint cycles) instead of enforcing draft -> frozen only.
Useful? React with 👍 / 👎.
| }, | ||
| ], | ||
| }); | ||
| const parsed = JSON.parse(content || '{"trustScore":0,"factors":[]}'); |
There was a problem hiding this comment.
Handle malformed trust-score JSON without 500s
Wrap this parse in the same fallback behavior as the legacy service (server/aiAnalysis.ts), which returns a score of 0 on parse/model-shape failures. As written, a non-JSON or malformed OpenAI response throws SyntaxError, and /api/assets/:assetId/calculate-trust-score only maps OpenAIConfigError/OpenAIClientError, so this path becomes an internal 500 instead of a graceful trust-score fallback.
Useful? React with 👍 / 👎.
Summary
Ports the 8 remaining write routes that touch external services from Express to Hono. Stacks on #40 → #39 → #38 → #37 → #36 → #34 → #33. Base:
feat/hono-phase-3b-domain-writes.Routes
External client matrix
worker/src/clients/openai.ts(new)OpenAIConfigError → 503,OpenAIClientError → 502worker/src/clients/chittymint.ts(new)MintClientError → 502 mint_unavailableworker/src/clients/chittyledger.ts(extended)LedgerClientError(404) → 404 not_found, else502 ledger_unavailableAll external calls use
AbortControllerwith per-call timeouts; no retries (caller concern, matches Phase 2c).Secrets required for prod
wrangler secret put OPENAI_API_KEY --env production— required before first OpenAI call. Handlers return503 service_unavailableuntil set.CHITTYMINT_TOKEN/CHITTYLEDGER_TOKENviawrangler secret put. Current Express path was unauthenticated public-API; preserved here.OPENAI_API_KEYis declared asOPENAI_API_KEY?: stringinworker/src/env.tsso it is never avarsentry. The value is never logged.OpenAI test strategy
Handlers are exercised in integration tests with
OPENAI_API_KEYunset — the assertion is the503 service_unavailablemapping (real handler path, real Neon for ownership checks, real Hono routing). Live OpenAI invocation is deferred to staging smoke-tests because:This is genuine error-path coverage of the 503/502/ownership-404/UUID-400 surfaces, not a mock. Real success path is covered by the existing Express service in staging and will be re-validated post-deploy via curl smoke tests.
ChittyMint endpoint gap (known)
CHITTYMINT_URLdefaults tohttps://mint.chitty.ccbut the path shape (/v1/chain/freeze,/v1/chain/mint) inherited from the legacyapi.chittycloud.comclient has not been verified live. Integration tests exercise the 502 mint_unavailable path against an unreachable host (real network error, real timeout). Real-success coverage requires either:mint.chitty.cc(preferred), orchittymintWorker (Phase 4).Asset state is not mutated when the upstream call fails — validated by the 502 tests that re-read
chitty_chain_statuspost-failure and assert it is unchanged.ChittyID minting deferral — NOT resolved here
This PR does not resolve Phase 3a's
chitty_id=NULLdeferral. Re-reading Express:POST /api/assets(Express:265) callsservices.id.generate('asset')and storeschittyIdat create time.POST /api/assets/:id/mint(Express:181) callsservices.chain.mint(asset.chittyId, ...)and storestransactionHashinblockchainHash.So
/mintmints an evidence token on chain, not a ChittyID. Create-time ChittyID generation remains deferred to a separate phase that adds a ChittyID client hittingid.chitty.cc.Express divergences
/calculate-trust-scorecallsaiAnalysisService.calculateTrustScore(OpenAI), not ChittyTrust. The migration spec said "ChittyTrust call" but Express truth is OpenAI — Express semantics preserved verbatim.assets.trust_scorecolumn isnumeric(3,1)(max 99.9). Output is clamped to[0, 99.9]before UPDATE. Documented inline./mintgate. Matches Express'schittyChainStatus === 'frozen'check only; no 7-day-elapsed check (aspirational in spec, not present in Express)./seed-demochittyId. Express generates ChittyIDs eagerly viachittyCloudMcp.generateChittyId(). Worker version leaveschittyIdNULL to match Phase 3a's deferral pattern — seeded rows still get minted via the standard/mintflow./seed-demoenv gate. New 403 gate whenENVIRONMENT !== "development". Express had no such gate (anyone authenticated could seed).Validation evidence
Typecheck
npm run check: 0 new errors inworker/(pre-existingserver/errors unchanged). Worker code compiles clean.Tests — real Neon, NO MOCKS
Ran the full worker integration suite on ephemeral Neon branch
phase-3c-test-5g5h(projectsteep-cloud-28172078, branchbr-wandering-sound-akrytlv6):New file
worker/__tests__/heavy-writes.integration.test.tsadds 30 tests covering:OPENAI_API_KEYacross trust-score/analyze/legal-doc/mintagainst unfrozen assetledger.chitty.ccfor nonexistent canonical ID — accepts 404 or 502 (both are real)/seed-demoin production env/seed-demoin development envFixture suffixes
5G/5Havoid collision with 5A..5L from prior phases.Wrangler dry-run
All bindings present (Hyperdrive, Assets, tail to chittytrack, all env vars).
Neon MCP state-change validation (BEGIN/ROLLBACK)
Executed via
run_sql_transactionagainst the test branch — full freeze → mint state-machine plus trust-score update, all rolled back:{ id: 34a4fe2d-..., chitty_chain_status: 'draft', trust_score: '0.0' }{ trust_score: '87.4' }{ chitty_chain_status: 'frozen', ipfs_hash: 'QmValidationHash' }{ chitty_chain_status: 'minted', blockchain_hash: '0xValidationTxHash', minting_fee: '0.100000' }Test plan
npm run check— 0 new worker errorsnpx wrangler deploy --dry-run --env productionsucceedswrangler secret put OPENAI_API_KEY --env productioncurl assets.chitty.cc/api/v1/statusconfirmsmigration_status: "PHASE_3C_HEAVY_WRITES"and all 27 migrated routes listedPOST /api/assets/:id/freezeonce mint endpoint shape is verified live🤖 Generated with Claude Code