Conversation
There was a problem hiding this comment.
Sorry @Connorbelez, your pull request is larger than the review limit of 150000 diff characters
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (98)
📝 WalkthroughWalkthroughThe PR introduces an audit trail system with append-only events, hash-chain integrity verification, and a document engine for template-based PDF generation. It includes demo pages showcasing audit traceability with mortgage lifecycle management, comprehensive end-to-end tests, UI components for audit visualization and document design, and supporting schema definitions, validators, and utilities. Changes
Sequence DiagramsequenceDiagram
participant Client as Client/Browser
participant AppAPI as App API
participant AuditComp as Audit Component
participant DB as Database
participant Crypto as Crypto/Hash
Client->>AppAPI: insert(event: {...})
AppAPI->>AuditComp: forward to component.lib.insert
AuditComp->>Crypto: computeHash(prevHash, event)
Crypto-->>AuditComp: hash
AuditComp->>DB: store audit_events with hash chain
AuditComp->>DB: create audit_outbox entry (pending)
DB-->>AuditComp: success
AuditComp-->>AppAPI: eventId
AppAPI-->>Client: eventId
Client->>AppAPI: verifyChain(entityId)
AppAPI->>AuditComp: forward to component.lib.verifyChain
AuditComp->>DB: fetch audit_events for entity
loop For each event
AuditComp->>Crypto: recompute hash
Crypto-->>AuditComp: computed hash
AuditComp->>AuditComp: compare with stored hash
end
AuditComp-->>AppAPI: { valid, brokenAt?, error? }
AppAPI-->>Client: verification result
Client->>AppAPI: emitPending()
AppAPI->>AuditComp: forward to component.lib.emitPending
AuditComp->>DB: query audit_outbox (status=pending, limit 100)
loop For each pending entry
AuditComp->>AuditComp: emit to external system
AuditComp->>DB: patch entry (emitted=true, status=emitted)
end
AuditComp-->>AppAPI: { emittedCount, failedCount }
AppAPI-->>Client: result
sequenceDiagram
participant Client as Client/Browser
participant Designer as PDF Designer Page
participant PdfMe as PdfMe UI
participant API as Document API
participant Gen as Generation Service
participant Storage as Storage
Client->>Designer: navigate to template
Designer->>API: fetch template, basePdf URL, variables
API-->>Designer: template data
Designer->>PdfMe: load pdfme Designer with fields
PdfMe-->>Designer: ready
Client->>Designer: add/edit field (drag on canvas)
Designer->>PdfMe: onChangeTemplate event
PdfMe-->>Designer: updated schemas
Designer->>Designer: sync fields to local state
Designer->>API: auto-save draft with fields
Client->>Designer: publish template
Designer->>API: publish(templateId)
API->>API: validate fields, verify hash
API->>Storage: check base PDF
API->>API: create immutable version
API-->>Designer: success
Designer-->>Client: version badge
Client->>Gen: select template on generate page
Gen->>API: prepareGeneration(templateId, values)
API->>API: validate variables, format values
API-->>Gen: formatted values, fields, dimensions
Gen->>Gen: client-side: generatePdfInBrowser
Gen->>Storage: upload generated PDF
Storage-->>Gen: pdfRef
Gen-->>Client: success with download link
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
Note Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
There was a problem hiding this comment.
Pull request overview
Introduces two new demo feature areas—Document Engine (PDF template authoring + generation) and Audit & Traceability (audit trail UI + Convex component outbox/retention)—and wires up supporting tooling (Vite/Vitest config, UI toasts, and Playwright E2E coverage).
Changes:
- Add Document Engine routes/components, Convex backend tables/mutations, and pdfme-based designer/generation utilities.
- Add Audit & Traceability demo UI plus an isolated Convex
auditTrailcomponent (schema, outbox processor, retention cron). - Expand tooling: Vite workaround for
@pdfme/ui, add Playwright E2E suites/helpers, and adjust linting/review scripts.
Reviewed changes
Copilot reviewed 96 out of 99 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| vite.config.ts | Adds pdfme/TanStack Start workaround plugin; adjusts Vitest excludes. |
| src/test/audit-traceability/shared.test.ts | Unit tests for audit-traceability shared helpers. |
| src/routes/demo/workos.tsx | Refactors repeated list rendering into components. |
| src/routes/demo/table.tsx | Makes “Go to page” input controlled by pagination state. |
| src/routes/demo/storybook.tsx | Connects submit button to a specific form via form attribute. |
| src/routes/demo/form.address.tsx | Improves postal-code validation by country; auto-clears submit message. |
| src/routes/demo/document-engine/templates.tsx | Adds templates management page for Document Engine demo. |
| src/routes/demo/document-engine/route.tsx | Adds Document Engine layout + navigation. |
| src/routes/demo/document-engine/library.tsx | Adds base PDF library page + upload entry point. |
| src/routes/demo/document-engine/index.tsx | Adds Document Engine dashboard page. |
| src/routes/demo/convex-workflow.tsx | Refactors status badge and step icon rendering. |
| src/routes/demo/convex-crons.tsx | Tightens interval validation before registering cron job. |
| src/routes/demo/audit-traceability/route.tsx | Adds Audit & Traceability layout + navigation. |
| src/routes/demo/audit-traceability/report.tsx | Adds compliance report UI and JSON download. |
| src/routes/demo/audit-traceability/pipeline.tsx | Adds outbox pipeline status/alerts UI with manual emission. |
| src/routes/demo/audit-traceability/audit-trail.tsx | Adds audit trail query UI + critical events watcher. |
| src/routes/demo/audit-traceability/access-log.tsx | Adds access log UI page. |
| src/routes/__root.tsx | Mounts Sonner Toaster at app root. |
| src/lib/document-engine/types.ts | Adds shared document-engine domain/type definitions. |
| src/lib/document-engine/signatory-utils.ts | Adds signatory color/label helpers. |
| src/lib/document-engine/pdfme-sync.ts | Adds conversions/merge logic between FieldConfig and pdfme schemas. |
| src/lib/document-engine/pdfme-plugins/signable-field.ts | Adds custom pdfme “signable field” plugin (UI + prop panel). |
| src/lib/document-engine/pdfme-plugins/interpolable-field.ts | Adds custom pdfme “interpolable field” plugin (pdf renderer + UI). |
| src/lib/document-engine/pdfme-plugins/index.ts | Exposes designer/generator plugin sets. |
| src/lib/document-engine/hash.ts | Adds browser SHA-256 helper. |
| src/lib/document-engine/formatting.ts | Adds type-aware variable formatting for interpolation. |
| src/lib/document-engine/client-generation.ts | Adds browser-side PDF generation + base-PDF hash verification. |
| src/hooks/use-audit-access-log.ts | Adds hook to log audit page access with strict-mode guard. |
| src/components/ui/sonner.tsx | Updates Toaster implementation and theme handling. |
| src/components/theme-toggle.tsx | Hardens localStorage reads/writes with try/catch. |
| src/components/storybook/button.tsx | Adds form prop passthrough to storybook Button. |
| src/components/header.tsx | Adds “Platform” demo section links (Document Engine + Audit & Traceability). |
| src/components/document-engine/variable-picker.tsx | Adds variable selector + inline create flow. |
| src/components/document-engine/signatory-panel.tsx | Adds signatory list/editor UI for templates/groups. |
| src/components/document-engine/pdf-upload-dialog.tsx | Adds base PDF upload dialog with server-side metadata extraction. |
| src/components/document-engine/pdf-designer.tsx | Adds React wrapper around pdfme Designer with sync logic. |
| src/components/document-engine/generation-results.tsx | Adds UI for generation outputs + PDF download links. |
| src/components/document-engine/field-config-panel.tsx | Adds sidebar editor for selected field configuration. |
| src/components/audit-traceability/summary-card.stories.tsx | Storybook stories for SummaryCard. |
| src/components/audit-traceability/shared.tsx | Shared Audit & Traceability UI components/helpers. |
| src/components/audit-traceability/shared.stories.tsx | Storybook stories for StatusIcon. |
| src/components/audit-traceability/severity-badge.stories.tsx | Storybook stories for SeverityBadge. |
| src/components/audit-traceability/page-badge.stories.tsx | Storybook stories for PageBadge. |
| src/components/audit-traceability/control-card.stories.tsx | Storybook stories for ControlCard. |
| src/components/audit-traceability/alerts-card.stories.tsx | Storybook stories for AlertsCard. |
| src/components/audit-traceability/access-log-content.stories.tsx | Storybook stories for AccessLogContent. |
| scripts/code-review.sh | Tweaks coderabbit invocation to review committed changes. |
| package.json | Adds pdfme + pdf-lib dependencies. |
| e2e/helpers/document-engine.ts | Adds shared Playwright helpers for Document Engine flows. |
| e2e/document-engine/variables.spec.ts | Adds E2E coverage for system variables UI. |
| e2e/document-engine/templates.spec.ts | Adds E2E coverage for templates UI and designer navigation. |
| e2e/document-engine/navigation.spec.ts | Adds E2E coverage for Document Engine layout navigation. |
| e2e/document-engine/library.spec.ts | Adds E2E coverage for base PDF upload/list/delete. |
| e2e/document-engine/groups.spec.ts | Adds E2E coverage for template groups UI. |
| e2e/document-engine/generate.spec.ts | Adds E2E coverage for generate page UI toggles/visibility. |
| e2e/document-engine/designer.spec.ts | Adds E2E coverage for designer initialization and basic actions. |
| e2e/auth/login.spec.ts | Adds required-env guard for WorkOS login E2E tests. |
| convex/schema.ts | Adds Document Engine tables and demo audit mortgage table; imports shared validators. |
| convex/documentEngine/validators.ts | Adds validators for document engine domain objects. |
| convex/documentEngine/templateVersions.ts | Adds queries for template version retrieval. |
| convex/documentEngine/templateTimeline.ts | Adds timeline-backed draft state history (undo/redo/checkpoints). |
| convex/documentEngine/templates.ts | Adds template CRUD + draft validation + publish/versioning logic. |
| convex/documentEngine/templateGroups.ts | Adds template group CRUD + signatory homogeneity enforcement. |
| convex/documentEngine/systemVariables.ts | Adds system variable CRUD with snake_case enforcement. |
| convex/documentEngine/generationHelpers.ts | Adds internal queries to prepare generation inputs and validate groups. |
| convex/documentEngine/dataModelEntities.ts | Adds entity catalog seeding and custom entity management. |
| convex/documentEngine/basePdfs.ts | Adds base PDF storage flows + server-side metadata/hash extraction. |
| convex/demo/triggers.ts | Fixes inserted-contact summary to use first/last name fields. |
| convex/demo/timeline.ts | Hardens undo/redo handling and ensures note upsert. |
| convex/demo/aggregate.ts | Reorders aggregate deletion relative to doc deletion. |
| convex/crons.ts | Adds host-app crons file (auditTrail handled by component). |
| convex/convex.config.ts | Registers auditTrail component with Convex app. |
| convex/components/auditTrail/schema.ts | Adds isolated audit trail component tables/indexes. |
| convex/components/auditTrail/internal.ts | Adds outbox processor + retention cleanup internal mutations. |
| convex/components/auditTrail/crons.ts | Adds component-owned cron schedule for outbox + retention. |
| convex/components/auditTrail/convex.config.ts | Declares auditTrail Convex component. |
| convex/components/auditTrail/_generated/server.ts | Generated component server helpers. |
| convex/components/auditTrail/_generated/dataModel.ts | Generated component data model types. |
| convex/components/auditTrail/_generated/component.ts | Generated component API typing. |
| convex/components/auditTrail/_generated/api.ts | Generated component api/internal exports. |
| convex/auditTrailClient.ts | Adds append-only client wrapper for interacting with auditTrail component. |
| convex/_generated/api.d.ts | Updates generated API typings to include new modules/components. |
| biome.json | Excludes e2e from Biome; disables filename convention rule. |
| AGENT_LESSONS.md | Adds internal lessons about Playwright/env handling. |
| .gitignore | Ignores generated review output file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function AccessLogPage() { | ||
| useAuditAccessLog("audit-trail"); | ||
| const accessLog = useQuery(api.demo.auditTraceability.getAccessLog, {}); |
There was a problem hiding this comment.
useAuditAccessLog("audit-trail") is logging this page view as audit.viewed.audit-trail, which will make the access-log page indistinguishable from the audit-trail page (and PageBadge will display the wrong page). Consider adding an explicit "access-log" member to the AuditPage union and logging that here so access-log views are tracked accurately.
| | Go to page: | ||
| <input | ||
| className="w-16 rounded-md border border-gray-700 bg-gray-800 px-2 py-1 outline-none focus:border-transparent focus:ring-2 focus:ring-blue-500" | ||
| defaultValue={table.getState().pagination.pageIndex + 1} | ||
| onChange={(e) => { | ||
| const page = e.target.value ? Number(e.target.value) - 1 : 0; | ||
| table.setPageIndex(page); | ||
| }} | ||
| type="number" | ||
| value={table.getState().pagination.pageIndex + 1} | ||
| /> |
There was a problem hiding this comment.
This pagination input is now fully controlled by table.getState().pagination.pageIndex + 1, but the onChange handler immediately forces empty input back to page 1 ("" -> pageIndex 0 -> value becomes 1). That makes it impossible to clear/edit the field naturally (e.g. select-all/delete, or temporarily type an out-of-range value). Consider keeping a local string state for the input and only committing to table.setPageIndex on blur/enter (or when the value parses cleanly).
| function mergeFieldMeta( | ||
| pdfmeSchema: PdfmeFieldSchema, | ||
| existing?: FieldMeta | ||
| ): FieldMeta | undefined { | ||
| const merged: FieldMeta = { | ||
| placeholder: pdfmeSchema.placeholder || existing?.placeholder || undefined, | ||
| helpText: pdfmeSchema.helpText || existing?.helpText || undefined, | ||
| readOnly: pdfmeSchema.fieldReadOnly ?? existing?.readOnly, | ||
| }; |
There was a problem hiding this comment.
mergeFieldMeta uses || when merging placeholder/helpText. Because empty string is falsy, clearing a value in the pdfme UI (""), or a plugin defaulting these fields to "", will cause the old existing value to be retained. This prevents users from actually clearing placeholder/help text once set. Use ?? / explicit undefined checks so empty strings can overwrite existing values (and optionally normalize "" -> undefined intentionally).
| if (existing.type === "interpolable") { | ||
| base.variableKey = | ||
| (pdfmeSchema as InterpolableSchema).variableKey || existing.variableKey; | ||
| } | ||
|
|
||
| if (existing.type === "signable") { | ||
| base.signableType = | ||
| ((pdfmeSchema as SignableSchema).signableType as SignableType) || | ||
| existing.signableType; | ||
| base.signatoryPlatformRole = | ||
| ((pdfmeSchema as SignableSchema).platformRole || undefined) ?? | ||
| existing.signatoryPlatformRole; | ||
| } |
There was a problem hiding this comment.
mergeExistingField uses || / ?? in a way that makes it impossible to unset several string fields via the pdfme designer. For example, if an interpolable field previously had variableKey set, changing it to "(None)" in the designer will likely produce an empty string, but "" || existing.variableKey keeps the old key. Same issue for signatoryPlatformRole (empty string becomes undefined, then ?? falls back to existing). This will make the UI feel broken when trying to remove variable/signatory bindings.
| .withIndex("by_entity") | ||
| .filter((q) => q.lt(q.field("timestamp"), cutoff)) |
There was a problem hiding this comment.
The retention query uses .withIndex("by_entity") (entityId, timestamp) but doesn't constrain entityId, and then filters by timestamp. This means cleanup will iterate in entityId order rather than oldest-first globally, and may never reach expired events for later entity IDs if there are always >100 expired rows earlier in the index. Consider adding an index that starts with timestamp (e.g. by_timestamp) and querying that for retention, or otherwise ensuring the scan order is based on timestamp.
| .withIndex("by_entity") | |
| .filter((q) => q.lt(q.field("timestamp"), cutoff)) | |
| .withIndex("by_timestamp", (q) => q.lt("timestamp", cutoff)) |
| style={ | ||
| { | ||
| "--normal-bg": "var(--popover)", | ||
| "--normal-text": "var(--popover-foreground)", | ||
| "--normal-border": "var(--border)", | ||
| "--border-radius": "var(--radius)", | ||
| } as React.CSSProperties | ||
| } | ||
| theme={theme as ToasterProps["theme"]} | ||
| theme="dark" | ||
| {...props} | ||
| /> |
There was a problem hiding this comment.
The toaster is now hard-coded to theme="dark", but the app has a light/dark/auto theme toggle that updates the documentElement class. In light mode, toast styling will remain dark, which is inconsistent and may reduce readability. Consider deriving the Sonner theme from the current resolved theme (or omitting the prop and letting your CSS variables/theme classes drive colors) so toasts match the active UI theme.
|
@greptile review |
|
✅ Unit tests committed locally. Commit: |
There was a problem hiding this comment.
Sorry @Connorbelez, your pull request is larger than the review limit of 150000 diff characters
Merge activity
|
…labels - Add dataModelEntities table with schema introspection seed, custom entity CRUD, and browsable two-panel picker (SystemPathBrowser) for variable system path selection - Replace inline error state with sonner toast notifications in groups and variables pages; mount Toaster in root layout - Fix truncated pdfme designer sidebar labels by setting options.labels and options.icons for interpolableField/signableField plugins - Refactor pdfme-sync.ts to reduce cognitive complexity by extracting shared helpers for schema conversion and field merging - Fix nested ternaries in workos.tsx and convex-workflow.tsx - Fix stray closing brace parse error in workos.tsx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convex requires camelCase filenames for module path resolution, which conflicts with biome's kebab-case default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
829f7a9 to
3504a0f
Compare
SPEC 1.2 updates: - §2 File Structure: corrected paths to convex/engine/ nesting - §9 Developer Checklist: fixed all file paths - §10 Open Questions: closed #1 (guard timing), #2 (confirmObligationPayment), #3 (generateObligations helper) - Removed effects/mortgage.ts, added effects/workosProvisioning.ts PRD 1.2 updates: - GT DoD #3: marked deal machine as descoped to Project 4 - Renamed seedInvestor → seedLender (schema table is lenders) - Marked seedDeal as descoped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SPEC 1.2 updates: - §2 File Structure: corrected paths to convex/engine/ nesting - §9 Developer Checklist: fixed all file paths - §10 Open Questions: closed #1 (guard timing), #2 (confirmObligationPayment), #3 (generateObligations helper) - Removed effects/mortgage.ts, added effects/workosProvisioning.ts PRD 1.2 updates: - GT DoD #3: marked deal machine as descoped to Project 4 - Renamed seedInvestor → seedLender (schema table is lenders) - Marked seedDeal as descoped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
#82) ft. ENG-23: cross-entity effects, reconciliation, and engine hardening - Replace obligation effect stubs with real cross-entity dispatch (emitObligationOverdue/Settled now read obligation → transition mortgage) - Add transitionMortgageInternal for scheduler/effect use - Add confirmObligationPayment (authedMutation + obligation:manage) - Add notifyAdminNewRequest as entry action on pending_review state - Filter assign-action warnings in effect scheduler (isBuiltInAction) - Extend reconciliation to handle mortgage + obligation entity types - Add machineContext explanatory comments to governed table schemas - Fix reconciliation test to use non-governed entity type (deal) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: seed mutations for all Phase 1 entities - Create convex/seed/ directory with 8 files - seedBroker: 2 brokers with FSRA license numbers, Ontario-based - seedBorrower: 5 borrowers with Ontario addresses, verified IDV - seedLender: 3 lenders with accreditation, broker-assigned - seedMortgage: 5 mortgages with varied terms + auto-generated obligations - generateObligations: interest-only bridge loan payment schedule - seedObligationStates: transitions obligations to due/overdue/settled mix - seedOnboardingRequest: 3 requests (pending_review, approved, rejected) - seedAll: orchestrator in dependency order, idempotent All seeds use executeTransition for non-initial states (proper journal entries). Each entity gets a SEED_CREATED journal entry for audit trail continuity. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: reconciliation cron + internal query - Add daily reconciliation cron (06:00 UTC) that runs Layer 1 check - Create reconciliationAction.ts with internalQuery (no auth required) and internalAction for cron scheduling - Discrepancies logged as P0 errors via console.error - On-demand adminQuery reconciliation remains available Resolves SPEC Open Question #5: daily cron + on-demand admin query. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: integration tests — guard failure, missing effects, cross-entity - Add guard failure test: mortgage DEFAULT_THRESHOLD_REACHED with 0 missed payments → rejected, status unchanged - Add missing effect handler test: unknown action → warn + succeed - Create crossEntity.test.ts with 4 tests proving full obligation→mortgage cascade: overdue dispatch, settlement cure, and journal chain consistency - Fix pre-existing test: "throws when no machine is registered" assertion Cross-entity tests manually invoke effects (convex-test doesn't auto-run scheduled functions), verifying the complete chain: obligation due→overdue → mortgage active→delinquent obligation overdue→settled → mortgage delinquent→active (cure) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> docs: ENG-23 — update SPEC 1.2 and PRD 1.2 on Notion SPEC 1.2 updates: - §2 File Structure: corrected paths to convex/engine/ nesting - §9 Developer Checklist: fixed all file paths - §10 Open Questions: closed #1 (guard timing), #2 (confirmObligationPayment), #3 (generateObligations helper) - Removed effects/mortgage.ts, added effects/workosProvisioning.ts PRD 1.2 updates: - GT DoD #3: marked deal machine as descoped to Project 4 - Renamed seedInvestor → seedLender (schema table is lenders) - Marked seedDeal as descoped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: ENG-23 — type reconciliationAction entityType parameter Use keyof typeof ENTITY_TABLE_MAP instead of string for type safety in collectLatestEntries function parameter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: ENG-23 — address code review findings in seed mutations - Fix idempotency: reuse existing user when entity doesn't exist yet (seedBorrower, seedLender, seedOnboardingRequest, seedMortgage) - Fix seedMortgage: reuse existing property instead of duplicating - Fix generateObligations: clamp day to prevent setMonth date drift - Note: seedLender entityType "borrower" is intentional — lenders are not yet a governed entity type in the GT engine Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ## Summary by Sourcery Implement cross-entity coordination between obligations and mortgages, extend reconciliation and scheduling infrastructure, and add idempotent seed data plus tests and cron-based health checks. New Features: - Enable cross-entity effects so obligation state changes drive corresponding mortgage transitions. - Introduce internal and admin-facing commands for mortgage transitions and confirming obligation payments. - Add an internal reconciliation query and daily cron-driven reconciliation check across governed entities. - Seed phase-1 entities (brokers, borrowers, lenders, mortgages, obligations, onboarding requests) with realistic, journal-backed demo data. - Provide an orchestrated seedAll mutation to populate a complete demo dataset in dependency order. Bug Fixes: - Ensure reconciliation skips non-governed entity types while handling mortgages and obligations correctly. - Prevent scheduling of XState built-in actions as effects and gracefully handle missing effect handlers. - Fix reconciliation tests to use non-governed entities and relax an over-specific transition engine error assertion. - Clamp generated obligation due dates to avoid calendar drift in monthly schedules. - Improve seed mutations to be idempotent by reusing existing users, properties, and entities. Enhancements: - Document machineContext usage for governed tables and add notification entry actions to onboarding requests. - Expand reconciliation utilities to support internal use and improve discrepancy reporting. - Strengthen guard behavior for mortgage default thresholds via explicit tests. Documentation: - Clarify governed vs non-governed entities and machine context expectations in schema comments. Tests: - Add cross-entity integration tests covering obligation→mortgage cascades and journal chain consistency. - Add tests for guard failures, missing effect handlers, and reconciliation behavior across entity types. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added automated daily health checks to verify system integrity. * Enabled obligation payment confirmation through the admin dashboard. * Added admin notifications for new onboarding requests. * **Improvements** * Enhanced coordination between related financial entities to ensure consistent state transitions. * Strengthened validation to prevent invalid state changes. * **Tests** * Added comprehensive test coverage for entity workflows and state validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
documenso Added document gen demo and audit trail demo biome update
#82) ft. ENG-23: cross-entity effects, reconciliation, and engine hardening - Replace obligation effect stubs with real cross-entity dispatch (emitObligationOverdue/Settled now read obligation → transition mortgage) - Add transitionMortgageInternal for scheduler/effect use - Add confirmObligationPayment (authedMutation + obligation:manage) - Add notifyAdminNewRequest as entry action on pending_review state - Filter assign-action warnings in effect scheduler (isBuiltInAction) - Extend reconciliation to handle mortgage + obligation entity types - Add machineContext explanatory comments to governed table schemas - Fix reconciliation test to use non-governed entity type (deal) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: seed mutations for all Phase 1 entities - Create convex/seed/ directory with 8 files - seedBroker: 2 brokers with FSRA license numbers, Ontario-based - seedBorrower: 5 borrowers with Ontario addresses, verified IDV - seedLender: 3 lenders with accreditation, broker-assigned - seedMortgage: 5 mortgages with varied terms + auto-generated obligations - generateObligations: interest-only bridge loan payment schedule - seedObligationStates: transitions obligations to due/overdue/settled mix - seedOnboardingRequest: 3 requests (pending_review, approved, rejected) - seedAll: orchestrator in dependency order, idempotent All seeds use executeTransition for non-initial states (proper journal entries). Each entity gets a SEED_CREATED journal entry for audit trail continuity. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: reconciliation cron + internal query - Add daily reconciliation cron (06:00 UTC) that runs Layer 1 check - Create reconciliationAction.ts with internalQuery (no auth required) and internalAction for cron scheduling - Discrepancies logged as P0 errors via console.error - On-demand adminQuery reconciliation remains available Resolves SPEC Open Question #5: daily cron + on-demand admin query. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ft. ENG-23: integration tests — guard failure, missing effects, cross-entity - Add guard failure test: mortgage DEFAULT_THRESHOLD_REACHED with 0 missed payments → rejected, status unchanged - Add missing effect handler test: unknown action → warn + succeed - Create crossEntity.test.ts with 4 tests proving full obligation→mortgage cascade: overdue dispatch, settlement cure, and journal chain consistency - Fix pre-existing test: "throws when no machine is registered" assertion Cross-entity tests manually invoke effects (convex-test doesn't auto-run scheduled functions), verifying the complete chain: obligation due→overdue → mortgage active→delinquent obligation overdue→settled → mortgage delinquent→active (cure) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> docs: ENG-23 — update SPEC 1.2 and PRD 1.2 on Notion SPEC 1.2 updates: - §2 File Structure: corrected paths to convex/engine/ nesting - §9 Developer Checklist: fixed all file paths - §10 Open Questions: closed #1 (guard timing), #2 (confirmObligationPayment), #3 (generateObligations helper) - Removed effects/mortgage.ts, added effects/workosProvisioning.ts PRD 1.2 updates: - GT DoD #3: marked deal machine as descoped to Project 4 - Renamed seedInvestor → seedLender (schema table is lenders) - Marked seedDeal as descoped Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: ENG-23 — type reconciliationAction entityType parameter Use keyof typeof ENTITY_TABLE_MAP instead of string for type safety in collectLatestEntries function parameter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: ENG-23 — address code review findings in seed mutations - Fix idempotency: reuse existing user when entity doesn't exist yet (seedBorrower, seedLender, seedOnboardingRequest, seedMortgage) - Fix seedMortgage: reuse existing property instead of duplicating - Fix generateObligations: clamp day to prevent setMonth date drift - Note: seedLender entityType "borrower" is intentional — lenders are not yet a governed entity type in the GT engine Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ## Summary by Sourcery Implement cross-entity coordination between obligations and mortgages, extend reconciliation and scheduling infrastructure, and add idempotent seed data plus tests and cron-based health checks. New Features: - Enable cross-entity effects so obligation state changes drive corresponding mortgage transitions. - Introduce internal and admin-facing commands for mortgage transitions and confirming obligation payments. - Add an internal reconciliation query and daily cron-driven reconciliation check across governed entities. - Seed phase-1 entities (brokers, borrowers, lenders, mortgages, obligations, onboarding requests) with realistic, journal-backed demo data. - Provide an orchestrated seedAll mutation to populate a complete demo dataset in dependency order. Bug Fixes: - Ensure reconciliation skips non-governed entity types while handling mortgages and obligations correctly. - Prevent scheduling of XState built-in actions as effects and gracefully handle missing effect handlers. - Fix reconciliation tests to use non-governed entities and relax an over-specific transition engine error assertion. - Clamp generated obligation due dates to avoid calendar drift in monthly schedules. - Improve seed mutations to be idempotent by reusing existing users, properties, and entities. Enhancements: - Document machineContext usage for governed tables and add notification entry actions to onboarding requests. - Expand reconciliation utilities to support internal use and improve discrepancy reporting. - Strengthen guard behavior for mortgage default thresholds via explicit tests. Documentation: - Clarify governed vs non-governed entities and machine context expectations in schema comments. Tests: - Add cross-entity integration tests covering obligation→mortgage cascades and journal chain consistency. - Add tests for guard failures, missing effect handlers, and reconciliation behavior across entity types. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added automated daily health checks to verify system integrity. * Enabled obligation payment confirmation through the admin dashboard. * Added admin notifications for new onboarding requests. * **Improvements** * Enhanced coordination between related financial entities to ensure consistent state transitions. * Strengthened validation to prevent invalid state changes. * **Tests** * Added comprehensive test coverage for entity workflows and state validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->

documenso
Added document gen demo and audit trail demo
biome update
Summary by CodeRabbit
Release Notes
New Features
Improvements
Tests