improvement(api-keys): move to workspace level (#1765)

* fix(billing): should allow restoring subscription (#1728)

* fix(already-cancelled-sub): UI should allow restoring subscription

* restore functionality fixed

* fix

* improvement(api-keys): move to workspace level

* remove migration to prep merge

* remove two more unused cols

* prep staging  merge

* add migration back

---------

Co-authored-by: Waleed <walif6@gmail.com>
Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
This commit is contained in:
Vikhyath Mondreti
2025-10-30 11:42:58 -07:00
committed by GitHub
co-authored by Waleed Siddharth Ganesan
parent c99bb0aaa2
commit fe9ebbf81b
61 changed files with 8208 additions and 1530 deletions
@@ -0,0 +1,12 @@
ALTER TABLE "workflow" DROP CONSTRAINT "workflow_pinned_api_key_id_api_key_id_fk";
--> statement-breakpoint
ALTER TABLE "workspace" ADD COLUMN "billed_account_user_id" text;--> statement-breakpoint
ALTER TABLE "workspace" ADD COLUMN "allow_personal_api_keys" boolean DEFAULT true NOT NULL;--> statement-breakpoint
UPDATE "workspace" SET "billed_account_user_id" = "owner_id" WHERE "billed_account_user_id" IS NULL;--> statement-breakpoint
ALTER TABLE "workspace" ALTER COLUMN "billed_account_user_id" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "workspace" ADD CONSTRAINT "workspace_billed_account_user_id_user_id_fk" FOREIGN KEY ("billed_account_user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "workflow" DROP COLUMN "deployed_state";--> statement-breakpoint
ALTER TABLE "workflow" DROP COLUMN "pinned_api_key_id";--> statement-breakpoint
ALTER TABLE "workflow" DROP COLUMN "collaborators";--> statement-breakpoint
ALTER TABLE "workflow" DROP COLUMN "is_published";--> statement-breakpoint
ALTER TABLE "workflow" DROP COLUMN "marketplace_data";
File diff suppressed because it is too large Load Diff
@@ -722,6 +722,13 @@
"when": 1761845605676,
"tag": "0103_careful_harpoon",
"breakpoints": true
},
{
"idx": 104,
"version": "7",
"when": 1761848118406,
"tag": "0104_orange_shinobi_shaw",
"breakpoints": true
}
]
}
+4 -5
View File
@@ -145,15 +145,10 @@ export const workflow = pgTable(
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
isDeployed: boolean('is_deployed').notNull().default(false),
deployedState: json('deployed_state'),
deployedAt: timestamp('deployed_at'),
pinnedApiKeyId: text('pinned_api_key_id').references(() => apiKey.id, { onDelete: 'set null' }),
collaborators: json('collaborators').notNull().default('[]'),
runCount: integer('run_count').notNull().default(0),
lastRunAt: timestamp('last_run_at'),
variables: json('variables').default('{}'),
isPublished: boolean('is_published').notNull().default(false),
marketplaceData: json('marketplace_data'),
},
(table) => ({
userIdIdx: index('workflow_user_id_idx').on(table.userId),
@@ -727,6 +722,10 @@ export const workspace = pgTable('workspace', {
ownerId: text('owner_id')
.notNull()
.references(() => user.id, { onDelete: 'cascade' }),
billedAccountUserId: text('billed_account_user_id')
.notNull()
.references(() => user.id, { onDelete: 'no action' }),
allowPersonalApiKeys: boolean('allow_personal_api_keys').notNull().default(true),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
})
-1
View File
@@ -158,7 +158,6 @@ class WorkflowExecutionResult:
class WorkflowStatus:
is_deployed: bool
deployed_at: Optional[str] = None
is_published: bool = False
needs_redeployment: bool = False
```
@@ -77,7 +77,6 @@ def status_example():
status = client.get_workflow_status("your-workflow-id")
print(f"Status: {{\n"
f" deployed: {status.is_deployed},\n"
f" published: {status.is_published},\n"
f" needs_redeployment: {status.needs_redeployment},\n"
f" deployed_at: {status.deployed_at}\n"
f"}}")
@@ -42,7 +42,6 @@ class WorkflowStatus:
"""Status of a workflow."""
is_deployed: bool
deployed_at: Optional[str] = None
is_published: bool = False
needs_redeployment: bool = False
@@ -296,7 +295,6 @@ class SimStudioClient:
return WorkflowStatus(
is_deployed=status_data.get('isDeployed', False),
deployed_at=status_data.get('deployedAt'),
is_published=status_data.get('isPublished', False),
needs_redeployment=status_data.get('needsRedeployment', False)
)
-2
View File
@@ -79,12 +79,10 @@ def test_workflow_status():
status = WorkflowStatus(
is_deployed=True,
deployed_at="2023-01-01T00:00:00Z",
is_published=False,
needs_redeployment=False
)
assert status.is_deployed is True
assert status.deployed_at == "2023-01-01T00:00:00Z"
assert status.is_published is False
assert status.needs_redeployment is False
-1
View File
@@ -157,7 +157,6 @@ interface WorkflowExecutionResult {
interface WorkflowStatus {
isDeployed: boolean;
deployedAt?: string;
isPublished: boolean;
needsRedeployment: boolean;
}
```
-1
View File
@@ -82,7 +82,6 @@ async function statusExample() {
const status = await client.getWorkflowStatus('your-workflow-id')
console.log('Status:', {
deployed: status.isDeployed,
published: status.isPublished,
needsRedeployment: status.needsRedeployment,
deployedAt: status.deployedAt,
})
-2
View File
@@ -72,7 +72,6 @@ describe('SimStudioClient', () => {
json: vi.fn().mockResolvedValue({
isDeployed: true,
deployedAt: '2023-01-01T00:00:00Z',
isPublished: false,
needsRedeployment: false,
}),
}
@@ -89,7 +88,6 @@ describe('SimStudioClient', () => {
json: vi.fn().mockResolvedValue({
isDeployed: false,
deployedAt: null,
isPublished: false,
needsRedeployment: true,
}),
}
-1
View File
@@ -22,7 +22,6 @@ export interface WorkflowExecutionResult {
export interface WorkflowStatus {
isDeployed: boolean
deployedAt?: string
isPublished: boolean
needsRedeployment: boolean
}