diff --git a/STARTER_ACCOUNT_WHITELIST.md b/STARTER_ACCOUNT_WHITELIST.md new file mode 100644 index 000000000..0274ad16c --- /dev/null +++ b/STARTER_ACCOUNT_WHITELIST.md @@ -0,0 +1,178 @@ +# Starter Account Whitelist System + +## Overview + +This feature implements an email-based whitelist system for controlling which users can receive starter virtual accounts. Unless a user's email is in the whitelist, they won't be able to get starter accounts. + +## How It Works + +### Database Schema + +A new table `starter_account_whitelist` stores whitelisted emails: + +```sql +CREATE TABLE "starter_account_whitelist" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "email" text NOT NULL UNIQUE, + "added_by" text NOT NULL REFERENCES "admins"("privy_did"), + "notes" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +``` + +### Behavior + +1. **Whitelist Check**: When a user signs up or requests starter accounts, their email is checked against the whitelist +2. **Case-Insensitive**: Emails are stored and compared in lowercase +3. **Admin-Only Management**: Only admins can add/remove emails from the whitelist +4. **Graceful Failure**: If email is not whitelisted, starter account creation silently skips (doesn't block user signup) + +### User Flow + +1. User signs up and registers a primary Safe +2. System extracts user's email from Privy (email auth, Google, etc.) +3. System checks if email exists in `starter_account_whitelist` +4. If whitelisted: Creates USD + EUR starter virtual accounts +5. If not whitelisted: Skips starter account creation, user proceeds normally + +## Admin Dashboard + +### Accessing the Whitelist Manager + +1. Navigate to `/admin` (requires admin privileges) +2. Click on "Starter Whitelist" tab +3. You'll see a list of all whitelisted emails + +### Adding an Email + +1. Click "Add Email" button +2. Enter email address +3. Optionally add notes (e.g., "VIP user", "Early adopter") +4. Click "Add to Whitelist" + +### Removing an Email + +1. Find the email in the list +2. Click the trash icon +3. Confirm deletion + +### Features + +- Real-time list of whitelisted emails +- Shows who added each email and when +- Optional notes field for context +- Search and filter capabilities (future enhancement) + +## Technical Implementation + +### Files Modified + +1. **Database**: + - `src/db/schema.ts` - Added `starterAccountWhitelist` table definition + - `drizzle/0113_amused_black_bird.sql` - Migration file + +2. **Backend**: + - `src/server/services/align-starter-accounts.ts` - Added whitelist check + - `src/server/routers/admin-router.ts` - Added TRPC procedures + - `src/server/routers/align-router.ts` - Pass user email + - `src/app/api/user/safes/register-primary/route.ts` - Pass user email + +3. **Frontend**: + - `src/components/admin/starter-whitelist-panel.tsx` - New whitelist UI + - `src/app/(public)/admin/page.tsx` - Integrated whitelist tab + +### API Endpoints (TRPC) + +```typescript +// List all whitelisted emails +api.admin.listStarterWhitelist.useQuery() + +// Add email to whitelist +api.admin.addToStarterWhitelist.useMutation({ + email: string, + notes?: string +}) + +// Remove email from whitelist +api.admin.removeFromStarterWhitelist.useMutation({ + id: string +}) +``` + +### Service Function + +```typescript +createStarterVirtualAccounts({ + userId: string, + workspaceId: string, + destinationAddress: string, + userEmail?: string // New parameter +}) +``` + +## Migration Guide + +### Development Environment + +The migration has already been generated: + +```bash +# Migration is auto-generated in drizzle/0113_amused_black_bird.sql +# To apply to dev database, restart the app +pnpm dev +``` + +### Production Deployment + +```bash +# Run migration on production database +pnpm --filter @zero-finance/web db:migrate:prod +``` + +## Security Considerations + +1. **Admin-Only Access**: All whitelist operations require admin privileges +2. **Email Validation**: Emails are validated using Zod schema +3. **Foreign Key Constraint**: `added_by` references `admins` table +4. **Audit Trail**: Tracks who added each email and when + +## Future Enhancements + +1. **Bulk Import**: Allow CSV upload of emails +2. **Expiration Dates**: Set time-limited whitelist entries +3. **Usage Tracking**: See which whitelisted emails have claimed accounts +4. **Email Verification**: Require email confirmation before granting access +5. **Regex Patterns**: Allow domain-based whitelisting (e.g., `*@company.com`) + +## Testing Checklist + +- [x] Database migration runs successfully +- [x] Admin can view whitelist +- [x] Admin can add emails +- [x] Admin can remove emails +- [x] Non-whitelisted user doesn't get starter accounts +- [x] Whitelisted user gets starter accounts +- [x] Email comparison is case-insensitive +- [x] UI shows proper error messages +- [x] TRPC procedures are protected by admin check + +## Troubleshooting + +### User not receiving starter accounts + +1. Check if email is in whitelist: Query `starter_account_whitelist` table +2. Verify email extraction: Check Privy user object for email field +3. Check logs: Look for "[Starter Accounts]" messages + +### Cannot add email to whitelist + +1. Verify you're logged in as admin +2. Check if email already exists (unique constraint) +3. Validate email format + +### Migration errors + +1. Ensure admins table exists first +2. Check database connection +3. Run migrations in order diff --git a/packages/web/drizzle/0113_amused_black_bird.sql b/packages/web/drizzle/0113_amused_black_bird.sql new file mode 100644 index 000000000..1a4518157 --- /dev/null +++ b/packages/web/drizzle/0113_amused_black_bird.sql @@ -0,0 +1,13 @@ +CREATE TABLE "starter_account_whitelist" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "email" text NOT NULL, + "added_by" text NOT NULL, + "notes" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "starter_account_whitelist_email_unique" UNIQUE("email") +); +--> statement-breakpoint +ALTER TABLE "user_requests" ALTER COLUMN "id" SET DEFAULT '49c03e92-18e5-41b6-b5db-6fe26a89a207';--> statement-breakpoint +ALTER TABLE "starter_account_whitelist" ADD CONSTRAINT "starter_account_whitelist_added_by_admins_privy_did_fk" FOREIGN KEY ("added_by") REFERENCES "public"."admins"("privy_did") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "starter_whitelist_email_idx" ON "starter_account_whitelist" USING btree ("email"); \ No newline at end of file diff --git a/packages/web/drizzle/meta/0113_snapshot.json b/packages/web/drizzle/meta/0113_snapshot.json new file mode 100644 index 000000000..5c888a540 --- /dev/null +++ b/packages/web/drizzle/meta/0113_snapshot.json @@ -0,0 +1,4657 @@ +{ + "id": "0b471720-87f1-4df7-b90e-975a17cfe9fc", + "prevId": "2df3a714-8f5a-40cb-8972-1e9fb7cbbf03", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.admins": { + "name": "admins", + "schema": "", + "columns": { + "privy_did": { + "name": "privy_did", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "added_by": { + "name": "added_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.allocation_strategies": { + "name": "allocation_strategies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_did": { + "name": "user_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "destination_safe_type": { + "name": "destination_safe_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "percentage": { + "name": "percentage", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_strategy_type_unique_idx": { + "name": "user_strategy_type_unique_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "destination_safe_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "allocation_strategies_workspace_idx": { + "name": "allocation_strategies_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "allocation_strategies_user_did_users_privy_did_fk": { + "name": "allocation_strategies_user_did_users_privy_did_fk", + "tableFrom": "allocation_strategies", + "tableTo": "users", + "columnsFrom": [ + "user_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auto_earn_configs": { + "name": "auto_earn_configs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_did": { + "name": "user_did", + "type": "varchar(66)", + "primaryKey": false, + "notNull": true + }, + "safe_address": { + "name": "safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "pct": { + "name": "pct", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_trigger": { + "name": "last_trigger", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_vault_address": { + "name": "auto_vault_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auto_earn_user_safe_unique_idx": { + "name": "auto_earn_user_safe_unique_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "safe_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auto_earn_workspace_idx": { + "name": "auto_earn_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chat_messages": { + "name": "chat_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "chat_id": { + "name": "chat_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "parts": { + "name": "parts", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "attachments": { + "name": "attachments", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "tool_name": { + "name": "tool_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tool_call_id": { + "name": "tool_call_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tool_result": { + "name": "tool_result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "chat_messages_chat_id_idx": { + "name": "chat_messages_chat_id_idx", + "columns": [ + { + "expression": "chat_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chat_messages_role_idx": { + "name": "chat_messages_role_idx", + "columns": [ + { + "expression": "role", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "chat_messages_chat_id_chats_id_fk": { + "name": "chat_messages_chat_id_chats_id_fk", + "tableFrom": "chat_messages", + "tableTo": "chats", + "columnsFrom": [ + "chat_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chats": { + "name": "chats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "share_path": { + "name": "share_path", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "chats_user_id_idx": { + "name": "chats_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chats_workspace_idx": { + "name": "chats_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "chats_share_path_idx": { + "name": "chats_share_path_idx", + "columns": [ + { + "expression": "share_path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "chats_user_id_users_privy_did_fk": { + "name": "chats_user_id_users_privy_did_fk", + "tableFrom": "chats", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "chats_share_path_unique": { + "name": "chats_share_path_unique", + "nullsNotDistinct": false, + "columns": [ + "share_path" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.companies": { + "name": "companies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "owner_privy_did": { + "name": "owner_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_address": { + "name": "payment_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preferred_network": { + "name": "preferred_network", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'solana'" + }, + "preferred_currency": { + "name": "preferred_currency", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'USDC'" + }, + "tax_id": { + "name": "tax_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "companies_owner_idx": { + "name": "companies_owner_idx", + "columns": [ + { + "expression": "owner_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "companies_workspace_idx": { + "name": "companies_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_clients": { + "name": "company_clients", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_company_id": { + "name": "client_company_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "company_clients_user_client_idx": { + "name": "company_clients_user_client_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "client_company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_clients_user_idx": { + "name": "company_clients_user_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_clients_workspace_idx": { + "name": "company_clients_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_clients_client_company_id_companies_id_fk": { + "name": "company_clients_client_company_id_companies_id_fk", + "tableFrom": "company_clients", + "tableTo": "companies", + "columnsFrom": [ + "client_company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_invite_links": { + "name": "company_invite_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "company_id": { + "name": "company_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "used_count": { + "name": "used_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + } + }, + "indexes": { + "company_invite_links_token_idx": { + "name": "company_invite_links_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_invite_links_company_idx": { + "name": "company_invite_links_company_idx", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_invite_links_workspace_idx": { + "name": "company_invite_links_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_invite_links_company_id_companies_id_fk": { + "name": "company_invite_links_company_id_companies_id_fk", + "tableFrom": "company_invite_links", + "tableTo": "companies", + "columnsFrom": [ + "company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "company_invite_links_token_unique": { + "name": "company_invite_links_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_members": { + "name": "company_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "company_id": { + "name": "company_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "company_members_company_user_idx": { + "name": "company_members_company_user_idx", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_members_user_idx": { + "name": "company_members_user_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "company_members_workspace_idx": { + "name": "company_members_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_members_company_id_companies_id_fk": { + "name": "company_members_company_id_companies_id_fk", + "tableFrom": "company_members", + "tableTo": "companies", + "columnsFrom": [ + "company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.earn_deposits": { + "name": "earn_deposits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_did": { + "name": "user_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "safe_address": { + "name": "safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "vault_address": { + "name": "vault_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "token_address": { + "name": "token_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "assets_deposited": { + "name": "assets_deposited", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "shares_received": { + "name": "shares_received", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "tx_hash": { + "name": "tx_hash", + "type": "varchar(66)", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deposit_percentage": { + "name": "deposit_percentage", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "apy_basis_points": { + "name": "apy_basis_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "asset_decimals": { + "name": "asset_decimals", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 6 + } + }, + "indexes": { + "earn_safe_address_idx": { + "name": "earn_safe_address_idx", + "columns": [ + { + "expression": "safe_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_vault_address_idx": { + "name": "earn_vault_address_idx", + "columns": [ + { + "expression": "vault_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_user_did_idx": { + "name": "earn_user_did_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_workspace_idx": { + "name": "earn_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "earn_deposits_user_did_users_privy_did_fk": { + "name": "earn_deposits_user_did_users_privy_did_fk", + "tableFrom": "earn_deposits", + "tableTo": "users", + "columnsFrom": [ + "user_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "earn_deposits_tx_hash_unique": { + "name": "earn_deposits_tx_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "tx_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.earn_vault_apy_snapshots": { + "name": "earn_vault_apy_snapshots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "vault_address": { + "name": "vault_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "chain_id": { + "name": "chain_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "apy_basis_points": { + "name": "apy_basis_points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "captured_at": { + "name": "captured_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "earn_vault_apy_snapshots_vault_idx": { + "name": "earn_vault_apy_snapshots_vault_idx", + "columns": [ + { + "expression": "vault_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_vault_apy_snapshots_vault_time_idx": { + "name": "earn_vault_apy_snapshots_vault_time_idx", + "columns": [ + { + "expression": "vault_address", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "captured_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.earn_withdrawals": { + "name": "earn_withdrawals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_did": { + "name": "user_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "safe_address": { + "name": "safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "vault_address": { + "name": "vault_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "token_address": { + "name": "token_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "assets_withdrawn": { + "name": "assets_withdrawn", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "shares_burned": { + "name": "shares_burned", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "tx_hash": { + "name": "tx_hash", + "type": "varchar(66)", + "primaryKey": false, + "notNull": true + }, + "user_op_hash": { + "name": "user_op_hash", + "type": "varchar(66)", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + } + }, + "indexes": { + "earn_withdrawals_safe_address_idx": { + "name": "earn_withdrawals_safe_address_idx", + "columns": [ + { + "expression": "safe_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_withdrawals_vault_address_idx": { + "name": "earn_withdrawals_vault_address_idx", + "columns": [ + { + "expression": "vault_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_withdrawals_user_did_idx": { + "name": "earn_withdrawals_user_did_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_withdrawals_workspace_idx": { + "name": "earn_withdrawals_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "earn_withdrawals_status_idx": { + "name": "earn_withdrawals_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "earn_withdrawals_user_did_users_privy_did_fk": { + "name": "earn_withdrawals_user_did_users_privy_did_fk", + "tableFrom": "earn_withdrawals", + "tableTo": "users", + "columnsFrom": [ + "user_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "earn_withdrawals_tx_hash_unique": { + "name": "earn_withdrawals_tx_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "tx_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.incoming_deposits": { + "name": "incoming_deposits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_did": { + "name": "user_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "safe_address": { + "name": "safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "tx_hash": { + "name": "tx_hash", + "type": "varchar(66)", + "primaryKey": false, + "notNull": true + }, + "from_address": { + "name": "from_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "token_address": { + "name": "token_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "block_number": { + "name": "block_number", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "swept": { + "name": "swept", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "swept_amount": { + "name": "swept_amount", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": false + }, + "swept_percentage": { + "name": "swept_percentage", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "swept_tx_hash": { + "name": "swept_tx_hash", + "type": "varchar(66)", + "primaryKey": false, + "notNull": false + }, + "swept_at": { + "name": "swept_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "incoming_deposits_safe_address_idx": { + "name": "incoming_deposits_safe_address_idx", + "columns": [ + { + "expression": "safe_address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "incoming_deposits_tx_hash_idx": { + "name": "incoming_deposits_tx_hash_idx", + "columns": [ + { + "expression": "tx_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "incoming_deposits_user_did_idx": { + "name": "incoming_deposits_user_did_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "incoming_deposits_workspace_idx": { + "name": "incoming_deposits_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "incoming_deposits_swept_idx": { + "name": "incoming_deposits_swept_idx", + "columns": [ + { + "expression": "swept", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "incoming_deposits_timestamp_idx": { + "name": "incoming_deposits_timestamp_idx", + "columns": [ + { + "expression": "timestamp", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "incoming_deposits_user_did_users_privy_did_fk": { + "name": "incoming_deposits_user_did_users_privy_did_fk", + "tableFrom": "incoming_deposits", + "tableTo": "users", + "columnsFrom": [ + "user_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "incoming_deposits_tx_hash_unique": { + "name": "incoming_deposits_tx_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "tx_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invoice_templates": { + "name": "invoice_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_data": { + "name": "template_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "usage_count": { + "name": "usage_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "invoice_templates_user_id_idx": { + "name": "invoice_templates_user_id_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "invoice_templates_name_idx": { + "name": "invoice_templates_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "invoice_templates_workspace_idx": { + "name": "invoice_templates_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invoice_templates_user_privy_did_users_privy_did_fk": { + "name": "invoice_templates_user_privy_did_users_privy_did_fk", + "tableFrom": "invoice_templates", + "tableTo": "users", + "columnsFrom": [ + "user_privy_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.offramp_transfers": { + "name": "offramp_transfers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "align_transfer_id": { + "name": "align_transfer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_to_send": { + "name": "amount_to_send", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destination_currency": { + "name": "destination_currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destination_payment_rails": { + "name": "destination_payment_rails", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "destination_bank_account_id": { + "name": "destination_bank_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "destination_bank_account_snapshot": { + "name": "destination_bank_account_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "deposit_amount": { + "name": "deposit_amount", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_token": { + "name": "deposit_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_network": { + "name": "deposit_network", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_address": { + "name": "deposit_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fee_amount": { + "name": "fee_amount", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quote_expires_at": { + "name": "quote_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "transaction_hash": { + "name": "transaction_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_op_hash": { + "name": "user_op_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "offramp_transfers_user_id_idx": { + "name": "offramp_transfers_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "offramp_transfers_workspace_idx": { + "name": "offramp_transfers_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "offramp_transfers_align_id_idx": { + "name": "offramp_transfers_align_id_idx", + "columns": [ + { + "expression": "align_transfer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "offramp_transfers_user_id_users_privy_did_fk": { + "name": "offramp_transfers_user_id_users_privy_did_fk", + "tableFrom": "offramp_transfers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "offramp_transfers_destination_bank_account_id_user_destination_bank_accounts_id_fk": { + "name": "offramp_transfers_destination_bank_account_id_user_destination_bank_accounts_id_fk", + "tableFrom": "offramp_transfers", + "tableTo": "user_destination_bank_accounts", + "columnsFrom": [ + "destination_bank_account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "offramp_transfers_align_transfer_id_unique": { + "name": "offramp_transfers_align_transfer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "align_transfer_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.onramp_transfers": { + "name": "onramp_transfers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "align_transfer_id": { + "name": "align_transfer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_currency": { + "name": "source_currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_rails": { + "name": "source_rails", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destination_network": { + "name": "destination_network", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destination_token": { + "name": "destination_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destination_address": { + "name": "destination_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_rails": { + "name": "deposit_rails", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_currency": { + "name": "deposit_currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_bank_account": { + "name": "deposit_bank_account", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "deposit_amount": { + "name": "deposit_amount", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deposit_message": { + "name": "deposit_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fee_amount": { + "name": "fee_amount", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "onramp_transfers_user_id_idx": { + "name": "onramp_transfers_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "onramp_transfers_workspace_idx": { + "name": "onramp_transfers_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "onramp_transfers_align_id_idx": { + "name": "onramp_transfers_align_id_idx", + "columns": [ + { + "expression": "align_transfer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "onramp_transfers_user_id_users_privy_did_fk": { + "name": "onramp_transfers_user_id_users_privy_did_fk", + "tableFrom": "onramp_transfers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "onramp_transfers_align_transfer_id_unique": { + "name": "onramp_transfers_align_transfer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "align_transfer_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.platform_totals": { + "name": "platform_totals", + "schema": "", + "columns": { + "token": { + "name": "token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "total_deposited": { + "name": "total_deposited", + "type": "numeric(78, 0)", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.shared_company_data": { + "name": "shared_company_data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "company_id": { + "name": "company_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "data_key": { + "name": "data_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data_value": { + "name": "data_value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "shared_company_data_company_key_idx": { + "name": "shared_company_data_company_key_idx", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "data_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "shared_company_data_workspace_idx": { + "name": "shared_company_data_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "shared_company_data_company_id_companies_id_fk": { + "name": "shared_company_data_company_id_companies_id_fk", + "tableFrom": "shared_company_data", + "tableTo": "companies", + "columnsFrom": [ + "company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.starter_account_whitelist": { + "name": "starter_account_whitelist", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "added_by": { + "name": "added_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "starter_whitelist_email_idx": { + "name": "starter_whitelist_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "starter_account_whitelist_added_by_admins_privy_did_fk": { + "name": "starter_account_whitelist_added_by_admins_privy_did_fk", + "tableFrom": "starter_account_whitelist", + "tableTo": "admins", + "columnsFrom": [ + "added_by" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "starter_account_whitelist_email_unique": { + "name": "starter_account_whitelist_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_classification_settings": { + "name": "user_classification_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prompt": { + "name": "prompt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_classification_settings_user_id_idx": { + "name": "user_classification_settings_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_classification_settings_priority_idx": { + "name": "user_classification_settings_priority_idx", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_classification_settings_enabled_idx": { + "name": "user_classification_settings_enabled_idx", + "columns": [ + { + "expression": "enabled", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_classification_settings_workspace_idx": { + "name": "user_classification_settings_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_classification_settings_user_id_users_privy_did_fk": { + "name": "user_classification_settings_user_id_users_privy_did_fk", + "tableFrom": "user_classification_settings", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_destination_bank_accounts": { + "name": "user_destination_bank_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "account_name": { + "name": "account_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bank_name": { + "name": "bank_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_holder_type": { + "name": "account_holder_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_holder_first_name": { + "name": "account_holder_first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "account_holder_last_name": { + "name": "account_holder_last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "account_holder_business_name": { + "name": "account_holder_business_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "city": { + "name": "city", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "street_line_1": { + "name": "street_line_1", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "street_line_2": { + "name": "street_line_2", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_type": { + "name": "account_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_number": { + "name": "account_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "routing_number": { + "name": "routing_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "iban_number": { + "name": "iban_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bic_swift": { + "name": "bic_swift", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_dest_bank_accounts_user_id_idx": { + "name": "user_dest_bank_accounts_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_dest_bank_accounts_workspace_idx": { + "name": "user_dest_bank_accounts_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_destination_bank_accounts_user_id_users_privy_did_fk": { + "name": "user_destination_bank_accounts_user_id_users_privy_did_fk", + "tableFrom": "user_destination_bank_accounts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_features": { + "name": "user_features", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "feature_name": { + "name": "feature_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "purchase_source": { + "name": "purchase_source", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'polar'" + }, + "purchase_reference": { + "name": "purchase_reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "activated_at": { + "name": "activated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_feature_unique_idx": { + "name": "user_feature_unique_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "feature_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_features_user_did_idx": { + "name": "user_features_user_did_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_features_workspace_idx": { + "name": "user_features_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_features_user_privy_did_users_privy_did_fk": { + "name": "user_features_user_privy_did_users_privy_did_fk", + "tableFrom": "user_features", + "tableTo": "users", + "columnsFrom": [ + "user_privy_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_funding_sources": { + "name": "user_funding_sources", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source_provider": { + "name": "source_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "align_virtual_account_id_ref": { + "name": "align_virtual_account_id_ref", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "account_tier": { + "name": "account_tier", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'full'" + }, + "owner_align_customer_id": { + "name": "owner_align_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_account_type": { + "name": "source_account_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_currency": { + "name": "source_currency", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_bank_name": { + "name": "source_bank_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_bank_address": { + "name": "source_bank_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_bank_beneficiary_name": { + "name": "source_bank_beneficiary_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_bank_beneficiary_address": { + "name": "source_bank_beneficiary_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_iban": { + "name": "source_iban", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_bic_swift": { + "name": "source_bic_swift", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_routing_number": { + "name": "source_routing_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_account_number": { + "name": "source_account_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_sort_code": { + "name": "source_sort_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_payment_rail": { + "name": "source_payment_rail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_payment_rails": { + "name": "source_payment_rails", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "destination_currency": { + "name": "destination_currency", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "destination_payment_rail": { + "name": "destination_payment_rail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "destination_address": { + "name": "destination_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_funding_sources_user_did_idx": { + "name": "user_funding_sources_user_did_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_funding_sources_workspace_idx": { + "name": "user_funding_sources_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_funding_sources_user_privy_did_users_privy_did_fk": { + "name": "user_funding_sources_user_privy_did_users_privy_did_fk", + "tableFrom": "user_funding_sources", + "tableTo": "users", + "columnsFrom": [ + "user_privy_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_invoice_preferences": { + "name": "user_invoice_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_privy_did": { + "name": "user_privy_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "default_seller_name": { + "name": "default_seller_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_seller_email": { + "name": "default_seller_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_seller_address": { + "name": "default_seller_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_seller_city": { + "name": "default_seller_city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_seller_postal_code": { + "name": "default_seller_postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_seller_country": { + "name": "default_seller_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_payment_terms": { + "name": "default_payment_terms", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_currency": { + "name": "default_currency", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_payment_type": { + "name": "default_payment_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_network": { + "name": "default_network", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_notes": { + "name": "default_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_terms": { + "name": "default_terms", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "profile_name": { + "name": "profile_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Default'" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_invoice_prefs_user_id_idx": { + "name": "user_invoice_prefs_user_id_idx", + "columns": [ + { + "expression": "user_privy_did", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_invoice_prefs_active_idx": { + "name": "user_invoice_prefs_active_idx", + "columns": [ + { + "expression": "is_active", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_invoice_prefs_workspace_idx": { + "name": "user_invoice_prefs_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_invoice_preferences_user_privy_did_users_privy_did_fk": { + "name": "user_invoice_preferences_user_privy_did_users_privy_did_fk", + "tableFrom": "user_invoice_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_privy_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_profiles": { + "name": "user_profiles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "privy_did": { + "name": "privy_did", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "payment_address": { + "name": "payment_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "primary_safe_address": { + "name": "primary_safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": false + }, + "business_name": { + "name": "business_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "default_wallet_id": { + "name": "default_wallet_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "skipped_or_completed_onboarding_stepper": { + "name": "skipped_or_completed_onboarding_stepper", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "is_insured": { + "name": "is_insured", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "insurance_activated_at": { + "name": "insurance_activated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_profiles_workspace_idx": { + "name": "user_profiles_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_profiles_default_wallet_id_user_wallets_id_fk": { + "name": "user_profiles_default_wallet_id_user_wallets_id_fk", + "tableFrom": "user_profiles", + "tableTo": "user_wallets", + "columnsFrom": [ + "default_wallet_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_profiles_privy_did_unique": { + "name": "user_profiles_privy_did_unique", + "nullsNotDistinct": false, + "columns": [ + "privy_did" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_requests": { + "name": "user_requests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "default": "'49c03e92-18e5-41b6-b5db-6fe26a89a207'" + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "company_id": { + "name": "company_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "sender_company_id": { + "name": "sender_company_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "recipient_company_id": { + "name": "recipient_company_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "wallet_address": { + "name": "wallet_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "currency_decimals": { + "name": "currency_decimals", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'db_pending'" + }, + "client": { + "name": "client", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "invoice_data": { + "name": "invoice_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_requests_workspace_idx": { + "name": "user_requests_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_requests_sender_company_id_companies_id_fk": { + "name": "user_requests_sender_company_id_companies_id_fk", + "tableFrom": "user_requests", + "tableTo": "companies", + "columnsFrom": [ + "sender_company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "user_requests_recipient_company_id_companies_id_fk": { + "name": "user_requests_recipient_company_id_companies_id_fk", + "tableFrom": "user_requests", + "tableTo": "companies", + "columnsFrom": [ + "recipient_company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_safes": { + "name": "user_safes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_did": { + "name": "user_did", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "safe_address": { + "name": "safe_address", + "type": "varchar(42)", + "primaryKey": false, + "notNull": true + }, + "safe_type": { + "name": "safe_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_earn_module_enabled": { + "name": "is_earn_module_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_safe_type_unique_idx": { + "name": "user_safe_type_unique_idx", + "columns": [ + { + "expression": "user_did", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "safe_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_safes_workspace_idx": { + "name": "user_safes_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_safes_user_did_users_privy_did_fk": { + "name": "user_safes_user_did_users_privy_did_fk", + "tableFrom": "user_safes", + "tableTo": "users", + "columnsFrom": [ + "user_did" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_wallets": { + "name": "user_wallets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "address": { + "name": "address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "network": { + "name": "network", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'gnosis'" + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_wallets_workspace_idx": { + "name": "user_wallets_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_wallets_address_unique": { + "name": "user_wallets_address_unique", + "nullsNotDistinct": false, + "columns": [ + "address" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "privy_did": { + "name": "privy_did", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "company_name": { + "name": "company_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "beneficiary_type": { + "name": "beneficiary_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "align_customer_id": { + "name": "align_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_provider": { + "name": "kyc_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_status": { + "name": "kyc_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'none'" + }, + "kyc_flow_link": { + "name": "kyc_flow_link", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "align_virtual_account_id": { + "name": "align_virtual_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_marked_done": { + "name": "kyc_marked_done", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "kyc_sub_status": { + "name": "kyc_sub_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_notification_sent": { + "name": "kyc_notification_sent", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "kyc_notification_status": { + "name": "kyc_notification_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "loops_contact_synced": { + "name": "loops_contact_synced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "user_role": { + "name": "user_role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'startup'" + }, + "contractor_invite_code": { + "name": "contractor_invite_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "primary_workspace_id": { + "name": "primary_workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "users_primary_workspace_idx": { + "name": "users_primary_workspace_idx", + "columns": [ + { + "expression": "primary_workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_align_customer_id_unique": { + "name": "users_align_customer_id_unique", + "nullsNotDistinct": false, + "columns": [ + "align_customer_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_invites": { + "name": "workspace_invites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "company_id": { + "name": "company_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false, + "default": "'member'" + }, + "share_inbox": { + "name": "share_inbox", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "share_company_data": { + "name": "share_company_data", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "add_as_safe_owner": { + "name": "add_as_safe_owner", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "used_at": { + "name": "used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "used_by": { + "name": "used_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_invites_token_idx": { + "name": "workspace_invites_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invites_workspace_idx": { + "name": "workspace_invites_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_invites_created_by_idx": { + "name": "workspace_invites_created_by_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_invites_workspace_id_workspaces_id_fk": { + "name": "workspace_invites_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_invites", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invites_company_id_companies_id_fk": { + "name": "workspace_invites_company_id_companies_id_fk", + "tableFrom": "workspace_invites", + "tableTo": "companies", + "columnsFrom": [ + "company_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "workspace_invites_created_by_users_privy_did_fk": { + "name": "workspace_invites_created_by_users_privy_did_fk", + "tableFrom": "workspace_invites", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "workspace_invites_used_by_users_privy_did_fk": { + "name": "workspace_invites_used_by_users_privy_did_fk", + "tableFrom": "workspace_invites", + "tableTo": "users", + "columnsFrom": [ + "used_by" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_invites_token_unique": { + "name": "workspace_invites_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_members": { + "name": "workspace_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "joined_at": { + "name": "joined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "workspace_members_workspace_user_idx": { + "name": "workspace_members_workspace_user_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_members_workspace_id_idx": { + "name": "workspace_members_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_members_user_id_idx": { + "name": "workspace_members_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_members_workspace_id_workspaces_id_fk": { + "name": "workspace_members_workspace_id_workspaces_id_fk", + "tableFrom": "workspace_members", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_members_user_id_users_privy_did_fk": { + "name": "workspace_members_user_id_users_privy_did_fk", + "tableFrom": "workspace_members", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_members_extended": { + "name": "workspace_members_extended", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_id": { + "name": "member_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "can_view_inbox": { + "name": "can_view_inbox", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "can_edit_expenses": { + "name": "can_edit_expenses", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "can_view_company_data": { + "name": "can_view_company_data", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_members_extended_member_id_workspace_members_id_fk": { + "name": "workspace_members_extended_member_id_workspace_members_id_fk", + "tableFrom": "workspace_members_extended", + "tableTo": "workspace_members", + "columnsFrom": [ + "member_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "align_customer_id": { + "name": "align_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_provider": { + "name": "kyc_provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_status": { + "name": "kyc_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'none'" + }, + "kyc_flow_link": { + "name": "kyc_flow_link", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_sub_status": { + "name": "kyc_sub_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kyc_marked_done": { + "name": "kyc_marked_done", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "kyc_notification_sent": { + "name": "kyc_notification_sent", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "kyc_notification_status": { + "name": "kyc_notification_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "align_virtual_account_id": { + "name": "align_virtual_account_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "beneficiary_type": { + "name": "beneficiary_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "company_name": { + "name": "company_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "workspace_type": { + "name": "workspace_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'business'" + } + }, + "indexes": { + "workspaces_align_customer_id_idx": { + "name": "workspaces_align_customer_id_idx", + "columns": [ + { + "expression": "align_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_kyc_status_idx": { + "name": "workspaces_kyc_status_idx", + "columns": [ + { + "expression": "kyc_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspaces_align_virtual_account_idx": { + "name": "workspaces_align_virtual_account_idx", + "columns": [ + { + "expression": "align_virtual_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspaces_created_by_users_privy_did_fk": { + "name": "workspaces_created_by_users_privy_did_fk", + "tableFrom": "workspaces", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "privy_did" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/web/drizzle/meta/_journal.json b/packages/web/drizzle/meta/_journal.json index 7e4e5fb69..08bccaecd 100644 --- a/packages/web/drizzle/meta/_journal.json +++ b/packages/web/drizzle/meta/_journal.json @@ -792,6 +792,13 @@ "when": 1760051342227, "tag": "0112_living_pet_avengers", "breakpoints": true + }, + { + "idx": 113, + "version": "7", + "when": 1761016732653, + "tag": "0113_amused_black_bird", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/web/src/app/(public)/admin/page.tsx b/packages/web/src/app/(public)/admin/page.tsx index 42566ac42..3eb4deb15 100644 --- a/packages/web/src/app/(public)/admin/page.tsx +++ b/packages/web/src/app/(public)/admin/page.tsx @@ -5,6 +5,7 @@ import { usePrivy } from '@privy-io/react-auth'; import AdminPanel from '@/components/admin/admin-panel'; import KycKanbanBoard from '@/components/admin/kyc-kanban-board'; import WorkspacesPanel from '@/components/admin/workspaces-panel'; +import StarterWhitelistPanel from '@/components/admin/starter-whitelist-panel'; import { Button } from '@/components/ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { api } from '@/trpc/react'; @@ -22,6 +23,7 @@ import { RefreshCw, ShieldAlert, Building2, + ListFilter, } from 'lucide-react'; import { Dialog, @@ -34,7 +36,7 @@ import { export default function AdminPage() { const { user, authenticated, login } = usePrivy(); const [activeView, setActiveView] = useState< - 'workspaces' | 'table' | 'kanban' + 'workspaces' | 'table' | 'kanban' | 'whitelist' >('workspaces'); const [isSyncing, setIsSyncing] = useState(false); @@ -195,7 +197,7 @@ export default function AdminPage() { - setActiveView(v as 'workspaces' | 'table' | 'kanban') + setActiveView(v as 'workspaces' | 'table' | 'kanban' | 'whitelist') } > @@ -211,6 +213,10 @@ export default function AdminPage() { KYC Kanban + + + Starter Whitelist + @@ -229,6 +235,10 @@ export default function AdminPage() { onRefresh={refetchUsers} /> + + + + diff --git a/packages/web/src/app/api/user/safes/register-primary/route.ts b/packages/web/src/app/api/user/safes/register-primary/route.ts index 353b8a480..bd2ddf956 100644 --- a/packages/web/src/app/api/user/safes/register-primary/route.ts +++ b/packages/web/src/app/api/user/safes/register-primary/route.ts @@ -111,10 +111,14 @@ export async function POST(request: NextRequest) { .returning(); // 7. Create starter virtual accounts for instant deposits (non-blocking) + const privyUser = await privyClient.getUser(privyDid); + const userEmail = privyUser.email?.address || privyUser.google?.email; + createStarterVirtualAccounts({ userId: privyDid, workspaceId, destinationAddress: safeAddress, + userEmail, }).catch((error) => { console.error( '[Safe Registration] Failed to create starter accounts:', diff --git a/packages/web/src/components/admin/starter-whitelist-panel.tsx b/packages/web/src/components/admin/starter-whitelist-panel.tsx new file mode 100644 index 000000000..941726482 --- /dev/null +++ b/packages/web/src/components/admin/starter-whitelist-panel.tsx @@ -0,0 +1,235 @@ +'use client'; + +import { useState } from 'react'; +import { api } from '@/trpc/react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog'; +import { Label } from '@/components/ui/label'; +import { Badge } from '@/components/ui/badge'; +import { toast } from 'sonner'; +import { Plus, Trash2, RefreshCw, Mail } from 'lucide-react'; +import { format } from 'date-fns'; + +export default function StarterWhitelistPanel() { + const [isAddDialogOpen, setIsAddDialogOpen] = useState(false); + const [email, setEmail] = useState(''); + const [notes, setNotes] = useState(''); + + const { + data: whitelist, + isLoading, + refetch, + } = api.admin.listStarterWhitelist.useQuery(); + + const addMutation = api.admin.addToStarterWhitelist.useMutation({ + onSuccess: () => { + toast.success('Email added to whitelist'); + refetch(); + setIsAddDialogOpen(false); + setEmail(''); + setNotes(''); + }, + onError: (error) => { + toast.error(error.message || 'Failed to add email'); + }, + }); + + const removeMutation = api.admin.removeFromStarterWhitelist.useMutation({ + onSuccess: () => { + toast.success('Email removed from whitelist'); + refetch(); + }, + onError: (error) => { + toast.error(error.message || 'Failed to remove email'); + }, + }); + + const handleAdd = () => { + if (!email.trim()) { + toast.error('Email is required'); + return; + } + addMutation.mutate({ + email: email.trim(), + notes: notes.trim() || undefined, + }); + }; + + const handleRemove = (id: string) => { + if ( + confirm('Are you sure you want to remove this email from the whitelist?') + ) { + removeMutation.mutate({ id }); + } + }; + + return ( + + +
+
+ Starter Account Whitelist + + Manage email addresses allowed to receive starter virtual accounts + +
+
+ + + + + + + + Add Email to Whitelist + + Users with this email will be able to receive starter + virtual accounts + + +
+
+ + setEmail(e.target.value)} + /> +
+
+ +