thevoidforge 21.0.0
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/dist/scripts/vault-read.d.ts +11 -0
- package/dist/scripts/vault-read.js +89 -0
- package/dist/scripts/voidforge.d.ts +20 -0
- package/dist/scripts/voidforge.js +404 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/wizard/api/auth.d.ts +5 -0
- package/dist/wizard/api/auth.js +133 -0
- package/dist/wizard/api/blueprint.d.ts +45 -0
- package/dist/wizard/api/blueprint.js +184 -0
- package/dist/wizard/api/cloud-providers.d.ts +16 -0
- package/dist/wizard/api/cloud-providers.js +363 -0
- package/dist/wizard/api/credentials.d.ts +1 -0
- package/dist/wizard/api/credentials.js +258 -0
- package/dist/wizard/api/danger-room.d.ts +18 -0
- package/dist/wizard/api/danger-room.js +401 -0
- package/dist/wizard/api/deploy.d.ts +4 -0
- package/dist/wizard/api/deploy.js +164 -0
- package/dist/wizard/api/prd.d.ts +1 -0
- package/dist/wizard/api/prd.js +363 -0
- package/dist/wizard/api/project.d.ts +1 -0
- package/dist/wizard/api/project.js +239 -0
- package/dist/wizard/api/projects.d.ts +6 -0
- package/dist/wizard/api/projects.js +648 -0
- package/dist/wizard/api/provision.d.ts +4 -0
- package/dist/wizard/api/provision.js +535 -0
- package/dist/wizard/api/terminal.d.ts +25 -0
- package/dist/wizard/api/terminal.js +241 -0
- package/dist/wizard/api/users.d.ts +6 -0
- package/dist/wizard/api/users.js +244 -0
- package/dist/wizard/api/war-room.d.ts +14 -0
- package/dist/wizard/api/war-room.js +45 -0
- package/dist/wizard/lib/ad-platform-core.d.ts +6 -0
- package/dist/wizard/lib/ad-platform-core.js +1 -0
- package/dist/wizard/lib/adapters/index.d.ts +52 -0
- package/dist/wizard/lib/adapters/index.js +38 -0
- package/dist/wizard/lib/adapters/sandbox-bank.d.ts +17 -0
- package/dist/wizard/lib/adapters/sandbox-bank.js +77 -0
- package/dist/wizard/lib/adapters/sandbox.d.ts +39 -0
- package/dist/wizard/lib/adapters/sandbox.js +174 -0
- package/dist/wizard/lib/adapters/stripe.d.ts +19 -0
- package/dist/wizard/lib/adapters/stripe.js +143 -0
- package/dist/wizard/lib/adapters/types.d.ts +9 -0
- package/dist/wizard/lib/adapters/types.js +10 -0
- package/dist/wizard/lib/agent-memory.d.ts +36 -0
- package/dist/wizard/lib/agent-memory.js +114 -0
- package/dist/wizard/lib/anomaly-detection.d.ts +59 -0
- package/dist/wizard/lib/anomaly-detection.js +122 -0
- package/dist/wizard/lib/anthropic.d.ts +21 -0
- package/dist/wizard/lib/anthropic.js +105 -0
- package/dist/wizard/lib/asset-scanner.d.ts +23 -0
- package/dist/wizard/lib/asset-scanner.js +107 -0
- package/dist/wizard/lib/audit-log.d.ts +23 -0
- package/dist/wizard/lib/audit-log.js +70 -0
- package/dist/wizard/lib/autonomy-controller.d.ts +76 -0
- package/dist/wizard/lib/autonomy-controller.js +183 -0
- package/dist/wizard/lib/body-parser.d.ts +2 -0
- package/dist/wizard/lib/body-parser.js +36 -0
- package/dist/wizard/lib/build-analytics.d.ts +39 -0
- package/dist/wizard/lib/build-analytics.js +91 -0
- package/dist/wizard/lib/build-step.d.ts +21 -0
- package/dist/wizard/lib/build-step.js +104 -0
- package/dist/wizard/lib/campaign-proposer.d.ts +39 -0
- package/dist/wizard/lib/campaign-proposer.js +180 -0
- package/dist/wizard/lib/campaign-state-machine.d.ts +63 -0
- package/dist/wizard/lib/campaign-state-machine.js +114 -0
- package/dist/wizard/lib/ci-generator.d.ts +14 -0
- package/dist/wizard/lib/ci-generator.js +187 -0
- package/dist/wizard/lib/claude-merge.d.ts +38 -0
- package/dist/wizard/lib/claude-merge.js +115 -0
- package/dist/wizard/lib/codegen/erd-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/erd-gen.js +98 -0
- package/dist/wizard/lib/codegen/integrations.d.ts +18 -0
- package/dist/wizard/lib/codegen/integrations.js +189 -0
- package/dist/wizard/lib/codegen/openapi-gen.d.ts +15 -0
- package/dist/wizard/lib/codegen/openapi-gen.js +79 -0
- package/dist/wizard/lib/codegen/prisma-types.d.ts +15 -0
- package/dist/wizard/lib/codegen/prisma-types.js +44 -0
- package/dist/wizard/lib/codegen/seed-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/seed-gen.js +128 -0
- package/dist/wizard/lib/compliance.d.ts +51 -0
- package/dist/wizard/lib/compliance.js +112 -0
- package/dist/wizard/lib/correlation-engine.d.ts +59 -0
- package/dist/wizard/lib/correlation-engine.js +151 -0
- package/dist/wizard/lib/cost-estimator.d.ts +22 -0
- package/dist/wizard/lib/cost-estimator.js +72 -0
- package/dist/wizard/lib/cost-tracker.d.ts +27 -0
- package/dist/wizard/lib/cost-tracker.js +37 -0
- package/dist/wizard/lib/daemon-aggregator.d.ts +71 -0
- package/dist/wizard/lib/daemon-aggregator.js +204 -0
- package/dist/wizard/lib/daemon-core.d.ts +6 -0
- package/dist/wizard/lib/daemon-core.js +5 -0
- package/dist/wizard/lib/dashboard-data.d.ts +132 -0
- package/dist/wizard/lib/dashboard-data.js +336 -0
- package/dist/wizard/lib/dashboard-ws.d.ts +25 -0
- package/dist/wizard/lib/dashboard-ws.js +91 -0
- package/dist/wizard/lib/deep-current.d.ts +77 -0
- package/dist/wizard/lib/deep-current.js +234 -0
- package/dist/wizard/lib/deploy-coordinator.d.ts +40 -0
- package/dist/wizard/lib/deploy-coordinator.js +86 -0
- package/dist/wizard/lib/deploy-log.d.ts +28 -0
- package/dist/wizard/lib/deploy-log.js +52 -0
- package/dist/wizard/lib/desktop-notify.d.ts +27 -0
- package/dist/wizard/lib/desktop-notify.js +98 -0
- package/dist/wizard/lib/dns/cloudflare-dns.d.ts +35 -0
- package/dist/wizard/lib/dns/cloudflare-dns.js +216 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.d.ts +31 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.js +148 -0
- package/dist/wizard/lib/dns/types.d.ts +22 -0
- package/dist/wizard/lib/dns/types.js +4 -0
- package/dist/wizard/lib/document-discovery.d.ts +33 -0
- package/dist/wizard/lib/document-discovery.js +145 -0
- package/dist/wizard/lib/env-validator.d.ts +14 -0
- package/dist/wizard/lib/env-validator.js +205 -0
- package/dist/wizard/lib/env-writer.d.ts +13 -0
- package/dist/wizard/lib/env-writer.js +26 -0
- package/dist/wizard/lib/exec.d.ts +30 -0
- package/dist/wizard/lib/exec.js +52 -0
- package/dist/wizard/lib/experiment.d.ts +70 -0
- package/dist/wizard/lib/experiment.js +169 -0
- package/dist/wizard/lib/extensions.d.ts +20 -0
- package/dist/wizard/lib/extensions.js +183 -0
- package/dist/wizard/lib/financial/adapter-factory.d.ts +47 -0
- package/dist/wizard/lib/financial/adapter-factory.js +225 -0
- package/dist/wizard/lib/financial/billing/base.d.ts +6 -0
- package/dist/wizard/lib/financial/billing/base.js +1 -0
- package/dist/wizard/lib/financial/billing/google-billing.d.ts +56 -0
- package/dist/wizard/lib/financial/billing/google-billing.js +298 -0
- package/dist/wizard/lib/financial/billing/meta-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/meta-billing.js +243 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.js +260 -0
- package/dist/wizard/lib/financial/campaign/base.d.ts +13 -0
- package/dist/wizard/lib/financial/campaign/base.js +1 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.d.ts +42 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.js +388 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.d.ts +41 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.js +311 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.d.ts +45 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.js +261 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.d.ts +40 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.js +350 -0
- package/dist/wizard/lib/financial/funding-auto.d.ts +44 -0
- package/dist/wizard/lib/financial/funding-auto.js +52 -0
- package/dist/wizard/lib/financial/funding-policy.d.ts +60 -0
- package/dist/wizard/lib/financial/funding-policy.js +179 -0
- package/dist/wizard/lib/financial/platform-planner.d.ts +47 -0
- package/dist/wizard/lib/financial/platform-planner.js +134 -0
- package/dist/wizard/lib/financial/reconciliation-engine.d.ts +78 -0
- package/dist/wizard/lib/financial/reconciliation-engine.js +193 -0
- package/dist/wizard/lib/financial/registry.d.ts +22 -0
- package/dist/wizard/lib/financial/registry.js +26 -0
- package/dist/wizard/lib/financial/reporting.d.ts +96 -0
- package/dist/wizard/lib/financial/reporting.js +198 -0
- package/dist/wizard/lib/financial/stablecoin/base.d.ts +6 -0
- package/dist/wizard/lib/financial/stablecoin/base.js +1 -0
- package/dist/wizard/lib/financial/stablecoin/circle.d.ts +54 -0
- package/dist/wizard/lib/financial/stablecoin/circle.js +367 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.d.ts +24 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.js +171 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.d.ts +47 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.js +202 -0
- package/dist/wizard/lib/financial/treasury-planner.d.ts +52 -0
- package/dist/wizard/lib/financial/treasury-planner.js +128 -0
- package/dist/wizard/lib/financial-core.d.ts +6 -0
- package/dist/wizard/lib/financial-core.js +5 -0
- package/dist/wizard/lib/financial-vault.d.ts +34 -0
- package/dist/wizard/lib/financial-vault.js +199 -0
- package/dist/wizard/lib/frontmatter.d.ts +30 -0
- package/dist/wizard/lib/frontmatter.js +96 -0
- package/dist/wizard/lib/gap-analysis.d.ts +37 -0
- package/dist/wizard/lib/gap-analysis.js +218 -0
- package/dist/wizard/lib/github.d.ts +22 -0
- package/dist/wizard/lib/github.js +261 -0
- package/dist/wizard/lib/headless-deploy.d.ts +14 -0
- package/dist/wizard/lib/headless-deploy.js +452 -0
- package/dist/wizard/lib/health-monitor.d.ts +15 -0
- package/dist/wizard/lib/health-monitor.js +91 -0
- package/dist/wizard/lib/health-poller.d.ts +9 -0
- package/dist/wizard/lib/health-poller.js +123 -0
- package/dist/wizard/lib/heartbeat.d.ts +15 -0
- package/dist/wizard/lib/heartbeat.js +827 -0
- package/dist/wizard/lib/http-helpers.d.ts +9 -0
- package/dist/wizard/lib/http-helpers.js +24 -0
- package/dist/wizard/lib/image-gen.d.ts +56 -0
- package/dist/wizard/lib/image-gen.js +159 -0
- package/dist/wizard/lib/instance-sizing.d.ts +26 -0
- package/dist/wizard/lib/instance-sizing.js +51 -0
- package/dist/wizard/lib/kongo/analytics.d.ts +29 -0
- package/dist/wizard/lib/kongo/analytics.js +179 -0
- package/dist/wizard/lib/kongo/campaigns.d.ts +52 -0
- package/dist/wizard/lib/kongo/campaigns.js +91 -0
- package/dist/wizard/lib/kongo/client.d.ts +58 -0
- package/dist/wizard/lib/kongo/client.js +221 -0
- package/dist/wizard/lib/kongo/jobs.d.ts +57 -0
- package/dist/wizard/lib/kongo/jobs.js +122 -0
- package/dist/wizard/lib/kongo/pages.d.ts +60 -0
- package/dist/wizard/lib/kongo/pages.js +150 -0
- package/dist/wizard/lib/kongo/provisioner.d.ts +64 -0
- package/dist/wizard/lib/kongo/provisioner.js +116 -0
- package/dist/wizard/lib/kongo/seed.d.ts +49 -0
- package/dist/wizard/lib/kongo/seed.js +237 -0
- package/dist/wizard/lib/kongo/types.d.ts +323 -0
- package/dist/wizard/lib/kongo/types.js +11 -0
- package/dist/wizard/lib/kongo/variants.d.ts +57 -0
- package/dist/wizard/lib/kongo/variants.js +88 -0
- package/dist/wizard/lib/kongo/webhooks.d.ts +41 -0
- package/dist/wizard/lib/kongo/webhooks.js +112 -0
- package/dist/wizard/lib/marker.d.ts +28 -0
- package/dist/wizard/lib/marker.js +79 -0
- package/dist/wizard/lib/migrator.d.ts +35 -0
- package/dist/wizard/lib/migrator.js +190 -0
- package/dist/wizard/lib/natural-language-deploy.d.ts +30 -0
- package/dist/wizard/lib/natural-language-deploy.js +186 -0
- package/dist/wizard/lib/network.d.ts +22 -0
- package/dist/wizard/lib/network.js +72 -0
- package/dist/wizard/lib/oauth-core.d.ts +6 -0
- package/dist/wizard/lib/oauth-core.js +5 -0
- package/dist/wizard/lib/open-browser.d.ts +1 -0
- package/dist/wizard/lib/open-browser.js +26 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.d.ts +209 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.js +269 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.d.ts +200 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.js +212 -0
- package/dist/wizard/lib/patterns/daemon-process.d.ts +88 -0
- package/dist/wizard/lib/patterns/daemon-process.js +271 -0
- package/dist/wizard/lib/patterns/financial-transaction.d.ts +161 -0
- package/dist/wizard/lib/patterns/financial-transaction.js +132 -0
- package/dist/wizard/lib/patterns/funding-plan.d.ts +136 -0
- package/dist/wizard/lib/patterns/funding-plan.js +200 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.d.ts +94 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.js +139 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.d.ts +67 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.js +216 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.d.ts +96 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.js +182 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.d.ts +218 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.js +264 -0
- package/dist/wizard/lib/prd-validator.d.ts +39 -0
- package/dist/wizard/lib/prd-validator.js +137 -0
- package/dist/wizard/lib/project-init.d.ts +24 -0
- package/dist/wizard/lib/project-init.js +193 -0
- package/dist/wizard/lib/project-registry.d.ts +86 -0
- package/dist/wizard/lib/project-registry.js +359 -0
- package/dist/wizard/lib/provision-manifest.d.ts +44 -0
- package/dist/wizard/lib/provision-manifest.js +164 -0
- package/dist/wizard/lib/provisioner-registry.d.ts +15 -0
- package/dist/wizard/lib/provisioner-registry.js +34 -0
- package/dist/wizard/lib/provisioners/aws-vps.d.ts +6 -0
- package/dist/wizard/lib/provisioners/aws-vps.js +643 -0
- package/dist/wizard/lib/provisioners/cloudflare.d.ts +6 -0
- package/dist/wizard/lib/provisioners/cloudflare.js +300 -0
- package/dist/wizard/lib/provisioners/docker.d.ts +6 -0
- package/dist/wizard/lib/provisioners/docker.js +75 -0
- package/dist/wizard/lib/provisioners/http-client.d.ts +20 -0
- package/dist/wizard/lib/provisioners/http-client.js +79 -0
- package/dist/wizard/lib/provisioners/railway.d.ts +6 -0
- package/dist/wizard/lib/provisioners/railway.js +413 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.js +54 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.js +112 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.d.ts +11 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.js +91 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.d.ts +5 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.js +185 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.js +36 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.d.ts +14 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.js +202 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.js +67 -0
- package/dist/wizard/lib/provisioners/self-deploy.d.ts +41 -0
- package/dist/wizard/lib/provisioners/self-deploy.js +185 -0
- package/dist/wizard/lib/provisioners/static-s3.d.ts +6 -0
- package/dist/wizard/lib/provisioners/static-s3.js +235 -0
- package/dist/wizard/lib/provisioners/types.d.ts +40 -0
- package/dist/wizard/lib/provisioners/types.js +4 -0
- package/dist/wizard/lib/provisioners/vercel.d.ts +6 -0
- package/dist/wizard/lib/provisioners/vercel.js +287 -0
- package/dist/wizard/lib/pty-manager.d.ts +42 -0
- package/dist/wizard/lib/pty-manager.js +231 -0
- package/dist/wizard/lib/rate-limiter-core.d.ts +5 -0
- package/dist/wizard/lib/rate-limiter-core.js +5 -0
- package/dist/wizard/lib/reconciliation.d.ts +43 -0
- package/dist/wizard/lib/reconciliation.js +173 -0
- package/dist/wizard/lib/revenue-types.d.ts +5 -0
- package/dist/wizard/lib/revenue-types.js +1 -0
- package/dist/wizard/lib/route-optimizer.d.ts +28 -0
- package/dist/wizard/lib/route-optimizer.js +93 -0
- package/dist/wizard/lib/s3-deploy.d.ts +19 -0
- package/dist/wizard/lib/s3-deploy.js +156 -0
- package/dist/wizard/lib/safety-tiers.d.ts +76 -0
- package/dist/wizard/lib/safety-tiers.js +134 -0
- package/dist/wizard/lib/sentry-generator.d.ts +15 -0
- package/dist/wizard/lib/sentry-generator.js +116 -0
- package/dist/wizard/lib/server-config.d.ts +13 -0
- package/dist/wizard/lib/server-config.js +23 -0
- package/dist/wizard/lib/service-install.d.ts +18 -0
- package/dist/wizard/lib/service-install.js +182 -0
- package/dist/wizard/lib/site-scanner.d.ts +80 -0
- package/dist/wizard/lib/site-scanner.js +262 -0
- package/dist/wizard/lib/ssh-deploy.d.ts +25 -0
- package/dist/wizard/lib/ssh-deploy.js +225 -0
- package/dist/wizard/lib/templates.d.ts +24 -0
- package/dist/wizard/lib/templates.js +219 -0
- package/dist/wizard/lib/totp.d.ts +35 -0
- package/dist/wizard/lib/totp.js +276 -0
- package/dist/wizard/lib/tower-auth.d.ts +43 -0
- package/dist/wizard/lib/tower-auth.js +352 -0
- package/dist/wizard/lib/tower-rate-limit.d.ts +14 -0
- package/dist/wizard/lib/tower-rate-limit.js +61 -0
- package/dist/wizard/lib/tower-session.d.ts +28 -0
- package/dist/wizard/lib/tower-session.js +119 -0
- package/dist/wizard/lib/treasury-backup.d.ts +23 -0
- package/dist/wizard/lib/treasury-backup.js +126 -0
- package/dist/wizard/lib/treasury-heartbeat.d.ts +82 -0
- package/dist/wizard/lib/treasury-heartbeat.js +1104 -0
- package/dist/wizard/lib/updater.d.ts +29 -0
- package/dist/wizard/lib/updater.js +190 -0
- package/dist/wizard/lib/user-manager.d.ts +39 -0
- package/dist/wizard/lib/user-manager.js +182 -0
- package/dist/wizard/lib/vault.d.ts +26 -0
- package/dist/wizard/lib/vault.js +161 -0
- package/dist/wizard/router.d.ts +5 -0
- package/dist/wizard/router.js +15 -0
- package/dist/wizard/server.d.ts +18 -0
- package/dist/wizard/server.js +436 -0
- package/package.json +59 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-Specific Funding Planner — pure logic for Google invoice settlement,
|
|
3
|
+
* Meta debit protection, and multi-project portfolio rebalancing.
|
|
4
|
+
*
|
|
5
|
+
* No API calls, no file I/O — fully testable deterministic functions.
|
|
6
|
+
* All monetary values use branded integer cents (Cents type).
|
|
7
|
+
*
|
|
8
|
+
* PRD Reference: §12.3 (Platform Billing), §15 (Rules Engine)
|
|
9
|
+
* Agents: Dockson (treasury), Heartbeat daemon
|
|
10
|
+
*/
|
|
11
|
+
import type { Cents } from '../patterns/funding-plan.js';
|
|
12
|
+
interface GoogleInvoice {
|
|
13
|
+
invoiceId: string;
|
|
14
|
+
amountCents: Cents;
|
|
15
|
+
dueDate: string;
|
|
16
|
+
status: 'pending' | 'overdue' | 'paid';
|
|
17
|
+
}
|
|
18
|
+
interface SettlementPlan {
|
|
19
|
+
invoiceId: string;
|
|
20
|
+
amountCents: Cents;
|
|
21
|
+
dueDate: string;
|
|
22
|
+
wireReference: string;
|
|
23
|
+
priority: number;
|
|
24
|
+
remainingBufferAfterCents: Cents;
|
|
25
|
+
}
|
|
26
|
+
interface ProjectTreasury {
|
|
27
|
+
projectId: string;
|
|
28
|
+
projectName: string;
|
|
29
|
+
bankBalanceCents: Cents;
|
|
30
|
+
minimumBufferCents: Cents;
|
|
31
|
+
dailySpendRateCents: Cents;
|
|
32
|
+
runwayDays: number;
|
|
33
|
+
}
|
|
34
|
+
interface RebalanceRecommendation {
|
|
35
|
+
fromProjectId: string;
|
|
36
|
+
toProjectId: string;
|
|
37
|
+
amountCents: Cents;
|
|
38
|
+
reason: string;
|
|
39
|
+
}
|
|
40
|
+
interface ExpectedDebit {
|
|
41
|
+
date: string;
|
|
42
|
+
amountCents: Cents;
|
|
43
|
+
}
|
|
44
|
+
export declare function planGoogleInvoiceSettlement(invoices: GoogleInvoice[], bankBalanceCents: Cents, bufferTargetCents: Cents): SettlementPlan[];
|
|
45
|
+
export declare function planMetaDebitProtection(expectedDebits: ExpectedDebit[], bankBalanceCents: Cents, bufferTargetCents: Cents): Cents;
|
|
46
|
+
export declare function generatePortfolioRebalancing(projects: ProjectTreasury[]): RebalanceRecommendation[];
|
|
47
|
+
export type { GoogleInvoice, SettlementPlan, ExpectedDebit, ProjectTreasury, RebalanceRecommendation, };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-Specific Funding Planner — pure logic for Google invoice settlement,
|
|
3
|
+
* Meta debit protection, and multi-project portfolio rebalancing.
|
|
4
|
+
*
|
|
5
|
+
* No API calls, no file I/O — fully testable deterministic functions.
|
|
6
|
+
* All monetary values use branded integer cents (Cents type).
|
|
7
|
+
*
|
|
8
|
+
* PRD Reference: §12.3 (Platform Billing), §15 (Rules Engine)
|
|
9
|
+
* Agents: Dockson (treasury), Heartbeat daemon
|
|
10
|
+
*/
|
|
11
|
+
// ── Google Invoice Settlement Planner ────────────────
|
|
12
|
+
// Prioritize by due date (nearest first). Reserve buffer after settlement.
|
|
13
|
+
// Generate wire instructions for each invoice.
|
|
14
|
+
export function planGoogleInvoiceSettlement(invoices, bankBalanceCents, bufferTargetCents) {
|
|
15
|
+
if (invoices.length === 0)
|
|
16
|
+
return [];
|
|
17
|
+
// Filter to actionable invoices (pending or overdue, not already paid)
|
|
18
|
+
const actionable = invoices.filter(inv => inv.status !== 'paid');
|
|
19
|
+
// Sort: overdue first, then by due date ascending
|
|
20
|
+
const sorted = [...actionable].sort((a, b) => {
|
|
21
|
+
if (a.status === 'overdue' && b.status !== 'overdue')
|
|
22
|
+
return -1;
|
|
23
|
+
if (a.status !== 'overdue' && b.status === 'overdue')
|
|
24
|
+
return 1;
|
|
25
|
+
return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime();
|
|
26
|
+
});
|
|
27
|
+
const plans = [];
|
|
28
|
+
let availableBalance = bankBalanceCents;
|
|
29
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
30
|
+
const invoice = sorted[i];
|
|
31
|
+
const invoiceAmount = invoice.amountCents;
|
|
32
|
+
// Reserve buffer: only settle if we can still maintain buffer afterward
|
|
33
|
+
const balanceAfterSettlement = availableBalance - invoiceAmount;
|
|
34
|
+
if (balanceAfterSettlement < bufferTargetCents) {
|
|
35
|
+
// Cannot settle this invoice without breaching buffer
|
|
36
|
+
// Still include it in the plan but mark the buffer breach
|
|
37
|
+
if (availableBalance > bufferTargetCents) {
|
|
38
|
+
// Partial settlement up to buffer is not supported — skip
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Balance already below buffer — cannot settle any more
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
const wireReference = `GOOG-INV-${invoice.invoiceId}-${Date.now().toString(36).toUpperCase()}`;
|
|
45
|
+
plans.push({
|
|
46
|
+
invoiceId: invoice.invoiceId,
|
|
47
|
+
amountCents: invoice.amountCents,
|
|
48
|
+
dueDate: invoice.dueDate,
|
|
49
|
+
wireReference,
|
|
50
|
+
priority: i + 1,
|
|
51
|
+
remainingBufferAfterCents: (balanceAfterSettlement),
|
|
52
|
+
});
|
|
53
|
+
availableBalance = balanceAfterSettlement;
|
|
54
|
+
}
|
|
55
|
+
return plans;
|
|
56
|
+
}
|
|
57
|
+
// ── Meta Debit Protection Planner ────────────────────
|
|
58
|
+
// Forecast 7-day debit total and ensure bank balance covers debits + buffer.
|
|
59
|
+
export function planMetaDebitProtection(expectedDebits, bankBalanceCents, bufferTargetCents) {
|
|
60
|
+
if (expectedDebits.length === 0)
|
|
61
|
+
return 0;
|
|
62
|
+
// Sum expected debits over the 7-day window
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;
|
|
65
|
+
const cutoff = now + sevenDaysMs;
|
|
66
|
+
const totalExpectedDebits = expectedDebits
|
|
67
|
+
.filter(d => new Date(d.date).getTime() <= cutoff)
|
|
68
|
+
.reduce((sum, d) => sum + d.amountCents, 0);
|
|
69
|
+
// Required buffer: total debits + buffer target
|
|
70
|
+
const requiredBalance = totalExpectedDebits + bufferTargetCents;
|
|
71
|
+
const deficit = requiredBalance - bankBalanceCents;
|
|
72
|
+
// If balance already covers debits + buffer, no additional buffer needed
|
|
73
|
+
if (deficit <= 0)
|
|
74
|
+
return 0;
|
|
75
|
+
return deficit;
|
|
76
|
+
}
|
|
77
|
+
// ── Portfolio Rebalancing ────────────────────────────
|
|
78
|
+
// For multi-project operators: suggest moving operating float from
|
|
79
|
+
// overfunded to underfunded projects.
|
|
80
|
+
export function generatePortfolioRebalancing(projects) {
|
|
81
|
+
if (projects.length < 2)
|
|
82
|
+
return [];
|
|
83
|
+
const recommendations = [];
|
|
84
|
+
// Calculate "excess" for each project: balance above (buffer + 30 days of spend)
|
|
85
|
+
const TARGET_RUNWAY_DAYS = 30;
|
|
86
|
+
const analyzed = projects.map(p => {
|
|
87
|
+
const targetBalance = p.minimumBufferCents +
|
|
88
|
+
p.dailySpendRateCents * TARGET_RUNWAY_DAYS;
|
|
89
|
+
const excess = p.bankBalanceCents - targetBalance;
|
|
90
|
+
return { project: p, targetBalanceCents: targetBalance, excessCents: excess };
|
|
91
|
+
});
|
|
92
|
+
// Split into overfunded and underfunded
|
|
93
|
+
const overfunded = analyzed
|
|
94
|
+
.filter(a => a.excessCents > 0)
|
|
95
|
+
.sort((a, b) => b.excessCents - a.excessCents); // most excess first
|
|
96
|
+
const underfunded = analyzed
|
|
97
|
+
.filter(a => a.excessCents < 0)
|
|
98
|
+
.sort((a, b) => a.excessCents - b.excessCents); // most deficit first
|
|
99
|
+
// Match overfunded to underfunded greedily
|
|
100
|
+
let overIdx = 0;
|
|
101
|
+
let underIdx = 0;
|
|
102
|
+
const remainingExcess = overfunded.map(o => o.excessCents);
|
|
103
|
+
const remainingDeficit = underfunded.map(u => Math.abs(u.excessCents));
|
|
104
|
+
while (overIdx < overfunded.length && underIdx < underfunded.length) {
|
|
105
|
+
const available = remainingExcess[overIdx];
|
|
106
|
+
const needed = remainingDeficit[underIdx];
|
|
107
|
+
if (available <= 0) {
|
|
108
|
+
overIdx++;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (needed <= 0) {
|
|
112
|
+
underIdx++;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const transferAmount = Math.min(available, needed);
|
|
116
|
+
const fromProject = overfunded[overIdx].project;
|
|
117
|
+
const toProject = underfunded[underIdx].project;
|
|
118
|
+
recommendations.push({
|
|
119
|
+
fromProjectId: fromProject.projectId,
|
|
120
|
+
toProjectId: toProject.projectId,
|
|
121
|
+
amountCents: Math.round(transferAmount),
|
|
122
|
+
reason: `${fromProject.projectName} has ${overfunded[overIdx].project.runwayDays}d runway ` +
|
|
123
|
+
`(${TARGET_RUNWAY_DAYS}d target) — transfer to ${toProject.projectName} ` +
|
|
124
|
+
`which has ${toProject.runwayDays}d runway`,
|
|
125
|
+
});
|
|
126
|
+
remainingExcess[overIdx] -= transferAmount;
|
|
127
|
+
remainingDeficit[underIdx] -= transferAmount;
|
|
128
|
+
if (remainingExcess[overIdx] <= 0)
|
|
129
|
+
overIdx++;
|
|
130
|
+
if (remainingDeficit[underIdx] <= 0)
|
|
131
|
+
underIdx++;
|
|
132
|
+
}
|
|
133
|
+
return recommendations;
|
|
134
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-Way Reconciliation Engine — pure logic for financial matching.
|
|
3
|
+
*
|
|
4
|
+
* Reconciles three data sources:
|
|
5
|
+
* 1. Provider transfers (stablecoin off-ramp records)
|
|
6
|
+
* 2. Bank transactions (settlement arrivals)
|
|
7
|
+
* 3. Platform spend (ad platform reported spend)
|
|
8
|
+
*
|
|
9
|
+
* No API calls, no file I/O — fully testable deterministic functions.
|
|
10
|
+
* Extends the existing reconciliation.ts pattern with stablecoin-specific matching.
|
|
11
|
+
*
|
|
12
|
+
* PRD Reference: §12.6 (ReconciliationRecord), §16 (Reporting and Reconciliation)
|
|
13
|
+
* Agents: Dockson (treasury), Heartbeat daemon
|
|
14
|
+
*/
|
|
15
|
+
type Cents = number & {
|
|
16
|
+
readonly __brand: 'Cents';
|
|
17
|
+
};
|
|
18
|
+
interface ProviderTransfer {
|
|
19
|
+
id: string;
|
|
20
|
+
providerTransferId: string;
|
|
21
|
+
amountCents: Cents;
|
|
22
|
+
feesCents: Cents;
|
|
23
|
+
netAmountCents: Cents;
|
|
24
|
+
status: 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
25
|
+
initiatedAt: string;
|
|
26
|
+
completedAt?: string;
|
|
27
|
+
reference?: string;
|
|
28
|
+
}
|
|
29
|
+
interface BankTransaction {
|
|
30
|
+
id: string;
|
|
31
|
+
amountCents: Cents;
|
|
32
|
+
date: string;
|
|
33
|
+
reference: string;
|
|
34
|
+
counterparty: string;
|
|
35
|
+
type: 'credit' | 'debit';
|
|
36
|
+
}
|
|
37
|
+
interface PlatformSpendEntry {
|
|
38
|
+
platform: 'google' | 'meta';
|
|
39
|
+
date: string;
|
|
40
|
+
spendCents: Cents;
|
|
41
|
+
invoiceId?: string;
|
|
42
|
+
}
|
|
43
|
+
type VarianceClassification = 'MATCHED' | 'WITHIN_THRESHOLD' | 'MISMATCH';
|
|
44
|
+
interface TransferBankMatch {
|
|
45
|
+
transferId: string;
|
|
46
|
+
bankTransactionId: string | null;
|
|
47
|
+
transferAmountCents: Cents;
|
|
48
|
+
bankAmountCents: Cents;
|
|
49
|
+
varianceCents: Cents;
|
|
50
|
+
classification: VarianceClassification;
|
|
51
|
+
}
|
|
52
|
+
interface BankSpendMatch {
|
|
53
|
+
bankTransactionId: string;
|
|
54
|
+
platform: 'google' | 'meta';
|
|
55
|
+
bankAmountCents: Cents;
|
|
56
|
+
spendAmountCents: Cents;
|
|
57
|
+
varianceCents: Cents;
|
|
58
|
+
classification: VarianceClassification;
|
|
59
|
+
}
|
|
60
|
+
interface ReconciliationReport {
|
|
61
|
+
date: string;
|
|
62
|
+
transferMatches: TransferBankMatch[];
|
|
63
|
+
spendMatches: BankSpendMatch[];
|
|
64
|
+
unmatchedTransfers: ProviderTransfer[];
|
|
65
|
+
unmatchedBankTransactions: BankTransaction[];
|
|
66
|
+
unmatchedSpend: PlatformSpendEntry[];
|
|
67
|
+
totalTransferredCents: Cents;
|
|
68
|
+
totalBankReceivedCents: Cents;
|
|
69
|
+
totalPlatformSpendCents: Cents;
|
|
70
|
+
overallVarianceCents: Cents;
|
|
71
|
+
mismatchCount: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function classifyVariance(varianceCents: Cents, referenceCents: Cents, thresholdBps: number): VarianceClassification;
|
|
74
|
+
export declare function matchTransferToBank(transfer: ProviderTransfer, transactions: BankTransaction[], thresholdBps?: number): TransferBankMatch;
|
|
75
|
+
export declare function matchBankToSpend(bankTransaction: BankTransaction, platformSpend: PlatformSpendEntry[], thresholdBps?: number): BankSpendMatch | null;
|
|
76
|
+
export declare function reconcileThreeWay(providerTransfers: ProviderTransfer[], bankTransactions: BankTransaction[], platformSpend: PlatformSpendEntry[], thresholdBps?: number): ReconciliationReport;
|
|
77
|
+
export declare function shouldFreeze(mismatchCount: number, consecutiveCount: number, maxConsecutive: number): boolean;
|
|
78
|
+
export type { Cents, ProviderTransfer, BankTransaction, PlatformSpendEntry, VarianceClassification, TransferBankMatch, BankSpendMatch, ReconciliationReport, };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-Way Reconciliation Engine — pure logic for financial matching.
|
|
3
|
+
*
|
|
4
|
+
* Reconciles three data sources:
|
|
5
|
+
* 1. Provider transfers (stablecoin off-ramp records)
|
|
6
|
+
* 2. Bank transactions (settlement arrivals)
|
|
7
|
+
* 3. Platform spend (ad platform reported spend)
|
|
8
|
+
*
|
|
9
|
+
* No API calls, no file I/O — fully testable deterministic functions.
|
|
10
|
+
* Extends the existing reconciliation.ts pattern with stablecoin-specific matching.
|
|
11
|
+
*
|
|
12
|
+
* PRD Reference: §12.6 (ReconciliationRecord), §16 (Reporting and Reconciliation)
|
|
13
|
+
* Agents: Dockson (treasury), Heartbeat daemon
|
|
14
|
+
*/
|
|
15
|
+
// ── Variance Classification ──────────────────────────
|
|
16
|
+
export function classifyVariance(varianceCents, referenceCents, thresholdBps) {
|
|
17
|
+
if (varianceCents === 0)
|
|
18
|
+
return 'MATCHED';
|
|
19
|
+
// Basis points: 1 bps = 0.01% = 1/10,000
|
|
20
|
+
if (referenceCents <= 0) {
|
|
21
|
+
// Can't compute percentage on zero reference — any variance is a mismatch
|
|
22
|
+
return varianceCents === 0 ? 'MATCHED' : 'MISMATCH';
|
|
23
|
+
}
|
|
24
|
+
const varianceBps = (varianceCents / referenceCents) * 10_000;
|
|
25
|
+
return varianceBps <= thresholdBps ? 'WITHIN_THRESHOLD' : 'MISMATCH';
|
|
26
|
+
}
|
|
27
|
+
// ── Transfer-to-Bank Matching ────────────────────────
|
|
28
|
+
export function matchTransferToBank(transfer, transactions, thresholdBps = 50) {
|
|
29
|
+
// Only match completed transfers
|
|
30
|
+
if (transfer.status !== 'completed') {
|
|
31
|
+
return {
|
|
32
|
+
transferId: transfer.id,
|
|
33
|
+
bankTransactionId: null,
|
|
34
|
+
transferAmountCents: transfer.netAmountCents,
|
|
35
|
+
bankAmountCents: 0,
|
|
36
|
+
varianceCents: transfer.netAmountCents,
|
|
37
|
+
classification: 'MISMATCH',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Find matching bank transaction by reference or amount proximity
|
|
41
|
+
let bestMatch = null;
|
|
42
|
+
let bestVariance = Infinity;
|
|
43
|
+
for (const txn of transactions) {
|
|
44
|
+
// Only match credits (incoming funds)
|
|
45
|
+
if (txn.type !== 'credit')
|
|
46
|
+
continue;
|
|
47
|
+
// Check reference match first (strongest signal)
|
|
48
|
+
const refMatch = transfer.reference &&
|
|
49
|
+
txn.reference.toLowerCase().includes(transfer.reference.toLowerCase());
|
|
50
|
+
const variance = Math.abs(transfer.netAmountCents - txn.amountCents);
|
|
51
|
+
// Reference match: accept with any variance within threshold
|
|
52
|
+
if (refMatch && variance < bestVariance) {
|
|
53
|
+
bestMatch = txn;
|
|
54
|
+
bestVariance = variance;
|
|
55
|
+
}
|
|
56
|
+
// Amount proximity match: must be within threshold
|
|
57
|
+
if (!refMatch && variance < bestVariance) {
|
|
58
|
+
const varianceBps = transfer.netAmountCents > 0
|
|
59
|
+
? (variance / transfer.netAmountCents) * 10_000
|
|
60
|
+
: Infinity;
|
|
61
|
+
if (varianceBps <= thresholdBps * 2) {
|
|
62
|
+
// Use 2x threshold for amount-only matching (less confident)
|
|
63
|
+
bestMatch = txn;
|
|
64
|
+
bestVariance = variance;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!bestMatch) {
|
|
69
|
+
return {
|
|
70
|
+
transferId: transfer.id,
|
|
71
|
+
bankTransactionId: null,
|
|
72
|
+
transferAmountCents: transfer.netAmountCents,
|
|
73
|
+
bankAmountCents: 0,
|
|
74
|
+
varianceCents: transfer.netAmountCents,
|
|
75
|
+
classification: 'MISMATCH',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const varianceCents = Math.abs(transfer.netAmountCents - bestMatch.amountCents);
|
|
79
|
+
return {
|
|
80
|
+
transferId: transfer.id,
|
|
81
|
+
bankTransactionId: bestMatch.id,
|
|
82
|
+
transferAmountCents: transfer.netAmountCents,
|
|
83
|
+
bankAmountCents: bestMatch.amountCents,
|
|
84
|
+
varianceCents,
|
|
85
|
+
classification: classifyVariance(varianceCents, transfer.netAmountCents, thresholdBps),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── Bank-to-Platform-Spend Matching ──────────────────
|
|
89
|
+
export function matchBankToSpend(bankTransaction, platformSpend, thresholdBps = 50) {
|
|
90
|
+
// Only match debits (outgoing payments to platforms)
|
|
91
|
+
if (bankTransaction.type !== 'debit')
|
|
92
|
+
return null;
|
|
93
|
+
// Find closest platform spend entry by amount
|
|
94
|
+
let bestMatch = null;
|
|
95
|
+
let bestVariance = Infinity;
|
|
96
|
+
for (const spend of platformSpend) {
|
|
97
|
+
const variance = Math.abs(bankTransaction.amountCents - spend.spendCents);
|
|
98
|
+
if (variance < bestVariance) {
|
|
99
|
+
bestMatch = spend;
|
|
100
|
+
bestVariance = variance;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!bestMatch)
|
|
104
|
+
return null;
|
|
105
|
+
const varianceCents = bestVariance;
|
|
106
|
+
const classification = classifyVariance(varianceCents, bankTransaction.amountCents, thresholdBps);
|
|
107
|
+
// Only return a match if it's within threshold or exact
|
|
108
|
+
if (classification === 'MISMATCH')
|
|
109
|
+
return null;
|
|
110
|
+
return {
|
|
111
|
+
bankTransactionId: bankTransaction.id,
|
|
112
|
+
platform: bestMatch.platform,
|
|
113
|
+
bankAmountCents: bankTransaction.amountCents,
|
|
114
|
+
spendAmountCents: bestMatch.spendCents,
|
|
115
|
+
varianceCents,
|
|
116
|
+
classification,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// ── Three-Way Reconciliation ─────────────────────────
|
|
120
|
+
// The main reconciliation function that ties all three sources together.
|
|
121
|
+
export function reconcileThreeWay(providerTransfers, bankTransactions, platformSpend, thresholdBps = 50) {
|
|
122
|
+
const transferMatches = [];
|
|
123
|
+
const spendMatches = [];
|
|
124
|
+
const matchedBankIds = new Set();
|
|
125
|
+
const matchedSpendIndices = new Set();
|
|
126
|
+
// Phase 1: Match provider transfers to bank transactions
|
|
127
|
+
const completedTransfers = providerTransfers.filter(t => t.status === 'completed');
|
|
128
|
+
const remainingBankTxns = [...bankTransactions];
|
|
129
|
+
for (const transfer of completedTransfers) {
|
|
130
|
+
const match = matchTransferToBank(transfer, remainingBankTxns, thresholdBps);
|
|
131
|
+
transferMatches.push(match);
|
|
132
|
+
if (match.bankTransactionId) {
|
|
133
|
+
matchedBankIds.add(match.bankTransactionId);
|
|
134
|
+
// Remove matched bank transaction from remaining pool
|
|
135
|
+
const idx = remainingBankTxns.findIndex(t => t.id === match.bankTransactionId);
|
|
136
|
+
if (idx >= 0)
|
|
137
|
+
remainingBankTxns.splice(idx, 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Phase 2: Match remaining bank debits to platform spend
|
|
141
|
+
const remainingSpend = [...platformSpend];
|
|
142
|
+
for (const bankTxn of remainingBankTxns) {
|
|
143
|
+
if (matchedBankIds.has(bankTxn.id))
|
|
144
|
+
continue;
|
|
145
|
+
const match = matchBankToSpend(bankTxn, remainingSpend, thresholdBps);
|
|
146
|
+
if (match) {
|
|
147
|
+
spendMatches.push(match);
|
|
148
|
+
matchedBankIds.add(bankTxn.id);
|
|
149
|
+
// Remove matched spend from remaining pool
|
|
150
|
+
const spendIdx = remainingSpend.findIndex(s => s.spendCents === match.spendAmountCents && s.platform === match.platform);
|
|
151
|
+
if (spendIdx >= 0) {
|
|
152
|
+
matchedSpendIndices.add(platformSpend.indexOf(remainingSpend[spendIdx]));
|
|
153
|
+
remainingSpend.splice(spendIdx, 1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Phase 3: Identify unmatched items
|
|
158
|
+
const unmatchedTransfers = providerTransfers.filter(t => {
|
|
159
|
+
if (t.status !== 'completed')
|
|
160
|
+
return true;
|
|
161
|
+
const match = transferMatches.find(m => m.transferId === t.id);
|
|
162
|
+
return !match || match.bankTransactionId === null;
|
|
163
|
+
});
|
|
164
|
+
const unmatchedBankTransactions = bankTransactions.filter(t => !matchedBankIds.has(t.id));
|
|
165
|
+
const unmatchedSpend = platformSpend.filter((_, i) => !matchedSpendIndices.has(i));
|
|
166
|
+
// Phase 4: Calculate totals
|
|
167
|
+
const totalTransferredCents = completedTransfers.reduce((sum, t) => (sum + t.netAmountCents), 0);
|
|
168
|
+
const totalBankReceivedCents = bankTransactions
|
|
169
|
+
.filter(t => t.type === 'credit')
|
|
170
|
+
.reduce((sum, t) => (sum + t.amountCents), 0);
|
|
171
|
+
const totalPlatformSpendCents = platformSpend.reduce((sum, s) => (sum + s.spendCents), 0);
|
|
172
|
+
const overallVarianceCents = Math.abs(totalTransferredCents - totalBankReceivedCents);
|
|
173
|
+
const mismatchCount = transferMatches.filter(m => m.classification === 'MISMATCH').length;
|
|
174
|
+
const today = new Date().toISOString().split('T')[0];
|
|
175
|
+
return {
|
|
176
|
+
date: today,
|
|
177
|
+
transferMatches,
|
|
178
|
+
spendMatches,
|
|
179
|
+
unmatchedTransfers,
|
|
180
|
+
unmatchedBankTransactions,
|
|
181
|
+
unmatchedSpend,
|
|
182
|
+
totalTransferredCents,
|
|
183
|
+
totalBankReceivedCents,
|
|
184
|
+
totalPlatformSpendCents,
|
|
185
|
+
overallVarianceCents,
|
|
186
|
+
mismatchCount,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// ── Freeze Decision ──────────────────────────────────
|
|
190
|
+
// Determines if operations should be frozen based on consecutive mismatches.
|
|
191
|
+
export function shouldFreeze(mismatchCount, consecutiveCount, maxConsecutive) {
|
|
192
|
+
return consecutiveCount >= maxConsecutive || mismatchCount > maxConsecutive;
|
|
193
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Financial provider and billing adapter registries.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which stablecoin providers, bank adapters, and ad billing adapters
|
|
5
|
+
* are implemented. New providers are added here first (implemented: false)
|
|
6
|
+
* then built out.
|
|
7
|
+
*/
|
|
8
|
+
interface ProviderEntry {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly implemented: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const STABLECOIN_PROVIDERS: Record<string, ProviderEntry>;
|
|
13
|
+
export declare const BANK_ADAPTERS: Record<string, ProviderEntry>;
|
|
14
|
+
export declare const BILLING_ADAPTERS: Record<string, ProviderEntry>;
|
|
15
|
+
export type StablecoinProviderId = keyof typeof STABLECOIN_PROVIDERS;
|
|
16
|
+
export type BankAdapterId = keyof typeof BANK_ADAPTERS;
|
|
17
|
+
export type BillingAdapterId = keyof typeof BILLING_ADAPTERS;
|
|
18
|
+
export { CircleSetup, CircleAdapter } from './stablecoin/circle.js';
|
|
19
|
+
export { MercuryBankAdapter } from './stablecoin/mercury.js';
|
|
20
|
+
export { GoogleBillingSetup, GoogleBillingAdapter } from './billing/google-billing.js';
|
|
21
|
+
export { MetaBillingSetup, MetaBillingAdapter } from './billing/meta-billing.js';
|
|
22
|
+
export { TikTokBillingSetup, TikTokBillingAdapter } from './billing/tiktok-billing.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Financial provider and billing adapter registries.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which stablecoin providers, bank adapters, and ad billing adapters
|
|
5
|
+
* are implemented. New providers are added here first (implemented: false)
|
|
6
|
+
* then built out.
|
|
7
|
+
*/
|
|
8
|
+
export const STABLECOIN_PROVIDERS = {
|
|
9
|
+
sandbox: { name: 'Sandbox (Demo)', implemented: true },
|
|
10
|
+
circle: { name: 'Circle', implemented: true },
|
|
11
|
+
bridge: { name: 'Bridge', implemented: false },
|
|
12
|
+
};
|
|
13
|
+
export const BANK_ADAPTERS = {
|
|
14
|
+
mercury: { name: 'Mercury', implemented: true },
|
|
15
|
+
};
|
|
16
|
+
export const BILLING_ADAPTERS = {
|
|
17
|
+
google: { name: 'Google Ads Billing', implemented: true },
|
|
18
|
+
meta: { name: 'Meta Ads Billing', implemented: true },
|
|
19
|
+
tiktok: { name: 'TikTok Ads Billing', implemented: true },
|
|
20
|
+
};
|
|
21
|
+
// ── Re-exports for convenience ───────────────────────
|
|
22
|
+
export { CircleSetup, CircleAdapter } from './stablecoin/circle.js';
|
|
23
|
+
export { MercuryBankAdapter } from './stablecoin/mercury.js';
|
|
24
|
+
export { GoogleBillingSetup, GoogleBillingAdapter } from './billing/google-billing.js';
|
|
25
|
+
export { MetaBillingSetup, MetaBillingAdapter } from './billing/meta-billing.js';
|
|
26
|
+
export { TikTokBillingSetup, TikTokBillingAdapter } from './billing/tiktok-billing.js';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Financial Reporting + Export — daily reports, monthly ledgers, and funding simulation.
|
|
3
|
+
*
|
|
4
|
+
* Pure logic — no API calls, no file I/O, fully testable.
|
|
5
|
+
* All monetary values use branded integer cents (Cents type).
|
|
6
|
+
* Output formats: markdown (daily), JSON (monthly), simulation object.
|
|
7
|
+
*
|
|
8
|
+
* PRD Reference: §16 (Reporting and Reconciliation)
|
|
9
|
+
* Agents: Dockson (treasury), Heartbeat daemon
|
|
10
|
+
*/
|
|
11
|
+
import type { Cents } from '../patterns/funding-plan.js';
|
|
12
|
+
import type { ReconciliationReport } from './reconciliation-engine.js';
|
|
13
|
+
import type { CampaignSpendProjection, FundingPlanConfig } from './treasury-planner.js';
|
|
14
|
+
interface DailyReportInput {
|
|
15
|
+
date: string;
|
|
16
|
+
revenueCents: Cents;
|
|
17
|
+
spendCents: Cents;
|
|
18
|
+
stablecoinBalanceCents: Cents;
|
|
19
|
+
pendingTransfersCents: Cents;
|
|
20
|
+
bankBalanceCents: Cents;
|
|
21
|
+
settledTodayCents: Cents;
|
|
22
|
+
reconciliation: ReconciliationReport | null;
|
|
23
|
+
activeCircuitBreakers: string[];
|
|
24
|
+
runwayDays: number;
|
|
25
|
+
fundingFrozen: boolean;
|
|
26
|
+
freezeReason: string | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function generateDailyReport(input: DailyReportInput): string;
|
|
29
|
+
interface TransferLedgerEntry {
|
|
30
|
+
id: string;
|
|
31
|
+
date: string;
|
|
32
|
+
direction: string;
|
|
33
|
+
amountCents: Cents;
|
|
34
|
+
feesCents: Cents;
|
|
35
|
+
netAmountCents: Cents;
|
|
36
|
+
status: string;
|
|
37
|
+
reference: string;
|
|
38
|
+
}
|
|
39
|
+
interface ReconciliationLedgerEntry {
|
|
40
|
+
id: string;
|
|
41
|
+
date: string;
|
|
42
|
+
platform: string;
|
|
43
|
+
spendCents: Cents;
|
|
44
|
+
bankSettledCents: Cents;
|
|
45
|
+
varianceCents: Cents;
|
|
46
|
+
result: string;
|
|
47
|
+
}
|
|
48
|
+
interface MonthlyLedger {
|
|
49
|
+
month: string;
|
|
50
|
+
generatedAt: string;
|
|
51
|
+
transfers: TransferLedgerEntry[];
|
|
52
|
+
reconciliations: ReconciliationLedgerEntry[];
|
|
53
|
+
summary: {
|
|
54
|
+
totalTransfersCents: Cents;
|
|
55
|
+
totalFeesCents: Cents;
|
|
56
|
+
totalNetTransferredCents: Cents;
|
|
57
|
+
totalSpendCents: Cents;
|
|
58
|
+
totalBankSettledCents: Cents;
|
|
59
|
+
totalVarianceCents: Cents;
|
|
60
|
+
transferCount: number;
|
|
61
|
+
reconciliationCount: number;
|
|
62
|
+
mismatchCount: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export declare function generateMonthlyLedger(month: string, transfers: TransferLedgerEntry[], reconciliations: ReconciliationLedgerEntry[]): MonthlyLedger;
|
|
66
|
+
interface SimulationDay {
|
|
67
|
+
day: number;
|
|
68
|
+
date: string;
|
|
69
|
+
bankBalanceCents: Cents;
|
|
70
|
+
spendCents: Cents;
|
|
71
|
+
offrampTriggered: boolean;
|
|
72
|
+
offrampAmountCents: Cents;
|
|
73
|
+
policyBlocked: boolean;
|
|
74
|
+
freezeRisk: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface SimulationResult {
|
|
77
|
+
config: {
|
|
78
|
+
startDate: string;
|
|
79
|
+
days: number;
|
|
80
|
+
startingBankBalanceCents: Cents;
|
|
81
|
+
bufferTargetCents: Cents;
|
|
82
|
+
maxDailyOfframpCents: Cents;
|
|
83
|
+
};
|
|
84
|
+
days: SimulationDay[];
|
|
85
|
+
summary: {
|
|
86
|
+
firstOfframpDay: number | null;
|
|
87
|
+
totalOfframpsCents: Cents;
|
|
88
|
+
offrampCount: number;
|
|
89
|
+
minimumBalanceCents: Cents;
|
|
90
|
+
minimumBalanceDay: number;
|
|
91
|
+
freezeRiskDays: number[];
|
|
92
|
+
finalBalanceCents: Cents;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export declare function simulateFunding(startDate: string, startingBankBalanceCents: Cents, config: FundingPlanConfig, campaigns: CampaignSpendProjection[], days: number, stablecoinAvailableCents: Cents, minimumBufferCents: Cents): SimulationResult;
|
|
96
|
+
export type { DailyReportInput, TransferLedgerEntry, ReconciliationLedgerEntry, MonthlyLedger, SimulationDay, SimulationResult, };
|