summaryrefslogtreecommitdiffhomepage
path: root/packages/console/core
diff options
context:
space:
mode:
authorFrank <[email protected]>2026-01-22 16:59:32 -0500
committerFrank <[email protected]>2026-01-22 17:02:46 -0500
commit5f3ab9395fc8f8543724dcda914d38fba0809049 (patch)
tree3be83aa5cc4e4556b62f9ff6b23933f8699eea63 /packages/console/core
parentfdac21688c9acc4087b83e71cb7e0fd1d2d57f00 (diff)
downloadopencode-5f3ab9395fc8f8543724dcda914d38fba0809049.tar.gz
opencode-5f3ab9395fc8f8543724dcda914d38fba0809049.zip
wip: zen black
Diffstat (limited to 'packages/console/core')
-rw-r--r--packages/console/core/migrations/0055_moaning_karnak.sql1
-rw-r--r--packages/console/core/migrations/meta/0055_snapshot.json1316
-rw-r--r--packages/console/core/migrations/meta/_journal.json9
-rw-r--r--packages/console/core/script/black-gift.ts9
-rw-r--r--packages/console/core/script/black-onboard.ts173
-rw-r--r--packages/console/core/script/lookup-user.ts2
-rw-r--r--packages/console/core/src/billing.ts65
-rw-r--r--packages/console/core/src/black.ts33
-rw-r--r--packages/console/core/src/schema/billing.sql.ts1
9 files changed, 1421 insertions, 188 deletions
diff --git a/packages/console/core/migrations/0055_moaning_karnak.sql b/packages/console/core/migrations/0055_moaning_karnak.sql
new file mode 100644
index 000000000..120ae727c
--- /dev/null
+++ b/packages/console/core/migrations/0055_moaning_karnak.sql
@@ -0,0 +1 @@
+ALTER TABLE `billing` ADD `time_subscription_selected` timestamp(3); \ No newline at end of file
diff --git a/packages/console/core/migrations/meta/0055_snapshot.json b/packages/console/core/migrations/meta/0055_snapshot.json
new file mode 100644
index 000000000..fadb753b4
--- /dev/null
+++ b/packages/console/core/migrations/meta/0055_snapshot.json
@@ -0,0 +1,1316 @@
+{
+ "version": "5",
+ "dialect": "mysql",
+ "id": "e630f63c-04a8-4b59-bf56-03efcdd1b011",
+ "prevId": "a0ade64b-b735-4a70-8d39-ebd84bc9e924",
+ "tables": {
+ "account": {
+ "name": "account",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "account_id_pk": {
+ "name": "account_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "auth": {
+ "name": "auth",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "enum('email','github','google')",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "subject": {
+ "name": "subject",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "provider": {
+ "name": "provider",
+ "columns": [
+ "provider",
+ "subject"
+ ],
+ "isUnique": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "columns": [
+ "account_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "auth_id_pk": {
+ "name": "auth_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "benchmark": {
+ "name": "benchmark",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "model": {
+ "name": "model",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "agent": {
+ "name": "agent",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "result": {
+ "name": "result",
+ "type": "mediumtext",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "time_created": {
+ "name": "time_created",
+ "columns": [
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "benchmark_id_pk": {
+ "name": "benchmark_id_pk",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "billing": {
+ "name": "billing",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "payment_method_id": {
+ "name": "payment_method_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "payment_method_type": {
+ "name": "payment_method_type",
+ "type": "varchar(32)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "payment_method_last4": {
+ "name": "payment_method_last4",
+ "type": "varchar(4)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "balance": {
+ "name": "balance",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "monthly_limit": {
+ "name": "monthly_limit",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "monthly_usage": {
+ "name": "monthly_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_monthly_usage_updated": {
+ "name": "time_monthly_usage_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload": {
+ "name": "reload",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload_trigger": {
+ "name": "reload_trigger",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload_amount": {
+ "name": "reload_amount",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "reload_error": {
+ "name": "reload_error",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_reload_error": {
+ "name": "time_reload_error",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_reload_locked_till": {
+ "name": "time_reload_locked_till",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription": {
+ "name": "subscription",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "varchar(28)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "subscription_plan": {
+ "name": "subscription_plan",
+ "type": "enum('20','100','200')",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_subscription_booked": {
+ "name": "time_subscription_booked",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_subscription_selected": {
+ "name": "time_subscription_selected",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "global_customer_id": {
+ "name": "global_customer_id",
+ "columns": [
+ "customer_id"
+ ],
+ "isUnique": true
+ },
+ "global_subscription_id": {
+ "name": "global_subscription_id",
+ "columns": [
+ "subscription_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "billing_workspace_id_id_pk": {
+ "name": "billing_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "payment": {
+ "name": "payment",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "invoice_id": {
+ "name": "invoice_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "payment_id": {
+ "name": "payment_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "amount": {
+ "name": "amount",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_refunded": {
+ "name": "time_refunded",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "payment_workspace_id_id_pk": {
+ "name": "payment_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "subscription": {
+ "name": "subscription",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "rolling_usage": {
+ "name": "rolling_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "fixed_usage": {
+ "name": "fixed_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_rolling_updated": {
+ "name": "time_rolling_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_fixed_updated": {
+ "name": "time_fixed_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "workspace_user_id": {
+ "name": "workspace_user_id",
+ "columns": [
+ "workspace_id",
+ "user_id"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "subscription_workspace_id_id_pk": {
+ "name": "subscription_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "usage": {
+ "name": "usage",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "model": {
+ "name": "model",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "input_tokens": {
+ "name": "input_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "output_tokens": {
+ "name": "output_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "reasoning_tokens": {
+ "name": "reasoning_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cache_read_tokens": {
+ "name": "cache_read_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cache_write_5m_tokens": {
+ "name": "cache_write_5m_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cache_write_1h_tokens": {
+ "name": "cache_write_1h_tokens",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cost": {
+ "name": "cost",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "key_id": {
+ "name": "key_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "enrichment": {
+ "name": "enrichment",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "usage_time_created": {
+ "name": "usage_time_created",
+ "columns": [
+ "workspace_id",
+ "time_created"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "usage_workspace_id_id_pk": {
+ "name": "usage_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip_rate_limit": {
+ "name": "ip_rate_limit",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "interval": {
+ "name": "interval",
+ "type": "varchar(10)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "count": {
+ "name": "count",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_rate_limit_ip_interval_pk": {
+ "name": "ip_rate_limit_ip_interval_pk",
+ "columns": [
+ "ip",
+ "interval"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "ip": {
+ "name": "ip",
+ "columns": {
+ "ip": {
+ "name": "ip",
+ "type": "varchar(45)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "usage": {
+ "name": "usage",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "ip_ip_pk": {
+ "name": "ip_ip_pk",
+ "columns": [
+ "ip"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "key": {
+ "name": "key",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "key": {
+ "name": "key",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_used": {
+ "name": "time_used",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "global_key": {
+ "name": "global_key",
+ "columns": [
+ "key"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "key_workspace_id_id_pk": {
+ "name": "key_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "model": {
+ "name": "model",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "model": {
+ "name": "model",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "model_workspace_model": {
+ "name": "model_workspace_model",
+ "columns": [
+ "workspace_id",
+ "model"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "model_workspace_id_id_pk": {
+ "name": "model_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "provider": {
+ "name": "provider",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "varchar(64)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "credentials": {
+ "name": "credentials",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "workspace_provider": {
+ "name": "workspace_provider",
+ "columns": [
+ "workspace_id",
+ "provider"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "provider_workspace_id_id_pk": {
+ "name": "provider_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "user": {
+ "name": "user",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_seen": {
+ "name": "time_seen",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "color": {
+ "name": "color",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "role": {
+ "name": "role",
+ "type": "enum('admin','member')",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "monthly_limit": {
+ "name": "monthly_limit",
+ "type": "int",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "monthly_usage": {
+ "name": "monthly_usage",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "time_monthly_usage_updated": {
+ "name": "time_monthly_usage_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "user_account_id": {
+ "name": "user_account_id",
+ "columns": [
+ "workspace_id",
+ "account_id"
+ ],
+ "isUnique": true
+ },
+ "user_email": {
+ "name": "user_email",
+ "columns": [
+ "workspace_id",
+ "email"
+ ],
+ "isUnique": true
+ },
+ "global_account_id": {
+ "name": "global_account_id",
+ "columns": [
+ "account_id"
+ ],
+ "isUnique": false
+ },
+ "global_email": {
+ "name": "global_email",
+ "columns": [
+ "email"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "user_workspace_id_id_pk": {
+ "name": "user_workspace_id_id_pk",
+ "columns": [
+ "workspace_id",
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ },
+ "workspace": {
+ "name": "workspace",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "varchar(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "time_created": {
+ "name": "time_created",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(now())"
+ },
+ "time_updated": {
+ "name": "time_updated",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
+ },
+ "time_deleted": {
+ "name": "time_deleted",
+ "type": "timestamp(3)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "slug": {
+ "name": "slug",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "columns": [
+ "id"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraint": {}
+ }
+ },
+ "views": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "tables": {},
+ "indexes": {}
+ }
+} \ No newline at end of file
diff --git a/packages/console/core/migrations/meta/_journal.json b/packages/console/core/migrations/meta/_journal.json
index dd0957e51..0314e38c9 100644
--- a/packages/console/core/migrations/meta/_journal.json
+++ b/packages/console/core/migrations/meta/_journal.json
@@ -386,6 +386,13 @@
"when": 1768603665356,
"tag": "0054_numerous_annihilus",
"breakpoints": true
+ },
+ {
+ "idx": 55,
+ "version": "5",
+ "when": 1769108945841,
+ "tag": "0055_moaning_karnak",
+ "breakpoints": true
}
]
-}
+} \ No newline at end of file
diff --git a/packages/console/core/script/black-gift.ts b/packages/console/core/script/black-gift.ts
index ec7db8799..c666a1ab6 100644
--- a/packages/console/core/script/black-gift.ts
+++ b/packages/console/core/script/black-gift.ts
@@ -5,8 +5,11 @@ import { BillingTable, PaymentTable, SubscriptionTable } from "../src/schema/bil
import { Identifier } from "../src/identifier.js"
import { centsToMicroCents } from "../src/util/price.js"
import { AuthTable } from "../src/schema/auth.sql.js"
+import { BlackData } from "../src/black.js"
+import { Actor } from "../src/actor.js"
const plan = "200"
+const couponID = "JAIr0Pe1"
const workspaceID = process.argv[2]
const seats = parseInt(process.argv[3])
@@ -61,16 +64,18 @@ const customerID =
.then((customer) => customer.id))())
console.log(`Customer ID: ${customerID}`)
-const couponID = "JAIr0Pe1"
const subscription = await Billing.stripe().subscriptions.create({
customer: customerID!,
items: [
{
- price: `price_1SmfyI2StuRr0lbXovxJNeZn`,
+ price: BlackData.planToPriceID({ plan }),
discounts: [{ coupon: couponID }],
quantity: seats,
},
],
+ metadata: {
+ workspaceID,
+ },
})
console.log(`Subscription ID: ${subscription.id}`)
diff --git a/packages/console/core/script/black-onboard.ts b/packages/console/core/script/black-onboard.ts
deleted file mode 100644
index 77e5b779e..000000000
--- a/packages/console/core/script/black-onboard.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-import { Billing } from "../src/billing.js"
-import { and, Database, eq, isNull, sql } from "../src/drizzle/index.js"
-import { UserTable } from "../src/schema/user.sql.js"
-import { BillingTable, PaymentTable, SubscriptionTable } from "../src/schema/billing.sql.js"
-import { Identifier } from "../src/identifier.js"
-import { centsToMicroCents } from "../src/util/price.js"
-import { AuthTable } from "../src/schema/auth.sql.js"
-
-const workspaceID = process.argv[2]
-const email = process.argv[3]
-
-console.log(`Onboarding workspace ${workspaceID} for email ${email}`)
-
-if (!workspaceID || !email) {
- console.error("Usage: bun foo.ts <workspaceID> <email>")
- process.exit(1)
-}
-
-// Look up the Stripe customer by email
-const customers = await Billing.stripe().customers.list({ email, limit: 10, expand: ["data.subscriptions"] })
-if (!customers.data) {
- console.error(`Error: No Stripe customer found for email ${email}`)
- process.exit(1)
-}
-const customer = customers.data.find((c) => c.subscriptions?.data[0]?.items.data[0]?.price.unit_amount === 20000)
-if (!customer) {
- console.error(`Error: No Stripe customer found for email ${email} with $200 subscription`)
- process.exit(1)
-}
-
-const customerID = customer.id
-const subscription = customer.subscriptions!.data[0]
-const subscriptionID = subscription.id
-
-// Validate the subscription is $200
-const amountInCents = subscription.items.data[0]?.price.unit_amount ?? 0
-if (amountInCents !== 20000) {
- console.error(`Error: Subscription amount is $${amountInCents / 100}, expected $200`)
- process.exit(1)
-}
-
-const subscriptionData = await Billing.stripe().subscriptions.retrieve(subscription.id, { expand: ["discounts"] })
-const couponID =
- typeof subscriptionData.discounts[0] === "string"
- ? subscriptionData.discounts[0]
- : subscriptionData.discounts[0]?.coupon?.id
-
-// Check if subscription is already tied to another workspace
-const existingSubscription = await Database.use((tx) =>
- tx
- .select({ workspaceID: BillingTable.workspaceID })
- .from(BillingTable)
- .where(sql`JSON_EXTRACT(${BillingTable.subscription}, '$.id') = ${subscriptionID}`)
- .then((rows) => rows[0]),
-)
-if (existingSubscription) {
- console.error(
- `Error: Subscription ${subscriptionID} is already tied to workspace ${existingSubscription.workspaceID}`,
- )
- process.exit(1)
-}
-
-// Look up the workspace billing and check if it already has a customer id or subscription
-const billing = await Database.use((tx) =>
- tx
- .select({ customerID: BillingTable.customerID, subscriptionID: BillingTable.subscriptionID })
- .from(BillingTable)
- .where(eq(BillingTable.workspaceID, workspaceID))
- .then((rows) => rows[0]),
-)
-if (billing?.subscriptionID) {
- console.error(`Error: Workspace ${workspaceID} already has a subscription: ${billing.subscriptionID}`)
- process.exit(1)
-}
-if (billing?.customerID) {
- console.warn(
- `Warning: Workspace ${workspaceID} already has a customer id: ${billing.customerID}, replacing with ${customerID}`,
- )
-}
-
-// Get the latest invoice and payment from the subscription
-const invoices = await Billing.stripe().invoices.list({
- subscription: subscriptionID,
- limit: 1,
- expand: ["data.payments"],
-})
-const invoice = invoices.data[0]
-const invoiceID = invoice?.id
-const paymentID = invoice?.payments?.data[0]?.payment.payment_intent as string | undefined
-
-// Get the default payment method from the customer
-const paymentMethodID = (customer.invoice_settings.default_payment_method ?? subscription.default_payment_method) as
- | string
- | null
-const paymentMethod = paymentMethodID ? await Billing.stripe().paymentMethods.retrieve(paymentMethodID) : null
-const paymentMethodLast4 = paymentMethod?.card?.last4 ?? null
-const paymentMethodType = paymentMethod?.type ?? null
-
-// Look up the user in the workspace
-const users = await Database.use((tx) =>
- tx
- .select({ id: UserTable.id, email: AuthTable.subject })
- .from(UserTable)
- .innerJoin(AuthTable, and(eq(AuthTable.accountID, UserTable.accountID), eq(AuthTable.provider, "email")))
- .where(and(eq(UserTable.workspaceID, workspaceID), isNull(UserTable.timeDeleted))),
-)
-if (users.length === 0) {
- console.error(`Error: No users found in workspace ${workspaceID}`)
- process.exit(1)
-}
-const user = users.length === 1 ? users[0] : users.find((u) => u.email === email)
-if (!user) {
- console.error(`Error: User with email ${email} not found in workspace ${workspaceID}`)
- process.exit(1)
-}
-
-// Set workspaceID in Stripe customer metadata
-await Billing.stripe().customers.update(customerID, {
- metadata: {
- workspaceID,
- },
-})
-
-await Database.transaction(async (tx) => {
- // Set customer id, subscription id, and payment method on workspace billing
- await tx
- .update(BillingTable)
- .set({
- customerID,
- subscriptionID,
- paymentMethodID,
- paymentMethodLast4,
- paymentMethodType,
- subscription: {
- status: "subscribed",
- coupon: couponID,
- seats: 1,
- plan: "200",
- },
- })
- .where(eq(BillingTable.workspaceID, workspaceID))
-
- // Create a row in subscription table
- await tx.insert(SubscriptionTable).values({
- workspaceID,
- id: Identifier.create("subscription"),
- userID: user.id,
- })
-
- // Create a row in payments table
- await tx.insert(PaymentTable).values({
- workspaceID,
- id: Identifier.create("payment"),
- amount: centsToMicroCents(amountInCents),
- customerID,
- invoiceID,
- paymentID,
- enrichment: {
- type: "subscription",
- couponID,
- },
- })
-})
-
-console.log(`Successfully onboarded workspace ${workspaceID}`)
-console.log(` Customer ID: ${customerID}`)
-console.log(` Subscription ID: ${subscriptionID}`)
-console.log(
- ` Payment Method: ${paymentMethodID ?? "(none)"} (${paymentMethodType ?? "unknown"} ending in ${paymentMethodLast4 ?? "????"})`,
-)
-console.log(` User ID: ${user.id}`)
-console.log(` Invoice ID: ${invoiceID ?? "(none)"}`)
-console.log(` Payment ID: ${paymentID ?? "(none)"}`)
diff --git a/packages/console/core/script/lookup-user.ts b/packages/console/core/script/lookup-user.ts
index 6c76d42c9..0a614bc15 100644
--- a/packages/console/core/script/lookup-user.ts
+++ b/packages/console/core/script/lookup-user.ts
@@ -244,7 +244,7 @@ function getSubscriptionStatus(row: {
return { weekly: null, rolling: null, rateLimited: null, retryIn: null }
}
- const black = BlackData.get({ plan: row.subscription.plan })
+ const black = BlackData.getLimits({ plan: row.subscription.plan })
const now = new Date()
const week = getWeekBounds(now)
diff --git a/packages/console/core/src/billing.ts b/packages/console/core/src/billing.ts
index 36e8a76b7..373f0c595 100644
--- a/packages/console/core/src/billing.ts
+++ b/packages/console/core/src/billing.ts
@@ -1,6 +1,6 @@
import { Stripe } from "stripe"
import { Database, eq, sql } from "./drizzle"
-import { BillingTable, PaymentTable, UsageTable } from "./schema/billing.sql"
+import { BillingTable, PaymentTable, SubscriptionTable, UsageTable } from "./schema/billing.sql"
import { Actor } from "./actor"
import { fn } from "./util/fn"
import { z } from "zod"
@@ -8,6 +8,7 @@ import { Resource } from "@opencode-ai/console-resource"
import { Identifier } from "./identifier"
import { centsToMicroCents } from "./util/price"
import { User } from "./user"
+import { BlackData } from "./black"
export namespace Billing {
export const ITEM_CREDIT_NAME = "opencode credits"
@@ -288,4 +289,66 @@ export namespace Billing {
return charge.receipt_url
},
)
+
+ export const subscribe = fn(z.object({
+ seats: z.number(),
+ coupon: z.string().optional(),
+ }), async ({ seats, coupon }) => {
+ const user = Actor.assert("user")
+ const billing = await Database.use((tx) =>
+ tx
+ .select({
+ customerID: BillingTable.customerID,
+ paymentMethodID: BillingTable.paymentMethodID,
+ subscriptionID: BillingTable.subscriptionID,
+ subscriptionPlan: BillingTable.subscriptionPlan,
+ timeSubscriptionSelected: BillingTable.timeSubscriptionSelected,
+ })
+ .from(BillingTable)
+ .where(eq(BillingTable.workspaceID, Actor.workspace()))
+ .then((rows) => rows[0]),
+ )
+
+ if (!billing) throw new Error("Billing record not found")
+ if (!billing.timeSubscriptionSelected) throw new Error("Not selected for subscription")
+ if (billing.subscriptionID) throw new Error("Already subscribed")
+ if (!billing.customerID) throw new Error("No customer ID")
+ if (!billing.paymentMethodID) throw new Error("No payment method")
+ if (!billing.subscriptionPlan) throw new Error("No subscription plan")
+
+ const subscription = await Billing.stripe().subscriptions.create({
+ customer: billing.customerID,
+ default_payment_method: billing.paymentMethodID,
+ items: [{ price: BlackData.planToPriceID({ plan: billing.subscriptionPlan }) }],
+ metadata: {
+ workspaceID: Actor.workspace(),
+ },
+ })
+
+ await Database.transaction(async (tx) => {
+ await tx
+ .update(BillingTable)
+ .set({
+ subscriptionID: subscription.id,
+ subscription: {
+ status: "subscribed",
+ coupon,
+ seats,
+ plan: billing.subscriptionPlan!,
+ },
+ subscriptionPlan: null,
+ timeSubscriptionBooked: null,
+ timeSubscriptionSelected: null,
+ })
+ .where(eq(BillingTable.workspaceID, Actor.workspace()))
+
+ await tx.insert(SubscriptionTable).values({
+ workspaceID: Actor.workspace(),
+ id: Identifier.create("subscription"),
+ userID: user.properties.userID,
+ })
+ })
+
+ return subscription.id
+ })
}
diff --git a/packages/console/core/src/black.ts b/packages/console/core/src/black.ts
index 13314a62d..93134de55 100644
--- a/packages/console/core/src/black.ts
+++ b/packages/console/core/src/black.ts
@@ -28,15 +28,28 @@ export namespace BlackData {
return input
})
- export const get = fn(
- z.object({
+ export const getLimits = fn(z.object({
plan: z.enum(SubscriptionPlan),
- }),
- ({ plan }) => {
- const json = JSON.parse(Resource.ZEN_BLACK_LIMITS.value)
- return Schema.parse(json)[plan]
- },
- )
+ }), ({ plan }) => {
+ const json = JSON.parse(Resource.ZEN_BLACK_LIMITS.value)
+ return Schema.parse(json)[plan]
+ })
+
+ export const planToPriceID = fn(z.object({
+ plan: z.enum(SubscriptionPlan),
+ }), ({ plan }) => {
+ if (plan === "200") return Resource.ZEN_BLACK_PRICE.plan200
+ if (plan === "100") return Resource.ZEN_BLACK_PRICE.plan100
+ return Resource.ZEN_BLACK_PRICE.plan20
+ })
+
+ export const priceIDToPlan = fn(z.object({
+ priceID: z.string(),
+ }), ({ priceID }) => {
+ if (priceID === Resource.ZEN_BLACK_PRICE.plan200) return "200"
+ if (priceID === Resource.ZEN_BLACK_PRICE.plan100) return "100"
+ return "20"
+ })
}
export namespace Black {
@@ -48,7 +61,7 @@ export namespace Black {
}),
({ plan, usage, timeUpdated }) => {
const now = new Date()
- const black = BlackData.get({ plan })
+ const black = BlackData.getLimits({ plan })
const rollingWindowMs = black.rollingWindow * 3600 * 1000
const rollingLimitInMicroCents = centsToMicroCents(black.rollingLimit * 100)
const windowStart = new Date(now.getTime() - rollingWindowMs)
@@ -83,7 +96,7 @@ export namespace Black {
timeUpdated: z.date(),
}),
({ plan, usage, timeUpdated }) => {
- const black = BlackData.get({ plan })
+ const black = BlackData.getLimits({ plan })
const now = new Date()
const week = getWeekBounds(now)
const fixedLimitInMicroCents = centsToMicroCents(black.fixedLimit * 100)
diff --git a/packages/console/core/src/schema/billing.sql.ts b/packages/console/core/src/schema/billing.sql.ts
index ae32ed5ce..6f5c55850 100644
--- a/packages/console/core/src/schema/billing.sql.ts
+++ b/packages/console/core/src/schema/billing.sql.ts
@@ -31,6 +31,7 @@ export const BillingTable = mysqlTable(
subscriptionID: varchar("subscription_id", { length: 28 }),
subscriptionPlan: mysqlEnum("subscription_plan", SubscriptionPlan),
timeSubscriptionBooked: utc("time_subscription_booked"),
+ timeSubscriptionSelected: utc("time_subscription_selected"),
},
(table) => [
...workspaceIndexes(table),