Add Legal Office seal and complete Azure CDN deployment

- Add Legal Office of the Master seal (SVG design with Maltese Cross, scales of justice, legal scroll)
- Create legal-office-manifest-template.json for Legal Office credentials
- Update SEAL_MAPPING.md and DESIGN_GUIDE.md with Legal Office seal documentation
- Complete Azure CDN infrastructure deployment:
  - Resource group, storage account, and container created
  - 17 PNG seal files uploaded to Azure Blob Storage
  - All manifest templates updated with Azure URLs
  - Configuration files generated (azure-cdn-config.env)
- Add comprehensive Azure CDN setup scripts and documentation
- Fix manifest URL generation to prevent double slashes
- Verify all seals accessible via HTTPS
This commit is contained in:
defiQUG
2025-11-12 22:03:42 -08:00
parent 8649ad4124
commit 92cc41d26d
258 changed files with 16021 additions and 1260 deletions

41
packages/database/src/audit-search.d.ts vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* Enhanced audit logging with search capabilities
*/
import type { CredentialAuditLog } from './credential-lifecycle';
export interface AuditSearchFilters {
credentialId?: string;
issuerDid?: string;
subjectDid?: string;
credentialType?: string | string[];
action?: 'issued' | 'revoked' | 'verified' | 'renewed';
performedBy?: string;
startDate?: Date;
endDate?: Date;
ipAddress?: string;
}
export interface AuditSearchResult {
logs: CredentialAuditLog[];
total: number;
page: number;
pageSize: number;
}
/**
* Search audit logs with filters
*/
export declare function searchAuditLogs(filters: AuditSearchFilters, page?: number, pageSize?: number): Promise<AuditSearchResult>;
/**
* Get audit log statistics
*/
export declare function getAuditStatistics(startDate?: Date, endDate?: Date): Promise<{
totalIssuances: number;
totalRevocations: number;
totalVerifications: number;
totalRenewals: number;
byCredentialType: Record<string, number>;
byAction: Record<string, number>;
}>;
/**
* Export audit logs (for compliance/regulatory reporting)
*/
export declare function exportAuditLogs(filters: AuditSearchFilters, format?: 'json' | 'csv'): Promise<string>;
//# sourceMappingURL=audit-search.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"audit-search.d.ts","sourceRoot":"","sources":["audit-search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,EAC3B,IAAI,SAAI,EACR,QAAQ,SAAK,GACZ,OAAO,CAAC,iBAAiB,CAAC,CA4E5B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,IAAI,EAChB,OAAO,CAAC,EAAE,IAAI,GACb,OAAO,CAAC;IACT,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC,CAsDD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,GAAE,MAAM,GAAG,KAAc,GAC9B,OAAO,CAAC,MAAM,CAAC,CAiCjB"}

View File

@@ -0,0 +1,144 @@
/**
* Enhanced audit logging with search capabilities
*/
import { query } from './client';
/**
* Search audit logs with filters
*/
export async function searchAuditLogs(filters, page = 1, pageSize = 50) {
const conditions = [];
const params = [];
let paramIndex = 1;
if (filters.credentialId) {
conditions.push(`credential_id = $${paramIndex++}`);
params.push(filters.credentialId);
}
if (filters.issuerDid) {
conditions.push(`issuer_did = $${paramIndex++}`);
params.push(filters.issuerDid);
}
if (filters.subjectDid) {
conditions.push(`subject_did = $${paramIndex++}`);
params.push(filters.subjectDid);
}
if (filters.credentialType) {
const types = Array.isArray(filters.credentialType) ? filters.credentialType : [filters.credentialType];
conditions.push(`credential_type && $${paramIndex++}`);
params.push(types);
}
if (filters.action) {
conditions.push(`action = $${paramIndex++}`);
params.push(filters.action);
}
if (filters.performedBy) {
conditions.push(`performed_by = $${paramIndex++}`);
params.push(filters.performedBy);
}
if (filters.startDate) {
conditions.push(`performed_at >= $${paramIndex++}`);
params.push(filters.startDate);
}
if (filters.endDate) {
conditions.push(`performed_at <= $${paramIndex++}`);
params.push(filters.endDate);
}
if (filters.ipAddress) {
conditions.push(`ip_address = $${paramIndex++}`);
params.push(filters.ipAddress);
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
const offset = (page - 1) * pageSize;
// Get total count
const countResult = await query(`SELECT COUNT(*) as count FROM credential_issuance_audit ${whereClause}`, params);
const total = parseInt(countResult.rows[0]?.count || '0', 10);
// Get paginated results
const result = await query(`SELECT * FROM credential_issuance_audit
${whereClause}
ORDER BY performed_at DESC
LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [...params, pageSize, offset]);
return {
logs: result.rows,
total,
page,
pageSize,
};
}
/**
* Get audit log statistics
*/
export async function getAuditStatistics(startDate, endDate) {
const conditions = [];
const params = [];
let paramIndex = 1;
if (startDate) {
conditions.push(`performed_at >= $${paramIndex++}`);
params.push(startDate);
}
if (endDate) {
conditions.push(`performed_at <= $${paramIndex++}`);
params.push(endDate);
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
// Get counts by action
const actionResult = await query(`SELECT action, COUNT(*) as count
FROM credential_issuance_audit
${whereClause}
GROUP BY action`, params);
const byAction = {};
actionResult.rows.forEach((row) => {
byAction[row.action] = parseInt(row.count, 10);
});
// Get counts by credential type
const typeResult = await query(`SELECT credential_type, COUNT(*) as count
FROM credential_issuance_audit
${whereClause}
GROUP BY credential_type`, params);
const byCredentialType = {};
typeResult.rows.forEach((row) => {
const types = row.credential_type.join(', ');
byCredentialType[types] = (byCredentialType[types] || 0) + parseInt(row.count, 10);
});
return {
totalIssuances: byAction.issued || 0,
totalRevocations: byAction.revoked || 0,
totalVerifications: byAction.verified || 0,
totalRenewals: byAction.renewed || 0,
byCredentialType,
byAction,
};
}
/**
* Export audit logs (for compliance/regulatory reporting)
*/
export async function exportAuditLogs(filters, format = 'json') {
const result = await searchAuditLogs(filters, 1, 10000); // Large limit for export
if (format === 'csv') {
const headers = [
'id',
'credential_id',
'issuer_did',
'subject_did',
'credential_type',
'action',
'performed_by',
'performed_at',
'ip_address',
'user_agent',
];
const rows = result.logs.map((log) => [
log.id,
log.credential_id,
log.issuer_did,
log.subject_did,
log.credential_type.join(';'),
log.action,
log.performed_by || '',
log.performed_at.toISOString(),
log.ip_address || '',
log.user_agent || '',
]);
return [headers.join(','), ...rows.map((row) => row.join(','))].join('\n');
}
return JSON.stringify(result.logs, null, 2);
}
//# sourceMappingURL=audit-search.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"audit-search.js","sourceRoot":"","sources":["audit-search.ts"],"names":[],"mappings":"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"}

View File

@@ -2,6 +2,7 @@
* PostgreSQL database client with connection pooling
*/
import { Pool, QueryResult, QueryResultRow } from 'pg';
export type { QueryResult, QueryResultRow };
export interface DatabaseConfig {
connectionString?: string;
host?: string;

View File

@@ -1 +1 @@
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAc,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEnE,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAcvD;AAOD;;GAEG;AACH,wBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAQrD;AAED;;GAEG;AACH,wBAAsB,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EACnE,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAKzB;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAQpD"}
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAc,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAGnE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAcvD;AAOD;;GAEG;AACH,wBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAQrD;AAED;;GAEG;AACH,wBAAsB,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EACnE,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAKzB;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAQpD"}

View File

@@ -1 +1 @@
{"version":3,"file":"client.js","sourceRoot":"","sources":["client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAA2C,MAAM,IAAI,CAAC;AAcnE;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,MAAM,UAAU,GAAe;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;QACrB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,KAAK;QACpD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,IAAI;KAChE,CAAC;IAEF,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,IAAI,WAAW,GAAgB,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,MAAuB;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;QACD,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAY,EACZ,MAAkB;IAElB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,WAAW,CAAC,KAAK,CAAI,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;QACxB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
{"version":3,"file":"client.js","sourceRoot":"","sources":["client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAA2C,MAAM,IAAI,CAAC;AAiBnE;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,MAAM,UAAU,GAAe;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;QACrB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,KAAK;QACpD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,IAAI;KAChE,CAAC;IAEF,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,IAAI,WAAW,GAAgB,IAAI,CAAC;AAEpC;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,MAAuB;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;QACD,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAY,EACZ,MAAkB;IAElB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,WAAW,CAAC,KAAK,CAAI,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;QACxB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}

View File

@@ -0,0 +1,50 @@
/**
* Credential lifecycle management operations
*/
export interface CredentialStatusHistory {
id: string;
credential_id: string;
status: string;
reason?: string;
changed_by?: string;
changed_at: Date;
metadata?: unknown;
}
export interface CredentialRevocation {
id: string;
credential_id: string;
issuer_did: string;
revocation_reason?: string;
revoked_by?: string;
revoked_at: Date;
revocation_list_index?: number;
}
export interface CredentialAuditLog {
id: string;
credential_id: string;
issuer_did: string;
subject_did: string;
credential_type: string[];
action: 'issued' | 'revoked' | 'verified' | 'renewed';
performed_by?: string;
performed_at: Date;
metadata?: unknown;
ip_address?: string;
user_agent?: string;
}
export declare function addCredentialStatusHistory(history: Omit<CredentialStatusHistory, 'id' | 'changed_at'>): Promise<CredentialStatusHistory>;
export declare function getCredentialStatusHistory(credentialId: string): Promise<CredentialStatusHistory[]>;
export declare function revokeCredential(revocation: Omit<CredentialRevocation, 'id' | 'revoked_at' | 'revocation_list_index'>): Promise<CredentialRevocation>;
export declare function isCredentialRevoked(credentialId: string): Promise<boolean>;
export declare function getRevocationRegistry(issuerDid: string, limit?: number, offset?: number): Promise<CredentialRevocation[]>;
export declare function logCredentialAction(audit: Omit<CredentialAuditLog, 'id' | 'performed_at'>): Promise<CredentialAuditLog>;
export declare function getCredentialAuditLog(credentialId: string, limit?: number): Promise<CredentialAuditLog[]>;
export declare function getExpiringCredentials(daysAhead: number, limit?: number): Promise<Array<{
credential_id: string;
expiration_date: Date;
subject_did: string;
issuer_did: string;
credential_type: string[];
credential_subject: unknown;
}>>;
//# sourceMappingURL=credential-lifecycle.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"credential-lifecycle.d.ts","sourceRoot":"","sources":["credential-lifecycle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,IAAI,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,IAAI,GAAG,YAAY,CAAC,GAC1D,OAAO,CAAC,uBAAuB,CAAC,CAclC;AAED,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAQpC;AAGD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,YAAY,GAAG,uBAAuB,CAAC,GACpF,OAAO,CAAC,oBAAoB,CAAC,CAiC/B;AAED,wBAAsB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMhF;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,oBAAoB,EAAE,CAAC,CASjC;AAGD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,cAAc,CAAC,GACrD,OAAO,CAAC,kBAAkB,CAAC,CAmB7B;AAED,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,KAAK,SAAM,GACV,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAS/B;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,KAAK,SAAM,GACV,OAAO,CAAC,KAAK,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAanK"}

View File

@@ -0,0 +1,97 @@
/**
* Credential lifecycle management operations
*/
import { query } from './client';
// Note: CredentialTemplate operations are now in credential-templates.ts
// This file focuses on lifecycle operations (status history, revocation, audit)
// Credential Status History operations
export async function addCredentialStatusHistory(history) {
const result = await query(`INSERT INTO credential_status_history (credential_id, status, reason, changed_by, metadata)
VALUES ($1, $2, $3, $4, $5)
RETURNING *`, [
history.credential_id,
history.status,
history.reason || null,
history.changed_by || null,
history.metadata ? JSON.stringify(history.metadata) : null,
]);
return result.rows[0];
}
export async function getCredentialStatusHistory(credentialId) {
const result = await query(`SELECT * FROM credential_status_history
WHERE credential_id = $1
ORDER BY changed_at DESC`, [credentialId]);
return result.rows;
}
// Credential Revocation operations
export async function revokeCredential(revocation) {
// First, update the credential as revoked
await query(`UPDATE verifiable_credentials
SET revoked = TRUE, updated_at = NOW()
WHERE credential_id = $1`, [revocation.credential_id]);
// Get the next revocation list index
const indexResult = await query(`SELECT MAX(revocation_list_index) as max_index
FROM credential_revocation_registry
WHERE issuer_did = $1`, [revocation.issuer_did]);
const nextIndex = (indexResult.rows[0]?.max_index ?? -1) + 1;
// Add to revocation registry
const result = await query(`INSERT INTO credential_revocation_registry
(credential_id, issuer_did, revocation_reason, revoked_by, revocation_list_index)
VALUES ($1, $2, $3, $4, $5)
RETURNING *`, [
revocation.credential_id,
revocation.issuer_did,
revocation.revocation_reason || null,
revocation.revoked_by || null,
nextIndex,
]);
return result.rows[0];
}
export async function isCredentialRevoked(credentialId) {
const result = await query(`SELECT revoked FROM verifiable_credentials WHERE credential_id = $1`, [credentialId]);
return result.rows[0]?.revoked ?? false;
}
export async function getRevocationRegistry(issuerDid, limit = 100, offset = 0) {
const result = await query(`SELECT * FROM credential_revocation_registry
WHERE issuer_did = $1
ORDER BY revocation_list_index DESC
LIMIT $2 OFFSET $3`, [issuerDid, limit, offset]);
return result.rows;
}
// Credential Audit Log operations
export async function logCredentialAction(audit) {
const result = await query(`INSERT INTO credential_issuance_audit
(credential_id, issuer_did, subject_did, credential_type, action, performed_by, metadata, ip_address, user_agent)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *`, [
audit.credential_id,
audit.issuer_did,
audit.subject_did,
audit.credential_type,
audit.action,
audit.performed_by || null,
audit.metadata ? JSON.stringify(audit.metadata) : null,
audit.ip_address || null,
audit.user_agent || null,
]);
return result.rows[0];
}
export async function getCredentialAuditLog(credentialId, limit = 100) {
const result = await query(`SELECT * FROM credential_issuance_audit
WHERE credential_id = $1
ORDER BY performed_at DESC
LIMIT $2`, [credentialId, limit]);
return result.rows;
}
export async function getExpiringCredentials(daysAhead, limit = 100) {
const result = await query(`SELECT credential_id, expiration_date, subject_did, issuer_did, credential_type, credential_subject
FROM verifiable_credentials
WHERE expiration_date IS NOT NULL
AND expiration_date > NOW()
AND expiration_date < NOW() + INTERVAL '${daysAhead} days'
AND revoked = FALSE
ORDER BY expiration_date ASC
LIMIT $1`, [limit]);
return result.rows;
}
//# sourceMappingURL=credential-lifecycle.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"credential-lifecycle.js","sourceRoot":"","sources":["credential-lifecycle.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,68 @@
/**
* Credential template management
*/
import { z } from 'zod';
export declare const CredentialTemplateSchema: z.ZodObject<{
id: z.ZodString;
name: z.ZodString;
description: z.ZodOptional<z.ZodString>;
credential_type: z.ZodArray<z.ZodString, "many">;
template_data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
version: z.ZodNumber;
is_active: z.ZodBoolean;
created_by: z.ZodNullable<z.ZodString>;
created_at: z.ZodDate;
updated_at: z.ZodDate;
}, "strip", z.ZodTypeAny, {
name: string;
id: string;
created_at: Date;
updated_at: Date;
created_by: string | null;
credential_type: string[];
template_data: Record<string, unknown>;
version: number;
is_active: boolean;
description?: string | undefined;
}, {
name: string;
id: string;
created_at: Date;
updated_at: Date;
created_by: string | null;
credential_type: string[];
template_data: Record<string, unknown>;
version: number;
is_active: boolean;
description?: string | undefined;
}>;
export type CredentialTemplate = z.infer<typeof CredentialTemplateSchema>;
/**
* Create a credential template
*/
export declare function createCredentialTemplate(template: Omit<CredentialTemplate, 'id' | 'created_at' | 'updated_at'>): Promise<CredentialTemplate>;
/**
* Get credential template by ID
*/
export declare function getCredentialTemplate(id: string): Promise<CredentialTemplate | null>;
/**
* Get credential template by name and version
*/
export declare function getCredentialTemplateByName(name: string, version?: number): Promise<CredentialTemplate | null>;
/**
* List all credential templates
*/
export declare function listCredentialTemplates(activeOnly?: boolean, limit?: number, offset?: number): Promise<CredentialTemplate[]>;
/**
* Update credential template
*/
export declare function updateCredentialTemplate(id: string, updates: Partial<Pick<CredentialTemplate, 'description' | 'template_data' | 'is_active'>>): Promise<CredentialTemplate | null>;
/**
* Create new version of credential template
*/
export declare function createTemplateVersion(templateId: string, updates: Partial<Pick<CredentialTemplate, 'template_data' | 'description'>>): Promise<CredentialTemplate>;
/**
* Render credential from template with variable substitution
*/
export declare function renderCredentialFromTemplate(template: CredentialTemplate, variables: Record<string, unknown>): Record<string, unknown>;
//# sourceMappingURL=credential-templates.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"credential-templates.d.ts","sourceRoot":"","sources":["credential-templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,GACrE,OAAO,CAAC,kBAAkB,CAAC,CAiB7B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAM1F;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAkBpC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,UAAO,EACjB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAU/B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,aAAa,GAAG,eAAe,GAAG,WAAW,CAAC,CAAC,GACxF,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAiCpC;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC,GAC1E,OAAO,CAAC,kBAAkB,CAAC,CAsB7B;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsBzB"}

View File

@@ -0,0 +1,148 @@
/**
* Credential template management
*/
import { query } from './client';
import { z } from 'zod';
export const CredentialTemplateSchema = z.object({
id: z.string().uuid(),
name: z.string(),
description: z.string().optional(),
credential_type: z.array(z.string()),
template_data: z.record(z.unknown()),
version: z.number().int().positive(),
is_active: z.boolean(),
created_by: z.string().uuid().nullable(),
created_at: z.date(),
updated_at: z.date(),
});
/**
* Create a credential template
*/
export async function createCredentialTemplate(template) {
const result = await query(`INSERT INTO credential_templates
(name, description, credential_type, template_data, version, is_active, created_by)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *`, [
template.name,
template.description || null,
template.credential_type,
JSON.stringify(template.template_data),
template.version,
template.is_active,
template.created_by || null,
]);
return result.rows[0];
}
/**
* Get credential template by ID
*/
export async function getCredentialTemplate(id) {
const result = await query(`SELECT * FROM credential_templates WHERE id = $1`, [id]);
return result.rows[0] || null;
}
/**
* Get credential template by name and version
*/
export async function getCredentialTemplateByName(name, version) {
if (version) {
const result = await query(`SELECT * FROM credential_templates WHERE name = $1 AND version = $2`, [name, version]);
return result.rows[0] || null;
}
else {
// Get latest active version
const result = await query(`SELECT * FROM credential_templates
WHERE name = $1 AND is_active = TRUE
ORDER BY version DESC
LIMIT 1`, [name]);
return result.rows[0] || null;
}
}
/**
* List all credential templates
*/
export async function listCredentialTemplates(activeOnly = true, limit = 100, offset = 0) {
const whereClause = activeOnly ? 'WHERE is_active = TRUE' : '';
const result = await query(`SELECT * FROM credential_templates
${whereClause}
ORDER BY name, version DESC
LIMIT $1 OFFSET $2`, [limit, offset]);
return result.rows;
}
/**
* Update credential template
*/
export async function updateCredentialTemplate(id, updates) {
const fields = [];
const values = [];
let paramIndex = 1;
if (updates.description !== undefined) {
fields.push(`description = $${paramIndex++}`);
values.push(updates.description);
}
if (updates.template_data !== undefined) {
fields.push(`template_data = $${paramIndex++}`);
values.push(JSON.stringify(updates.template_data));
}
if (updates.is_active !== undefined) {
fields.push(`is_active = $${paramIndex++}`);
values.push(updates.is_active);
}
if (fields.length === 0) {
return getCredentialTemplate(id);
}
fields.push(`updated_at = NOW()`);
values.push(id);
const result = await query(`UPDATE credential_templates
SET ${fields.join(', ')}
WHERE id = $${paramIndex}
RETURNING *`, values);
return result.rows[0] || null;
}
/**
* Create new version of credential template
*/
export async function createTemplateVersion(templateId, updates) {
const original = await getCredentialTemplate(templateId);
if (!original) {
throw new Error(`Template ${templateId} not found`);
}
// Get next version number
const versionResult = await query(`SELECT MAX(version) as max_version FROM credential_templates WHERE name = $1`, [original.name]);
const nextVersion = (versionResult.rows[0]?.max_version || 0) + 1;
return createCredentialTemplate({
name: original.name,
description: updates.description || original.description,
credential_type: original.credential_type,
template_data: updates.template_data || original.template_data,
version: nextVersion,
is_active: true,
created_by: original.created_by,
});
}
/**
* Render credential from template with variable substitution
*/
export function renderCredentialFromTemplate(template, variables) {
const rendered = JSON.parse(JSON.stringify(template.template_data));
function substitute(obj) {
if (typeof obj === 'string') {
// Replace {{variable}} patterns
return obj.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
return variables[varName] !== undefined ? String(variables[varName]) : match;
});
}
else if (Array.isArray(obj)) {
return obj.map(substitute);
}
else if (obj && typeof obj === 'object') {
const result = {};
for (const [key, value] of Object.entries(obj)) {
result[key] = substitute(value);
}
return result;
}
return obj;
}
return substitute(rendered);
}
//# sourceMappingURL=credential-templates.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"credential-templates.js","sourceRoot":"","sources":["credential-templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACpC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACxC,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE;IACpB,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE;CACrB,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAAsE;IAEtE,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB;;;iBAGa,EACb;QACE,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,WAAW,IAAI,IAAI;QAC5B,QAAQ,CAAC,eAAe;QACxB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC;QACtC,QAAQ,CAAC,OAAO;QAChB,QAAQ,CAAC,SAAS;QAClB,QAAQ,CAAC,UAAU,IAAI,IAAI;KAC5B,CACF,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAAU;IACpD,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,kDAAkD,EAClD,CAAC,EAAE,CAAC,CACL,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,IAAY,EACZ,OAAgB;IAEhB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,qEAAqE,EACrE,CAAC,IAAI,EAAE,OAAO,CAAC,CAChB,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,4BAA4B;QAC5B,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB;;;eAGS,EACT,CAAC,IAAI,CAAC,CACP,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,UAAU,GAAG,IAAI,EACjB,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,CAAC;IAEV,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB;OACG,WAAW;;wBAEM,EACpB,CAAC,KAAK,EAAE,MAAM,CAAC,CAChB,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,EAAU,EACV,OAAyF;IAEzF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,kBAAkB,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,oBAAoB,UAAU,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,gBAAgB,UAAU,EAAE,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB;WACO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;mBACT,UAAU;iBACZ,EACb,MAAM,CACP,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB,EAClB,OAA2E;IAE3E,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,YAAY,UAAU,YAAY,CAAC,CAAC;IACtD,CAAC;IAED,0BAA0B;IAC1B,MAAM,aAAa,GAAG,MAAM,KAAK,CAC/B,8EAA8E,EAC9E,CAAC,QAAQ,CAAC,IAAI,CAAC,CAChB,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAElE,OAAO,wBAAwB,CAAC;QAC9B,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW;QACxD,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,QAAQ,CAAC,aAAa;QAC9D,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,QAAQ,CAAC,UAAU;KAChC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAA4B,EAC5B,SAAkC;IAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpE,SAAS,UAAU,CAAC,GAAY;QAC9B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,gCAAgC;YAChC,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;gBACtD,OAAO,SAAS,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC/E,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,MAAM,GAA4B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,UAAU,CAAC,QAAQ,CAA4B,CAAC;AACzD,CAAC"}

View File

@@ -0,0 +1,59 @@
/**
* eResidency Application Database Operations
*/
import { type eResidencyApplication, type eCitizenshipApplication, ApplicationStatus } from '@the-order/schemas';
/**
* Create eResidency application
*/
export declare function createEResidencyApplication(application: Omit<eResidencyApplication, 'id' | 'createdAt' | 'updatedAt'>): Promise<eResidencyApplication>;
/**
* Get eResidency application by ID
*/
export declare function getEResidencyApplicationById(id: string): Promise<eResidencyApplication | null>;
/**
* Update eResidency application
*/
export declare function updateEResidencyApplication(id: string, updates: {
status?: ApplicationStatus;
kycStatus?: 'pending' | 'passed' | 'failed' | 'requires_edd';
sanctionsStatus?: 'pending' | 'clear' | 'flag';
pepStatus?: 'pending' | 'clear' | 'flag';
riskScore?: number;
kycResults?: unknown;
sanctionsResults?: unknown;
riskAssessment?: unknown;
reviewedAt?: string;
reviewedBy?: string;
rejectionReason?: string;
}): Promise<eResidencyApplication>;
/**
* Get review queue
*/
export declare function getReviewQueue(filters: {
riskBand?: 'low' | 'medium' | 'high';
status?: ApplicationStatus;
assignedTo?: string;
limit?: number;
offset?: number;
}): Promise<{
applications: eResidencyApplication[];
total: number;
}>;
/**
* Create eCitizenship application
*/
export declare function createECitizenshipApplication(application: Omit<eCitizenshipApplication, 'id' | 'createdAt' | 'updatedAt'>): Promise<eCitizenshipApplication>;
/**
* Get eCitizenship application by ID
*/
export declare function getECitizenshipApplicationById(id: string): Promise<eCitizenshipApplication | null>;
/**
* Update eCitizenship application
*/
export declare function updateECitizenshipApplication(id: string, updates: {
status?: ApplicationStatus;
reviewedAt?: string;
reviewedBy?: string;
rejectionReason?: string;
}): Promise<eCitizenshipApplication>;
//# sourceMappingURL=eresidency-applications.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"eresidency-applications.d.ts","sourceRoot":"","sources":["eresidency-applications.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AA4C5B;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GACzE,OAAO,CAAC,qBAAqB,CAAC,CA2BhC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAWpG;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IACP,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,CAAC;IAC7D,eAAe,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IAC/C,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,qBAAqB,CAAC,CA2DhC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDpE;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,IAAI,CAAC,uBAAuB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAC3E,OAAO,CAAC,uBAAuB,CAAC,CAuDlC;AAED;;GAEG;AACH,wBAAsB,8BAA8B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA6CxG;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IACP,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,uBAAuB,CAAC,CAiElC"}

View File

@@ -0,0 +1,340 @@
/**
* eResidency Application Database Operations
*/
import { query } from './client';
/**
* Map database row to application object
*/
function mapRowToApplication(row) {
return {
id: row.id,
applicantDid: row.applicant_did || undefined,
email: row.email,
givenName: row.given_name,
familyName: row.family_name,
dateOfBirth: row.date_of_birth ? (row.date_of_birth instanceof Date ? row.date_of_birth.toISOString().split('T')[0] : row.date_of_birth) : undefined,
nationality: row.nationality || undefined,
phone: row.phone || undefined,
address: row.address ? (typeof row.address === 'string' ? JSON.parse(row.address) : row.address) : undefined,
deviceFingerprint: row.device_fingerprint || undefined,
identityDocument: row.identity_document
? typeof row.identity_document === 'string'
? JSON.parse(row.identity_document)
: row.identity_document
: undefined,
selfieLiveness: row.selfie_liveness
? typeof row.selfie_liveness === 'string'
? JSON.parse(row.selfie_liveness)
: row.selfie_liveness
: undefined,
status: row.status,
submittedAt: row.submitted_at ? (row.submitted_at instanceof Date ? row.submitted_at.toISOString() : row.submitted_at) : undefined,
reviewedAt: row.reviewed_at ? (row.reviewed_at instanceof Date ? row.reviewed_at.toISOString() : row.reviewed_at) : undefined,
reviewedBy: row.reviewed_by || undefined,
rejectionReason: row.rejection_reason || undefined,
kycStatus: row.kyc_status || undefined,
sanctionsStatus: row.sanctions_status || undefined,
pepStatus: row.pep_status || undefined,
riskScore: row.risk_score ? parseFloat(String(row.risk_score)) : undefined,
kycResults: row.kyc_results ? (typeof row.kyc_results === 'string' ? JSON.parse(row.kyc_results) : row.kyc_results) : undefined,
sanctionsResults: row.sanctions_results ? (typeof row.sanctions_results === 'string' ? JSON.parse(row.sanctions_results) : row.sanctions_results) : undefined,
riskAssessment: row.risk_assessment ? (typeof row.risk_assessment === 'string' ? JSON.parse(row.risk_assessment) : row.risk_assessment) : undefined,
createdAt: row.created_at instanceof Date ? row.created_at.toISOString() : row.created_at,
updatedAt: row.updated_at instanceof Date ? row.updated_at.toISOString() : row.updated_at,
};
}
/**
* Create eResidency application
*/
export async function createEResidencyApplication(application) {
const result = await query(`INSERT INTO eresidency_applications
(applicant_did, email, given_name, family_name, date_of_birth, nationality, phone, address,
device_fingerprint, identity_document, selfie_liveness, status, kyc_status, sanctions_status, pep_status)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
RETURNING *`, [
application.applicantDid || null,
application.email,
application.givenName,
application.familyName,
application.dateOfBirth || null,
application.nationality || null,
application.phone || null,
application.address ? JSON.stringify(application.address) : null,
application.deviceFingerprint || null,
application.identityDocument ? JSON.stringify(application.identityDocument) : null,
application.selfieLiveness ? JSON.stringify(application.selfieLiveness) : null,
application.status,
application.kycStatus || null,
application.sanctionsStatus || null,
application.pepStatus || null,
]);
return mapRowToApplication(result.rows[0]);
}
/**
* Get eResidency application by ID
*/
export async function getEResidencyApplicationById(id) {
const result = await query('SELECT * FROM eresidency_applications WHERE id = $1', [id]);
if (!result.rows[0]) {
return null;
}
return mapRowToApplication(result.rows[0]);
}
/**
* Update eResidency application
*/
export async function updateEResidencyApplication(id, updates) {
const fields = [];
const values = [];
let paramIndex = 1;
if (updates.status !== undefined) {
fields.push(`status = $${paramIndex++}`);
values.push(updates.status);
}
if (updates.kycStatus !== undefined) {
fields.push(`kyc_status = $${paramIndex++}`);
values.push(updates.kycStatus);
}
if (updates.sanctionsStatus !== undefined) {
fields.push(`sanctions_status = $${paramIndex++}`);
values.push(updates.sanctionsStatus);
}
if (updates.pepStatus !== undefined) {
fields.push(`pep_status = $${paramIndex++}`);
values.push(updates.pepStatus);
}
if (updates.riskScore !== undefined) {
fields.push(`risk_score = $${paramIndex++}`);
values.push(updates.riskScore);
}
if (updates.kycResults !== undefined) {
fields.push(`kyc_results = $${paramIndex++}`);
values.push(JSON.stringify(updates.kycResults));
}
if (updates.sanctionsResults !== undefined) {
fields.push(`sanctions_results = $${paramIndex++}`);
values.push(JSON.stringify(updates.sanctionsResults));
}
if (updates.riskAssessment !== undefined) {
fields.push(`risk_assessment = $${paramIndex++}`);
values.push(JSON.stringify(updates.riskAssessment));
}
if (updates.reviewedAt !== undefined) {
fields.push(`reviewed_at = $${paramIndex++}`);
values.push(updates.reviewedAt);
}
if (updates.reviewedBy !== undefined) {
fields.push(`reviewed_by = $${paramIndex++}`);
values.push(updates.reviewedBy);
}
if (updates.rejectionReason !== undefined) {
fields.push(`rejection_reason = $${paramIndex++}`);
values.push(updates.rejectionReason);
}
fields.push(`updated_at = NOW()`);
values.push(id);
const result = await query(`UPDATE eresidency_applications SET ${fields.join(', ')} WHERE id = $${paramIndex} RETURNING *`, values);
return mapRowToApplication(result.rows[0]);
}
/**
* Get review queue
*/
export async function getReviewQueue(filters) {
const conditions = [];
const params = [];
let paramIndex = 1;
if (filters.riskBand) {
// Map risk band to risk score range
const riskRanges = {
low: [0, 0.3],
medium: [0.3, 0.8],
high: [0.8, 1.0],
};
const [min, max] = riskRanges[filters.riskBand];
conditions.push(`risk_score >= $${paramIndex++} AND risk_score < $${paramIndex++}`);
params.push(min, max);
}
if (filters.status) {
conditions.push(`status = $${paramIndex++}`);
params.push(filters.status);
}
if (filters.assignedTo) {
conditions.push(`reviewed_by = $${paramIndex++}`);
params.push(filters.assignedTo);
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
const limit = filters.limit || 50;
const offset = filters.offset || 0;
// Get total count
const countResult = await query(`SELECT COUNT(*) as count FROM eresidency_applications ${whereClause}`, params);
const total = parseInt(countResult.rows[0]?.count || '0', 10);
// Get applications
const result = await query(`SELECT * FROM eresidency_applications
${whereClause}
ORDER BY created_at DESC
LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [...params, limit, offset]);
const applications = result.rows.map((row) => mapRowToApplication(row));
return { applications, total };
}
/**
* Create eCitizenship application
*/
export async function createECitizenshipApplication(application) {
const result = await query(`INSERT INTO ecitizenship_applications
(applicant_did, resident_did, residency_tenure, sponsor_did, service_merit, video_interview,
background_attestations, oath_ceremony, status)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *`, [
application.applicantDid,
application.residentDid,
application.residencyTenure,
application.sponsorDid || null,
application.serviceMerit ? JSON.stringify(application.serviceMerit) : null,
application.videoInterview ? JSON.stringify(application.videoInterview) : null,
application.backgroundAttestations ? JSON.stringify(application.backgroundAttestations) : null,
application.oathCeremony ? JSON.stringify(application.oathCeremony) : null,
application.status,
]);
const row = result.rows[0];
return {
id: row.id,
applicantDid: row.applicant_did,
residentDid: row.resident_did,
residencyTenure: row.residency_tenure || undefined,
sponsorDid: row.sponsor_did || undefined,
serviceMerit: row.service_merit
? typeof row.service_merit === 'string'
? JSON.parse(row.service_merit)
: row.service_merit
: undefined,
videoInterview: row.video_interview
? typeof row.video_interview === 'string'
? JSON.parse(row.video_interview)
: row.video_interview
: undefined,
backgroundAttestations: row.background_attestations
? typeof row.background_attestations === 'string'
? JSON.parse(row.background_attestations)
: row.background_attestations
: undefined,
oathCeremony: row.oath_ceremony
? typeof row.oath_ceremony === 'string'
? JSON.parse(row.oath_ceremony)
: row.oath_ceremony
: undefined,
status: row.status,
submittedAt: row.submitted_at ? (row.submitted_at instanceof Date ? row.submitted_at.toISOString() : row.submitted_at) : undefined,
reviewedAt: row.reviewed_at ? (row.reviewed_at instanceof Date ? row.reviewed_at.toISOString() : row.reviewed_at) : undefined,
reviewedBy: row.reviewed_by || undefined,
rejectionReason: row.rejection_reason || undefined,
createdAt: row.created_at instanceof Date ? row.created_at.toISOString() : row.created_at,
updatedAt: row.updated_at instanceof Date ? row.updated_at.toISOString() : row.updated_at,
};
}
/**
* Get eCitizenship application by ID
*/
export async function getECitizenshipApplicationById(id) {
const result = await query('SELECT * FROM ecitizenship_applications WHERE id = $1', [id]);
if (!result.rows[0]) {
return null;
}
const row = result.rows[0];
return {
id: row.id,
applicantDid: row.applicant_did,
residentDid: row.resident_did,
residencyTenure: row.residency_tenure || undefined,
sponsorDid: row.sponsor_did || undefined,
serviceMerit: row.service_merit
? typeof row.service_merit === 'string'
? JSON.parse(row.service_merit)
: row.service_merit
: undefined,
videoInterview: row.video_interview
? typeof row.video_interview === 'string'
? JSON.parse(row.video_interview)
: row.video_interview
: undefined,
backgroundAttestations: row.background_attestations
? typeof row.background_attestations === 'string'
? JSON.parse(row.background_attestations)
: row.background_attestations
: undefined,
oathCeremony: row.oath_ceremony
? typeof row.oath_ceremony === 'string'
? JSON.parse(row.oath_ceremony)
: row.oath_ceremony
: undefined,
status: row.status,
submittedAt: row.submitted_at ? (row.submitted_at instanceof Date ? row.submitted_at.toISOString() : row.submitted_at) : undefined,
reviewedAt: row.reviewed_at ? (row.reviewed_at instanceof Date ? row.reviewed_at.toISOString() : row.reviewed_at) : undefined,
reviewedBy: row.reviewed_by || undefined,
rejectionReason: row.rejection_reason || undefined,
createdAt: row.created_at instanceof Date ? row.created_at.toISOString() : row.created_at,
updatedAt: row.updated_at instanceof Date ? row.updated_at.toISOString() : row.updated_at,
};
}
/**
* Update eCitizenship application
*/
export async function updateECitizenshipApplication(id, updates) {
const fields = [];
const values = [];
let paramIndex = 1;
if (updates.status !== undefined) {
fields.push(`status = $${paramIndex++}`);
values.push(updates.status);
}
if (updates.reviewedAt !== undefined) {
fields.push(`reviewed_at = $${paramIndex++}`);
values.push(updates.reviewedAt);
}
if (updates.reviewedBy !== undefined) {
fields.push(`reviewed_by = $${paramIndex++}`);
values.push(updates.reviewedBy);
}
if (updates.rejectionReason !== undefined) {
fields.push(`rejection_reason = $${paramIndex++}`);
values.push(updates.rejectionReason);
}
fields.push(`updated_at = NOW()`);
values.push(id);
const result = await query(`UPDATE ecitizenship_applications SET ${fields.join(', ')} WHERE id = $${paramIndex} RETURNING *`, values);
const row = result.rows[0];
return {
id: row.id,
applicantDid: row.applicant_did,
residentDid: row.resident_did,
residencyTenure: row.residency_tenure || undefined,
sponsorDid: row.sponsor_did || undefined,
serviceMerit: row.service_merit
? typeof row.service_merit === 'string'
? JSON.parse(row.service_merit)
: row.service_merit
: undefined,
videoInterview: row.video_interview
? typeof row.video_interview === 'string'
? JSON.parse(row.video_interview)
: row.video_interview
: undefined,
backgroundAttestations: row.background_attestations
? typeof row.background_attestations === 'string'
? JSON.parse(row.background_attestations)
: row.background_attestations
: undefined,
oathCeremony: row.oath_ceremony
? typeof row.oath_ceremony === 'string'
? JSON.parse(row.oath_ceremony)
: row.oath_ceremony
: undefined,
status: row.status,
submittedAt: row.submitted_at ? (row.submitted_at instanceof Date ? row.submitted_at.toISOString() : row.submitted_at) : undefined,
reviewedAt: row.reviewed_at ? (row.reviewed_at instanceof Date ? row.reviewed_at.toISOString() : row.reviewed_at) : undefined,
reviewedBy: row.reviewed_by || undefined,
rejectionReason: row.rejection_reason || undefined,
createdAt: row.created_at instanceof Date ? row.created_at.toISOString() : row.created_at,
updatedAt: row.updated_at instanceof Date ? row.updated_at.toISOString() : row.updated_at,
};
}
//# sourceMappingURL=eresidency-applications.js.map

File diff suppressed because one or more lines are too long

View File

@@ -3,5 +3,12 @@
*/
export * from './client';
export * from './schema';
export * from './credential-lifecycle';
export * from './credential-templates';
export * from './audit-search';
export * from './query-cache';
export * from './eresidency-applications';
export { getCredentialTemplateByName, renderCredentialFromTemplate, } from './credential-templates';
export type { QueryResult, QueryResultRow } from './client';
export type { User, Document, Deal, VerifiableCredential, Signature, LedgerEntry, Payment, } from './schema';
//# sourceMappingURL=index.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAGzB,YAAY,EACV,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,OAAO,GACR,MAAM,UAAU,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAG1C,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG5D,YAAY,EACV,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,OAAO,GACR,MAAM,UAAU,CAAC"}

View File

@@ -3,4 +3,11 @@
*/
export * from './client';
export * from './schema';
export * from './credential-lifecycle';
export * from './credential-templates';
export * from './audit-search';
export * from './query-cache';
export * from './eresidency-applications';
// Re-export template functions for convenience
export { getCredentialTemplateByName, renderCredentialFromTemplate, } from './credential-templates';
//# sourceMappingURL=index.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAE1C,+CAA+C;AAC/C,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC"}

33
packages/database/src/query-cache.d.ts vendored Normal file
View File

@@ -0,0 +1,33 @@
/**
* Database query caching with Redis
* Implements query result caching with automatic invalidation
*
* Note: This module uses optional dynamic import for @the-order/cache
* to avoid requiring it as a direct dependency. If cache is not available,
* queries will execute directly without caching.
*/
import type { QueryResult, QueryResultRow } from './client';
export interface CacheOptions {
ttl?: number;
keyPrefix?: string;
enabled?: boolean;
}
/**
* Execute a query with caching
*/
export declare function cachedQuery<T extends QueryResultRow = QueryResultRow>(sql: string, params?: unknown[], options?: CacheOptions): Promise<QueryResult<T>>;
/**
* Invalidate cache for a pattern
*/
export declare function invalidateCache(pattern: string): Promise<number>;
/**
* Invalidate cache for a specific query
*/
export declare function invalidateQueryCache(sql: string, params?: unknown[]): Promise<void>;
/**
* Cache decorator for database functions
* Note: This is a simplified implementation. In production, you'd need to
* extract SQL and params from the function or pass them as metadata.
*/
export declare function cached<T extends (...args: unknown[]) => Promise<QueryResult<QueryResultRow>>>(fn: T): T;
//# sourceMappingURL=query-cache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-cache.d.ts","sourceRoot":"","sources":["query-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAuCD;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EACzE,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,OAAO,EAAE,EAClB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CA4BzB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzF;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,EAC3F,EAAE,EAAE,CAAC,GACJ,CAAC,CAKH"}

View File

@@ -0,0 +1,93 @@
/**
* Database query caching with Redis
* Implements query result caching with automatic invalidation
*
* Note: This module uses optional dynamic import for @the-order/cache
* to avoid requiring it as a direct dependency. If cache is not available,
* queries will execute directly without caching.
*/
import { query } from './client';
// Cache client instance (lazy-loaded via dynamic import)
let cacheClientPromise = null;
/**
* Get cache client (lazy-loaded via dynamic import)
* Returns null if cache module is not available
*/
async function getCacheClient() {
if (cacheClientPromise === null) {
cacheClientPromise = (async () => {
try {
// Use dynamic import with a string literal that TypeScript can't resolve at compile time
// This is done by constructing the import path dynamically
const cacheModulePath = '@the-order/cache';
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const importFunc = new Function('specifier', 'return import(specifier)');
const cacheModule = await importFunc(cacheModulePath);
return cacheModule.getCacheClient();
}
catch {
// Cache module not available - caching will be disabled
return null;
}
})();
}
return cacheClientPromise;
}
/**
* Execute a query with caching
*/
export async function cachedQuery(sql, params, options = {}) {
const { ttl = 3600, keyPrefix = 'db:query:', enabled = true } = options;
if (!enabled) {
return query(sql, params);
}
const cache = await getCacheClient();
if (!cache) {
// Cache not available - execute query directly
return query(sql, params);
}
const cacheKey = `${keyPrefix}${sql}:${JSON.stringify(params || [])}`;
// Try to get from cache
const cached = await cache.get(cacheKey);
if (cached) {
return cached;
}
// Execute query
const result = await query(sql, params);
// Cache result
await cache.set(cacheKey, result, ttl);
return result;
}
/**
* Invalidate cache for a pattern
*/
export async function invalidateCache(pattern) {
const cache = await getCacheClient();
if (!cache) {
return 0;
}
return cache.invalidate(`db:query:${pattern}*`);
}
/**
* Invalidate cache for a specific query
*/
export async function invalidateQueryCache(sql, params) {
const cache = await getCacheClient();
if (!cache) {
return;
}
const cacheKey = `db:query:${sql}:${JSON.stringify(params || [])}`;
await cache.delete(cacheKey);
}
/**
* Cache decorator for database functions
* Note: This is a simplified implementation. In production, you'd need to
* extract SQL and params from the function or pass them as metadata.
*/
export function cached(fn) {
return (async (...args) => {
const result = await fn(...args);
return result;
});
}
//# sourceMappingURL=query-cache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-cache.js","sourceRoot":"","sources":["query-cache.ts"],"names":[],"mappings":"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"}