@@ -7,23 +7,17 @@ import type { Env } from '../index';
77 */
88
99// ── ChittyLedger ─────────────────────────────────────────────
10- // Evidence pipeline: documents → evidence, disputes → cases, actions → custody log
10+ // Audit trail: entries, chain verification, custody queries
11+ // NOTE: Evidence/case operations live on ChittyEvidence, not ChittyLedger.
1112
12- export interface LedgerEvidencePayload {
13- filename : string ;
14- fileType : string ;
15- fileSize ?: string ;
16- description ?: string ;
17- evidenceTier : string ;
18- caseId ?: string ;
19- }
20-
21- export interface LedgerCustodyEntry {
22- evidenceId : string ;
13+ export interface LedgerEntryPayload {
14+ entityType : 'transaction' | 'evidence' | 'custody' | 'audit' ;
15+ entityId ?: string ;
2316 action : string ;
24- performedBy : string ;
25- location ?: string ;
26- notes ?: string ;
17+ actor ?: string ;
18+ actorType ?: 'user' | 'service' | 'system' ;
19+ metadata ?: Record < string , unknown > ;
20+ status ?: 'pending' | 'confirmed' | 'rejected' ;
2721}
2822
2923export function ledgerClient ( env : Env ) {
@@ -38,63 +32,55 @@ export function ledgerClient(env: Env) {
3832 headers [ 'Authorization' ] = `Bearer ${ env . CHITTYLEDGER_TOKEN } ` ;
3933 }
4034
41- async function post < T > ( path : string , body : unknown ) : Promise < T | null > {
42- try {
43- const res = await fetch ( `${ baseUrl } ${ path } ` , {
44- method : 'POST' ,
45- headers,
46- body : JSON . stringify ( body ) ,
47- } ) ;
48- if ( ! res . ok ) {
49- console . error ( `[ledger] ${ path } failed: ${ res . status } ` ) ;
50- return null ;
51- }
52- return await res . json ( ) as T ;
53- } catch ( err ) {
54- console . error ( `[ledger] ${ path } error:` , err ) ;
55- return null ;
56- }
57- }
58-
5935 return {
60- /** Push a document into ChittyLedger as evidence */
61- createEvidence : ( payload : LedgerEvidencePayload ) =>
62- post < { id : string } > ( '/api/evidence' , payload ) ,
63-
64- /** Record a chain-of-custody event */
65- addCustodyEntry : ( entry : LedgerCustodyEntry ) =>
66- post ( '/api/evidence/' + entry . evidenceId + '/custody' , entry ) ,
67-
68- /** Create or link a case in ChittyLedger */
69- createCase : ( payload : { caseNumber : string ; title : string ; caseType : string ; description ?: string } ) =>
70- post < { id : string } > ( '/api/cases' , payload ) ,
36+ /** Add an audit/custody/evidence entry to the ledger */
37+ addEntry : async ( entry : LedgerEntryPayload ) : Promise < { id : string ; sequenceNumber : number ; hash : string } | null > => {
38+ try {
39+ const res = await fetch ( `${ baseUrl } /entries` , {
40+ method : 'POST' , headers, body : JSON . stringify ( entry ) ,
41+ } ) ;
42+ if ( ! res . ok ) { console . error ( `[ledger] POST /entries failed: ${ res . status } ` ) ; return null ; }
43+ return await res . json ( ) as { id : string ; sequenceNumber : number ; hash : string } ;
44+ } catch ( err ) { console . error ( '[ledger] POST /entries error:' , err ) ; return null ; }
45+ } ,
7146
72- /** Get evidence by case */
73- getEvidenceByCase : async ( caseId : string ) : Promise < Record < string , unknown > [ ] > => {
47+ /** Search ledger entries */
48+ searchEntries : async ( params : { entityType ?: string ; entityId ?: string ; actor ?: string ; status ?: string ; limit ?: number } ) : Promise < Record < string , unknown > [ ] > => {
7449 try {
75- const qs = new URLSearchParams ( { caseId } ) . toString ( ) ;
76- const res = await fetch ( `${ baseUrl } /api/evidence?${ qs } ` , { headers } ) ;
50+ const qs = new URLSearchParams (
51+ Object . entries ( params ) . filter ( ( [ , v ] ) => v !== undefined ) . map ( ( [ k , v ] ) => [ k , String ( v ) ] as [ string , string ] )
52+ ) . toString ( ) ;
53+ const res = await fetch ( `${ baseUrl } /entries${ qs ? `?${ qs } ` : '' } ` , { headers } ) ;
7754 if ( ! res . ok ) return [ ] ;
7855 return await res . json ( ) as Record < string , unknown > [ ] ;
7956 } catch { return [ ] ; }
8057 } ,
8158
82- /** Get facts for a case (if supported) */
83- getFactsForCase : async ( caseId : string ) : Promise < Record < string , unknown > [ ] > => {
59+ /** Get chain of custody for an entity */
60+ getChainOfCustody : async ( entityId : string ) : Promise < Record < string , unknown > [ ] > => {
8461 try {
85- const res = await fetch ( `${ baseUrl } /api/cases/ ${ encodeURIComponent ( caseId ) } /facts ` , { headers } ) ;
62+ const res = await fetch ( `${ baseUrl } /custody/ ${ encodeURIComponent ( entityId ) } ` , { headers } ) ;
8663 if ( ! res . ok ) return [ ] ;
8764 return await res . json ( ) as Record < string , unknown > [ ] ;
8865 } catch { return [ ] ; }
8966 } ,
9067
91- /** Get contradictions for a case (if supported) */
92- getContradictionsForCase : async ( caseId : string ) : Promise < Record < string , unknown > [ ] > => {
68+ /** Verify ledger chain integrity */
69+ verifyChain : async ( ) : Promise < { valid : boolean ; errors : string [ ] } | null > => {
9370 try {
94- const res = await fetch ( `${ baseUrl } /api/cases/${ encodeURIComponent ( caseId ) } /contradictions` , { headers } ) ;
95- if ( ! res . ok ) return [ ] ;
96- return await res . json ( ) as Record < string , unknown > [ ] ;
97- } catch { return [ ] ; }
71+ const res = await fetch ( `${ baseUrl } /verify` , { headers } ) ;
72+ if ( ! res . ok ) return null ;
73+ return await res . json ( ) as { valid : boolean ; errors : string [ ] } ;
74+ } catch { return null ; }
75+ } ,
76+
77+ /** Get ledger statistics */
78+ getStatistics : async ( ) : Promise < Record < string , unknown > | null > => {
79+ try {
80+ const res = await fetch ( `${ baseUrl } /statistics` , { headers } ) ;
81+ if ( ! res . ok ) return null ;
82+ return await res . json ( ) as Record < string , unknown > ;
83+ } catch { return null ; }
9884 } ,
9985 } ;
10086}
@@ -132,7 +118,7 @@ export function evidenceClient(env: Env) {
132118 const baseUrl = env . CHITTYEVIDENCE_URL ;
133119 if ( ! baseUrl ) return null ;
134120
135- const headers = { 'X-Source-Service' : 'chittycommand' } ;
121+ const headers : Record < string , string > = { 'X-Source-Service' : 'chittycommand' } ;
136122
137123 async function get < T > ( path : string ) : Promise < T | null > {
138124 try {
@@ -145,7 +131,35 @@ export function evidenceClient(env: Env) {
145131 }
146132 }
147133
134+ async function post < T > ( path : string , body : unknown ) : Promise < T | null > {
135+ try {
136+ const res = await fetch ( `${ baseUrl } ${ path } ` , {
137+ method : 'POST' ,
138+ headers : { ...headers , 'Content-Type' : 'application/json' } ,
139+ body : JSON . stringify ( body ) ,
140+ } ) ;
141+ if ( ! res . ok ) { console . error ( `[evidence] POST ${ path } failed: ${ res . status } ` ) ; return null ; }
142+ return await res . json ( ) as T ;
143+ } catch ( err ) {
144+ console . error ( `[evidence] POST ${ path } error:` , err ) ;
145+ return null ;
146+ }
147+ }
148+
148149 return {
150+ /** Submit a document to the evidence pipeline */
151+ submitDocument : ( payload : { filename : string ; fileType : string ; fileSize ?: string ; description ?: string ; evidenceTier ?: string ; caseId ?: string } ) =>
152+ post < { id : string ; submission_id ?: string } > ( '/collect' , {
153+ file_name : payload . filename ,
154+ document_type : payload . fileType ,
155+ description : payload . description ,
156+ case_id : payload . caseId ,
157+ } ) ,
158+
159+ /** Record a chain-of-custody event on a document */
160+ addCustodyEntry : ( documentId : string , entry : { action : string ; performedBy : string ; location ?: string ; notes ?: string } ) =>
161+ post < Record < string , unknown > > ( `/legal/documents/${ encodeURIComponent ( documentId ) } /custody` , entry ) ,
162+
149163 /** Get enriched facts for a case (facts + entities + amounts) */
150164 getEnrichedFacts : ( caseId : string ) =>
151165 get < EvidenceFact [ ] > ( `/facts/cases/${ encodeURIComponent ( caseId ) } /enriched` ) ,
0 commit comments