@cyber-eco/services • Docs
@cyber-eco/services¶
Classes¶
CacheService¶
Multi-level cache service with L1 (in-memory) and optional L2 (external) caching
Constructors¶
new CacheService()¶
new CacheService(
config?):CacheService
Parameters¶
• config?: CacheConfig
Returns¶
Defined in¶
packages/services/src/core/CacheService.ts:13
Methods¶
get()¶
get\<
T>(key):Promise\<null|T>
Get value from cache (L1 → L2 → miss)
Type Parameters¶
• T
Parameters¶
• key: string
Returns¶
Promise\<null | T>
Defined in¶
packages/services/src/core/CacheService.ts:27
set()¶
set\<
T>(key,value,collection?):Promise\<void>
Set value in cache (both L1 and L2)
Type Parameters¶
• T
Parameters¶
• key: string
• value: T
• collection?: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/core/CacheService.ts:50
delete()¶
delete(
key):Promise\<void>
Delete value from cache
Parameters¶
• key: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/core/CacheService.ts:62
deletePattern()¶
deletePattern(
pattern):Promise\<void>
Delete all keys matching a pattern
Parameters¶
• pattern: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/core/CacheService.ts:72
clear()¶
clear():
Promise\<void>
Clear entire cache
Returns¶
Promise\<void>
Defined in¶
packages/services/src/core/CacheService.ts:82
DataLayerService¶
DataLayerService - The main orchestrator for all data operations Handles permissions, caching, sync events, and webhooks
Implements¶
IDataLayerService
Constructors¶
new DataLayerService()¶
new DataLayerService(
config):DataLayerService
Parameters¶
• config: DataLayerConfig
Returns¶
Defined in¶
packages/services/src/core/DataLayerService.ts:33
Methods¶
setPermissionChecker()¶
setPermissionChecker(
checker):void
Set the permission checker (used for circular dependency resolution)
Parameters¶
• checker: PermissionChecker
Returns¶
void
Implementation of¶
IDataLayerService.setPermissionChecker
Defined in¶
packages/services/src/core/DataLayerService.ts:56
get()¶
get\<
T>(userId,collection,id):Promise\<null|T>
Read a document
Type Parameters¶
• T
Parameters¶
• userId: string
• collection: string
• id: string
Returns¶
Promise\<null | T>
Implementation of¶
IDataLayerService.get
Defined in¶
packages/services/src/core/DataLayerService.ts:93
create()¶
create\<
T>(userId,collection,data,id?):Promise\<string>
Create a document
Type Parameters¶
• T extends Record\<string, unknown>
Parameters¶
• userId: string
• collection: string
• data: T
• id?: string
Returns¶
Promise\<string>
Implementation of¶
IDataLayerService.create
Defined in¶
packages/services/src/core/DataLayerService.ts:120
update()¶
update(
userId,collection,id,data):Promise\<void>
Update a document
Parameters¶
• userId: string
• collection: string
• id: string
• data: Record\<string, unknown>
Returns¶
Promise\<void>
Implementation of¶
IDataLayerService.update
Defined in¶
packages/services/src/core/DataLayerService.ts:176
delete()¶
delete(
userId,collection,id):Promise\<void>
Delete a document
Parameters¶
• userId: string
• collection: string
• id: string
Returns¶
Promise\<void>
Implementation of¶
IDataLayerService.delete
Defined in¶
packages/services/src/core/DataLayerService.ts:228
query()¶
query\<
T>(userId,collection,filters,options?):Promise\<PaginatedResult\<T>>
Query documents
Type Parameters¶
• T
Parameters¶
• userId: string
• collection: string
• filters: QueryFilter[]
• options?: QueryOptions
Returns¶
Promise\<PaginatedResult\<T>>
Implementation of¶
IDataLayerService.query
Defined in¶
packages/services/src/core/DataLayerService.ts:268
subscribe()¶
subscribe\<
T>(userId,collection,id,callback):Unsubscribe
Subscribe to a document. Permission is checked before the Firestore listener is attached. Returns an unsubscribe function that also tears down the listener.
Type Parameters¶
• T
Parameters¶
• userId: string
• collection: string
• id: string
• callback
Returns¶
Unsubscribe
Implementation of¶
IDataLayerService.subscribe
Defined in¶
packages/services/src/core/DataLayerService.ts:302
batchWrite()¶
batchWrite(
userId,operations):Promise\<void>
Batch write operations
Parameters¶
• userId: string
• operations: object[]
Returns¶
Promise\<void>
Implementation of¶
IDataLayerService.batchWrite
Defined in¶
packages/services/src/core/DataLayerService.ts:343
InMemoryLRUCache¶
In-memory LRU cache implementation
Implements¶
CacheBackend
Constructors¶
new InMemoryLRUCache()¶
new InMemoryLRUCache(
maxEntries):InMemoryLRUCache
Parameters¶
• maxEntries: number = 1000
Returns¶
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:15
Methods¶
get()¶
get\<
T>(key):Promise\<null|T>
Type Parameters¶
• T
Parameters¶
• key: string
Returns¶
Promise\<null | T>
Implementation of¶
CacheBackend.get
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:20
set()¶
set\<
T>(key,value,ttlMs?):Promise\<void>
Type Parameters¶
• T
Parameters¶
• key: string
• value: T
• ttlMs?: number
Returns¶
Promise\<void>
Implementation of¶
CacheBackend.set
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:40
delete()¶
delete(
key):Promise\<void>
Parameters¶
• key: string
Returns¶
Promise\<void>
Implementation of¶
CacheBackend.delete
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:57
deletePattern()¶
deletePattern(
pattern):Promise\<void>
Parameters¶
• pattern: string
Returns¶
Promise\<void>
Implementation of¶
CacheBackend.deletePattern
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:61
clear()¶
clear():
Promise\<void>
Returns¶
Promise\<void>
Implementation of¶
CacheBackend.clear
Defined in¶
packages/services/src/core/InMemoryLRUCache.ts:80
QueryService¶
Query utility service for cache key generation and pagination
Constructors¶
new QueryService()¶
new QueryService():
QueryService
Returns¶
Methods¶
generateCacheKey()¶
generateCacheKey(
collection,filters,options?):string
Generate a deterministic cache key from query parameters
Parameters¶
• collection: string
• filters: QueryFilter[]
• options?: QueryOptions
Returns¶
string
Defined in¶
packages/services/src/core/QueryService.ts:10
buildPaginationOptions()¶
buildPaginationOptions(
page,pageSize):QueryOptions
Build pagination options from page/pageSize
Parameters¶
• page: number
• pageSize: number
Returns¶
QueryOptions
Defined in¶
packages/services/src/core/QueryService.ts:39
extractPageInfo()¶
extractPageInfo\<
T>(result,pageSize):object
Extract pagination info from result
Type Parameters¶
• T
Parameters¶
• result: PaginatedResult\<T>
• pageSize: number
Returns¶
object
page¶
page:
number
pageSize¶
pageSize:
number
totalPages¶
totalPages:
number
hasNext¶
hasNext:
boolean
Defined in¶
packages/services/src/core/QueryService.ts:49
SyncService¶
In-process event broadcasting service for real-time data synchronization
Constructors¶
new SyncService()¶
new SyncService():
SyncService
Returns¶
Defined in¶
packages/services/src/core/SyncService.ts:9
Methods¶
broadcast()¶
broadcast(
event):void
Broadcast a sync event to all subscribers
Parameters¶
• event: SyncEvent
Returns¶
void
Defined in¶
packages/services/src/core/SyncService.ts:16
subscribe()¶
subscribe(
callback):Unsubscribe
Subscribe to sync events
Parameters¶
• callback
Returns¶
Unsubscribe
Defined in¶
packages/services/src/core/SyncService.ts:29
resolveConflict()¶
resolveConflict\<
T>(local,remote,strategy):T
Resolve conflicts between local and remote data
Type Parameters¶
• T
Parameters¶
• local: T
• remote: T
• strategy: ConflictResolution = 'remote-wins'
Returns¶
T
Defined in¶
packages/services/src/core/SyncService.ts:39
WebhookService¶
In-memory webhook event queue and registration service Note: Does not handle HTTP delivery - consumers handle that externally
Constructors¶
new WebhookService()¶
new WebhookService():
WebhookService
Returns¶
Defined in¶
packages/services/src/core/WebhookService.ts:11
Methods¶
register()¶
register(
webhook):void
Register a webhook endpoint
Parameters¶
• webhook: WebhookRegistration
Returns¶
void
Defined in¶
packages/services/src/core/WebhookService.ts:19
unregister()¶
unregister(
id):void
Unregister a webhook endpoint
Parameters¶
• id: string
Returns¶
void
Defined in¶
packages/services/src/core/WebhookService.ts:26
emit()¶
emit(
event):void
Emit an event to all registered webhooks
Parameters¶
• event: WebhookEvent
Returns¶
void
Defined in¶
packages/services/src/core/WebhookService.ts:33
getRegistrations()¶
getRegistrations():
WebhookRegistration[]
Get all registered webhooks
Returns¶
WebhookRegistration[]
Defined in¶
packages/services/src/core/WebhookService.ts:50
getQueuedEvents()¶
getQueuedEvents():
WebhookEvent[]
Get queued events (for external processing)
Returns¶
WebhookEvent[]
Defined in¶
packages/services/src/core/WebhookService.ts:57
clearQueue()¶
clearQueue():
void
Clear the event queue
Returns¶
void
Defined in¶
packages/services/src/core/WebhookService.ts:64
AuditService¶
AuditService provides audit log recording and retrieval.
All data operations go through the injected IDataLayerService --
this service has ZERO firebase imports.
Constructors¶
new AuditService()¶
new AuditService(
dataLayer):AuditService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/AuditService.ts:26
Methods¶
logEvent()¶
logEvent(
userId,event):Promise\<string>
Create a new audit log entry with auto-generated id and timestamp.
Parameters¶
• userId: string
The user performing the auditable action
• event: Omit\<AuditLogEntry, "id" | "timestamp">
The event data (id and timestamp are auto-generated)
Returns¶
Promise\<string>
The id of the created audit log entry
Defined in¶
packages/services/src/domain/AuditService.ts:37
getAuditLogs()¶
getAuditLogs(
userId,options?):Promise\<AuditLogEntry[]>
Retrieve paginated audit logs for a user.
Results are sorted by timestamp descending (most recent first).
When category is provided, only entries whose resourceType matches are returned.
Parameters¶
• userId: string
The user whose audit logs to retrieve
• options?: GetAuditLogsOptions
Pagination and filtering options
Returns¶
Promise\<AuditLogEntry[]>
Array of audit log entries
Defined in¶
packages/services/src/domain/AuditService.ts:65
getRecentEvents()¶
getRecentEvents(
userId,limit?):Promise\<AuditLogEntry[]>
Shorthand to retrieve the most recent audit events for a user.
Parameters¶
• userId: string
The user whose recent events to retrieve
• limit?: number
Maximum number of entries (default 5)
Returns¶
Promise\<AuditLogEntry[]>
Array of the most recent audit log entries
Defined in¶
packages/services/src/domain/AuditService.ts:105
ConsentService¶
Manages user consent lifecycle for connected OAuth applications.
Example¶
const consent = new ConsentService(dataLayer);
const id = await consent.grantConsent('user-1', {
userId: 'user-1',
clientId: 'app-client-id',
appName: 'My App',
scopes: ['profile:read'],
});
Constructors¶
new ConsentService()¶
new ConsentService(
dataLayer):ConsentService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/ConsentService.ts:32
Methods¶
grantConsent()¶
grantConsent(
userId,consent):Promise\<string>
Grant consent for an OAuth app to access user data.
Creates a new consent record with an auto-generated id and timestamp.
Parameters¶
• userId: string
The user granting consent
• consent: Omit\<OAuthConsent, "id" | "grantedAt">
Consent details (id and grantedAt are auto-generated)
Returns¶
Promise\<string>
The id of the created consent record
Defined in¶
packages/services/src/domain/ConsentService.ts:45
revokeConsent()¶
revokeConsent(
userId,clientId):Promise\<void>
Revoke consent for an OAuth app.
Sets revokedAt on the active consent record. The document is
never deleted (GDPR: consent records must be retained for audit).
No-op if the user has no active consent for this clientId.
Parameters¶
• userId: string
The user revoking consent
• clientId: string
The OAuth app's client identifier
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/ConsentService.ts:78
getConsent()¶
getConsent(
userId,clientId):Promise\<null|OAuthConsent>
Get the active (non-revoked) consent for a user/app pair.
Parameters¶
• userId: string
The user whose consent to look up
• clientId: string
The OAuth app's client identifier
Returns¶
Promise\<null | OAuthConsent>
The active consent, or null if none exists
Defined in¶
packages/services/src/domain/ConsentService.ts:101
getUserConsents()¶
getUserConsents(
userId):Promise\<OAuthConsent[]>
Get all consent records for a user, including revoked ones.
Returns the full consent history for audit/transparency purposes.
Parameters¶
• userId: string
The user whose consents to list
Returns¶
Promise\<OAuthConsent[]>
Array of all consent records (active and revoked)
Defined in¶
packages/services/src/domain/ConsentService.ts:113
hasConsent()¶
hasConsent(
userId,clientId):Promise\<boolean>
Check if a user has an active (non-revoked) consent for an app.
Parameters¶
• userId: string
The user to check
• clientId: string
The OAuth app's client identifier
Returns¶
Promise\<boolean>
True if an active consent exists
Defined in¶
packages/services/src/domain/ConsentService.ts:131
updateLastUsed()¶
updateLastUsed(
userId,clientId):Promise\<void>
Update the lastUsedAt timestamp on an active consent.
Called when an OAuth app makes an API request on behalf of the user. No-op if no active consent exists.
Parameters¶
• userId: string
The user whose consent to update
• clientId: string
The OAuth app's client identifier
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/ConsentService.ts:145
DashboardService¶
DashboardService - Provides dashboard metrics and activity feeds
Constructors¶
new DashboardService()¶
new DashboardService(
dataLayer):DashboardService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/DashboardService.ts:34
Methods¶
getDashboardMetrics()¶
getDashboardMetrics(
userId):Promise\<DashboardMetric[]>
Parameters¶
• userId: string
Returns¶
Promise\<DashboardMetric[]>
Defined in¶
packages/services/src/domain/DashboardService.ts:36
getActivityFeed()¶
getActivityFeed(
userId,options?):Promise\<ActivityItem[]>
Parameters¶
• userId: string
• options?
• options.limit?: number
Returns¶
Promise\<ActivityItem[]>
Defined in¶
packages/services/src/domain/DashboardService.ts:122
getAppUsageStats()¶
getAppUsageStats(
userId):Promise\<Record\<string,unknown>>
Parameters¶
• userId: string
Returns¶
Promise\<Record\<string, unknown>>
Defined in¶
packages/services/src/domain/DashboardService.ts:184
DataExportService¶
DataExportService - GDPR-compliant data export functionality
Constructors¶
new DataExportService()¶
new DataExportService(
dataLayer):DataExportService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/DataExportService.ts:30
Methods¶
exportToJSON()¶
exportToJSON(
userId,collections?):Promise\<string>
Parameters¶
• userId: string
• collections?: string[]
Returns¶
Promise\<string>
Defined in¶
packages/services/src/domain/DataExportService.ts:32
exportToCSV()¶
exportToCSV(
userId,collections?):Promise\<string>
Parameters¶
• userId: string
• collections?: string[]
Returns¶
Promise\<string>
Defined in¶
packages/services/src/domain/DataExportService.ts:37
getExportableData()¶
getExportableData(
userId,collections?):Promise\<UserDataExport>
Parameters¶
• userId: string
• collections?: string[]
Returns¶
Promise\<UserDataExport>
Defined in¶
packages/services/src/domain/DataExportService.ts:76
ExpensePermissionError¶
Thrown when a user lacks the required role for an operation
Extends¶
Error
Constructors¶
new ExpensePermissionError()¶
new ExpensePermissionError(
message):ExpensePermissionError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/ExpenseService.ts:21
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
ExpenseValidationError¶
Thrown when input validation fails
Extends¶
Error
Constructors¶
new ExpenseValidationError()¶
new ExpenseValidationError(
message):ExpenseValidationError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/ExpenseService.ts:29
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
ExpenseNotFoundError¶
Thrown when a requested resource is not found
Extends¶
Error
Constructors¶
new ExpenseNotFoundError()¶
new ExpenseNotFoundError(
message):ExpenseNotFoundError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/ExpenseService.ts:37
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
ExpenseService¶
ExpenseService - Domain service for group expense tracking.
Implements the core business logic for CyberEco's Group Expenses feature: create/manage expense groups, add expenses with flexible splits, compute balances, simplify debts, record settlements, and export data.
Uses constructor injection of IDataLayerService (StorageAdapter pattern). ZERO firebase imports — all data access goes through the data layer.
Example¶
const service = new ExpenseService(dataLayer);
const groupId = await service.createGroup('user-1', { name: 'Trip', type: 'friends' });
await service.addExpense(groupId, 'user-1', { ... });
const balances = await service.calculateBalances(groupId, 'user-1');
Constructors¶
new ExpenseService()¶
new ExpenseService(
dataLayer):ExpenseService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/ExpenseService.ts:112
Methods¶
createGroup()¶
createGroup(
userId,input):Promise\<string>
Create a new expense group. The creator is automatically assigned the owner role.
Parameters¶
• userId: string
ID of the user creating the group
• input: CreateGroupInput
Group creation parameters
Returns¶
Promise\<string>
The ID of the created group
Throws¶
If the name is empty or exceeds 100 characters
Defined in¶
packages/services/src/domain/ExpenseService.ts:124
getGroup()¶
getGroup(
groupId,userId):Promise\<null|ExpenseGroup>
Get an expense group by ID. Verifies the user is a member.
Parameters¶
• groupId: string
The group document ID
• userId: string
The user requesting access
Returns¶
Promise\<null | ExpenseGroup>
The expense group, or null if not found
Throws¶
If the user is not a group member
Defined in¶
packages/services/src/domain/ExpenseService.ts:173
getUserGroups()¶
getUserGroups(
userId):Promise\<ExpenseGroup[]>
List all expense groups where the user is a member.
Parameters¶
• userId: string
The user to list groups for
Returns¶
Promise\<ExpenseGroup[]>
Array of expense groups
Defined in¶
packages/services/src/domain/ExpenseService.ts:194
deleteGroup()¶
deleteGroup(
groupId,userId):Promise\<void>
Delete an expense group and all its expenses and settlements. Only the group owner can perform this operation (GDPR right to erasure).
Parameters¶
• groupId: string
The group to delete
• userId: string
The user requesting deletion (must be owner)
Returns¶
Promise\<void>
Throws¶
If the group does not exist
Throws¶
If the user is not the group owner
Defined in¶
packages/services/src/domain/ExpenseService.ts:217
addMember()¶
addMember(
groupId,userId,member):Promise\<ExpenseGroup>
Add a member to an expense group. Requires admin+ role.
Parameters¶
• groupId: string
The group to add the member to
• userId: string
The user performing the action (must be admin+)
• member
The member to add (userId and displayName required)
• member.userId: string
• member.displayName: string
• member.role?: AppRole
Returns¶
Promise\<ExpenseGroup>
The updated expense group
Throws¶
If the acting user lacks admin+ role
Throws¶
If the group is at max capacity or member already exists
Defined in¶
packages/services/src/domain/ExpenseService.ts:281
removeMember()¶
removeMember(
groupId,userId,targetUserId):Promise\<ExpenseGroup>
Remove a member from an expense group. Requires admin+ role. The owner cannot be removed.
Parameters¶
• groupId: string
The group to remove the member from
• userId: string
The user performing the action (must be admin+)
• targetUserId: string
The user to remove
Returns¶
Promise\<ExpenseGroup>
The updated expense group
Throws¶
If the acting user lacks admin+ role
Throws¶
If trying to remove the owner or a non-member
Defined in¶
packages/services/src/domain/ExpenseService.ts:342
addExpense()¶
addExpense(
groupId,userId,input):Promise\<string>
Add an expense to a group. Any group member can add expenses. Validates that splits match the total amount and populates memberIds from the group for Firestore security rules.
Parameters¶
• groupId: string
The group to add the expense to
• userId: string
The user adding the expense (must be member+)
• input: AddExpenseInput
Expense details including amount, splits, and payer
Returns¶
Promise\<string>
The ID of the created expense
Throws¶
If the expense data is invalid
Defined in¶
packages/services/src/domain/ExpenseService.ts:394
getExpenses()¶
getExpenses(
groupId,userId,options?):Promise\<object>
Get expenses for a group with pagination. Sorted by date descending.
Parameters¶
• groupId: string
The group to list expenses for
• userId: string
The user requesting the list (must be member+)
• options?: GetExpensesOptions
Pagination options (page, limit)
Returns¶
Promise\<object>
Object with expenses array, total count, current page, and total pages
expenses¶
expenses:
Expense[]
total¶
total:
number
page¶
page:
number
pages¶
pages:
number
Defined in¶
packages/services/src/domain/ExpenseService.ts:445
calculateBalances()¶
calculateBalances(
groupId,userId):Promise\<Balance[]>
Calculate net balances for a group from all expenses and settlements. Returns directional debts: "fromUser owes toUser amount".
Parameters¶
• groupId: string
The group to calculate balances for
• userId: string
The requesting user (must be member+)
Returns¶
Promise\<Balance[]>
Array of Balance objects representing directional debts
Defined in¶
packages/services/src/domain/ExpenseService.ts:498
simplifyDebts()¶
staticsimplifyDebts(rawBalances):Balance[]
Simplify debts using a greedy matching algorithm. Minimizes the number of transactions needed to settle all debts. This is a pure function — no side effects.
Parameters¶
• rawBalances: Balance[]
Array of directional debt balances
Returns¶
Balance[]
Simplified array of balances with minimum transactions
Defined in¶
packages/services/src/domain/ExpenseService.ts:567
recordSettlement()¶
recordSettlement(
groupId,userId,input):Promise\<string>
Record a settlement between two group members. The recording user must be either the payer or the receiver.
Parameters¶
• groupId: string
The group the settlement belongs to
• userId: string
The user recording the settlement (must be fromUserId or toUserId)
• input: RecordSettlementInput
Settlement details
Returns¶
Promise\<string>
The ID of the created settlement
Throws¶
If the user is not a settlement participant
Defined in¶
packages/services/src/domain/ExpenseService.ts:629
exportGroup()¶
exportGroup(
groupId,userId):Promise\<ExpenseGroupExport>
Export all group data as a structured JSON payload. Only the group owner can export (Tenet #1: Digital Sovereignty).
Parameters¶
• groupId: string
The group to export
• userId: string
The requesting user (must be owner)
Returns¶
Promise\<ExpenseGroupExport>
Complete group export including expenses, settlements, and balances
Defined in¶
packages/services/src/domain/ExpenseService.ts:689
equalSplit()¶
staticequalSplit(amount,participantIds):ExpenseSplit[]
Calculate an equal split of an amount among participants. Rounding remainder is assigned to the first participant.
Parameters¶
• amount: number
Total amount to split
• participantIds: string[]
User IDs of participants
Returns¶
ExpenseSplit[]
Array of ExpenseSplit with calculated amounts
Throws¶
If fewer than 2 participants or amount is not positive
Defined in¶
packages/services/src/domain/ExpenseService.ts:731
percentageSplit()¶
staticpercentageSplit(amount,participants):ExpenseSplit[]
Calculate a percentage-based split of an amount. Percentages must sum to 100.
Parameters¶
• amount: number
Total amount to split
• participants: object[]
Array of userId + percentage pairs
Returns¶
ExpenseSplit[]
Array of ExpenseSplit with calculated amounts and percentages
Throws¶
If percentages don't sum to 100 or fewer than 2 participants
Defined in¶
packages/services/src/domain/ExpenseService.ts:758
exactSplit()¶
staticexactSplit(totalAmount,participants):ExpenseSplit[]
Validate an exact split where amounts are specified directly. Amounts must sum to the total.
Parameters¶
• totalAmount: number
The total expense amount
• participants: object[]
Array of userId + amount pairs
Returns¶
ExpenseSplit[]
Array of ExpenseSplit with the exact amounts
Throws¶
If amounts don't sum to total or fewer than 2 participants
Defined in¶
packages/services/src/domain/ExpenseService.ts:792
MfaService¶
App-layer TOTP multi-factor authentication.
Backend-agnostic by construction: MFA state (TwoFactorConfig) is persisted
through the injected IDataLayerService, so this works with ANY storage
backend (Firebase today, Supabase/own later) and does NOT require the auth
backend to offer native MFA. Secrets and backup-code hashes are stored
server-side and never returned to the client (except the one-time enrollment
payload). This service has ZERO firebase imports.
Implements¶
MfaProvider
Constructors¶
new MfaService()¶
new MfaService(
dataLayer):MfaService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/MfaService.ts:40
Methods¶
setupTotp()¶
setupTotp(
userId,accountLabel):Promise\<MfaSetup>
Begin TOTP enrollment: returns secret + otpauth URI + backup codes.
Parameters¶
• userId: string
• accountLabel: string
Returns¶
Promise\<MfaSetup>
Implementation of¶
MfaProvider.setupTotp
Defined in¶
packages/services/src/domain/MfaService.ts:61
verifyAndEnable()¶
verifyAndEnable(
userId,code):Promise\<boolean>
Verify a code and enable MFA for the user.
Parameters¶
• userId: string
• code: string
Returns¶
Promise\<boolean>
Implementation of¶
MfaProvider.verifyAndEnable
Defined in¶
packages/services/src/domain/MfaService.ts:78
verify()¶
verify(
userId,code):Promise\<boolean>
Verify a TOTP code or consume a backup code (used at the login challenge).
Parameters¶
• userId: string
• code: string
Returns¶
Promise\<boolean>
Implementation of¶
MfaProvider.verify
Defined in¶
packages/services/src/domain/MfaService.ts:90
disable()¶
disable(
userId):Promise\<void>
Disable MFA and clear the stored secret/backup codes.
Parameters¶
• userId: string
Returns¶
Promise\<void>
Implementation of¶
MfaProvider.disable
Defined in¶
packages/services/src/domain/MfaService.ts:111
getStatus()¶
getStatus(
userId):Promise\<MfaStatus>
Client-safe status.
Parameters¶
• userId: string
Returns¶
Promise\<MfaStatus>
Implementation of¶
MfaProvider.getStatus
Defined in¶
packages/services/src/domain/MfaService.ts:117
regenerateBackupCodes()¶
regenerateBackupCodes(
userId):Promise\<string[]>
Regenerate backup codes; returns the new plaintext codes once.
Parameters¶
• userId: string
Returns¶
Promise\<string[]>
Implementation of¶
MfaProvider.regenerateBackupCodes
Defined in¶
packages/services/src/domain/MfaService.ts:127
NotificationService¶
NotificationService - Manages cross-app notifications
Constructors¶
new NotificationService()¶
new NotificationService(
dataLayer):NotificationService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/NotificationService.ts:9
Methods¶
createNotification()¶
createNotification(
userId,notification):Promise\<string>
Parameters¶
• userId: string
• notification: Omit\<Notification, "read" | "id" | "createdAt">
Returns¶
Promise\<string>
Defined in¶
packages/services/src/domain/NotificationService.ts:11
getUserNotifications()¶
getUserNotifications(
userId,options?):Promise\<Notification[]>
Parameters¶
• userId: string
• options?
• options.unreadOnly?: boolean
• options.limit?: number
Returns¶
Promise\<Notification[]>
Defined in¶
packages/services/src/domain/NotificationService.ts:27
markNotificationRead()¶
markNotificationRead(
userId,notificationId):Promise\<void>
Parameters¶
• userId: string
• notificationId: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/NotificationService.ts:52
subscribeToUserNotifications()¶
subscribeToUserNotifications(
_userId,_callback):Unsubscribe
Parameters¶
• _userId: string
• _callback
Returns¶
Unsubscribe
Defined in¶
packages/services/src/domain/NotificationService.ts:58
OAuthValidationError¶
Thrown when input validation fails (e.g., empty name, invalid scope).
Extends¶
Error
Constructors¶
new OAuthValidationError()¶
new OAuthValidationError(
message):OAuthValidationError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/OAuthService.ts:19
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
OAuthNotFoundError¶
Thrown when an OAuth app is not found or has been deleted.
Extends¶
Error
Constructors¶
new OAuthNotFoundError()¶
new OAuthNotFoundError(
message):OAuthNotFoundError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/OAuthService.ts:27
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
OAuthPermissionError¶
Thrown when a developer tries to modify an app they don't own.
Extends¶
Error
Constructors¶
new OAuthPermissionError()¶
new OAuthPermissionError(
message):OAuthPermissionError
Parameters¶
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/OAuthService.ts:35
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
OAuthService¶
Manages OAuth application registration and API key authentication.
Example¶
const oauth = new OAuthService(dataLayer);
const { app, clientSecret } = await oauth.registerApp(userId, {
name: 'My App',
description: 'A cool app',
redirectUris: ['https://example.com/callback'],
requestedScopes: ['profile:read'],
});
// clientSecret is shown once — store it securely
Constructors¶
new OAuthService()¶
new OAuthService(
dataLayer):OAuthService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/OAuthService.ts:100
Methods¶
registerApp()¶
registerApp(
developerId,input):Promise\<object>
Register a new OAuth application.
Generates a clientId (UUID) and clientSecret (64-char hex). The secret is hashed with SHA-256 before storage and returned in plaintext exactly once.
Parameters¶
• developerId: string
The user registering the app
• input: RegisterAppInput
App registration details
Returns¶
Promise\<object>
The created app and the plaintext client secret (shown once)
app¶
app:
OAuthApp
clientSecret¶
clientSecret:
string
Throws¶
If input is invalid or developer has too many apps
Defined in¶
packages/services/src/domain/OAuthService.ts:118
getApp()¶
getApp(
clientId):Promise\<null|OAuthApp>
Get an OAuth app by its clientId.
Parameters¶
• clientId: string
The app's client identifier
Returns¶
Promise\<null | OAuthApp>
The app, or null if not found
Defined in¶
packages/services/src/domain/OAuthService.ts:170
getDeveloperApps()¶
getDeveloperApps(
developerId):Promise\<OAuthApp[]>
List all apps registered by a developer, sorted by createdAt descending.
Parameters¶
• developerId: string
The developer whose apps to list
Returns¶
Promise\<OAuthApp[]>
Array of OAuth apps (includes deleted apps for audit)
Defined in¶
packages/services/src/domain/OAuthService.ts:191
updateApp()¶
updateApp(
developerId,clientId,input):Promise\<OAuthApp>
Update an existing OAuth app.
Only the app's developer (owner) can update it. Deleted apps cannot be updated.
Parameters¶
• developerId: string
The developer requesting the update
• clientId: string
The app's client identifier
• input: UpdateAppInput
Fields to update
Returns¶
Promise\<OAuthApp>
The updated app
Throws¶
If developerId doesn't match the app's owner
Throws¶
If app not found or deleted
Throws¶
If updated fields are invalid
Defined in¶
packages/services/src/domain/OAuthService.ts:216
deleteApp()¶
deleteApp(
developerId,clientId):Promise\<void>
Soft-delete an OAuth app by setting its status to 'deleted'.
Only the app's developer (owner) can delete it. In Phase 2, this will also revoke all tokens and consents.
Parameters¶
• developerId: string
The developer requesting deletion
• clientId: string
The app's client identifier
Returns¶
Promise\<void>
Throws¶
If developerId doesn't match the app's owner
Throws¶
If app not found
Defined in¶
packages/services/src/domain/OAuthService.ts:285
rotateSecret()¶
rotateSecret(
developerId,clientId):Promise\<object>
Rotate the client secret for an app.
The old secret is invalidated immediately. The new secret is returned in plaintext exactly once.
Parameters¶
• developerId: string
The developer requesting rotation
• clientId: string
The app's client identifier
Returns¶
Promise\<object>
The new plaintext client secret (shown once)
clientSecret¶
clientSecret:
string
Throws¶
If developerId doesn't match the app's owner
Throws¶
If app not found or deleted
Defined in¶
packages/services/src/domain/OAuthService.ts:324
validateApiKey()¶
validateApiKey(
clientId,clientSecret):Promise\<null|OAuthApp>
Validate an API key (clientId + clientSecret pair).
Used by middleware to authenticate Bearer tokens in the format
clientId:clientSecret.
Parameters¶
• clientId: string
The app's client identifier
• clientSecret: string
The plaintext secret to validate
Returns¶
Promise\<null | OAuthApp>
The app if valid, or null if invalid/inactive
Defined in¶
packages/services/src/domain/OAuthService.ts:372
OAuthTokenError¶
Base error for all OAuth token operations.
Extends¶
Error
Constructors¶
new OAuthTokenError()¶
new OAuthTokenError(
code,message):OAuthTokenError
Parameters¶
• code: string
• message: string
Returns¶
Overrides¶
Error.constructor
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:35
Properties¶
stackTraceLimit¶
staticstackTraceLimit:number
The Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
Inherited from¶
Error.stackTraceLimit
Defined in¶
node_modules/@types/node/globals.d.ts:67
cause?¶
optionalcause:unknown
Inherited from¶
Error.cause
Defined in¶
node_modules/typescript/lib/lib.es2022.error.d.ts:24
name¶
name:
string
Inherited from¶
Error.name
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1076
message¶
message:
string
Inherited from¶
Error.message
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1077
stack?¶
optionalstack:string
Inherited from¶
Error.stack
Defined in¶
node_modules/typescript/lib/lib.es5.d.ts:1078
code¶
readonlycode:string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:33
Methods¶
captureStackTrace()¶
staticcaptureStackTrace(targetObject,constructorOpt?):void
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters¶
• targetObject: object
• constructorOpt?: Function
Returns¶
void
Inherited from¶
Error.captureStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:51
prepareStackTrace()¶
staticprepareStackTrace(err,stackTraces):any
Parameters¶
• err: Error
• stackTraces: CallSite[]
Returns¶
any
See¶
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from¶
Error.prepareStackTrace
Defined in¶
node_modules/@types/node/globals.d.ts:55
OAuthTokenService¶
Manages the OAuth 2.0 Authorization Code flow with PKCE, token issuance, refresh token rotation, revocation, and introspection.
Example¶
const tokenService = new OAuthTokenService(dataLayer, 'my-jwt-secret');
// Generate authorization code
const code = await tokenService.generateAuthorizationCode({
clientId: 'app-id', userId: 'user-id',
redirectUri: 'https://app.com/cb',
scopes: ['profile:read'],
codeChallenge: 'sha256-of-verifier',
});
// Exchange for tokens
const tokens = await tokenService.exchangeCode({
code, codeVerifier: 'original-verifier',
clientId: 'app-id', clientSecret: 'secret',
redirectUri: 'https://app.com/cb',
});
Constructors¶
new OAuthTokenService()¶
new OAuthTokenService(
dataLayer,jwtSecret):OAuthTokenService
Parameters¶
• dataLayer: IDataLayerService
The data layer service for storage operations
• jwtSecret: string
Secret key for HMAC-SHA256 JWT signing
Returns¶
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:115
Methods¶
generateAuthorizationCode()¶
generateAuthorizationCode(
params):Promise\<string>
Generate an authorization code for the OAuth 2.0 Authorization Code flow.
The code is stored with a SHA-256 hash of the PKCE code challenge and expires after 10 minutes.
Parameters¶
• params: GenerateCodeParams
Authorization parameters
Returns¶
Promise\<string>
The opaque authorization code string
Throws¶
If parameters are invalid
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:132
exchangeCode()¶
exchangeCode(
params):Promise\<OAuthTokenPair>
Exchange an authorization code for an access token and refresh token.
Validates the code, verifies PKCE, marks the code as used, and issues a new token pair.
Parameters¶
• params: ExchangeCodeParams
Code exchange parameters
Returns¶
Promise\<OAuthTokenPair>
Token pair (access_token, refresh_token, expires_in, token_type, scope)
Throws¶
If code is invalid, expired, used, or PKCE fails
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:172
refreshToken()¶
refreshToken(
params):Promise\<OAuthTokenPair>
Refresh an access token using a refresh token.
Implements token rotation: the old refresh token is revoked and a new one is issued. If a revoked refresh token is reused (potential replay attack), all tokens in the family are revoked.
Parameters¶
• params: RefreshTokenParams
Refresh parameters
Returns¶
Promise\<OAuthTokenPair>
New token pair
Throws¶
If refresh token is invalid or revoked
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:232
revokeToken()¶
revokeToken(
token):Promise\<void>
Revoke a token (access or refresh).
For refresh tokens, also revokes all tokens in the same family.
Parameters¶
• token: string
The plaintext token to revoke
Returns¶
Promise\<void>
Throws¶
If token is not found
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:289
introspectToken()¶
introspectToken(
token):Promise\<TokenIntrospectionResponse>
Introspect a token to check its validity and metadata (RFC 7662).
Parameters¶
• token: string
The plaintext token to introspect
Returns¶
Promise\<TokenIntrospectionResponse>
Introspection response with active status and metadata
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:322
validateAccessToken()¶
validateAccessToken(
token):Promise\<null|object>
Validate an access token and return its claims.
Used by API middleware to authenticate requests.
Parameters¶
• token: string
The plaintext access token (JWT)
Returns¶
Promise\<null | object>
Token claims if valid, or null if invalid/expired/revoked
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:380
revokeAllClientTokens()¶
revokeAllClientTokens(
clientId):Promise\<void>
Revoke all tokens issued to a specific client. Used when an app is deleted or its secret is rotated.
Parameters¶
• clientId: string
The client ID whose tokens should be revoked
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:410
PermissionService¶
PermissionService - Manages app and resource permissions with 4-tier role hierarchy
Constructors¶
new PermissionService()¶
new PermissionService(
dataLayer):PermissionService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/PermissionService.ts:9
Methods¶
hasAppAccess()¶
hasAppAccess(
userId,appId):Promise\<boolean>
Parameters¶
• userId: string
• appId: string
Returns¶
Promise\<boolean>
Defined in¶
packages/services/src/domain/PermissionService.ts:13
grantAppAccess()¶
grantAppAccess(
userId,appId,roles,grantedBy,features):Promise\<void>
Parameters¶
• userId: string
• appId: string
• roles: AppRole[]
• grantedBy: string
• features: string[] = []
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/PermissionService.ts:38
revokeAppAccess()¶
revokeAppAccess(
userId,appId,revokedBy):Promise\<void>
Parameters¶
• userId: string
• appId: string
• revokedBy: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/PermissionService.ts:98
hasAppFeature()¶
hasAppFeature(
userId,appId,feature):Promise\<boolean>
Parameters¶
• userId: string
• appId: string
• feature: string
Returns¶
Promise\<boolean>
Defined in¶
packages/services/src/domain/PermissionService.ts:127
getUserPermissions()¶
getUserPermissions(
userId):Promise\<AppPermission[]>
Parameters¶
• userId: string
Returns¶
Promise\<AppPermission[]>
Defined in¶
packages/services/src/domain/PermissionService.ts:156
addUserRole()¶
addUserRole(
userId,appId,role):Promise\<void>
Parameters¶
• userId: string
• appId: string
• role: AppRole
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/PermissionService.ts:173
hasRole()¶
hasRole(
userId,appId,role):Promise\<boolean>
Parameters¶
• userId: string
• appId: string
• role: AppRole
Returns¶
Promise\<boolean>
Defined in¶
packages/services/src/domain/PermissionService.ts:201
canAccessResource()¶
canAccessResource(
userId,resourceType,resourceId,permission):Promise\<boolean>
Parameters¶
• userId: string
• resourceType: string
• resourceId: string
• permission: string
Returns¶
Promise\<boolean>
Defined in¶
packages/services/src/domain/PermissionService.ts:233
grantResourcePermission()¶
grantResourcePermission(
userId,resourceType,resourceId,permissions,grantedBy,expiresAt?):Promise\<void>
Parameters¶
• userId: string
• resourceType: string
• resourceId: string
• permissions: string[]
• grantedBy: string
• expiresAt?: string
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/PermissionService.ts:320
getPermissionLogs()¶
getPermissionLogs(
userId,limit):Promise\<unknown[]>
Parameters¶
• userId: string
• limit: number = 50
Returns¶
Promise\<unknown[]>
Defined in¶
packages/services/src/domain/PermissionService.ts:370
evaluatePermission()¶
evaluatePermission(
userId,collection,action,documentId?):Promise\<boolean>
Main permission evaluation function used by DataLayerService
Parameters¶
• userId: string
• collection: string
• action: "read" | "write" | "delete"
• documentId?: string
Returns¶
Promise\<boolean>
Defined in¶
packages/services/src/domain/PermissionService.ts:396
SharedDataService¶
SharedDataService - Manages centralized data shared across CyberEco apps
Constructors¶
new SharedDataService()¶
new SharedDataService(
dataLayer):SharedDataService
Parameters¶
• dataLayer: IDataLayerService
Returns¶
Defined in¶
packages/services/src/domain/SharedDataService.ts:14
Methods¶
getSharedUserProfile()¶
getSharedUserProfile(
userId,requesterId):Promise\<null|User>
Parameters¶
• userId: string
• requesterId: string
Returns¶
Promise\<null | User>
Defined in¶
packages/services/src/domain/SharedDataService.ts:18
updateSharedUserProfile()¶
updateSharedUserProfile(
userId,updates):Promise\<void>
Parameters¶
• userId: string
• updates: Partial\<User>
Returns¶
Promise\<void>
Defined in¶
packages/services/src/domain/SharedDataService.ts:22
linkAppToUserProfile()¶
linkAppToUserProfile(
userId,appId,appProfileId,settings?):Promise\<void>
Parameters¶
• userId: string
• appId: string
• appProfileId: string
• settings?: Record\<string, unknown>
Returns¶
Promise\<void>
Deprecated¶
Violates Tenet #1 (Digital Sovereignty). App state should not
be embedded in the user's canonical record. Use the apps field on User
for connected app IDs instead.
Defined in¶
packages/services/src/domain/SharedDataService.ts:34
createTransaction()¶
createTransaction(
userId,transaction):Promise\<string>
Parameters¶
• userId: string
• transaction: Omit\<Transaction, "id" | "createdAt">
Returns¶
Promise\<string>
Defined in¶
packages/services/src/domain/SharedDataService.ts:53
getUserTransactions()¶
getUserTransactions(
userId,options?):Promise\<Transaction[]>
Parameters¶
• userId: string
• options?
• options.appId?: string
• options.source?: string
• options.type?: "expense" | "income" | "transfer" | "settlement"
• options.startDate?: string
• options.endDate?: string
• options.limit?: number
Returns¶
Promise\<Transaction[]>
Defined in¶
packages/services/src/domain/SharedDataService.ts:60
createSharedGroup()¶
createSharedGroup(
userId,group):Promise\<string>
Parameters¶
• userId: string
• group: Omit\<SharedGroup, "id" | "createdAt">
Returns¶
Promise\<string>
Defined in¶
packages/services/src/domain/SharedDataService.ts:109
getUserGroups()¶
getUserGroups(
userId):Promise\<SharedGroup[]>
Parameters¶
• userId: string
Returns¶
Promise\<SharedGroup[]>
Defined in¶
packages/services/src/domain/SharedDataService.ts:116
linkGroupToApp()¶
linkGroupToApp(
userId,groupId,appId,appGroupId,features):Promise\<void>
Parameters¶
• userId: string
• groupId: string
• appId: string
• appGroupId: string
• features: string[]
Returns¶
Promise\<void>
Deprecated¶
Violates Tenet #1 (Digital Sovereignty). App-specific state
should not be embedded in shared group documents. Apps that need group
association should store a groupId reference in their own collection.
Defined in¶
packages/services/src/domain/SharedDataService.ts:135
generateFinancialSummary()¶
generateFinancialSummary(
userId,startDate,endDate):Promise\<FinancialSummary>
Parameters¶
• userId: string
• startDate: string
• endDate: string
Returns¶
Promise\<FinancialSummary>
Defined in¶
packages/services/src/domain/SharedDataService.ts:154
Interfaces¶
GetAuditLogsOptions¶
Options for querying audit logs.
Properties¶
category?¶
optionalcategory:string
Filter by resourceType
Defined in¶
packages/services/src/domain/AuditService.ts:10
limit?¶
optionallimit:number
Maximum number of entries to return (default 50)
Defined in¶
packages/services/src/domain/AuditService.ts:12
offset?¶
optionaloffset:number
Number of entries to skip for pagination
Defined in¶
packages/services/src/domain/AuditService.ts:14
GetExpensesOptions¶
Options for paginated expense listing
Properties¶
page?¶
optionalpage:number
Defined in¶
packages/services/src/domain/ExpenseService.ts:47
limit?¶
optionallimit:number
Defined in¶
packages/services/src/domain/ExpenseService.ts:48
CreateGroupInput¶
Input for creating an expense group
Properties¶
name¶
name:
string
Defined in¶
packages/services/src/domain/ExpenseService.ts:53
description?¶
optionaldescription:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:54
type¶
type:
"family"|"friends"|"community"|"organization"|"other"
Defined in¶
packages/services/src/domain/ExpenseService.ts:55
currency?¶
optionalcurrency:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:56
settings?¶
optionalsettings:Partial\<ExpenseGroupSettings>
Defined in¶
packages/services/src/domain/ExpenseService.ts:57
AddExpenseInput¶
Input for adding an expense
Properties¶
description¶
description:
string
Defined in¶
packages/services/src/domain/ExpenseService.ts:62
amount¶
amount:
number
Defined in¶
packages/services/src/domain/ExpenseService.ts:63
currency?¶
optionalcurrency:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:64
paidBy¶
paidBy:
string
Defined in¶
packages/services/src/domain/ExpenseService.ts:65
splitType¶
splitType:
SplitType
Defined in¶
packages/services/src/domain/ExpenseService.ts:66
splits¶
splits:
ExpenseSplit[]
Defined in¶
packages/services/src/domain/ExpenseService.ts:67
date?¶
optionaldate:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:68
category?¶
optionalcategory:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:69
notes?¶
optionalnotes:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:70
RecordSettlementInput¶
Input for recording a settlement
Properties¶
fromUserId¶
fromUserId:
string
Defined in¶
packages/services/src/domain/ExpenseService.ts:75
toUserId¶
toUserId:
string
Defined in¶
packages/services/src/domain/ExpenseService.ts:76
amount¶
amount:
number
Defined in¶
packages/services/src/domain/ExpenseService.ts:77
currency?¶
optionalcurrency:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:78
date?¶
optionaldate:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:79
notes?¶
optionalnotes:string
Defined in¶
packages/services/src/domain/ExpenseService.ts:80
RegisterAppInput¶
Input for registering a new OAuth application.
Properties¶
name¶
name:
string
Defined in¶
packages/services/src/domain/OAuthService.ts:45
description¶
description:
string
Defined in¶
packages/services/src/domain/OAuthService.ts:46
redirectUris¶
redirectUris:
string[]
Defined in¶
packages/services/src/domain/OAuthService.ts:47
requestedScopes¶
requestedScopes:
OAuthScope[]
Defined in¶
packages/services/src/domain/OAuthService.ts:48
iconUrl?¶
optionaliconUrl:string
Defined in¶
packages/services/src/domain/OAuthService.ts:49
homepageUrl?¶
optionalhomepageUrl:string
Defined in¶
packages/services/src/domain/OAuthService.ts:50
UpdateAppInput¶
Input for updating an existing OAuth application.
Properties¶
name?¶
optionalname:string
Defined in¶
packages/services/src/domain/OAuthService.ts:55
description?¶
optionaldescription:string
Defined in¶
packages/services/src/domain/OAuthService.ts:56
redirectUris?¶
optionalredirectUris:string[]
Defined in¶
packages/services/src/domain/OAuthService.ts:57
requestedScopes?¶
optionalrequestedScopes:OAuthScope[]
Defined in¶
packages/services/src/domain/OAuthService.ts:58
iconUrl?¶
optionaliconUrl:string
Defined in¶
packages/services/src/domain/OAuthService.ts:59
homepageUrl?¶
optionalhomepageUrl:string
Defined in¶
packages/services/src/domain/OAuthService.ts:60
GenerateCodeParams¶
Parameters for generating an authorization code.
Properties¶
clientId¶
clientId:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:46
userId¶
userId:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:47
redirectUri¶
redirectUri:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:48
scopes¶
scopes:
OAuthScope[]
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:49
codeChallenge¶
codeChallenge:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:50
state?¶
optionalstate:string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:51
ExchangeCodeParams¶
Parameters for exchanging an authorization code for tokens.
Properties¶
code¶
code:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:56
codeVerifier¶
codeVerifier:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:57
clientId¶
clientId:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:58
clientSecret¶
clientSecret:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:59
redirectUri¶
redirectUri:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:60
RefreshTokenParams¶
Parameters for refreshing tokens.
Properties¶
refreshToken¶
refreshToken:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:65
clientId¶
clientId:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:66
clientSecret¶
clientSecret:
string
Defined in¶
packages/services/src/domain/OAuthTokenService.ts:67
CyberEcoDataLayer¶
Properties¶
core¶
core:
DataLayerService
Defined in¶
packages/services/src/factories/createDataLayer.ts:10
permissions¶
permissions:
PermissionService
Defined in¶
packages/services/src/factories/createDataLayer.ts:11
sharedData¶
sharedData:
SharedDataService
Defined in¶
packages/services/src/factories/createDataLayer.ts:12
notifications¶
notifications:
NotificationService
Defined in¶
packages/services/src/factories/createDataLayer.ts:13
dashboard¶
dashboard:
DashboardService
Defined in¶
packages/services/src/factories/createDataLayer.ts:14
dataExport¶
dataExport:
DataExportService
Defined in¶
packages/services/src/factories/createDataLayer.ts:15
Functions¶
createDataLayer()¶
createDataLayer(
config):CyberEcoDataLayer
Factory function to create a fully wired CyberEco data layer Resolves circular dependency between DataLayerService and PermissionService
Parameters¶
• config: DataLayerConfig