@hasna/treasury 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +85 -0
- package/dist/adapters/fixtures.d.ts +31 -0
- package/dist/adapters/fixtures.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +42 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/api/index.d.ts +37 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/cli/context.d.ts +9 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/dashboard.d.ts +5 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4353 -0
- package/dist/cli/namespaces.d.ts +7 -0
- package/dist/cli/namespaces.d.ts.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/core/app-home.d.ts +9 -0
- package/dist/core/app-home.d.ts.map +1 -0
- package/dist/core/errors.d.ts +8 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/db/audit.d.ts +16 -0
- package/dist/db/audit.d.ts.map +1 -0
- package/dist/db/backup.d.ts +14 -0
- package/dist/db/backup.d.ts.map +1 -0
- package/dist/db/database.d.ts +40 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/migration-plan.d.ts +14 -0
- package/dist/db/migration-plan.d.ts.map +1 -0
- package/dist/db/schema.d.ts +8 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/generated/storage-kit/health.d.ts +20 -0
- package/dist/generated/storage-kit/health.d.ts.map +1 -0
- package/dist/generated/storage-kit/index.d.ts +8 -0
- package/dist/generated/storage-kit/index.d.ts.map +1 -0
- package/dist/generated/storage-kit/migrations.d.ts +48 -0
- package/dist/generated/storage-kit/migrations.d.ts.map +1 -0
- package/dist/generated/storage-kit/mode.d.ts +48 -0
- package/dist/generated/storage-kit/mode.d.ts.map +1 -0
- package/dist/generated/storage-kit/pool.d.ts +34 -0
- package/dist/generated/storage-kit/pool.d.ts.map +1 -0
- package/dist/generated/storage-kit/query.d.ts +36 -0
- package/dist/generated/storage-kit/query.d.ts.map +1 -0
- package/dist/generated/storage-kit/tls.d.ts +26 -0
- package/dist/generated/storage-kit/tls.d.ts.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23773 -0
- package/dist/mcp/compact.d.ts +12 -0
- package/dist/mcp/compact.d.ts.map +1 -0
- package/dist/mcp/http.d.ts +38 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +32 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +6243 -0
- package/dist/mcp/tools/domain.d.ts +10 -0
- package/dist/mcp/tools/domain.d.ts.map +1 -0
- package/dist/mcp/tools/standard.d.ts +4 -0
- package/dist/mcp/tools/standard.d.ts.map +1 -0
- package/dist/mcp/tools/storage.d.ts +4 -0
- package/dist/mcp/tools/storage.d.ts.map +1 -0
- package/dist/release/package-smoke.d.ts +11 -0
- package/dist/release/package-smoke.d.ts.map +1 -0
- package/dist/server/app.d.ts +19 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/auth-constants.d.ts +22 -0
- package/dist/server/auth-constants.d.ts.map +1 -0
- package/dist/server/auth.d.ts +147 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/health.d.ts +23 -0
- package/dist/server/health.d.ts.map +1 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +2094 -0
- package/dist/server/list-query.d.ts +7 -0
- package/dist/server/list-query.d.ts.map +1 -0
- package/dist/services/authorization-constants.d.ts +14 -0
- package/dist/services/authorization-constants.d.ts.map +1 -0
- package/dist/services/authorization.d.ts +95 -0
- package/dist/services/authorization.d.ts.map +1 -0
- package/dist/services/balances.d.ts +33 -0
- package/dist/services/balances.d.ts.map +1 -0
- package/dist/services/context.d.ts +24 -0
- package/dist/services/context.d.ts.map +1 -0
- package/dist/services/entities.d.ts +14 -0
- package/dist/services/entities.d.ts.map +1 -0
- package/dist/services/forecast.d.ts +10 -0
- package/dist/services/forecast.d.ts.map +1 -0
- package/dist/services/fx.d.ts +33 -0
- package/dist/services/fx.d.ts.map +1 -0
- package/dist/services/ingest.d.ts +19 -0
- package/dist/services/ingest.d.ts.map +1 -0
- package/dist/services/registry.d.ts +33 -0
- package/dist/services/registry.d.ts.map +1 -0
- package/dist/services/runway.d.ts +28 -0
- package/dist/services/runway.d.ts.map +1 -0
- package/dist/services/storage.d.ts +35 -0
- package/dist/services/storage.d.ts.map +1 -0
- package/dist/services/sweeps.d.ts +26 -0
- package/dist/services/sweeps.d.ts.map +1 -0
- package/dist/types/index.d.ts +133 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/docker-compose.yml +53 -0
- package/hasna.contract.json +20 -0
- package/openapi.json +615 -0
- package/package.json +80 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ListParams {
|
|
2
|
+
limit: number | null;
|
|
3
|
+
offset: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function parseListParams(query: Record<string, string>): ListParams;
|
|
6
|
+
export declare function applyList<T>(items: T[], params: ListParams): T[];
|
|
7
|
+
//# sourceMappingURL=list-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-query.d.ts","sourceRoot":"","sources":["../../src/server/list-query.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAMzE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,EAAE,CAGhE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-app authorization domain NAMES (BUILD-SPEC §6.3 / §10.1). This is the ONLY
|
|
3
|
+
* file that differs between the 9 apps' security stacks — `authorization.ts` is
|
|
4
|
+
* byte-identical everywhere and imports the names from here. It exports EXACTLY
|
|
5
|
+
* four members: the ACTION union, the ROLE union (which MUST include the three
|
|
6
|
+
* reserved roles "system" | "owner" | "admin"), the `allActions` array, and the
|
|
7
|
+
* `rolePermissions` role→action map (system/owner/admin get every action; each
|
|
8
|
+
* domain role gets its narrower set).
|
|
9
|
+
*/
|
|
10
|
+
export type AuthorizationAction = "read" | "write" | "recommend" | "export" | "admin";
|
|
11
|
+
export type AuthorizationRole = "system" | "owner" | "admin" | "treasurer" | "analyst" | "auditor" | "integration";
|
|
12
|
+
export declare const allActions: AuthorizationAction[];
|
|
13
|
+
export declare const rolePermissions: Record<AuthorizationRole, Set<AuthorizationAction>>;
|
|
14
|
+
//# sourceMappingURL=authorization-constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization-constants.d.ts","sourceRoot":"","sources":["../../src/services/authorization-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtF,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,OAAO,GACP,OAAO,GACP,WAAW,GACX,SAAS,GACT,SAAS,GACT,aAAa,CAAC;AAElB,eAAO,MAAM,UAAU,EAAE,mBAAmB,EAAsD,CAAC;AAEnG,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAQ/E,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { allActions, rolePermissions, type AuthorizationAction, type AuthorizationRole } from "./authorization-constants.js";
|
|
2
|
+
/**
|
|
3
|
+
* COPY-VERBATIM security stack (BUILD-SPEC §6.3 / §10.1). This file is byte-for-byte
|
|
4
|
+
* IDENTICAL across all 9 apps — the ONLY per-app difference is the import above,
|
|
5
|
+
* which resolves to that app's `authorization-constants.ts` (domain ACTION/ROLE
|
|
6
|
+
* *names* only). The MECHANISM — deny-by-default authorize(), role→action map, and
|
|
7
|
+
* STRICT entity-dimension scoping — is NOT a per-app design choice.
|
|
8
|
+
*
|
|
9
|
+
* STRICT deny-by-default entity scoping (§1c): an `entity_id` is an authorized
|
|
10
|
+
* *reference*, never a bearer capability. Resolving or guessing an id grants
|
|
11
|
+
* NOTHING. Only a `bypass` principal (the trusted internal SYSTEM context used for
|
|
12
|
+
* bootstrap/migration/tests) is entity-unrestricted. A non-bypass principal with
|
|
13
|
+
* NO entity/org set resolves to the EMPTY allowed set and gets NO access — we NEVER
|
|
14
|
+
* return `true` (or `null`) for an unscoped principal. Admin/owner ROLES widen the
|
|
15
|
+
* ACTION dimension only; they never grant cross-entity reach without an explicit
|
|
16
|
+
* entity set. MCP/HTTP callers thread their OWN principal here, never SYSTEM bypass.
|
|
17
|
+
*/
|
|
18
|
+
export type { AuthorizationAction, AuthorizationRole };
|
|
19
|
+
export { allActions, rolePermissions };
|
|
20
|
+
export interface AuthorizationContext {
|
|
21
|
+
actor_id: string;
|
|
22
|
+
roles: AuthorizationRole[];
|
|
23
|
+
/** Single allowed entity id (legacy single-tenant credential). */
|
|
24
|
+
entity_id?: string;
|
|
25
|
+
/** The allowed entity id set — the principal's tenant boundary. */
|
|
26
|
+
entity_ids?: string[];
|
|
27
|
+
/** Org-style credential aliases, accepted as entity-scope ids for compatibility. */
|
|
28
|
+
org_id?: string;
|
|
29
|
+
org_ids?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* SYSTEM bypass. Set ONLY by trusted internal callers (bootstrap, migration,
|
|
32
|
+
* seed, unit tests) — NEVER the dispatch context of an authenticated MCP or HTTP
|
|
33
|
+
* caller. A bypass principal skips entity scoping and every action gate.
|
|
34
|
+
*/
|
|
35
|
+
bypass?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface AuthorizationResource {
|
|
38
|
+
/** The single entity the operation touches. */
|
|
39
|
+
entity_id?: string;
|
|
40
|
+
/** A group of entities (e.g. a consolidation run) — ALL must be allowed. */
|
|
41
|
+
entity_ids?: string[];
|
|
42
|
+
resource?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* SYSTEM bypass context. Trusted internal use ONLY (migrations, seed, tests) — it
|
|
46
|
+
* is NEVER the context for an authenticated transport caller, which would defeat
|
|
47
|
+
* tenant isolation (BUILD-SPEC failure class 1).
|
|
48
|
+
*/
|
|
49
|
+
export declare const SYSTEM_AUTHORIZATION_CONTEXT: AuthorizationContext;
|
|
50
|
+
/**
|
|
51
|
+
* Deny-by-default single-entity check. `bypass` is unrestricted; a resource with
|
|
52
|
+
* no entity to check is not blocked by scoping; every other case requires the id
|
|
53
|
+
* to be in the principal's explicit allowlist. An unscoped non-bypass principal
|
|
54
|
+
* (empty allowlist) can reach NO entity.
|
|
55
|
+
*/
|
|
56
|
+
export declare function hasEntityAccess(context: AuthorizationContext, entityId?: string): boolean;
|
|
57
|
+
/** Group form: the principal must be scoped to EVERY entity in the set. */
|
|
58
|
+
export declare function hasAllEntityAccess(context: AuthorizationContext, entityIds: string[]): boolean;
|
|
59
|
+
export declare function roleAllows(role: AuthorizationRole, action: AuthorizationAction): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The principal's allowed entity set, or `null` when UNCONSTRAINED. ONLY the
|
|
62
|
+
* bypass/SYSTEM context is unconstrained; EVERY authenticated principal is
|
|
63
|
+
* constrained to its explicit allowlist. An unscoped non-bypass principal
|
|
64
|
+
* therefore resolves to the EMPTY array (sees nothing) — never wildcard. This is
|
|
65
|
+
* the single source of truth for entity isolation on list ops.
|
|
66
|
+
*/
|
|
67
|
+
export declare function allowedEntityIds(context?: AuthorizationContext): string[] | null;
|
|
68
|
+
/** Post-filter form: whether a principal may see a specific entity's rows. */
|
|
69
|
+
export declare function principalCanSeeEntity(entityId: string, context?: AuthorizationContext): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* SQL predicate that constrains a list query to the principal's allowed entity
|
|
72
|
+
* set, so cross-entity rows are isolated BY CONSTRUCTION — not merely because a
|
|
73
|
+
* caller supplied an `entity_id` filter. `null` when the principal is unconstrained.
|
|
74
|
+
* A principal constrained to an empty set yields an always-false predicate so no
|
|
75
|
+
* rows leak (deny-by-default).
|
|
76
|
+
*/
|
|
77
|
+
export declare function entityScopeFilter(context?: AuthorizationContext, column?: string): {
|
|
78
|
+
clause: string;
|
|
79
|
+
params: string[];
|
|
80
|
+
} | null;
|
|
81
|
+
/** In-memory form of entityScopeFilter for already-materialized rows. */
|
|
82
|
+
export declare function scopeToEntities<T extends {
|
|
83
|
+
entity_id: string;
|
|
84
|
+
}>(rows: T[], context?: AuthorizationContext): T[];
|
|
85
|
+
/**
|
|
86
|
+
* Deny by default: BOTH the entity scope AND the action scope must pass. Throws
|
|
87
|
+
* PermissionDeniedError otherwise. The SAME context flows through the /v1 serve
|
|
88
|
+
* tier AND the MCP tools — MCP tools thread the CALLER principal, never a SYSTEM
|
|
89
|
+
* bypass (BUILD-SPEC failure class 1).
|
|
90
|
+
*/
|
|
91
|
+
export declare function authorize(action: AuthorizationAction, context?: AuthorizationContext, resource?: AuthorizationResource): void;
|
|
92
|
+
export declare function authorizeAll(actions: AuthorizationAction[], context?: AuthorizationContext, resource?: AuthorizationResource): void;
|
|
93
|
+
/** Union of actions the given roles grant (used to advertise a credential's scope). */
|
|
94
|
+
export declare function scopesForRoles(roles: AuthorizationRole[]): AuthorizationAction[];
|
|
95
|
+
//# sourceMappingURL=authorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;;;;;;;;;GAeG;AAIH,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AAEvC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,oBAI1C,CAAC;AAgBF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAIzF;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAE9F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAExF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,MAAM,EAAE,GAAG,IAAI,CAIhF;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAG/F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,CAAC,EAAE,oBAAoB,EAC9B,MAAM,SAAc,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAK7C;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7D,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,CAAC,EAAE,oBAAoB,GAC7B,CAAC,EAAE,CAKL;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,oBAAoB,EAC9B,QAAQ,GAAE,qBAA0B,GACnC,IAAI,CAYN;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,OAAO,CAAC,EAAE,oBAAoB,EAC9B,QAAQ,GAAE,qBAA0B,GACnC,IAAI,CAEN;AAED,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,mBAAmB,EAAE,CAMhF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type BalanceSnapshot, type AccountKind } from "../types/index.js";
|
|
3
|
+
export interface RecordBalanceInput {
|
|
4
|
+
entity_id: string;
|
|
5
|
+
account_ref: string;
|
|
6
|
+
account_kind: AccountKind;
|
|
7
|
+
currency: string;
|
|
8
|
+
amount_minor: number;
|
|
9
|
+
as_of?: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Cache a balance snapshot (from an upstream adapter or manual entry). */
|
|
13
|
+
export declare function recordBalance(rc: RunContext, input: RecordBalanceInput): Promise<BalanceSnapshot>;
|
|
14
|
+
export interface ListBalancesInput {
|
|
15
|
+
entity_id?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function listBalances(rc: RunContext, input: ListBalancesInput): Promise<BalanceSnapshot[]>;
|
|
18
|
+
export interface ConsolidatedInput {
|
|
19
|
+
base?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ConsolidatedBalances {
|
|
22
|
+
base_currency: string;
|
|
23
|
+
as_of: string;
|
|
24
|
+
total_in_base_minor: number;
|
|
25
|
+
by_currency: Array<{
|
|
26
|
+
currency: string;
|
|
27
|
+
total_minor: number;
|
|
28
|
+
in_base_minor: number;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/** Consolidated balance across visible entities, converted to a single base. */
|
|
32
|
+
export declare function consolidatedBalances(rc: RunContext, input: ConsolidatedInput): Promise<ConsolidatedBalances>;
|
|
33
|
+
//# sourceMappingURL=balances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balances.d.ts","sourceRoot":"","sources":["../../src/services/balances.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,EAAmB,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE5F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,WAAW,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2EAA2E;AAC3E,wBAAsB,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwBvG;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAOvG;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtF;AAED,gFAAgF;AAChF,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAkBlH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { QueryClient } from "../db/database.js";
|
|
2
|
+
import type { ApiPrincipal, ApiScope } from "../server/auth.js";
|
|
3
|
+
import { type AuthorizationAction, type AuthorizationContext } from "./authorization.js";
|
|
4
|
+
/** Everything an op needs: the store + the authenticated caller principal. */
|
|
5
|
+
export interface RunContext {
|
|
6
|
+
db: QueryClient;
|
|
7
|
+
auth: AuthorizationContext;
|
|
8
|
+
scopes: ApiScope[];
|
|
9
|
+
}
|
|
10
|
+
/** Build a run context from an authenticated API principal (serve + MCP). */
|
|
11
|
+
export declare function contextFromPrincipal(db: QueryClient, principal: ApiPrincipal): RunContext;
|
|
12
|
+
/**
|
|
13
|
+
* A local/dev owner context (used by the CLI in local loopback mode when no
|
|
14
|
+
* scoped credential is supplied). Full scopes + bypass. Scoped credentials
|
|
15
|
+
* still exercise the real deny-by-default path on every transport.
|
|
16
|
+
*/
|
|
17
|
+
export declare function localOwnerContext(db: QueryClient): RunContext;
|
|
18
|
+
/**
|
|
19
|
+
* Deny-by-default gate for a single op: the principal must hold the required
|
|
20
|
+
* scope AND be authorized for the action on the target entity (§1c). Threading
|
|
21
|
+
* this on EVERY transport (serve + MCP) — not a SYSTEM bypass — is mandatory.
|
|
22
|
+
*/
|
|
23
|
+
export declare function guard(rc: RunContext, scope: ApiScope, action: AuthorizationAction, entity_id?: string): void;
|
|
24
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAa,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAgC,MAAM,oBAAoB,CAAC;AAGlI,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,WAAW,CAAC;IAChB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,GAAG,UAAU,CAWzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,WAAW,GAAG,UAAU,CAM7D;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAK5G"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type EntityRef } from "../types/index.js";
|
|
3
|
+
export interface CreateEntityInput {
|
|
4
|
+
name: string;
|
|
5
|
+
base_currency: string;
|
|
6
|
+
entity_slug?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function createEntity(rc: RunContext, input: CreateEntityInput): Promise<EntityRef>;
|
|
9
|
+
export declare function listEntities(rc: RunContext): Promise<EntityRef[]>;
|
|
10
|
+
export declare function getEntity(rc: RunContext, input: {
|
|
11
|
+
entity_id: string;
|
|
12
|
+
}): Promise<EntityRef>;
|
|
13
|
+
export declare function requireEntity(rc: RunContext, entity_id: string): Promise<EntityRef>;
|
|
14
|
+
//# sourceMappingURL=entities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/services/entities.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMzF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,CAmB/F;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CASvE;AAED,wBAAsB,SAAS,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAGhG;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAIzF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type CashForecast } from "../types/index.js";
|
|
3
|
+
export interface ForecastInput {
|
|
4
|
+
entity_id?: string;
|
|
5
|
+
base?: string;
|
|
6
|
+
horizon_months?: number;
|
|
7
|
+
}
|
|
8
|
+
/** Short-horizon linear cash projection from current cash minus monthly burn. */
|
|
9
|
+
export declare function cashForecast(rc: RunContext, input: ForecastInput): Promise<CashForecast>;
|
|
10
|
+
//# sourceMappingURL=forecast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../src/services/forecast.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAmB,KAAK,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AAmB3F,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,iFAAiF;AACjF,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAmB9F"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type QueryClient } from "../db/database.js";
|
|
2
|
+
import { type RunContext } from "./context.js";
|
|
3
|
+
import { type FxRate, type FxExposureReport } from "../types/index.js";
|
|
4
|
+
export interface RecordRateInput {
|
|
5
|
+
base_currency: string;
|
|
6
|
+
quote_currency: string;
|
|
7
|
+
rate: number;
|
|
8
|
+
as_of?: string;
|
|
9
|
+
source?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function recordFxRate(rc: RunContext, input: RecordRateInput): Promise<FxRate>;
|
|
12
|
+
export declare function listFxRates(rc: RunContext): Promise<FxRate[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Convert an integer minor amount from one currency to another using the most
|
|
15
|
+
* recently captured rate for the pair (either direction). Throws if no rate
|
|
16
|
+
* path exists so exposure/runway never silently under-count.
|
|
17
|
+
*/
|
|
18
|
+
export declare function convertMinor(db: QueryClient, amountMinor: number, from: string, to: string): Promise<number>;
|
|
19
|
+
export interface ExposureInput {
|
|
20
|
+
base?: string;
|
|
21
|
+
}
|
|
22
|
+
/** FX exposure across every balance the principal can see, converted to `base`. */
|
|
23
|
+
export declare function fxExposure(rc: RunContext, input: ExposureInput): Promise<FxExposureReport>;
|
|
24
|
+
/** Sum balances by currency, filtered to the principal's visible entities. */
|
|
25
|
+
export declare function visibleBalanceSums(rc: RunContext): Promise<Array<{
|
|
26
|
+
currency: string;
|
|
27
|
+
total_minor: number;
|
|
28
|
+
}>>;
|
|
29
|
+
export declare function entityFilter(rc: RunContext, column?: string): {
|
|
30
|
+
clause: string;
|
|
31
|
+
params: unknown[];
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=fx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx.d.ts","sourceRoot":"","sources":["../../src/services/fx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAmB,KAAK,MAAM,EAAE,KAAK,gBAAgB,EAAyB,MAAM,mBAAmB,CAAC;AAE/G,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB1F;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAalH;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mFAAmF;AACnF,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAchG;AAED,8EAA8E;AAC9E,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAMlH;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,SAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAMxG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import type { UpstreamAdapters } from "../adapters/types.js";
|
|
3
|
+
export interface IngestResult {
|
|
4
|
+
balances_ingested: number;
|
|
5
|
+
fx_rates_ingested: number;
|
|
6
|
+
cost_feeds_ingested: number;
|
|
7
|
+
sources: {
|
|
8
|
+
balances: string;
|
|
9
|
+
fx: string;
|
|
10
|
+
cost: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pull balances / FX / cost from read-adapters and cache them with provenance.
|
|
15
|
+
* v0 uses fixture adapters; v1 swaps in live upstream calls. Deny-by-default:
|
|
16
|
+
* the caller must hold write scope and be scoped to the entities it ingests.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ingestFromAdapters(rc: RunContext, adapters: UpstreamAdapters): Promise<IngestResult>;
|
|
19
|
+
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/services/ingest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAKtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuB1G"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RunContext } from "./context.js";
|
|
2
|
+
import type { ApiScope } from "../server/auth.js";
|
|
3
|
+
import type { AuthorizationAction } from "./authorization.js";
|
|
4
|
+
export type FieldType = "string" | "int" | "number" | "bool";
|
|
5
|
+
export type FieldLocation = "path" | "query" | "body";
|
|
6
|
+
export interface OpField {
|
|
7
|
+
name: string;
|
|
8
|
+
type: FieldType;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
location: FieldLocation;
|
|
11
|
+
description?: string;
|
|
12
|
+
}
|
|
13
|
+
export type Profile = "minimal" | "standard" | "full";
|
|
14
|
+
export interface OpDef {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
scope: ApiScope;
|
|
18
|
+
action: AuthorizationAction;
|
|
19
|
+
mutating: boolean;
|
|
20
|
+
http: {
|
|
21
|
+
method: "GET" | "POST" | "PATCH" | "DELETE";
|
|
22
|
+
path: string;
|
|
23
|
+
};
|
|
24
|
+
operationId: string;
|
|
25
|
+
cli: string[];
|
|
26
|
+
fields: OpField[];
|
|
27
|
+
profiles: Profile[];
|
|
28
|
+
run(rc: RunContext, input: Record<string, unknown>): Promise<unknown>;
|
|
29
|
+
}
|
|
30
|
+
export declare const OPS: OpDef[];
|
|
31
|
+
export declare function opByName(name: string): OpDef | undefined;
|
|
32
|
+
export declare function coerceField(field: OpField, raw: unknown): unknown;
|
|
33
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/services/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAU9D,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAMD,eAAO,MAAM,GAAG,EAAE,KAAK,EAiStB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAExD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAgBjE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type CostFeed, type RunwayReport } from "../types/index.js";
|
|
3
|
+
export interface RecordCostFeedInput {
|
|
4
|
+
entity_id: string;
|
|
5
|
+
currency: string;
|
|
6
|
+
monthly_burn_minor: number;
|
|
7
|
+
as_of?: string;
|
|
8
|
+
source?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Record a monthly net cash burn for an entity (feeds runway + forecast). */
|
|
11
|
+
export declare function recordCostFeed(rc: RunContext, input: RecordCostFeedInput): Promise<CostFeed>;
|
|
12
|
+
export declare function listCostFeeds(rc: RunContext, input: {
|
|
13
|
+
entity_id?: string;
|
|
14
|
+
}): Promise<CostFeed[]>;
|
|
15
|
+
/** Latest cost feed per (entity, currency), optionally scoped to one entity. */
|
|
16
|
+
declare function latestCostFeeds(rc: RunContext, entity_id?: string): Promise<CostFeed[]>;
|
|
17
|
+
declare function sumBalancesInBase(rc: RunContext, base: string, entity_id?: string): Promise<number>;
|
|
18
|
+
export interface EntityRunwayInput {
|
|
19
|
+
entity_id: string;
|
|
20
|
+
base?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function entityRunway(rc: RunContext, input: EntityRunwayInput): Promise<RunwayReport>;
|
|
23
|
+
export interface GroupRunwayInput {
|
|
24
|
+
base?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function groupRunway(rc: RunContext, input: GroupRunwayInput): Promise<RunwayReport>;
|
|
27
|
+
export { latestCostFeeds, sumBalancesInBase };
|
|
28
|
+
//# sourceMappingURL=runway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runway.d.ts","sourceRoot":"","sources":["../../src/services/runway.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,EAAmB,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8EAA8E;AAC9E,wBAAsB,cAAc,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqBlG;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAOtG;AAED,gFAAgF;AAChF,iBAAe,eAAe,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgBtF;AAED,iBAAe,iBAAiB,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBlG;AAOD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiBlG;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiBhG;AAED,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type QueryClient } from "../db/database.js";
|
|
3
|
+
export declare const SYNC_TABLES: Record<string, string[]>;
|
|
4
|
+
export declare const AUDIT_TABLES: string[];
|
|
5
|
+
export interface StorageStatus {
|
|
6
|
+
mode: "local" | "cloud";
|
|
7
|
+
dsn_present: boolean;
|
|
8
|
+
sqlite_path: string;
|
|
9
|
+
migrations_applied: number;
|
|
10
|
+
remote_reachable: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Redacted storage status (BUILD-SPEC §4.6). Emits NO DSN/secret value and NO
|
|
14
|
+
* full config object. `remote_reachable` is computed by probing, never hardcoded.
|
|
15
|
+
*/
|
|
16
|
+
export declare function storageStatus(rc: RunContext): Promise<StorageStatus>;
|
|
17
|
+
export interface SyncOptions {
|
|
18
|
+
tables?: string[];
|
|
19
|
+
/** Injected counterpart store (tests). When absent, the cloud store is opened. */
|
|
20
|
+
target?: QueryClient;
|
|
21
|
+
}
|
|
22
|
+
export interface SyncResult {
|
|
23
|
+
direction: "push" | "pull";
|
|
24
|
+
tables: Record<string, number>;
|
|
25
|
+
audit_excluded: string[];
|
|
26
|
+
}
|
|
27
|
+
/** Push local rows to the cloud store. Elevated scope + audit; audit tables excluded. */
|
|
28
|
+
export declare function storagePush(rc: RunContext, opts?: SyncOptions): Promise<SyncResult>;
|
|
29
|
+
/** Pull cloud rows into the local store. Elevated scope + audit; audit tables excluded. */
|
|
30
|
+
export declare function storagePull(rc: RunContext, opts?: SyncOptions): Promise<SyncResult>;
|
|
31
|
+
export declare function storageSync(rc: RunContext, opts?: SyncOptions): Promise<{
|
|
32
|
+
push: SyncResult;
|
|
33
|
+
pull: SyncResult;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/services/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMnE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAMhD,CAAC;AACF,eAAO,MAAM,YAAY,UAAgB,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAoB1E;AAyBD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAaD,yFAAyF;AACzF,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7F;AAED,2FAA2F;AAC3F,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7F;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAKzH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type RunContext } from "./context.js";
|
|
2
|
+
import { type SweepRecommendation, type SweepStatus } from "../types/index.js";
|
|
3
|
+
export declare function listSweeps(rc: RunContext, input?: {
|
|
4
|
+
status?: SweepStatus;
|
|
5
|
+
}): Promise<SweepRecommendation[]>;
|
|
6
|
+
export declare function getSweep(rc: RunContext, input: {
|
|
7
|
+
id: string;
|
|
8
|
+
}): Promise<SweepRecommendation>;
|
|
9
|
+
export interface GenerateSweepsInput {
|
|
10
|
+
base?: string;
|
|
11
|
+
min_runway_months?: number;
|
|
12
|
+
healthy_runway_months?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Generate intercompany-funding RECOMMENDATIONS (advisory only — treasury never
|
|
16
|
+
* moves money; execution must be requested through the controls service). Lifts
|
|
17
|
+
* short-runway entities toward `min_runway_months` funded by entities holding a
|
|
18
|
+
* surplus above `healthy_runway_months`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateSweeps(rc: RunContext, input: GenerateSweepsInput): Promise<SweepRecommendation[]>;
|
|
21
|
+
export interface UpdateSweepInput {
|
|
22
|
+
id: string;
|
|
23
|
+
status: SweepStatus;
|
|
24
|
+
}
|
|
25
|
+
export declare function updateSweepStatus(rc: RunContext, input: UpdateSweepInput): Promise<SweepRecommendation>;
|
|
26
|
+
//# sourceMappingURL=sweeps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sweeps.d.ts","sourceRoot":"","sources":["../../src/services/sweeps.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAKtD,OAAO,EAAuC,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMpH,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAoBrH;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAMlG;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAsE/G;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAY7G"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export type Iso4217 = string;
|
|
2
|
+
export interface EntityRef {
|
|
3
|
+
entity_id: string;
|
|
4
|
+
entity_slug: string | null;
|
|
5
|
+
name: string;
|
|
6
|
+
base_currency: Iso4217;
|
|
7
|
+
created_at: string;
|
|
8
|
+
updated_at: string;
|
|
9
|
+
}
|
|
10
|
+
export type AccountKind = "bank" | "wallet";
|
|
11
|
+
export interface BalanceSnapshot {
|
|
12
|
+
id: string;
|
|
13
|
+
entity_id: string;
|
|
14
|
+
account_ref: string;
|
|
15
|
+
account_kind: AccountKind;
|
|
16
|
+
currency: Iso4217;
|
|
17
|
+
amount_minor: number;
|
|
18
|
+
as_of: string;
|
|
19
|
+
source: string;
|
|
20
|
+
captured_at: string;
|
|
21
|
+
}
|
|
22
|
+
export interface FxRate {
|
|
23
|
+
id: string;
|
|
24
|
+
base_currency: Iso4217;
|
|
25
|
+
quote_currency: Iso4217;
|
|
26
|
+
rate: number;
|
|
27
|
+
as_of: string;
|
|
28
|
+
source: string;
|
|
29
|
+
captured_at: string;
|
|
30
|
+
}
|
|
31
|
+
export interface CostFeed {
|
|
32
|
+
id: string;
|
|
33
|
+
entity_id: string;
|
|
34
|
+
currency: Iso4217;
|
|
35
|
+
monthly_burn_minor: number;
|
|
36
|
+
as_of: string;
|
|
37
|
+
source: string;
|
|
38
|
+
captured_at: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CurrencyExposure {
|
|
41
|
+
currency: Iso4217;
|
|
42
|
+
total_minor: number;
|
|
43
|
+
in_base_minor: number;
|
|
44
|
+
}
|
|
45
|
+
export interface FxExposureReport {
|
|
46
|
+
base_currency: Iso4217;
|
|
47
|
+
as_of: string;
|
|
48
|
+
total_in_base_minor: number;
|
|
49
|
+
exposures: CurrencyExposure[];
|
|
50
|
+
}
|
|
51
|
+
export interface RunwayReport {
|
|
52
|
+
scope: "entity" | "group";
|
|
53
|
+
entity_id: string | null;
|
|
54
|
+
base_currency: Iso4217;
|
|
55
|
+
cash_in_base_minor: number;
|
|
56
|
+
monthly_burn_in_base_minor: number;
|
|
57
|
+
runway_months: number | null;
|
|
58
|
+
as_of: string;
|
|
59
|
+
}
|
|
60
|
+
export interface ForecastPoint {
|
|
61
|
+
month_index: number;
|
|
62
|
+
month: string;
|
|
63
|
+
projected_cash_in_base_minor: number;
|
|
64
|
+
}
|
|
65
|
+
export interface CashForecast {
|
|
66
|
+
scope: "entity" | "group";
|
|
67
|
+
entity_id: string | null;
|
|
68
|
+
base_currency: Iso4217;
|
|
69
|
+
horizon_months: number;
|
|
70
|
+
starting_cash_in_base_minor: number;
|
|
71
|
+
monthly_burn_in_base_minor: number;
|
|
72
|
+
points: ForecastPoint[];
|
|
73
|
+
as_of: string;
|
|
74
|
+
}
|
|
75
|
+
export type SweepStatus = "recommended" | "acknowledged" | "dismissed";
|
|
76
|
+
/**
|
|
77
|
+
* A sweep / intercompany-funding RECOMMENDATION. Treasury is read/advisory and
|
|
78
|
+
* NEVER moves money itself — executing a recommendation must be requested
|
|
79
|
+
* through the controls service, which issues the single-use authorization token.
|
|
80
|
+
*/
|
|
81
|
+
export interface SweepRecommendation {
|
|
82
|
+
id: string;
|
|
83
|
+
from_entity_id: string;
|
|
84
|
+
to_entity_id: string;
|
|
85
|
+
currency: Iso4217;
|
|
86
|
+
amount_minor: number;
|
|
87
|
+
rationale: string;
|
|
88
|
+
status: SweepStatus;
|
|
89
|
+
requires_controls_authorization: true;
|
|
90
|
+
created_at: string;
|
|
91
|
+
updated_at: string;
|
|
92
|
+
}
|
|
93
|
+
export interface AuditEvent {
|
|
94
|
+
id: number;
|
|
95
|
+
entity_id: string | null;
|
|
96
|
+
actor_id: string;
|
|
97
|
+
action: string;
|
|
98
|
+
detail: string;
|
|
99
|
+
prev_hash: string;
|
|
100
|
+
row_hash: string;
|
|
101
|
+
created_at: string;
|
|
102
|
+
}
|
|
103
|
+
export declare class TreasuryError extends Error {
|
|
104
|
+
static suggestion: string;
|
|
105
|
+
code: string;
|
|
106
|
+
constructor(message: string);
|
|
107
|
+
}
|
|
108
|
+
export declare class EntityNotFoundError extends TreasuryError {
|
|
109
|
+
static suggestion: string;
|
|
110
|
+
code: string;
|
|
111
|
+
constructor(id: string);
|
|
112
|
+
}
|
|
113
|
+
export declare class SweepNotFoundError extends TreasuryError {
|
|
114
|
+
static suggestion: string;
|
|
115
|
+
code: string;
|
|
116
|
+
constructor(id: string);
|
|
117
|
+
}
|
|
118
|
+
export declare class ValidationError extends TreasuryError {
|
|
119
|
+
static suggestion: string;
|
|
120
|
+
code: string;
|
|
121
|
+
constructor(message: string);
|
|
122
|
+
}
|
|
123
|
+
export declare class PermissionDeniedError extends TreasuryError {
|
|
124
|
+
static suggestion: string;
|
|
125
|
+
code: string;
|
|
126
|
+
constructor(action: string, resource?: string);
|
|
127
|
+
}
|
|
128
|
+
export declare class UnauthorizedError extends TreasuryError {
|
|
129
|
+
static suggestion: string;
|
|
130
|
+
code: string;
|
|
131
|
+
constructor(message?: string);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,eAAO,MAAM,WAAW,QAAc,CAAC"}
|