Compare commits

...
Author SHA1 Message Date
Brandon Thomas a569947608 cleanup 2026-03-05 21:20:22 -05:00
Brandon Thomas 9d66a880f9 codegen 2026-03-05 21:02:56 -05:00
Brandon Thomas 7c2b0f310e Handler to record tracking data 2026-03-05 21:01:51 -05:00
Brandon Thomas d374317a77 one more alter statement for tracking (this is to thwart abuse) (#1106)
Without these I won't know if someone is spamming us with fraudulent
data
2026-03-05 20:20:18 -05:00
Brandon Thomas f342befb0b user signup referrer (#1105)
see last PR
2026-03-05 20:07:38 -05:00
Brandon Thomas 13d1afd88d schema change: find out how users find us (#1104)
We're totally blind. Google Analytics helps a little bit, but we need to
know which communities find ArtCraft the most valuable. (Am I wasting my
time posting to Reddit?)
2026-03-05 19:56:55 -05:00
bflatastic 135dea926b viewer 3d fixed on artcraft-website media page 2026-03-06 02:08:51 +07:00
Brandon Thomas 4f68100c8f support handler to add balances to accounts (#1103) 2026-03-05 10:35:26 -05:00
Brandon Thomas 908f5cd3d6 support endpoints for looking up payments entities (#1102)
This will make support and issuing refunds easier
2026-03-05 10:01:15 -05:00
Brandon Thomas 5a57e48fcb Bt modify mod user lookup (#1101) 2026-03-05 09:38:00 -05:00
Brandon Thomas 69666c2646 rename pool acquire variant to be better (#1100) 2026-03-05 09:20:29 -05:00
Brandon Thomas 4ed8b2111b list wallet ledger entries for support (#1099) 2026-03-05 09:15:52 -05:00
Brandon Thomas d0fe9e1676 list user wallets for support (#1098) 2026-03-05 08:51:38 -05:00
Brandon Thomas d455056c61 moderator list user jobs handler (for oncall support) (#1097)
Helps us quickly find issues with user jobs so we can unstick jobs,
issue refunds, etc.
2026-03-05 08:16:25 -05:00
Brandon Thomas f17388c9de more moderator handlers (#1096) 2026-03-05 07:18:27 -05:00
Brandon Thomas 7665a07227 admin dashboard cors (#1095) 2026-03-05 06:51:42 -05:00
Brandon Thomas 6dc55c1b62 moderator user lookup (#1094) 2026-03-05 06:40:40 -05:00
Brandon Thomas 0d565563b2 add missing api docs (#1093) 2026-03-05 05:55:03 -05:00
bflatastic 0125539cd4 reduce credits modal padding 2026-03-04 23:35:49 +07:00
Brandon Thomas f141434821 Bump Artcraft to 0.12.0 2026-03-04 09:55:31 -05:00
Brandon Thomas af12616426 Add Nano Banana 2 and Seedream 5 Lite to the app (#1089) 2026-03-04 09:55:00 -05:00
Brandon Thomas 62c5836176 fix compile error - forgot enum values 2026-03-04 09:25:41 -05:00
Brandon Thomas 520117d5d3 Add new models: Seedream 5 Lite, Nano Banana 2 (#1088) 2026-03-04 09:19:34 -05:00
Brandon Thomas 2e23c0c1b4 refactor: move fal webhook client bindings into sub module 2026-03-04 05:51:08 -05:00
Brandon Thomas cd76b7c87f fix pricing data handler 2026-03-04 05:35:25 -05:00
Brandon Thomas 668300d280 port the flux models to the artcraft router (via artcraft API) (#1087) 2026-03-04 04:52:23 -05:00
BFlat 1650fff9dc bug fix: aspect ratio picker options stuck 2026-03-04 16:45:42 +07:00
BFlat 91a4fa8da0 credits and subscription states to show properly after login/logout 2026-03-04 16:17:59 +07:00
Brandon Thomas 621d404992 port gpt-image-1.5 and nano banana to artcraft_router (#1086) 2026-03-04 03:41:52 -05:00
Brandon Thomas 96c751e038 add seedream 4/4.5 to artcraft_router (#1085) 2026-03-03 19:10:05 -05:00
Brandon Thomas 4c1eb5fce1 add prompt context items (video references) to Seedance 2.0 2026-03-03 18:01:06 -05:00
BFlat 2a2e1ddf30 failed tasks inside task queue and image generation session (#1084)
- failed tasks to show in image generation session view
- failed tasks now show in task queue dropdown
- completed and failed tasks clearable on "clear all" click
- styling updates
2026-03-04 00:21:09 +07:00
Brandon Thomas 367f4fb675 handle tauri jobs failure; frontend events (#1083) 2026-03-03 11:11:34 -05:00
Brandon Thomas 074ae52190 simulate job failures with a test prompt to flux-1 dev (#1081) 2026-03-03 10:03:19 -05:00
bflatastic 77297c7a36 gallery loading skeleton gap fix 2026-03-03 13:55:06 +07:00
BFlat 0337e64f9d library performance fixes (#1080)
## Library/Gallery Modal Improvements

### Performance
- Library items are cached so reopening the modal is instant instead of
loading from scratch every time
- Only visible sections are rendered - off-screen groups are swapped out
as you scroll, keeping things smooth even with lots of media
- Username session is cached to skip a redundant API call on every open

### UX
- Replaced loading spinner with a skeleton grid placeholder
- New items from completed generations appear at the top without wiping
the library
- Library auto-refreshes when a generation finishes (if open)
- Refresh icon spins while refreshing
2026-03-03 11:34:43 +07:00
BFlat 7ee421cfbe open reference image as media (#1079) 2026-03-03 01:38:12 +07:00
Brandon Thomas cb2f43cc43 bump website link (fix) 2026-03-02 12:43:17 -05:00
Brandon Thomas 20d4c9a9e7 bump website links 2026-03-02 12:38:55 -05:00
bflatastic 711078a4e4 3d pages button center fix 2026-03-02 23:48:17 +07:00
Brandon Thomas d45b82109d script for handling oncall scenarios where the user has duplicate accounts (#1078) 2026-03-02 11:05:03 -05:00
Brandon Thomas e5bd4b2577 bump artcraft 0.10.0 -> 0.11.0 2026-03-02 09:22:37 -05:00
bflatastic 841a44d923 lightbox modal next/prev video not changing bug fix 2026-03-02 19:42:04 +07:00
bflatastic 5ac0088b47 added model name mappings and generation count cost estimate 2026-03-02 19:39:05 +07:00
Brandon Thomas 3654676a13 Fix netlify docs (#1077) 2026-03-02 07:11:17 -05:00
Brandon Thomas 748fd316c1 show NBP cost estimates in artcraft (#1076) 2026-03-02 06:05:14 -05:00
Brandon Thomas aab8cbdfe1 NBP via artcraft_router in Tauri; image cost estimates in tauri (#1075) 2026-03-02 05:13:23 -05:00
Brandon Thomas bc91785628 fix compile error 2026-03-02 02:52:16 -05:00
Brandon Thomas d9f5e0e78b model router: fal nbp (#1074)
we'll soon be able to support fal API keys and cost estimates for Nano
Banana Pro

- NBP cost estimates
- NBP at ArtCraft
- NBP at FAL
2026-03-01 23:48:28 -05:00
bflatastic 428f7c5c7a update tp pricing 2026-03-02 00:11:27 +07:00
bflatastic 3b6a30bb52 pricing page update 2026-03-01 22:26:25 +07:00
Brandon Thomas 66d58660fb image model router with nano banana pro (#1073) 2026-03-01 04:58:50 -05:00
Brandon Thomas f828cd2980 refactor how router plans are built 2026-03-01 02:38:34 -05:00
Brandon Thomas 052949e012 move package 2026-03-01 02:26:06 -05:00
Brandon Thomas 6d8c0fe381 rename storyteller_client -> artcraft_client 2026-03-01 02:13:44 -05:00
Brandon Thomas a18042d8e0 bump artcraft version -> 0.10.0 2026-03-01 01:36:36 -05:00
bflatastic 2992902c8e credits icon update, buy credits modal restyled 2026-03-01 12:37:44 +07:00
BFlat 08ceb5fb08 logo removal, tooltip/menu fixes, added center icon (#1071)
### UI Refinements: Topbar, Menu, and Tooltips
- **Top bar organization:** Removed the extra logo from the top bar and
added the Artcraft icon to the center text for a cleaner layout.
- **Menu interaction:** Improved the behavior of the menu icon selector
so that confusing tooltips no longer appear when the menu is temporarily
disabled (e.g., during product switching).
- **Tooltip positioning:** Fixed an issue where tooltips were
occasionally extending beyond the edges of the screen, ensuring they now
stay fully visible.
2026-03-01 12:21:37 +07:00
Brandon Thomas 28beaab2c5 label as 0.9.x 2026-02-28 08:30:33 -05:00
99592a1bff credits usage UI (#1053)
- shows credits to be deducted on generate buttons
- credits usage modal to show costs in detail (toggleable from bottom
right)

Do not merge. Awaiting backend cost calculation implementation.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-02-28 08:27:44 -05:00
Brandon Thomas e600980b20 tauri controller for cost estimation (#1067)
We can add caching to this later.
2026-02-28 06:58:58 -05:00
Brandon Thomas 159e8796ea pricing updates 2026-02-28 06:02:39 -05:00
Brandon Thomas 6d9cd01464 cost estimator endpoint (#1065) 2026-02-28 00:29:09 -05:00
BFlat 90b8e89c61 task queue to show estimated time, seedance 2 progress time adjustmen… (#1064)
…t, model name mapping
2026-02-28 02:14:33 +07:00
Brandon Thomas c00d6c62ca Refund failed Seedance 2 Pro generations, Fix Seedance 2 client (#1061) 2026-02-27 02:02:54 -05:00
BFlat e8d88ca318 lightbox navigation and performance updates (#1059)
**Lightbox & Gallery Navigation Improvements**
- Added prev/next navigation buttons to lightbox (hover-visible arrows
on left/right of image)
- Added arrow key (←/→) keyboard navigation between gallery items in
lightbox
- Gallery builds a flat ordered item list to power sequential lightbox
navigation
- Debounced prompt/batch API calls (180ms) to prevent spam when rapidly
navigating
- Stale in-flight responses are cancelled so wrong data never flashes
- Added shimmer loading skeletons for prompt, reference images, and
generation details
- Removed focus outlines on nav buttons and modal when using arrow keys
- Fixed toggleBulkSelect used-before-declaration error in gallery modal
- Added display name for flux_dev_juggernaut
2026-02-25 23:09:44 -08:00
bflatastic cbf83ac2dd bulk select thumbnails fixes 2026-02-26 13:03:02 +07:00
bflatastic ce91aa2485 pricing text update and social icons bug fix 2026-02-26 00:26:20 +07:00
Brandon Thomas 46c73b08bd fix seedance api (#1057) 2026-02-25 06:58:26 +07:00
Brandon Thomas 73b17b2005 fix seedance api break (#1056) 2026-02-25 06:24:31 +07:00
Brandon Thomas b3ae7e44cc Bt fix seedance api (#1055) 2026-02-25 05:33:38 +07:00
Brandon Thomas c466c68c33 bump artcraft 0.7 -> 0.8 2026-02-25 05:14:46 +07:00
Brandon Thomas 74e1150f3c log hostnames 2026-02-25 04:52:43 +07:00
BFlatandBrandon Thomas 3e0bf8ebfd more controls for seedance 2.0 (#1052)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-02-25 04:21:52 +07:00
Brandon Thomas f36a5d5e02 model router (#1054)
This is the new middleware I'll use for model routing.
2026-02-24 21:04:57 +07:00
Brandon Thomas 9545dba684 bump github download links on website (#1051) 2026-02-23 10:09:34 +07:00
Brandon Thomas 9506885529 seedance 2026-02-22 14:43:45 +07:00
Brandon Thomas ed6dd542d3 fix wreq compression (#1050)
this was silently broken across all calls - yikes
2026-02-22 13:01:39 +07:00
Brandon Thomas 21aba384a6 artcraft 0.7.0 2026-02-22 10:18:56 +07:00
Brandon Thomas 895a38cd04 job 2026-02-22 10:06:24 +07:00
Brandon Thomas f947c78bf5 fix openssl build issues (again) (#1049) 2026-02-22 09:41:25 +07:00
617 changed files with 22031 additions and 3684 deletions
+3
View File
@@ -68,6 +68,9 @@ __pycache__/
# We use diesel for DB migrations only. We don't care about its codgen.
_ignored_schema.rs
# Diesel lock file
.diesel_lock
# AI Chat Sidecar has its own schema managed by diesel, but we don't care for diesel codegen.
crates/programs/aichatbot-sidecar/_ignored_schema.rs
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE wallets\nSET\n banked_credits = ?,\n version = version + 1\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "01f6369e0ab7b0fa5b95b4595827dcf15897f3b50cce5b1dc421101b157b7008"
}
@@ -0,0 +1,102 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n j.status as `job_status: enums::common::job_status_plus::JobStatusPlus`,\n j.failure_reason as job_failure_reason,\n wle.credits_delta,\n wle.maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n j.on_success_result_entity_token as `on_success_result_media_token: tokens::tokens::media_files::MediaFileToken`,\n j.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n wle.token as `wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n wle.entry_type as `wallet_ledger_entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`\nFROM generic_inference_jobs as j\nLEFT OUTER JOIN users as u\n ON j.maybe_creator_user_token = u.token\nLEFT OUTER JOIN wallet_ledger_entries as wle\n ON wle.maybe_entity_ref = j.token\nWHERE u.token = ?\nORDER BY j.id DESC\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "job_status: enums::common::job_status_plus::JobStatusPlus",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 76
}
},
{
"ordinal": 1,
"name": "job_failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 2,
"name": "credits_delta",
"type_info": {
"type": "Long",
"flags": "",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 3,
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "on_success_result_media_token: tokens::tokens::media_files::MediaFileToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "wallet_ledger_entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
"type_info": {
"type": "VarString",
"flags": "BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
true,
true,
true,
true,
false,
true,
true
]
},
"hash": "0757d81ba153b2ad2df25df3dd92b655ef08b95f5f83251bf3573f9be3a9f8d1"
}
@@ -1,12 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO users\nSET\n token = ?,\n \n is_temporary = ?,\n \n username = ?,\n display_name = ?,\n\n username_is_generated = ?,\n username_is_not_customized = ?,\n\n email_address = ?,\n email_gravatar_hash = ?,\n\n email_confirmed = FALSE,\n email_confirmed_by_google = ?,\n email_is_synthetic = ?,\n \n was_eagerly_provisioned = ?,\n\n profile_markdown = ?,\n profile_rendered_html = ?,\n user_role_slug = ?,\n\n password_hash = ?,\n is_without_password = ?,\n\n maybe_feature_flags = ?,\n\n ip_address_creation = ?,\n ip_address_last_login = ?,\n ip_address_last_update = ?,\n\n maybe_source = ?,\n\n maybe_signup_method = ?\n ",
"query": "\nINSERT INTO users\nSET\n token = ?,\n \n is_temporary = ?,\n \n username = ?,\n display_name = ?,\n\n username_is_generated = ?,\n username_is_not_customized = ?,\n\n email_address = ?,\n email_gravatar_hash = ?,\n\n email_confirmed = FALSE,\n email_confirmed_by_google = ?,\n email_is_synthetic = ?,\n \n was_eagerly_provisioned = ?,\n\n profile_markdown = ?,\n profile_rendered_html = ?,\n user_role_slug = ?,\n\n password_hash = ?,\n is_without_password = ?,\n\n maybe_feature_flags = ?,\n\n ip_address_creation = ?,\n ip_address_last_login = ?,\n ip_address_last_update = ?,\n\n maybe_source = ?,\n\n maybe_signup_method = ?,\n\n maybe_referral_url = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 22
"Right": 23
},
"nullable": []
},
"hash": "56746bcb993cb33f5492f401ce4fc3fd44d91fed660c2f106cb22e482dffa740"
"hash": "08996721482fe897c2721298c04cf0eba5fcf1d04d57397b8afab3dd59feaa8c"
}
@@ -0,0 +1,80 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n user_subscriptions.subscription_namespace as `subscription_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n user_subscriptions.maybe_stripe_subscription_id,\n users.token as `user_token: tokens::tokens::users::UserToken`,\n users.email_address,\n users.username,\n users.display_name\nFROM user_subscriptions\nINNER JOIN users ON users.token = user_subscriptions.user_token\nWHERE\n user_subscriptions.maybe_stripe_customer_id = ?\n AND user_subscriptions.deleted_at IS NULL\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nORDER BY user_subscriptions.created_at DESC\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "subscription_namespace: enums::common::payments_namespace::PaymentsNamespace",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "maybe_stripe_subscription_id",
"type_info": {
"type": "VarString",
"flags": "UNIQUE_KEY | BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 2,
"name": "user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "email_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 4,
"name": "username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 5,
"name": "display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
true,
false,
false,
false,
false
]
},
"hash": "3390084f700ef2444691a02c691a59ccdd66bc8b096547e89c68b58b04dd44e4"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 14
},
"nullable": []
},
"hash": "33aa8a1cf85bf1b8b68f4e2ab46541f25d7e8bb5eeb503c5ec14cb5e115f69ce"
}
@@ -0,0 +1,102 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w.token as `token: tokens::tokens::wallets::WalletToken`,\n w.wallet_namespace as `wallet_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n w.owner_user_token as `owner_user_token: tokens::tokens::users::UserToken`,\n w.banked_credits as `banked_credits: u32`,\n w.monthly_credits as `monthly_credits: u32`,\n w.version,\n w.created_at as `created_at: DateTime<Utc>`,\n w.updated_at as `updated_at: DateTime<Utc>`\nFROM wallets as w\nWHERE w.token = ?\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::wallets::WalletToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "wallet_namespace: enums::common::payments_namespace::PaymentsNamespace",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "owner_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "banked_credits: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 4,
"name": "monthly_credits: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 5,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 6,
"name": "created_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 7,
"name": "updated_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "35b09082ebb923c8c3191eaee8553b7c3badbd9152ee43999f7c8ff1a6410fe9"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nUPDATE wallet_ledger_entries\nSET\n is_refunded = TRUE,\n maybe_linked_refund_ledger_token = ?\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "6701a7adad65bc351e4600dad3ebf0f5dbdefa7dc9a0f890790cfaf368bf572d"
}
@@ -0,0 +1,91 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n w.token as `token: tokens::tokens::wallets::WalletToken`,\n w.wallet_namespace as `wallet_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n w.banked_credits as `banked_credits: u32`,\n w.monthly_credits as `monthly_credits: u32`,\n w.version,\n w.created_at as `created_at: DateTime<Utc>`,\n w.updated_at as `updated_at: DateTime<Utc>`\nFROM wallets as w\nWHERE w.owner_user_token = ?\nORDER BY w.id DESC\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::wallets::WalletToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "wallet_namespace: enums::common::payments_namespace::PaymentsNamespace",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "banked_credits: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 3,
"name": "monthly_credits: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 4,
"name": "version",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 5,
"name": "created_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 6,
"name": "updated_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "69b6e933ad400bc574204de301dde6748d2a1723f47c12e86afc05033a60d3a2"
}
@@ -0,0 +1,146 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n wallet_token as `wallet_token: tokens::tokens::wallets::WalletToken`,\n entry_type as `entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`,\n maybe_entity_ref,\n credits_delta,\n banked_credits_before as `banked_credits_before: u32`,\n banked_credits_after as `banked_credits_after: u32`,\n monthly_credits_before as `monthly_credits_before: u32`,\n monthly_credits_after as `monthly_credits_after: u32`,\n created_at as `created_at: DateTime<Utc>`,\n is_refunded as `is_refunded: bool`,\n maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`\nFROM wallet_ledger_entries\nWHERE wallet_token = ?\nORDER BY id DESC\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "wallet_token: tokens::tokens::wallets::WalletToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "maybe_entity_ref",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 4,
"name": "credits_delta",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 5,
"name": "banked_credits_before: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 6,
"name": "banked_credits_after: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "monthly_credits_before: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "monthly_credits_after: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 9,
"name": "created_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 10,
"name": "is_refunded: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 11,
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
false,
false,
false,
false,
false,
false,
false,
true
]
},
"hash": "7f874f4ac43d8c66e3ea8cb2fb56f57b93047355dd9faee4df48799f6d1be00a"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\n INSERT INTO web_referrals (\n url,\n domain,\n utm_source,\n utm_medium,\n utm_campaign,\n ip_address,\n anonymous_visitor_token\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 7
},
"nullable": []
},
"hash": "80f73702374593c141d183d86bd8af73d37fd7118914d0ba12a02f53c1b84c78"
}
@@ -0,0 +1,201 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.username = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 2,
"name": "display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "username_is_generated: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 4,
"name": "is_temporary: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 5,
"name": "username_is_not_customized: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 6,
"name": "email_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 7,
"name": "email_confirmed: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 8,
"name": "email_is_synthetic: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 9,
"name": "is_without_password: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 10,
"name": "ip_address_creation",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 11,
"name": "ip_address_last_login",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "email_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "is_banned: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 15,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 16,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "97599bdc5467b8750d2546cc6f78457c26d93c3be52921ad9b3531fd88498194"
}
@@ -0,0 +1,135 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n entry_type as `entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`,\n maybe_entity_ref,\n credits_delta,\n banked_credits_before as `banked_credits_before: u32`,\n banked_credits_after as `banked_credits_after: u32`,\n monthly_credits_before as `monthly_credits_before: u32`,\n monthly_credits_after as `monthly_credits_after: u32`,\n is_refunded as `is_refunded: bool`,\n maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n created_at as `created_at: DateTime<Utc>`\nFROM wallet_ledger_entries\nWHERE token = ?\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "maybe_entity_ref",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 3,
"name": "credits_delta",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 4,
"name": "banked_credits_before: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 5,
"name": "banked_credits_after: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 6,
"name": "monthly_credits_before: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "monthly_credits_after: u32",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 8,
"name": "is_refunded: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 9,
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "created_at: DateTime<Utc>",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
true,
false,
false,
false,
false,
false,
false,
true,
false
]
},
"hash": "9c28e9f8f163407755acaca1fb4a72849679b6bf98b8c87e1761200300111232"
}
@@ -0,0 +1,102 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n wallet_token as `wallet_token: tokens::tokens::wallets::WalletToken`,\n entry_type,\n is_refunded as `is_refunded: bool`,\n credits_delta,\n banked_credits_before,\n banked_credits_after,\n monthly_credits_before,\n monthly_credits_after\nFROM wallet_ledger_entries\nWHERE token = ?\nLIMIT 1\nFOR UPDATE\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "wallet_token: tokens::tokens::wallets::WalletToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "entry_type",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "is_refunded: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 3,
"name": "credits_delta",
"type_info": {
"type": "Long",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 11
}
},
{
"ordinal": 4,
"name": "banked_credits_before",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 5,
"name": "banked_credits_after",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 6,
"name": "monthly_credits_before",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
},
{
"ordinal": 7,
"name": "monthly_credits_after",
"type_info": {
"type": "Long",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 10
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "a7365998006f4d40ad26efb42e6958a7aed689562a4c5b8c91cbe0033d0270e7"
}
@@ -1,6 +1,6 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n jobs.maybe_external_third_party_id as `order_id`,\n jobs.maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n jobs.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n jobs.creator_ip_address,\n jobs.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`\n\nFROM generic_inference_jobs as jobs\n\nWHERE jobs.maybe_external_third_party = ?\n AND jobs.status NOT IN ('complete_success', 'complete_failure')\n AND jobs.maybe_external_third_party_id IS NOT NULL\n\nLIMIT 25000\n ",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n jobs.maybe_external_third_party_id as `order_id`,\n jobs.maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n jobs.maybe_creator_anonymous_visitor_token as `maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken`,\n jobs.creator_ip_address,\n jobs.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`,\n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n jobs.maybe_wallet_ledger_entry_token as `maybe_wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`\n\nFROM generic_inference_jobs as jobs\n\nWHERE jobs.maybe_external_third_party = ?\n AND jobs.status NOT IN ('complete_success', 'complete_failure')\n AND jobs.maybe_external_third_party_id IS NOT NULL\n\nLIMIT 25000\n ",
"describe": {
"columns": [
{
@@ -72,6 +72,16 @@
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 7,
"name": "maybe_wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
@@ -84,8 +94,9 @@
true,
false,
false,
true,
true
]
},
"hash": "ca96942d8214edb84f163cf40131ceed873209e86718054e1502219fc81d2dc6"
"hash": "cb33fd483f0fef7ec2a1f5950218f312a19e38c7971b88db949ccaa05bf7b7c4"
}
@@ -0,0 +1,201 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.email_address = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 2,
"name": "display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "username_is_generated: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 4,
"name": "is_temporary: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 5,
"name": "username_is_not_customized: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 6,
"name": "email_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 7,
"name": "email_confirmed: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 8,
"name": "email_is_synthetic: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 9,
"name": "is_without_password: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 10,
"name": "ip_address_creation",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 11,
"name": "ip_address_last_login",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "email_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "is_banned: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 15,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 16,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "d023eb33c9a06f8b07b1e5d1e255dbb730244bbd764a49d519473e50751a3ddc"
}
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_wallet_ledger_entry_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 15
},
"nullable": []
},
"hash": "ee228ab4a079fde6b3683b6cde2a2384d3def27a5d09baa5caf00a521d5d2bcd"
}
@@ -0,0 +1,201 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.token = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "username",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 2,
"name": "display_name",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "username_is_generated: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 4,
"name": "is_temporary: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 5,
"name": "username_is_not_customized: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 6,
"name": "email_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 7,
"name": "email_confirmed: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 8,
"name": "email_is_synthetic: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 9,
"name": "is_without_password: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 10,
"name": "ip_address_creation",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 11,
"name": "ip_address_last_login",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 12,
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "email_gravatar_hash",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "is_banned: bool",
"type_info": {
"type": "Tiny",
"flags": "NOT_NULL",
"char_set": 63,
"max_size": 1
}
},
{
"ordinal": 15,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 16,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "fd92483d9f1849d5b7f04076446fa98688fec46bb1cba20d005bc8dad4d1c093"
}
Generated
+316 -134
View File
@@ -548,7 +548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f39be698127218cca460cb624878c9aa4e2b47dba3b277963d2bf00bad263b"
dependencies = [
"android_log-sys",
"env_filter",
"env_filter 0.1.0",
"log",
]
@@ -618,9 +618,9 @@ checksum = "70033777eb8b5124a81a1889416543dddef2de240019b674c81285a2635a7e1e"
[[package]]
name = "anyhow"
version = "1.0.98"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "arbitrary"
@@ -677,10 +677,12 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "artcraft"
version = "0.6.0"
version = "0.0.1"
dependencies = [
"anyhow",
"artcraft_api_defs",
"artcraft_client",
"artcraft_router",
"base64 0.22.1",
"build_metadata",
"bytes",
@@ -713,7 +715,6 @@ dependencies = [
"serde_json",
"serial_test",
"sqlite_tasks",
"storyteller_client",
"tauri",
"tauri-build",
"tauri-plugin-dialog",
@@ -737,6 +738,7 @@ dependencies = [
name = "artcraft_api_defs"
version = "0.0.1"
dependencies = [
"anyhow",
"chrono",
"enums",
"enums_public",
@@ -749,6 +751,54 @@ dependencies = [
"workspace-build-acceleration",
]
[[package]]
name = "artcraft_client"
version = "0.0.1"
dependencies = [
"anyhow",
"artcraft_api_defs",
"backoff",
"chrono",
"cloudflare_errors",
"cookie 0.18.1",
"enums",
"enums_public",
"errors",
"idempotency",
"log",
"mimetypes",
"reqwest 0.12.23",
"serde",
"serde_derive",
"serde_json",
"tokens",
"tokio",
"url",
"url-builder",
"uuid 1.18.1",
"workspace-build-acceleration",
]
[[package]]
name = "artcraft_router"
version = "0.0.1"
dependencies = [
"anyhow",
"artcraft_api_defs",
"artcraft_client",
"fal_client",
"log",
"seedance2pro",
"serde",
"serde_derive",
"strum 0.28.0",
"test_data",
"tokens",
"tokio",
"uuid 1.18.1",
"workspace-build-acceleration",
]
[[package]]
name = "ashpd"
version = "0.9.2"
@@ -1239,6 +1289,28 @@ dependencies = [
"url",
]
[[package]]
name = "aws-lc-rs"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9"
dependencies = [
"aws-lc-sys",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.37.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]]
name = "aws-region"
version = "0.26.0"
@@ -1956,7 +2028,7 @@ checksum = "a1d8af896b707212cd0e99c112a78c9497dd32994192a463ed2f7419d29bd8c6"
dependencies = [
"serde",
"thiserror 2.0.12",
"toml 0.8.22",
"toml 0.8.23",
]
[[package]]
@@ -1989,7 +2061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257"
dependencies = [
"serde",
"toml 0.8.22",
"toml 0.8.23",
]
[[package]]
@@ -2208,7 +2280,7 @@ dependencies = [
"bucket_paths",
"crockford",
"easyenv",
"env_logger 0.11.8",
"env_logger 0.11.9",
"errors",
"filesys",
"hashing",
@@ -3349,7 +3421,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.60.2",
"windows-sys 0.61.2",
]
[[package]]
@@ -3605,7 +3677,7 @@ name = "easyenv"
version = "0.1.0"
dependencies = [
"dotenv",
"env_logger 0.11.8",
"env_logger 0.11.9",
"log",
"storyteller_root",
"workspace-build-acceleration",
@@ -3705,7 +3777,7 @@ dependencies = [
"serde_json",
"sqlx",
"storyteller_root",
"strum",
"strum 0.26.2",
"tokens",
"tokio",
"workspace-build-acceleration",
@@ -3810,7 +3882,7 @@ dependencies = [
"cc",
"memchr",
"rustc_version 0.4.0",
"toml 0.8.22",
"toml 0.8.23",
"vswhom",
"winreg 0.52.0",
]
@@ -3867,8 +3939,8 @@ dependencies = [
"sqlx",
"sqlx-core",
"sqlx-mysql",
"strum",
"toml 0.8.22",
"strum 0.26.2",
"toml 0.8.23",
"utoipa",
"workspace-build-acceleration",
]
@@ -3881,8 +3953,8 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"strum",
"toml 0.8.22",
"strum 0.26.2",
"toml 0.8.23",
"utoipa",
"workspace-build-acceleration",
]
@@ -3906,6 +3978,16 @@ dependencies = [
"regex",
]
[[package]]
name = "env_filter"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -3921,13 +4003,13 @@ dependencies = [
[[package]]
name = "env_logger"
version = "0.11.8"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"env_filter 1.0.0",
"jiff",
"log",
]
@@ -4601,7 +4683,7 @@ dependencies = [
"serde",
"serde_json",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"tracing",
"tracing-subscriber",
]
@@ -4863,7 +4945,7 @@ dependencies = [
"cloudflare_mitigation",
"cookie_store 0.0.1",
"env",
"env_logger 0.11.8",
"env_logger 0.11.9",
"errors",
"filesys",
"futures 0.3.31",
@@ -5459,7 +5541,7 @@ dependencies = [
"hyper 1.6.0",
"hyper-util",
"log",
"rustls 0.23.13",
"rustls 0.23.36",
"rustls-native-certs 0.8.0",
"rustls-pki-types",
"tokio",
@@ -5514,7 +5596,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.5.10",
"socket2 0.6.2",
"system-configuration 0.6.1",
"tokio",
"tower-service",
@@ -6595,11 +6677,11 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
[[package]]
name = "log"
version = "0.4.27"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
dependencies = [
"serde",
"serde_core",
"value-bag",
]
@@ -6642,7 +6724,7 @@ dependencies = [
name = "logging"
version = "0.0.1"
dependencies = [
"env_logger 0.11.8",
"env_logger 0.11.9",
"log",
"workspace-build-acceleration",
]
@@ -6667,6 +6749,12 @@ dependencies = [
"workspace-build-acceleration",
]
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "lru_time_cache"
version = "0.11.11"
@@ -6955,7 +7043,7 @@ dependencies = [
"sqlx",
"tokens",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"workspace-build-acceleration",
]
@@ -6979,7 +7067,7 @@ dependencies = [
"serde_json",
"sqlx",
"storyteller_root",
"strum",
"strum 0.26.2",
"tempdir",
"tokens",
"tokio",
@@ -7198,17 +7286,17 @@ dependencies = [
[[package]]
name = "native-tls"
version = "0.2.14"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-probe 0.2.1",
"openssl-sys",
"schannel",
"security-framework",
"security-framework 3.7.0",
"security-framework-sys",
"tempfile",
]
@@ -7896,7 +7984,7 @@ dependencies = [
"testing",
"thiserror 2.0.12",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"url",
"workspace-build-acceleration",
"wreq",
@@ -7928,15 +8016,15 @@ dependencies = [
"testing",
"thiserror 2.0.12",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"workspace-build-acceleration",
]
[[package]]
name = "openssl"
version = "0.10.71"
version = "0.10.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
dependencies = [
"bitflags 2.11.0",
"cfg-if",
@@ -7964,6 +8052,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "openssl-src"
version = "300.4.2+3.4.1"
@@ -7975,9 +8069,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.106"
version = "0.9.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
dependencies = [
"cc",
"libc",
@@ -8958,37 +9052,44 @@ dependencies = [
[[package]]
name = "quinn"
version = "0.11.5"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases 0.2.1",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls 0.23.13",
"socket2 0.5.10",
"thiserror 1.0.63",
"rustls 0.23.36",
"socket2 0.6.2",
"thiserror 2.0.12",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.8"
version = "0.11.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
dependencies = [
"aws-lc-rs",
"bytes",
"rand 0.8.5",
"getrandom 0.3.1",
"lru-slab",
"rand 0.9.2",
"ring",
"rustc-hash",
"rustls 0.23.13",
"rustls 0.23.36",
"rustls-pki-types",
"slab",
"thiserror 1.0.63",
"thiserror 2.0.12",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
@@ -9335,7 +9436,7 @@ dependencies = [
"pin-project-lite",
"r2d2",
"rand 0.9.2",
"rustls 0.23.13",
"rustls 0.23.36",
"rustls-native-certs 0.8.0",
"ryu",
"sha1_smol",
@@ -9429,9 +9530,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.12.2"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
@@ -9554,7 +9655,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls 0.23.13",
"rustls 0.23.36",
"rustls-native-certs 0.8.0",
"rustls-pki-types",
"serde",
@@ -9591,20 +9692,21 @@ dependencies = [
"http-body-util",
"hyper 1.6.0",
"hyper-rustls 0.27.3",
"hyper-tls",
"hyper-util",
"js-sys",
"log",
"native-tls",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls 0.23.36",
"rustls-pki-types",
"rustls-platform-verifier",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.2",
"tokio",
"tokio-native-tls",
"tokio-rustls 0.26.0",
"tower 0.5.3",
"tower-http",
"tower-service",
@@ -9640,7 +9742,7 @@ dependencies = [
"serde_derive",
"sqlx",
"sqlx-core",
"toml 0.8.22",
"toml 0.8.23",
"workspace-build-acceleration",
]
@@ -9786,7 +9888,7 @@ dependencies = [
"testing",
"thiserror 2.0.12",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"workspace-build-acceleration",
]
@@ -9963,15 +10065,16 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.13"
version = "0.23.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b"
dependencies = [
"aws-lc-rs",
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki 0.102.8",
"rustls-webpki 0.103.9",
"subtle",
"zeroize",
]
@@ -9982,10 +10085,10 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"openssl-probe 0.1.5",
"rustls-pemfile 1.0.4",
"schannel",
"security-framework",
"security-framework 2.10.0",
]
[[package]]
@@ -9994,11 +10097,11 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a"
dependencies = [
"openssl-probe",
"openssl-probe 0.1.5",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"schannel",
"security-framework",
"security-framework 2.10.0",
]
[[package]]
@@ -10026,9 +10129,37 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
dependencies = [
"web-time",
"zeroize",
]
[[package]]
name = "rustls-platform-verifier"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [
"core-foundation 0.10.0",
"core-foundation-sys",
"jni 0.21.1",
"log",
"once_cell",
"rustls 0.23.36",
"rustls-native-certs 0.8.0",
"rustls-platform-verifier-android",
"rustls-webpki 0.103.9",
"security-framework 3.7.0",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
@@ -10050,6 +10181,18 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustls-webpki"
version = "0.103.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
dependencies = [
"aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.14"
@@ -10101,11 +10244,11 @@ dependencies = [
[[package]]
name = "schannel"
version = "0.1.23"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
dependencies = [
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -10260,15 +10403,59 @@ dependencies = [
]
[[package]]
name = "security-framework-sys"
version = "2.10.0"
name = "security-framework"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [
"bitflags 2.11.0",
"core-foundation 0.10.0",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "seedance2-pro-job"
version = "0.0.1"
dependencies = [
"actix-web",
"actix_helpers",
"anyhow",
"bootstrap",
"bucket_paths",
"cloud_storage",
"concurrency",
"config",
"easyenv",
"enums",
"errors",
"hashing",
"jobs_common",
"log",
"mysql_queries",
"reqwest 0.12.23",
"seedance2pro",
"serde",
"serde_derive",
"serde_json",
"server_environment",
"sqlx",
"tokens",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "seedance2pro"
version = "0.0.1"
@@ -10276,7 +10463,7 @@ dependencies = [
"chrono",
"cloudflare_errors",
"env",
"env_logger 0.11.8",
"env_logger 0.11.9",
"errors",
"log",
"rand 0.9.2",
@@ -10544,9 +10731,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
version = "0.6.8"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
dependencies = [
"serde",
]
@@ -11322,6 +11509,7 @@ dependencies = [
"actix_helpers",
"anyhow",
"artcraft_api_defs",
"artcraft_router",
"async-stripe 0.26.0",
"async-trait",
"base64 0.22.1",
@@ -11386,6 +11574,7 @@ dependencies = [
"resend-rs",
"reusable_types",
"rust-s3",
"rustls 0.23.36",
"seedance2pro",
"serde",
"serde_derive",
@@ -11393,8 +11582,8 @@ dependencies = [
"server_environment",
"speculoos",
"sqlx",
"strum",
"strum_macros",
"strum 0.26.2",
"strum_macros 0.26.4",
"tempdir",
"tempfile",
"testing",
@@ -11402,7 +11591,7 @@ dependencies = [
"time",
"tokens",
"tokio",
"toml 0.8.22",
"toml 0.8.23",
"tts_common",
"url",
"url_config",
@@ -11417,34 +11606,6 @@ dependencies = [
"zip 0.6.6",
]
[[package]]
name = "storyteller_client"
version = "0.0.1"
dependencies = [
"anyhow",
"artcraft_api_defs",
"backoff",
"chrono",
"cloudflare_errors",
"cookie 0.18.1",
"enums",
"enums_public",
"errors",
"idempotency",
"log",
"mimetypes",
"reqwest 0.12.23",
"serde",
"serde_derive",
"serde_json",
"tokens",
"tokio",
"url",
"url-builder",
"uuid 1.18.1",
"workspace-build-acceleration",
]
[[package]]
name = "storyteller_root"
version = "0.0.1"
@@ -11507,7 +11668,16 @@ version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
dependencies = [
"strum_macros",
"strum_macros 0.26.4",
]
[[package]]
name = "strum"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
dependencies = [
"strum_macros 0.28.0",
]
[[package]]
@@ -11523,6 +11693,18 @@ dependencies = [
"syn 2.0.106",
]
[[package]]
name = "strum_macros"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]]
name = "subprocess"
version = "0.2.9"
@@ -11850,7 +12032,7 @@ dependencies = [
"cfg-expr",
"heck 0.5.0",
"pkg-config",
"toml 0.8.22",
"toml 0.8.23",
"version-compare",
]
@@ -12272,7 +12454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56eaa45f707bedf34d19312c26d350bc0f3c59a47e58e8adbeecdc850d2c13a0"
dependencies = [
"embed-resource",
"toml 0.8.22",
"toml 0.8.23",
]
[[package]]
@@ -12519,7 +12701,7 @@ dependencies = [
"sqlx",
"sqlx-core",
"sqlx-mysql",
"strum",
"strum 0.26.2",
"utoipa",
"workspace-build-acceleration",
]
@@ -12599,7 +12781,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls 0.23.13",
"rustls 0.23.36",
"rustls-pki-types",
"tokio",
]
@@ -12647,22 +12829,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
dependencies = [
"serde",
"serde_spanned 0.6.8",
"toml_datetime 0.6.9",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_edit 0.19.15",
]
[[package]]
name = "toml"
version = "0.8.22"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
dependencies = [
"indexmap 2.9.0",
"serde",
"serde_spanned 0.6.8",
"toml_datetime 0.6.9",
"toml_edit 0.22.26",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_edit 0.22.27",
]
[[package]]
@@ -12682,9 +12864,9 @@ dependencies = [
[[package]]
name = "toml_datetime"
version = "0.6.9"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
dependencies = [
"serde",
]
@@ -12706,8 +12888,8 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.9.0",
"serde",
"serde_spanned 0.6.8",
"toml_datetime 0.6.9",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"winnow 0.5.40",
]
@@ -12718,7 +12900,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [
"indexmap 2.9.0",
"toml_datetime 0.6.9",
"toml_datetime 0.6.11",
"winnow 0.5.40",
]
@@ -12729,20 +12911,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
dependencies = [
"indexmap 2.9.0",
"toml_datetime 0.6.9",
"toml_datetime 0.6.11",
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.22.26"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap 2.9.0",
"serde",
"serde_spanned 0.6.8",
"toml_datetime 0.6.9",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_write",
"winnow 0.7.13",
]
@@ -12758,9 +12940,9 @@ dependencies = [
[[package]]
name = "toml_write"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]]
name = "toml_writer"
@@ -13421,9 +13603,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "value-bag"
version = "1.10.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0"
[[package]]
name = "vcpkg"
@@ -13869,7 +14051,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"strum",
"strum 0.26.2",
"workspace-build-acceleration",
]
@@ -14785,7 +14967,7 @@ dependencies = [
"rustls-pki-types",
"schemars",
"scopeguard",
"security-framework",
"security-framework 2.10.0",
"semver 1.0.23",
"serde",
"serde_json",
@@ -14837,7 +15019,7 @@ dependencies = [
"cloudflare_mitigation",
"cookie_store 0.0.1",
"env",
"env_logger 0.11.8",
"env_logger 0.11.9",
"errors",
"filesys",
"futures 0.3.31",
+14 -10
View File
@@ -7,7 +7,7 @@ members = [
# API clients for external services
# These might be custom implementations or wrappers over other client libraries.
"crates/api_clients/artcraft/artcraft_api_defs", # TODO: api_clients/{artcraft}/{api_defs,client}
"crates/api_clients/artcraft/storyteller_client",
"crates/api_clients/artcraft/artcraft_client",
"crates/api_clients/cloud_storage",
"crates/api_clients/fal_client",
"crates/api_clients/google_drive_common",
@@ -72,6 +72,7 @@ members = [
"crates/lib/files/videos",
"crates/lib/http_headers",
"crates/lib/idempotency",
"crates/api_clients/artcraft/artcraft_router",
"crates/lib/image_algorithms",
"crates/lib/jobs_common",
"crates/lib/jwt_light",
@@ -117,7 +118,7 @@ members = [
"crates/service/job/email_sender_job",
"crates/service/job/es-update-job",
"crates/service/job/inference_job",
#"crates/service/job/seedance2_pro_job",
"crates/service/job/seedance2_pro_job",
"crates/service/job/tts_download_job",
"crates/service/job/tts_inference_job",
"crates/service/job/w2l_download_job",
@@ -207,6 +208,7 @@ workspace-build-acceleration = { path = "crates/workspace-build-acceleration" }
# Setting paths here ensures we don't need to do so in every crate's Cargo.toml
# It makes refactoring much easier.
actix_artcraft = { path = "crates/lib/actix_artcraft" }
artcraft_router = { path = "crates/api_clients/artcraft/artcraft_router" }
actix_helpers = { path = "crates/lib/actix_helpers" }
artcraft_api_defs = { path = "crates/api_clients/artcraft/artcraft_api_defs" }
build_metadata = { path = "crates/lib/build_metadata" }
@@ -238,7 +240,7 @@ seedance2pro = { path = "crates/api_clients/seedance2pro" }
primitives = { path = "crates/lib/data/primitives" }
shared_service_components = { path = "crates/lib/shared_service_components" }
sqlite_tasks = { path = "crates/schema/database/sqlite_tasks" }
storyteller_client = { path = "crates/api_clients/artcraft/storyteller_client" }
artcraft_client = { path = "crates/api_clients/artcraft/artcraft_client" }
subprocess_common = { path = "crates/lib/subprocess_common" }
test_data = { path = "crates/lib/test_data" }
testing = { path = "crates/lib/testing" }
@@ -261,32 +263,33 @@ actix-utils = "3.0.1"
actix-web = "4.7.0" # TODO(bt): We're behind and need to bump versions.
actix-web-actors = "4.3.1+deprecated"
actix-web-lab = "0.20.2"
anyhow = "1.0.98"
anyhow = "1.0.102"
base64 = "0.22.1"
bstr = "1.12.1"
bytes = "1.10.1"
chrono = { version = "0.4.41", features = ["serde"] }
cookie = "0.18.1"
env = "1.0.1"
env_logger = "0.11.8"
env_logger = "0.11.9"
futures = { version = "0.3.31" }
hex-literal = "1.0.0"
indexmap = "2.9.0"
log = "0.4.27"
log = "0.4.29"
md-5 = "0.10.6" # insecure but used for gravatar
once_cell = "1.21.3"
r2d2 = "0.8.10"
rand = "0.9.1"
redis = { version = "1.0.2", features = ["r2d2", "tokio-rustls-comp", "tokio-comp", "cluster-async", "aio"] }
regex = "1.12.2"
regex = "1.12.3"
reqwest = { version = "0.12.23", default-features = false, features = [ "charset", "http2", "system-proxy", "json", "cookies", "rustls-tls", "gzip" ] }
reqwest-websocket = { version = "0.5.0" }
serde = { version = "1.0.219", features = ["derive"] }
serde = { version = "1.0.219", features = ["derive"] }
serde_derive = "1.0.219"
serde_json = "1.0.140"
serde_yaml = "0.9.34+deprecated"
sha2 = "0.11.0-rc.2"
sha3 = "0.10.8"
strum = { version = "0.28.0", features = ["derive"] }
tauri = { version = "2.8.3", features = ["unstable", "devtools"] } # NB: "devtools" prevents App Store distribution; "ubstable" is needed for window access
tauri-plugin-dialog = "2.3.3"
tauri-plugin-fs = "2.4.2"
@@ -296,7 +299,7 @@ tempdir = "0.3.7"
tempfile = "3.20.0"
thiserror = "2.0.12"
tokio = { version = "1.45.1", features = ["macros"] }
toml = "0.8.22"
toml = "0.8.23"
url = { version = "2.5.4", features = ["serde"] }
uuid = "1.18.1"
@@ -310,5 +313,6 @@ uuid = "1.18.1"
# choco install pkgconfiglite -y
# choco install llvm -y
# choco install nasm -y
wreq = { version = "6.0.0-rc.28", features = ["json", "multipart", "cookies", "ws", "stream", "query", "form", "gzip"] }
wreq-util = "3.0.0-rc.10"
wreq = { version = "6.0.0-rc.28", features = ["json", "query", "form", "multipart", "cookies", "ws", "stream", "gzip", "brotli", "zstd", "deflate"] }
+1 -1
View File
@@ -55,7 +55,7 @@ We haven't abandoned text-to-asset generation for quick prototyping and ideation
| Provider | Features |
|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Artcraft | Nano Banana, Nano Banana Pro, GPT-Image-1 / 1.5, Seedream 4 / 4.5, Flux 1.1 / Kontext, Veo 2 / 3 / 3.1, Kling 1.6 / 2.1 / 2.5 / 2.6, Seedance, Sora 2 / Pro, Hunyuan 3d 2 / 3 |
| Artcraft | Nano Banana, Nano Banana Pro, GPT-Image-1 / 1.5, Seedance 2 / Seedream 4 / 4.5, Flux 1.1 / Kontext, Veo 2 / 3 / 3.1, Kling 1.6 / 2.1 / 2.5 / 2.6, Seedance, Sora 2 / Pro, Hunyuan 3d 2 / 3 |
| Grok | Grok Imagine, Grok Video |
| Midjourney | Image Gen (all versions) |
| Sora | Sora 1, Sora 2, GPT-Image-1 |
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
DROP COLUMN
maybe_wallet_ledger_entry_token;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN
maybe_wallet_ledger_entry_token VARCHAR(32) DEFAULT NULL;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE wallet_ledger_entries
DROP COLUMN
is_refunded;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE wallet_ledger_entries
ADD COLUMN
is_refunded BOOLEAN NOT NULL DEFAULT FALSE;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE wallet_ledger_entries
DROP COLUMN
maybe_linked_refund_ledger_token;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE wallet_ledger_entries
ADD COLUMN
maybe_linked_refund_ledger_token VARCHAR(32) DEFAULT NULL;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
DROP COLUMN
maybe_referral_url;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
ADD COLUMN
maybe_referral_url VARCHAR(255) DEFAULT NULL;
@@ -0,0 +1,5 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE web_referrals;
@@ -0,0 +1,27 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Records of web referrals
CREATE TABLE web_referrals (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- The referral URL
url VARCHAR(255) NOT NULL,
-- The parsed out referral domain
domain VARCHAR(255) DEFAULT NULL,
utm_source VARCHAR(32) DEFAULT NULL,
utm_medium VARCHAR(32) DEFAULT NULL,
utm_campaign VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- ========== INDICES ==========
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE web_referrals
DROP COLUMN ip_address,
DROP COLUMN anonymous_visitor_token;
@@ -0,0 +1,7 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE web_referrals
ADD COLUMN ip_address VARCHAR(40) NOT NULL,
ADD COLUMN anonymous_visitor_token VARCHAR(32) DEFAULT NULL;
@@ -182,6 +182,9 @@ CREATE TABLE generic_inference_jobs (
is_from_api_user BOOLEAN NOT NULL DEFAULT FALSE,
is_for_twitch BOOLEAN NOT NULL DEFAULT FALSE,
-- If credits were spent for this job, this references the corresponding wallet ledger entry.
maybe_wallet_ledger_entry_token VARCHAR(32) DEFAULT NULL,
-- ========== DEVELOPMENT AND DEBUGGING METADATA ==========
-- If true, the request gets a "debug" flag, which may do different
@@ -220,6 +220,9 @@ CREATE TABLE users (
-- statistical evaluation.)
was_eagerly_provisioned BOOLEAN NOT NULL DEFAULT false,
-- The referral URL the user arrived from when signing up.
maybe_referral_url VARCHAR(255) DEFAULT NULL,
-- ========== MODERATION DETAILS ==========
-- Different than deleted.
@@ -40,6 +40,12 @@ CREATE TABLE wallet_ledger_entries (
-- Balance of monthly credits after the event.
monthly_credits_after INTEGER UNSIGNED NOT NULL DEFAULT 0,
-- Whether this ledger entry has been refunded.
is_refunded BOOLEAN NOT NULL DEFAULT FALSE,
-- If this entry was refunded, this points to the refund ledger entry.
maybe_linked_refund_ledger_token VARCHAR(32) DEFAULT NULL,
-- ========== RECORD TIMESTAMPS ==========
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -0,0 +1,31 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Records of web referrals
CREATE TABLE web_referrals (
-- Not used for anything except replication.
id BIGINT(20) NOT NULL AUTO_INCREMENT,
-- The referral URL
url VARCHAR(255) NOT NULL,
-- The parsed out referral domain
domain VARCHAR(255) DEFAULT NULL,
utm_source VARCHAR(32) DEFAULT NULL,
utm_medium VARCHAR(32) DEFAULT NULL,
utm_campaign VARCHAR(255) DEFAULT NULL,
ip_address VARCHAR(40) NOT NULL,
anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- ========== INDICES ==========
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
+13 -4
View File
@@ -33,7 +33,7 @@ RUN apt-get update \
FROM ubuntu:jammy as rust-base
# NB: This can be "stable" or another version.
ARG RUST_TOOLCHAIN="1.86.0"
ARG RUST_TOOLCHAIN="1.93.0"
WORKDIR /tmp
@@ -44,13 +44,16 @@ WORKDIR /tmp
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \
build-essential \
clang \
cmake \
curl \
ffmpeg \
fontconfig \
git \
libclang-dev \
libfontconfig1-dev \
libssl-dev \
musl-tools \
perl \
pkg-config
# NB: Fix for fontconfig (servo-fontconfig-sys): https://github.com/alacritty/alacritty/issues/4423#issuecomment-727277235
@@ -129,12 +132,17 @@ RUN du -hsc * | sort -hr
# Build all the binaries.
RUN SQLX_OFFLINE=true \
RUST_BACKTRACE=full \
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
$HOME/.cargo/bin/cargo build -vv \
$HOME/.cargo/bin/cargo build \
--release \
--bin storyteller-web
RUN SQLX_OFFLINE=true \
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
$HOME/.cargo/bin/cargo build \
--release \
--bin seedance2-pro-job
RUN SQLX_OFFLINE=true \
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \
$HOME/.cargo/bin/cargo build \
@@ -194,6 +202,7 @@ RUN echo -n ${GIT_SHA} > GIT_SHA
# Copy all the binaries (except those that need a GPU):
COPY --from=builder /tmp/target/release/storyteller-web /
COPY --from=builder /tmp/target/release/seedance2-pro-job /
COPY --from=builder /tmp/target/release/dummy-service /
COPY --from=builder /tmp/target/release/analytics-job /
COPY --from=builder /tmp/target/release/email-sender-job /
@@ -36,3 +36,4 @@ serde_json.workspace = true
utoipa = { version = "4", features = ["chrono", "actix_extras"] }
[dev-dependencies]
anyhow.workspace = true
@@ -0,0 +1,116 @@
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
use enums::common::generation::common_image_model::CommonImageModel;
use enums::common::generation::common_video_resolution::CommonVideoResolution;
use enums::common::generation_provider::GenerationProvider;
pub const ESTIMATE_IMAGE_COST_PATH: &str = "/v1/generate/cost_estimate/image";
/// Request body for the image cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateImageCostRequest {
/// The image model to estimate costs for.
pub model: CommonImageModel,
/// The provider to route the generation through.
pub provider: GenerationProvider,
/// The type of generation (determines whether input images are involved).
/// This is a tagged enum, so it looks like:
/// "generation_mode": {"type": "text_to_image"}
/// "generation_mode": {"type": "image_edit", "count": 2}
pub generation_mode: GenerationMode,
/// Optional aspect ratio.
pub aspect_ratio: Option<CommonAspectRatio>,
/// Optional resolution.
pub resolution: Option<CommonVideoResolution>,
/// Number of images to generate in parallel.
pub image_batch_count: Option<u16>,
}
/// Describes the type of image generation being requested.
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GenerationMode {
/// No input images — generate from prompt only.
TextToImage,
/// One or more input images are provided for editing/compositing.
ImageEdit { count: u32 },
}
/// Response body for the image cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateImageCostResponse {
pub success: bool,
/// Estimated cost in credits.
pub cost_in_credits: Option<u64>,
/// Estimated cost in USD cents.
pub cost_in_usd_cents: Option<u64>,
/// Whether the generation is free for this user/plan.
pub is_free: bool,
/// Whether the user has unlimited generations.
pub is_unlimited: bool,
/// Whether the user is rate limited.
pub is_rate_limited: bool,
/// Whether the output will have a watermark.
pub has_watermark: bool,
}
/// Error response for the image cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateImageCostError {
pub success: bool,
pub error_type: EstimateImageCostErrorType,
pub error_message: String,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum EstimateImageCostErrorType {
InvalidProviderForModel,
InvalidInput,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization_text_to_image() {
let request = EstimateImageCostRequest {
model: CommonImageModel::NanaBananaPro,
provider: GenerationProvider::Artcraft,
generation_mode: GenerationMode::TextToImage,
aspect_ratio: None,
resolution: None,
image_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
assert!(serialized.contains("\"generation_mode\":{\"type\":\"text_to_image\"}"));
}
#[test]
fn test_serialization_image_edit() {
let request = EstimateImageCostRequest {
model: CommonImageModel::NanaBananaPro,
provider: GenerationProvider::Artcraft,
generation_mode: GenerationMode::ImageEdit { count: 2 },
aspect_ratio: None,
resolution: None,
image_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
assert!(serialized.contains("\"generation_mode\":{\"type\":\"image_edit\",\"count\":2}"));
}
}
@@ -0,0 +1,122 @@
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
use enums::common::generation::common_video_model::CommonVideoModel;
use enums::common::generation::common_video_resolution::CommonVideoResolution;
use enums::common::generation_provider::GenerationProvider;
pub const ESTIMATE_VIDEO_COST_PATH: &str = "/v1/generate/cost_estimate/video";
/// Request body for the video cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateVideoCostRequest {
/// The video model to estimate costs for.
pub model: CommonVideoModel,
/// The provider to route the generation through.
pub provider: GenerationProvider,
/// The type of generation (determines how many input images are involved).
/// This is a tagged enum, so it looks like:
/// "generation_mode": {"type": "text_to_video"}
/// "generation_mode": {"type": "reference_image_to_video", "count": 1}
pub generation_mode: GenerationMode,
/// Optional aspect ratio.
pub aspect_ratio: Option<CommonAspectRatio>,
/// Optional resolution.
pub resolution: Option<CommonVideoResolution>,
/// Duration in seconds.
pub duration_seconds: Option<u16>,
/// Number of videos to generate in parallel.
pub video_batch_count: Option<u16>,
}
/// Describes the type of video generation being requested.
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GenerationMode {
TextToVideo,
StartFrameToVideo,
StartAndEndFrameToVideo,
ReferenceImageToVideo { count: u32 },
}
/// Response body for the video cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateVideoCostResponse {
pub success: bool,
/// Estimated cost in credits.
pub cost_in_credits: Option<u64>,
/// Estimated cost in USD cents.
pub cost_in_usd_cents: Option<u64>,
/// Whether the generation is free for this user/plan.
pub is_free: bool,
/// Whether the user has unlimited generations.
pub is_unlimited: bool,
/// Whether the user is rate limited.
pub is_rate_limited: bool,
/// Whether the output will have a watermark.
pub has_watermark: bool,
}
/// Error response for the video cost estimate endpoint.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateVideoCostError {
pub success: bool,
pub error_type: EstimateVideoCostErrorType,
pub error_message: String,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum EstimateVideoCostErrorType {
InvalidProviderForModel,
InvalidInput,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization_tagging1() {
let request = EstimateVideoCostRequest {
model: CommonVideoModel::GrokVideo,
provider: GenerationProvider::Artcraft,
generation_mode: GenerationMode::TextToVideo,
aspect_ratio: None,
resolution: None,
duration_seconds: None,
video_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
assert!(serialized.contains("\"generation_mode\":{\"type\":\"text_to_video\"}"));
//assert_eq!(serialized, "{}");
}
#[test]
fn test_serialization_tagging2() {
let request = EstimateVideoCostRequest {
model: CommonVideoModel::GrokVideo,
provider: GenerationProvider::Artcraft,
generation_mode: GenerationMode::ReferenceImageToVideo { count: 1 },
aspect_ratio: None,
resolution: None,
duration_seconds: None,
video_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
assert!(serialized.contains("\"generation_mode\":{\"type\":\"reference_image_to_video\",\"count\":1}"));
}
}
@@ -0,0 +1,2 @@
pub mod estimate_image_cost;
pub mod estimate_video_cost;
@@ -0,0 +1,68 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_5_lite";
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedream5LiteMultiFunctionImageGenRequest {
/// Idempotency token to prevent duplicate requests.
pub uuid_idempotency_token: String,
/// Text prompt to generate the image from.
pub prompt: Option<String>,
/// Image media tokens to include in the editing context.
/// If present, we're doing image editing (image-to-image / image-editing)
/// If absent, we're doing image generation (text-to-image)
pub image_media_tokens: Option<Vec<MediaFileToken>>,
/// Number of images to generate. Default is one.
pub num_images: Option<BytedanceSeedream5LiteMultiFunctionImageGenNumImages>,
pub max_images: Option<BytedanceSeedream5LiteMultiFunctionImageGenMaxImages>,
pub image_size: Option<BytedanceSeedream5LiteMultiFunctionImageGenImageSize>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedream5LiteMultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedream5LiteMultiFunctionImageGenMaxImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedream5LiteMultiFunctionImageGenImageSize {
// Square
Square,
SquareHd,
// Tall
PortraitFourThree,
PortraitSixteenNine,
// Wide
LandscapeFourThree,
LandscapeSixteenNine,
// Auto (NB: 5 Lite max is auto_3K, not auto_4K like V4.5)
Auto2k,
Auto3k,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedream5LiteMultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -1,5 +1,7 @@
pub mod bytedance_seedream_v4_multi_function_image_gen;
pub mod bytedance_seedream_v4p5_multi_function_image_gen;
pub mod bytedance_seedream_5_lite_multi_function_image_gen;
pub mod gpt_image_1p5_multi_function_image_gen;
pub mod nano_banana_2_multi_function_image_gen;
pub mod nano_banana_multi_function_image_gen;
pub mod nano_banana_pro_multi_function_image_gen;
@@ -0,0 +1,74 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/nano_banana_2";
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct NanaBanana2MultiFunctionImageGenRequest {
/// Idempotency token to prevent duplicate requests.
pub uuid_idempotency_token: String,
/// Text prompt to generate the image from.
pub prompt: Option<String>,
/// Image media tokens to include in the editing context.
/// If present, we're doing image editing (image-to-image / image-editing)
/// If absent, we're doing image generation (text-to-image)
pub image_media_tokens: Option<Vec<MediaFileToken>>,
/// Number of images to generate. Default is one.
pub num_images: Option<NanaBanana2MultiFunctionImageGenNumImages>,
/// Resolution of the image to generate. Default is OneK (1K).
pub resolution: Option<NanaBanana2MultiFunctionImageGenImageResolution>,
/// Aspect ratio of the images to generate. Default is "1:1"
pub aspect_ratio: Option<NanaBanana2MultiFunctionImageGenAspectRatio>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanaBanana2MultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanaBanana2MultiFunctionImageGenImageResolution {
HalfK,
OneK,
TwoK,
FourK,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanaBanana2MultiFunctionImageGenAspectRatio {
// Auto (only for image editing)
Auto, // Default for image editing.
// Square
OneByOne, // Default for text-to-image
// Wide
FiveByFour,
FourByThree,
ThreeByTwo,
SixteenByNine,
TwentyOneByNine,
// Tall
FourByFive,
ThreeByFour,
TwoByThree,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct NanaBanana2MultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -1,3 +1,4 @@
pub mod cost_estimate;
pub mod image;
pub mod object;
pub mod video;
@@ -33,7 +33,7 @@ pub struct Seedance2p0MultiFunctionVideoGenRequest {
pub batch_count: Option<Seedance2p0BatchCount>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Seedance2p0AspectRatio {
/// 16:9 landscape (1280x720)
@@ -48,7 +48,7 @@ pub enum Seedance2p0AspectRatio {
Portrait3x4,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Seedance2p0BatchCount {
One,
@@ -66,3 +66,20 @@ pub struct Seedance2p0MultiFunctionVideoGenResponse {
/// All inference job tokens for the batch (includes `inference_job_token` as the first entry).
pub all_inference_job_tokens: Vec<InferenceJobToken>,
}
#[cfg(test)]
mod tests {
use super::*;
fn aspect_to_string(input: Seedance2p0AspectRatio) -> anyhow::Result<String> {
let val = serde_json::to_string(&input)?;
Ok(val.replace("\"", ""))
}
#[test]
fn just_testing_snake_case() -> anyhow::Result<()> {
// Ugh, not sure what these are...
assert_eq!(aspect_to_string(Seedance2p0AspectRatio::Landscape16x9)?, "landscape16x9");
Ok(())
}
}
@@ -4,8 +4,10 @@ pub mod credits;
pub mod generate;
pub mod jobs;
pub mod media_file;
pub mod moderation;
pub mod prompts;
pub mod stripe_artcraft;
pub mod subscriptions;
pub mod users;
pub mod utils;
pub mod utils;
pub mod web_referrals;
@@ -0,0 +1 @@
pub mod user;
@@ -0,0 +1,33 @@
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
use enums::common::job_status_plus::JobStatusPlus;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use utoipa::ToSchema;
pub const LIST_USER_JOBS_PATH: &str = "/v1/moderation/jobs/user/{user_token}/list";
#[derive(Deserialize, ToSchema)]
pub struct ListUserJobsPathInfo {
pub user_token: UserToken,
}
#[derive(Serialize, ToSchema)]
pub struct ListUserJobsResponse {
pub success: bool,
pub jobs: Vec<ListUserJobsEntry>,
}
#[derive(Serialize, ToSchema)]
pub struct ListUserJobsEntry {
pub job_status: JobStatusPlus,
pub job_failure_reason: Option<String>,
pub credits_delta: Option<i32>,
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
pub on_success_result_media_token: Option<MediaFileToken>,
pub job_token: InferenceJobToken,
pub wallet_ledger_entry_token: Option<WalletLedgerEntryToken>,
pub wallet_ledger_entry_type: Option<WalletLedgerEntryType>,
}
@@ -0,0 +1 @@
pub mod list_user_jobs;
@@ -0,0 +1,4 @@
pub mod jobs;
pub mod user;
pub mod wallet_ledger_entries;
pub mod wallets;
@@ -0,0 +1,2 @@
pub mod user_lookup;
pub mod user_lookup_by_stripe_customer_id;
@@ -0,0 +1,39 @@
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::users::UserToken;
use utoipa::ToSchema;
pub const MODERATOR_USER_LOOKUP_PATH: &str = "/v1/moderation/users/lookup";
#[derive(Deserialize, ToSchema)]
pub struct ModeratorUserLookupRequest {
pub search: String,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorUserLookupSuccessResponse {
pub success: bool,
pub maybe_user: Option<ModeratorUserLookupUserDetails>,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorUserLookupUserDetails {
pub token: UserToken,
pub username: String,
pub display_name: String,
pub username_is_generated: bool,
pub is_temporary: bool,
pub username_is_not_customized: bool,
pub email_address: String,
pub email_confirmed: bool,
pub email_is_synthetic: bool,
pub is_without_password: bool,
pub ip_address_creation: String,
pub ip_address_last_login: String,
pub maybe_avatar_media_file_token: Option<MediaFileToken>,
pub email_gravatar_hash: String,
pub is_banned: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,27 @@
use enums::common::payments_namespace::PaymentsNamespace;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::users::UserToken;
use utoipa::ToSchema;
pub const MODERATOR_USER_LOOKUP_BY_STRIPE_CUSTOMER_ID_PATH: &str = "/v1/moderation/users/lookup_by_stripe_customer_id";
#[derive(Deserialize, ToSchema)]
pub struct ModeratorUserLookupByStripeCustomerIdRequest {
pub stripe_customer_id: String,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorUserLookupByStripeCustomerIdResponse {
pub success: bool,
pub users: Vec<ModeratorUserLookupByStripeCustomerIdEntry>,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorUserLookupByStripeCustomerIdEntry {
pub subscription_namespace: PaymentsNamespace,
pub maybe_stripe_subscription_id: Option<String>,
pub token: UserToken,
pub email_address: String,
pub username: String,
pub display_name: String,
}
@@ -0,0 +1,35 @@
use chrono::{DateTime, Utc};
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use tokens::tokens::wallets::WalletToken;
use utoipa::ToSchema;
pub const LIST_WALLET_LEDGER_ENTRIES_BY_WALLET_PATH: &str = "/v1/moderation/wallet_ledger_entries/wallet/{wallet_token}/list";
#[derive(Deserialize, ToSchema)]
pub struct ListWalletLedgerEntriesByWalletPathInfo {
pub wallet_token: WalletToken,
}
#[derive(Serialize, ToSchema)]
pub struct ListWalletLedgerEntriesByWalletResponse {
pub success: bool,
pub entries: Vec<ListWalletLedgerEntriesByWalletEntry>,
}
#[derive(Serialize, ToSchema)]
pub struct ListWalletLedgerEntriesByWalletEntry {
pub token: WalletLedgerEntryToken,
pub wallet_token: WalletToken,
pub entry_type: WalletLedgerEntryType,
pub maybe_entity_ref: Option<String>,
pub credits_delta: i32,
pub banked_credits_before: u32,
pub banked_credits_after: u32,
pub monthly_credits_before: u32,
pub monthly_credits_after: u32,
pub created_at: DateTime<Utc>,
pub is_refunded: bool,
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
}
@@ -0,0 +1,2 @@
pub mod list_wallet_ledger_entries_by_wallet;
pub mod moderator_get_wallet_ledger_entry;
@@ -0,0 +1,33 @@
use chrono::{DateTime, Utc};
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use utoipa::ToSchema;
pub const MODERATOR_GET_WALLET_LEDGER_ENTRY_PATH: &str = "/v1/moderation/wallet_ledger_entry/{wallet_ledger_entry_token}";
#[derive(Deserialize, ToSchema)]
pub struct ModeratorGetWalletLedgerEntryPathInfo {
pub wallet_ledger_entry_token: WalletLedgerEntryToken,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorGetWalletLedgerEntryResponse {
pub success: bool,
pub maybe_entry: Option<ModeratorGetWalletLedgerEntryDetails>,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorGetWalletLedgerEntryDetails {
pub token: WalletLedgerEntryToken,
pub entry_type: WalletLedgerEntryType,
pub maybe_entity_ref: Option<String>,
pub credits_delta: i32,
pub banked_credits_before: u32,
pub banked_credits_after: u32,
pub monthly_credits_before: u32,
pub monthly_credits_after: u32,
pub is_refunded: bool,
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
pub created_at: DateTime<Utc>,
}
@@ -0,0 +1,30 @@
use chrono::{DateTime, Utc};
use enums::common::payments_namespace::PaymentsNamespace;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::users::UserToken;
use tokens::tokens::wallets::WalletToken;
use utoipa::ToSchema;
pub const LIST_USER_WALLETS_PATH: &str = "/v1/moderation/wallets/user/{user_token}/list";
#[derive(Deserialize, ToSchema)]
pub struct ListUserWalletsPathInfo {
pub user_token: UserToken,
}
#[derive(Serialize, ToSchema)]
pub struct ListUserWalletsResponse {
pub success: bool,
pub wallets: Vec<ListUserWalletsEntry>,
}
#[derive(Serialize, ToSchema)]
pub struct ListUserWalletsEntry {
pub token: WalletToken,
pub wallet_namespace: PaymentsNamespace,
pub banked_credits: u32,
pub monthly_credits: u32,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,3 @@
pub mod list_user_wallets;
pub mod moderator_add_banked_balance_to_wallet;
pub mod moderator_get_wallet;
@@ -0,0 +1,20 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::wallets::WalletToken;
use utoipa::ToSchema;
pub const MODERATOR_ADD_BANKED_BALANCE_TO_WALLET_PATH: &str = "/v1/moderation/wallet/{wallet_token}/add_banked_balance";
#[derive(Deserialize, ToSchema)]
pub struct ModeratorAddBankedBalanceToWalletPathInfo {
pub wallet_token: WalletToken,
}
#[derive(Deserialize, ToSchema)]
pub struct ModeratorAddBankedBalanceToWalletRequest {
pub credits: u16,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorAddBankedBalanceToWalletResponse {
pub success: bool,
}
@@ -0,0 +1,31 @@
use chrono::{DateTime, Utc};
use enums::common::payments_namespace::PaymentsNamespace;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::users::UserToken;
use tokens::tokens::wallets::WalletToken;
use utoipa::ToSchema;
pub const MODERATOR_GET_WALLET_PATH: &str = "/v1/moderation/wallet/{wallet_token}";
#[derive(Deserialize, ToSchema)]
pub struct ModeratorGetWalletPathInfo {
pub wallet_token: WalletToken,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorGetWalletResponse {
pub success: bool,
pub maybe_wallet: Option<ModeratorGetWalletDetails>,
}
#[derive(Serialize, ToSchema)]
pub struct ModeratorGetWalletDetails {
pub token: WalletToken,
pub wallet_namespace: PaymentsNamespace,
pub owner_user_token: UserToken,
pub banked_credits: u32,
pub monthly_credits: u32,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -11,6 +11,11 @@ pub struct StripeArtcraftCreateSubscriptionCheckoutWithUserSignupRequest {
pub plan: Option<ArtcraftSubscriptionSlug>,
pub cadence: Option<PlanBillingCadence>,
/// Optional: The referral URL the user arrived from when signing up.
/// The browser can send `document.referrer` to the backend so we know how people are finding us.
/// If the browser doesn't send this parameter, we'll try the `referer` header.
pub maybe_referral_url: Option<String>,
}
#[derive(Serialize, Deserialize, ToSchema, Debug, Copy, Clone)]
@@ -0,0 +1,17 @@
use serde_derive::{Deserialize, Serialize};
use utoipa::ToSchema;
pub const LOG_WEB_REFERRAL_URL_PATH: &str = "/v1/web_referrals/record";
#[derive(Deserialize, ToSchema)]
pub struct LogWebReferralRequest {
/// Optional: The referral URL the user arrived from when signing up.
/// The browser can send `document.referrer` to the backend so we know how people are finding us.
/// If the browser doesn't send this parameter, we'll try the `referer` header.
pub maybe_referral_url: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub struct LogWebReferralResponse {
pub success: bool,
}
@@ -0,0 +1 @@
pub mod log_web_referral;
@@ -1,5 +1,5 @@
[package]
name = "storyteller_client"
name = "artcraft_client"
edition = "2021"
version = "0.0.1"
authors = [
@@ -15,7 +15,7 @@ normal = ["workspace-build-acceleration"]
# unused_imports = "forbid"
[lib]
name = "storyteller_client"
name = "artcraft_client"
path = "src/lib.rs"
[dependencies]
@@ -1,3 +1,4 @@
pub mod parse_multi_cookie_header;
pub mod storyteller_avt_cookie;
pub mod storyteller_credential_set;
pub mod storyteller_session_cookie;
@@ -0,0 +1,35 @@
use crate::credentials::storyteller_avt_cookie::StorytellerAvtCookie;
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
use crate::credentials::storyteller_session_cookie::StorytellerSessionCookie;
use cookie::Cookie;
/// Parses a multi-cookie header string (e.g. `"visitor=abc; session=xyz"`) and extracts
/// the known Storyteller cookies by name.
///
/// Returns `Ok(Some(...))` if at least one recognised cookie is present,
/// `Ok(None)` if the input is empty or contains no recognised cookies,
/// and `Err` if any individual cookie segment fails to parse.
pub fn parse_multi_cookie_header(header: &str) -> Result<Option<StorytellerCredentialSet>, cookie::ParseError> {
let mut avt: Option<StorytellerAvtCookie> = None;
let mut session: Option<StorytellerSessionCookie> = None;
for segment in header.split(';') {
let segment = segment.trim();
if segment.is_empty() {
continue;
}
let cookie = Cookie::parse(segment.to_owned())?;
if avt.is_none() {
avt = StorytellerAvtCookie::maybe_from_cookie(&cookie);
}
if session.is_none() {
session = StorytellerSessionCookie::maybe_from_cookie(&cookie);
}
}
if avt.is_none() && session.is_none() {
return Ok(None);
}
Ok(Some(StorytellerCredentialSet::initialize(avt, session)))
}
@@ -1,3 +1,4 @@
use crate::credentials::parse_multi_cookie_header::parse_multi_cookie_header;
use crate::credentials::storyteller_avt_cookie::StorytellerAvtCookie;
use crate::credentials::storyteller_session_cookie::StorytellerSessionCookie;
@@ -25,6 +26,10 @@ impl StorytellerCredentialSet {
}
}
pub fn parse_multi_cookie_header(header: &str) -> Result<Option<Self>, cookie::ParseError> {
parse_multi_cookie_header(header)
}
pub fn initialize_with_just_cookie(session: StorytellerSessionCookie) -> Self {
Self {
avt: None,
@@ -0,0 +1,20 @@
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
use crate::error::storyteller_error::StorytellerError;
use crate::utils::api_host::ApiHost;
use crate::utils::basic_json_post_request::basic_json_post_request;
use artcraft_api_defs::generate::cost_estimate::estimate_image_cost::{
EstimateImageCostRequest, EstimateImageCostResponse, ESTIMATE_IMAGE_COST_PATH,
};
pub async fn estimate_image_cost(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: EstimateImageCostRequest,
) -> Result<EstimateImageCostResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
ESTIMATE_IMAGE_COST_PATH,
maybe_creds,
request,
).await?)
}
@@ -0,0 +1 @@
pub mod estimate_image_cost;
@@ -0,0 +1,2 @@
pub mod image;
pub mod video;
@@ -0,0 +1,20 @@
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
use crate::error::storyteller_error::StorytellerError;
use crate::utils::api_host::ApiHost;
use crate::utils::basic_json_post_request::basic_json_post_request;
use artcraft_api_defs::generate::cost_estimate::estimate_video_cost::{
EstimateVideoCostRequest, EstimateVideoCostResponse, ESTIMATE_VIDEO_COST_PATH,
};
pub async fn estimate_video_cost(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: EstimateVideoCostRequest,
) -> Result<EstimateVideoCostResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
ESTIMATE_VIDEO_COST_PATH,
maybe_creds,
request,
).await?)
}
@@ -0,0 +1 @@
pub mod estimate_video_cost;
@@ -0,0 +1,18 @@
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
use crate::error::storyteller_error::StorytellerError;
use crate::utils::api_host::ApiHost;
use crate::utils::basic_json_post_request::basic_json_post_request;
use artcraft_api_defs::generate::image::multi_function::bytedance_seedream_5_lite_multi_function_image_gen::{BytedanceSeedream5LiteMultiFunctionImageGenRequest, BytedanceSeedream5LiteMultiFunctionImageGenResponse, BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH};
pub async fn bytedance_seedream_5_lite_multi_function_image_gen(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: BytedanceSeedream5LiteMultiFunctionImageGenRequest,
) -> Result<BytedanceSeedream5LiteMultiFunctionImageGenResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH,
maybe_creds,
request,
).await?)
}
@@ -1,5 +1,7 @@
pub mod bytedance_seedream_v4_multi_function_image_gen_image;
pub mod bytedance_seedream_v4p5_multi_function_image_gen_image;
pub mod bytedance_seedream_5_lite_multi_function_image_gen_image;
pub mod gpt_image_1p5_multi_function_image_gen_image;
pub mod nano_banana_2_multi_function_image_gen_image;
pub mod nano_banana_multi_function_image_gen_image;
pub mod nano_banana_pro_multi_function_image_gen_image;
@@ -0,0 +1,18 @@
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
use crate::error::storyteller_error::StorytellerError;
use crate::utils::api_host::ApiHost;
use crate::utils::basic_json_post_request::basic_json_post_request;
use artcraft_api_defs::generate::image::multi_function::nano_banana_2_multi_function_image_gen::{NanaBanana2MultiFunctionImageGenRequest, NanaBanana2MultiFunctionImageGenResponse, NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH};
pub async fn nano_banana_2_multi_function_image_gen(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: NanaBanana2MultiFunctionImageGenRequest,
) -> Result<NanaBanana2MultiFunctionImageGenResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH,
maybe_creds,
request,
).await?)
}

Some files were not shown because too many files have changed in this diff Show More