Compare commits

..
Author SHA1 Message Date
Tanish Manku 2fb1097eb1 Moodboard (HTML): card grouping with color picker and drop targeting
- CardNodeHtml: vertical-flex card container that owns its children's
  layout (children fill card width, heights follow natural aspect for
  images/videos or own height for text).
- cardLayout: pure helpers (DEFAULT_CARD_WIDTH/PADDING/COLOR,
  childRenderedHeight) used by the card node + store.
- MoodboardHtmlColorPicker: hex/rgb picker with preset swatches for
  card backgrounds.
- findDropTarget: top-level hit-test on pointer-up so a drag can form
  a new card with the target + dragged node, or append to an existing
  card.
2026-04-29 12:33:10 -07:00
Tanish Manku f260e1cee4 PageEditor: drop video items only on the HTML moodboard tab
Early-returns in both gallery-drop handlers when the item's mediaClass
is "video" and the active tab can't render video:

- 3D tab: already branches image vs dimensional; video would fall into
  the image branch and try to uploadPlaneFromMediaToken against a video
  URL. Skip it.
- 2D / Konva moodboard: their drop listeners call addImage
  unconditionally, which would load the video URL into an HTMLImageElement
  and fail. Skip unless the active tab is MOODBOARD_HTML.

Gallery drag is globally enabled in the sibling commit, so this is the
failsafe that keeps drops on non-video tabs from producing broken state.
2026-04-23 14:28:11 -07:00
Tanish Manku 9e07954d4f Gallery: enable dragging video items
Removes the video-specific early-return that blocked the drag gesture
in GalleryDraggableItem's pointerdown and the matching video filter in
the pointerup emitter. Videos now get the same drag cursor, tooltip
("Drag to add"), and gallery-image-drop dispatch as images.

The HTML moodboard's gallery-drop listener already branches on
mediaClass to route videos into addVideo, so this unblocks the drag
source end of that path. Other tabs' drop listeners are gated in a
follow-up so dropping a video somewhere that can't render it no-ops
cleanly.
2026-04-23 14:27:44 -07:00
Tanish Manku 0d519023a2 Moodboard (HTML): video nodes with playback controls and scrub bar
Renders VideoNode items on the HTML moodboard with an HTML <video>
element plus a hover-fade overlay:

- Center play/pause button — always visible when paused, fades in on
  hover while playing.
- Bottom-right mute toggle — fades in on hover.
- Bottom scrub bar with a tall hit area — click or drag to seek,
  updates live from the video's timeupdate event.

Controls stop pointerdown propagation so clicking them doesn't start
a node-drag gesture. Gallery drops and the Library picker route to
addVideo or addImage based on the item's mediaClass, measuring video
dimensions via a metadata-only <video> probe. The Library picker's
forceFilter="image" is removed so videos and images can both be picked.
2026-04-23 14:27:06 -07:00
Tanish Manku 181d2a36ca Moodboard: VideoNode type + addVideo store action
Adds a video kind to the shared MoodboardNode union alongside image,
text, and group. `addVideo` mirrors `addImage` and defaults to a
Milanote-style silent looping autoplay (muted/loop/autoplay all true) —
browsers only permit autoplay when muted, so these three travel
together.

Group/delete/move/AABB all work on BaseNode fields, so videos pick up
grouping, multi-select, and undo for free. The existing Konva moodboard
renderer's node switch falls through unknown kinds, so it silently
ignores video nodes rather than crashing.
2026-04-23 14:25:18 -07:00
Tanish Manku 8d4346d566 Moodboard (HTML): parallel experiment page, no canvas
Stands up PageMoodboardHtml alongside PageMoodboard — renders the same
moodboard content (image/text/group nodes) entirely with absolutely-
positioned divs, CSS transforms, and pointer events. Shares the store
with PageMoodboard so switching tabs preserves the board.

- New page at app/src/pages/PageMoodboardHtml with HTML-only stage,
  background grid, nodes, overlay transformer (8 resize handles + 1
  rotate), marquee + lasso selection, viewport pan/zoom, paste and
  gallery drop handlers, and a shortcut-aware text edit overlay.
- Reuses MoodboardStore, layout utilities, MoodboardToolbar,
  TextEditOverlay, and the non-render interaction hooks from the
  existing Konva moodboard unchanged.
- Experimental flag `moodboardHtmlPageEnabled` gates a new apps-menu
  entry and a Settings → Experimental toggle.
- PageEditor: gallery drop targets the HTML stage element when the
  MOODBOARD_HTML tab is active.
2026-04-23 14:24:41 -07:00
BFlat acbd86a4af styling/moodboard page (#1407)
## Moodboard polish

A pass to make the Moodboard feel consistent with the rest of the app.

### What's new
- **Floating toolbar** shared between the 3D Editor and Moodboard -
centered and no longer glued to the top edge.
- **Moodboard toolbar** rebuilt to match: mode picker (Select / Lasso /
Text), a primary `+` dropdown for **Upload Image** and **Pick from
Library**, plus Group, Fit-to-grid, Pack, Auto-group, Undo / Redo,
Delete.
- **Empty state CTA** in the center of a blank moodboard with the same
Select Image / Pick from Library flow PageDraw uses.
- **Theme support** across the moodboard - background, grid dots,
toolbar, and empty-state card all adapt to light / gray / black / aurora
/ sunset themes.
- **Platform-aware shortcut hints** in toolbar tooltips - `⌘G` on Mac,
`Ctrl+G` on Windows / Linux.
- **Topbar titles** added for Moodboard and Storyboard tabs.
2026-04-22 18:12:04 +07:00
Tanish Manku 5fe4137634 Moodboard: move page-height class into Moodboard root
Every other tab applies its `h-[calc(100vh-56px)]` on its own root div;
the PageEditor wrappers stay bare. Moodboard was the outlier — wrapper
had `w-screen` + inline height of `calc(100vh - 68px)` (wrong 68px,
causing a 12px gap at the bottom). Move the class into `Moodboard.tsx`'s
root and drop the wrapper styling so it matches the rest.
2026-04-20 23:32:34 -07:00
Tanish Manku 1c9e9297cb Moodboard: disable Fit to grid when nothing is selected
Removes the old "fall back to all nodes" behavior — matches Figma/Sketch,
where layout actions require an explicit target.
2026-04-20 23:24:44 -07:00
Tanish Manku 982f3ad78d Moodboard: viewport state, recenter indicator, shortcut cheatsheet, canvas perf
Lifts `viewport` (zoom/pan) and `canvasSize` into the moodboard store so
overlays and a future minimap can read the camera without drilling refs.
Adds a recenter pill in the bottom-right that appears when nothing in the
current viewport intersects any content, and a translucent shortcut
cheatsheet that appears after holding Ctrl/Cmd alone for 3s.

New Figma-style shortcuts: V/L/T tool switches, Cmd/Ctrl+A select all,
Cmd/Ctrl+G group, Cmd/Ctrl+Shift+G ungroup, Shift+1 zoom-to-fit.

Consolidates all previously-duplicated rect / AABB / clamp / viewport math
into `layout/geometry.ts` (removes private copies from useSelection,
useViewportControls, MoodboardStore, and packCollage). Exports include
`computeContentBounds`, `computeVisibleRect`, `anyContentVisible`,
`fitViewportToBounds`, `panToCenterOn`, `ZOOM_MIN/MAX` — everything a
future minimap overlay will need.

Canvas perf pass:
- Level-of-detail dotted grid (doubles effective spacing as you zoom out
  so dot count stays bounded; dot radius tracks screen pixels).
- React.memo on ImageNode, TextNode, GroupNode, MoodboardBackground.
- Stable onSelect contract (children receive (id, e) and call a single
  parent callback, letting memo skip children on camera/selection-only
  renders).
- GroupNode subscribes only to its own children via useShallow, not the
  full nodes map.
- TextNode's editingTextId selector collapsed to a per-node boolean.
- MoodboardStage's transient subscription narrowed to {marquee, lassoPath}
  so setIsPanning / setEditingText don't churn the whole Stage.
- visibleViewport memoized so marquee/lasso drags don't force the
  background sceneFunc to re-run.
2026-04-20 23:24:38 -07:00
Tanish Manku a24b154d52 Experimental: Moodboard page
New Konva-based 2D canvas for collaging reference imagery, gated behind an
experimental flag mirroring Storyboard. Supports drag-drop from OS, gallery,
and clipboard; rectangle marquee and lasso selection; grouping with
group-local coordinates so rotation/scale transforms children correctly;
fit-to-grid, justified-rows collage pack, and DBSCAN proximity auto-group;
wheel-zoom around cursor and middle-mouse / spacebar pan; per-item dashed
outlines to distinguish grouped vs individually-selected; 50-entry snapshot
undo/redo. Also fixes a pre-existing bug where disabling the experimental
flag didn't reset gated page state.
2026-04-20 20:40:18 -07:00
2342 changed files with 48310 additions and 104760 deletions
+1 -19
View File
@@ -42,21 +42,6 @@ then the story, then the fine print.
- A method that calls another method in the same file should appear *above* the method
it calls. This lets readers follow the call chain downward.
### Ordering within test modules
Put test cases first, helpers last. A reader opening a test file should immediately see
*what* is being tested before *how* the test machinery works.
1. **Imports**
2. **Constants** (test IDs, URLs, fixture data) — small context that tests reference
3. **Test functions** or **sub-modules** grouped by category
4. **Helper functions** (builders, pipeline runners, assertions)
Group related tests into sub-modules (`mod pricing_tests { ... }`) when a category has 2+
tests. Don't create a sub-module for a single test. Keep nesting to two levels max
(`mod tests { mod category { ... } }`). Shared helpers go in the parent module so
sub-modules can reach them via `use super::*`.
## Naming
- Handler functions: `{verb}_{noun}_handler` (e.g. `get_health_check_handler`, `login_handler`)
@@ -68,10 +53,7 @@ sub-modules can reach them via `use super::*`.
## Imports
- Group imports: std, external crates, internal workspace crates, `crate::` imports
- Prefer `use` imports over inline fully-qualified paths. Inline qualification is acceptable
only for genuine one-off references where adding an import would be noise, or for types
that collide with std prelude names (`Result`, `Option`, `Error`). If you reference a symbol
more than once, always import it.
- Use fully qualified paths for one-off references; `use` for repeated references
- Prefer specific imports over wildcards, except in `api_doc.rs` and test modules
- When two crates export a type with the same name, alias with a suffix describing the source crate:
`use enums::...::CommonResolution as CommonResolutionEnum;`
+1 -27
View File
@@ -10,28 +10,10 @@
## Test Patterns
- Tests live in `#[cfg(test)] mod tests { ... }` at the bottom of each file
- Group related tests into sub-modules by category (e.g. `mod pricing_tests`, `mod resolution_tests`)
- Only create a sub-module when it has 2+ tests — don't wrap a single test in its own module
- Keep nesting shallow: `mod tests { mod category { ... } }` is fine; a third level is rarely needed
- Shared helpers used by multiple sub-modules belong in the parent `mod tests`, not duplicated in each sub-module
- Group related tests in sub-modules: `mod explicit_checks`, `mod mechanical_checks`
- Enum tests should cover: serialization, deserialization, `to_str`/`from_str` round-trip, variant count
- Password/crypto tests: be mindful of computation cost, don't add too many bcrypt test cases
## Test File Layout
Put test cases first, helpers last. Engineers should see the actual tests before scrolling
to understand helper plumbing.
Within a `mod tests { ... }` block:
1. **Imports** at the top
2. **Constants** (test data IDs, URLs, etc.) — small context that tests reference
3. **Test functions** (`#[test]` / `#[tokio::test]`) grouped by category
4. **Helper functions** (builders, pipeline runners, etc.) at the very bottom
If tests are grouped into sub-modules, the same rule applies within each sub-module:
constants first, then tests, then helpers at the end of that sub-module.
## What to Test
- New error types and their mappings
@@ -39,14 +21,6 @@ constants first, then tests, then helpers at the end of that sub-module.
- Hash/deduplication functions with known inputs
- Edge cases in parsers (empty input, missing fields, malformed data)
## Imports in Tests
- Import test fixtures and constants with `use`, not inline fully-qualified paths.
Write `use test_data::web::image_urls::JUNO_AT_LAKE_IMAGE_URL;` at the top,
then reference `JUNO_AT_LAKE_IMAGE_URL` in test bodies.
- Same rule applies to enum variants used in match arms — import them, don't write
`crate::some::deep::module::MyEnum::Variant` inline.
## What Not to Test
- Don't add integration tests that require a running database unless explicitly asked
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO tasks (\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 9
},
"nullable": []
},
"hash": "01a0bf33e8331c19dc73f064c54eaa863bec158ef7713450a06c75e246f5f08c"
}
@@ -1,102 +0,0 @@
{
"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 `request_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": [
{
"ordinal": 0,
"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": 1,
"name": "request_id",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 2,
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 5,
"name": "creator_set_visibility: enums::common::visibility::Visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 6,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"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": {
"Right": 1
},
"nullable": [
false,
true,
true,
true,
false,
false,
true,
true
]
},
"hash": "1ddb2207db50e2dbfb37d26c006bffe2d8f5fb011855d5a86d01f395c36df759"
}
@@ -1,12 +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_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 maybe_debug_log_event_token = ?,\n\n frontend_failure_category = ?,\n failure_reason = ?,\n\n status = ?\n ",
"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 frontend_failure_category = ?,\n failure_reason = ?,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 17
"Right": 16
},
"nullable": []
},
"hash": "c73be10c5677f78f81bc1c29872fd5af889790c3b2a8de27eb8ab64383c638d6"
"hash": "29916e73a1784ea0b70ef4f637520b05efccc31e01840f681e9b042f82eb8f7e"
}
@@ -1,135 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n\n jobs.maybe_external_third_party as `external_third_party: enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty`,\n jobs.maybe_external_third_party_id as `external_third_party_id`,\n\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\n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n jobs.maybe_debug_log_event_token as `maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken`,\n\n jobs.created_at,\n jobs.updated_at\n\nFROM generic_inference_jobs as jobs\n\nWHERE jobs.maybe_external_third_party = ?\nAND jobs.maybe_external_third_party_id = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"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": 1,
"name": "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": 2,
"name": "external_third_party: enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 3,
"name": "external_third_party_id",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 4,
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "maybe_creator_anonymous_visitor_token: tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 7,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 10,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
true,
true,
true,
true,
false,
true,
true,
false,
false
]
},
"hash": "31d85cc0013f29e6db2d272ee6e709cca79b46496a2c222960f1a1419175f00b"
}
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n queue_status_url,\n queue_response_url,\n prompt_token,\n frontend_subscriber_id,\n frontend_subscriber_payload\n FROM tasks\n WHERE\n provider = ?\n AND provider_job_id = ?\n ",
"query": "\n SELECT\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload\n FROM tasks\n WHERE\n provider = ?\n AND provider_job_id = ?\n ",
"describe": {
"columns": [
{
@@ -39,28 +39,13 @@
"type_info": "Text"
},
{
"name": "queue_status_url",
"name": "frontend_subscriber_id",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "queue_response_url",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "prompt_token",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "frontend_subscriber_id",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "frontend_subscriber_payload",
"ordinal": 11,
"ordinal": 8,
"type_info": "Text"
}
],
@@ -76,11 +61,8 @@
true,
true,
true,
true,
true,
true,
true
]
},
"hash": "35677894f7b02f32a1bf6396fa6d10caba69bb0f3f03ee7ffbfa1437689d42df"
"hash": "38ff2df237b16f077865711dd81261de1b5fa05a9787679ce9ccd4ac576b1069"
}
@@ -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\n maybe_referral_url = ?,\n maybe_landing_url = ?,\n\n maybe_referral_partner = ?,\n maybe_referral_user_token = ?\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 maybe_landing_url = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 26
"Right": 24
},
"nullable": []
},
"hash": "867b22640ae6c49c26973a32d36439933dceef881313a7f3385d61ebe5faeb34"
"hash": "3aacc0d270a9073ee5a38595cc32ab7793e0e8b9ce3ad81f554e7198fd0fd509"
}
@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO tasks (\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n queue_status_url,\n queue_response_url,\n prompt_token,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "4fc9674ae39abaadc36054c200290ec95d0e2c7765336f0fa97805a2265f5c4c"
}
@@ -1,146 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nORDER BY ur.id DESC\nLIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id: u64",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "invited_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "invited_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "invited_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "invited_email_address: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "referrer_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "referrer_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 7,
"name": "referrer_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_referral_code_token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "maybe_referral_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_landing_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false
]
},
"hash": "507a60f98f6da63620abc28a5a83772f29ffcfdfcc8d30bfa7c611d73073ca16"
}
@@ -1,58 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: UserReferralCodeToken`,\n owner_user_token as `owner_user_token: UserToken`,\n code,\n code_lowercase\nFROM user_referral_codes\nWHERE code_lowercase = ?\n AND deleted_at IS NULL\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "owner_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "code",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "code_lowercase",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "56462cb07d49a001095ff118bfdf4fab4c30d1c7e6dca09a11e82f5956508e0b"
}
@@ -1,25 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: tokens::tokens::users::UserToken`\nFROM users\n WHERE username = ?\nLIMIT 1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
},
"hash": "566a2d56735180e0f17484789d0debd03c68bda20354882e111476bab6132723"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO user_referral_codes (\n token,\n code,\n code_lowercase,\n owner_user_token\n)\nVALUES (?, ?, ?, ?)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "5e2e68267e858b449de90dbf0d5b20d60b8cb82c4a4ddf56a49200ac92912817"
}
@@ -1,12 +1,12 @@
{
"db_name": "MySQL",
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n is_user_upload = ?,\n is_intermediate_system_file = ?,\n\n origin_category = ?, \n origin_product_category = ?, \n maybe_origin_model_type = ?, \n maybe_origin_model_token = ?, \n maybe_origin_filename = ?,\n\n is_batch_generated = ?,\n maybe_batch_token = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n maybe_duration_millis = ?,\n maybe_audio_encoding = ?, \n maybe_video_encoding = ?, \n maybe_frame_width = ?, \n maybe_frame_height = ?,\n maybe_prompt_token = ?,\n checksum_sha2 = ?,\n \n maybe_engine_category = ?,\n\n maybe_title = ?,\n maybe_text_transcript = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n\n maybe_creator_user_token = ?, \n maybe_creator_anonymous_visitor_token = ?, \n\n creator_ip_address = ?, \n creator_set_visibility = ?, \n\n maybe_creator_file_synthetic_id = ?, \n maybe_creator_category_synthetic_id = ?,\n\n extra_file_modification_info = ?,\n\n maybe_generation_provider = ?,\n\n maybe_cover_image_media_file_token = ?,\n\n maybe_mod_user_token = ?,\n is_generated_on_prem = ?,\n generated_by_worker = ?,\n generated_by_cluster = ?\n ",
"query": "\n INSERT INTO media_files\n SET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n is_user_upload = ?,\n is_intermediate_system_file = ?,\n\n origin_category = ?, \n origin_product_category = ?, \n maybe_origin_model_type = ?, \n maybe_origin_model_token = ?, \n maybe_origin_filename = ?,\n\n is_batch_generated = ?,\n maybe_batch_token = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n maybe_duration_millis = ?,\n maybe_audio_encoding = ?, \n maybe_video_encoding = ?, \n maybe_frame_width = ?, \n maybe_frame_height = ?,\n maybe_prompt_token = ?,\n checksum_sha2 = ?,\n \n maybe_engine_category = ?,\n\n maybe_title = ?,\n maybe_text_transcript = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n public_bucket_directory_hash = ?, \n maybe_public_bucket_prefix = ?, \n maybe_public_bucket_extension = ?, \n\n maybe_creator_user_token = ?, \n maybe_creator_anonymous_visitor_token = ?, \n\n creator_ip_address = ?, \n creator_set_visibility = ?, \n\n maybe_creator_file_synthetic_id = ?, \n maybe_creator_category_synthetic_id = ?,\n\n extra_file_modification_info = ?,\n\n maybe_cover_image_media_file_token = ?,\n\n maybe_mod_user_token = ?,\n is_generated_on_prem = ?,\n generated_by_worker = ?,\n generated_by_cluster = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 41
"Right": 40
},
"nullable": []
},
"hash": "a4901f904aa1c00d9afc23faa7008816c6e1b653bd6ad9f0b6772e32000be544"
"hash": "87d5511700985daaabfc9f2972f018d56b6672c07be082daa7c1a782400cb18d"
}
@@ -1,12 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n maybe_prompt_token = ?,\n maybe_batch_token = ?,\n\n maybe_title = ?,\n maybe_duration_millis = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_scene_source_media_file_token = ?,\n\n is_intermediate_system_file = ?,\n is_user_upload = ?,\n\n maybe_generation_provider = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n ",
"query": "\nINSERT INTO media_files\nSET\n token = ?,\n\n media_class = ?,\n media_type = ?,\n\n origin_category = ?,\n origin_product_category = ?,\n\n maybe_engine_category = ?,\n maybe_animation_type = ?,\n\n maybe_mime_type = ?,\n file_size_bytes = ?,\n\n checksum_sha2 = ?,\n\n maybe_prompt_token = ?,\n maybe_batch_token = ?,\n\n maybe_title = ?,\n maybe_duration_millis = ?,\n\n public_bucket_directory_hash = ?,\n maybe_public_bucket_prefix = ?,\n maybe_public_bucket_extension = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n maybe_scene_source_media_file_token = ?,\n is_intermediate_system_file = ?,\n\n maybe_creator_file_synthetic_id = ?,\n maybe_creator_category_synthetic_id = ?,\n\n is_user_upload = TRUE,\n\n maybe_origin_model_type = NULL,\n maybe_origin_model_token = NULL\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 27
"Right": 25
},
"nullable": []
},
"hash": "7369b2f3fd9e7c1e968dc5501ef9bea7e1610fd7a044a0f9ad8b908dfada2b6a"
"hash": "8d6c1f608ec25a74dddf375d525c3e30467c5eba5389094401b74b7dc74552d7"
}
@@ -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_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 maybe_debug_log_event_token = ?,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 16
},
"nullable": []
},
"hash": "8f8b64c0af5383ff3baaa8aa2f2aa22cc760addd850d618ce543fe05816d11e0"
}
@@ -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 = NULL,\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 maybe_debug_log_event_token = ?,\n\n frontend_failure_category = NULL,\n failure_reason = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 14
},
"nullable": []
},
"hash": "99dae5c5f3b3a8e9ce105bff9a9754c3aee92dbf217288c9a7eb925004e3d259"
}
@@ -1,6 +1,6 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n jobs.attempt_count,\n\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\n jobs.product_category as `product_category: enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory`,\n jobs.inference_category as `inference_category: enums::by_table::generic_inference_jobs::inference_category::InferenceCategory`,\n jobs.maybe_model_type,\n jobs.maybe_model_token,\n jobs.maybe_raw_inference_text,\n jobs.maybe_inference_args,\n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n\n jobs.frontend_failure_category as `maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory`,\n jobs.failure_reason,\n\n jobs.on_success_result_entity_type as maybe_result_entity_type,\n jobs.on_success_result_entity_token as maybe_result_entity_token,\n jobs.on_success_result_batch_token as maybe_result_batch_token,\n\n model_weights.title as maybe_model_weights_title,\n tts_models.title as maybe_tts_model_title,\n voice_conversion_models.title as maybe_voice_conversion_model_title,\n\n tts_results.public_bucket_wav_audio_path as maybe_tts_public_bucket_path,\n voice_conversion_results.public_bucket_hash as maybe_voice_conversion_public_bucket_hash,\n\n media_files.public_bucket_directory_hash as maybe_media_file_public_bucket_directory_hash,\n media_files.maybe_public_bucket_prefix as maybe_media_file_public_bucket_prefix,\n media_files.maybe_public_bucket_extension as maybe_media_file_public_bucket_extension,\n\n jobs.assigned_worker as maybe_assigned_worker,\n jobs.assigned_cluster as maybe_assigned_cluster,\n\n jobs.is_keepalive_required,\n\n jobs.created_at,\n jobs.updated_at,\n\n jobs.first_started_at as maybe_first_started_at,\n jobs.successfully_completed_at as maybe_successfully_completed_at,\n\n NOW() as database_clock\n\nFROM generic_inference_jobs as jobs\n\nLEFT OUTER JOIN model_weights ON jobs.maybe_model_token = model_weights.token\nLEFT OUTER JOIN tts_models ON jobs.maybe_model_token = tts_models.token\nLEFT OUTER JOIN voice_conversion_models ON jobs.maybe_model_token = voice_conversion_models.token\n\nLEFT OUTER JOIN tts_results ON jobs.on_success_result_entity_token = tts_results.token\nLEFT OUTER JOIN voice_conversion_results ON jobs.on_success_result_entity_token = voice_conversion_results.token\nLEFT OUTER JOIN media_files ON jobs.on_success_result_entity_token = media_files.token\n\nWHERE jobs.token = ?\n ",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n jobs.attempt_count,\n\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\n jobs.product_category as `product_category: enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory`,\n jobs.inference_category as `inference_category: enums::by_table::generic_inference_jobs::inference_category::InferenceCategory`,\n jobs.maybe_model_type,\n jobs.maybe_model_token,\n jobs.maybe_raw_inference_text,\n jobs.maybe_inference_args,\n\n jobs.frontend_failure_category as `maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory`,\n jobs.failure_reason,\n\n jobs.on_success_result_entity_type as maybe_result_entity_type,\n jobs.on_success_result_entity_token as maybe_result_entity_token,\n jobs.on_success_result_batch_token as maybe_result_batch_token,\n\n model_weights.title as maybe_model_weights_title,\n tts_models.title as maybe_tts_model_title,\n voice_conversion_models.title as maybe_voice_conversion_model_title,\n\n tts_results.public_bucket_wav_audio_path as maybe_tts_public_bucket_path,\n voice_conversion_results.public_bucket_hash as maybe_voice_conversion_public_bucket_hash,\n\n media_files.public_bucket_directory_hash as maybe_media_file_public_bucket_directory_hash,\n media_files.maybe_public_bucket_prefix as maybe_media_file_public_bucket_prefix,\n media_files.maybe_public_bucket_extension as maybe_media_file_public_bucket_extension,\n\n jobs.assigned_worker as maybe_assigned_worker,\n jobs.assigned_cluster as maybe_assigned_cluster,\n\n jobs.is_keepalive_required,\n\n jobs.created_at,\n jobs.updated_at,\n\n jobs.first_started_at as maybe_first_started_at,\n jobs.successfully_completed_at as maybe_successfully_completed_at,\n\n NOW() as database_clock\n\nFROM generic_inference_jobs as jobs\n\nLEFT OUTER JOIN model_weights ON jobs.maybe_model_token = model_weights.token\nLEFT OUTER JOIN tts_models ON jobs.maybe_model_token = tts_models.token\nLEFT OUTER JOIN voice_conversion_models ON jobs.maybe_model_token = voice_conversion_models.token\n\nLEFT OUTER JOIN tts_results ON jobs.on_success_result_entity_token = tts_results.token\nLEFT OUTER JOIN voice_conversion_results ON jobs.on_success_result_entity_token = voice_conversion_results.token\nLEFT OUTER JOIN media_files ON jobs.on_success_result_entity_token = media_files.token\n\nWHERE jobs.token = ?\n ",
"describe": {
"columns": [
{
@@ -125,16 +125,6 @@
},
{
"ordinal": 12,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory",
"type_info": {
"type": "VarString",
@@ -144,7 +134,7 @@
}
},
{
"ordinal": 14,
"ordinal": 13,
"name": "failure_reason",
"type_info": {
"type": "VarString",
@@ -154,7 +144,7 @@
}
},
{
"ordinal": 15,
"ordinal": 14,
"name": "maybe_result_entity_type",
"type_info": {
"type": "VarString",
@@ -164,7 +154,7 @@
}
},
{
"ordinal": 16,
"ordinal": 15,
"name": "maybe_result_entity_token",
"type_info": {
"type": "VarString",
@@ -174,7 +164,7 @@
}
},
{
"ordinal": 17,
"ordinal": 16,
"name": "maybe_result_batch_token",
"type_info": {
"type": "VarString",
@@ -184,7 +174,7 @@
}
},
{
"ordinal": 18,
"ordinal": 17,
"name": "maybe_model_weights_title",
"type_info": {
"type": "VarString",
@@ -194,7 +184,7 @@
}
},
{
"ordinal": 19,
"ordinal": 18,
"name": "maybe_tts_model_title",
"type_info": {
"type": "VarString",
@@ -204,7 +194,7 @@
}
},
{
"ordinal": 20,
"ordinal": 19,
"name": "maybe_voice_conversion_model_title",
"type_info": {
"type": "VarString",
@@ -214,7 +204,7 @@
}
},
{
"ordinal": 21,
"ordinal": 20,
"name": "maybe_tts_public_bucket_path",
"type_info": {
"type": "VarString",
@@ -224,7 +214,7 @@
}
},
{
"ordinal": 22,
"ordinal": 21,
"name": "maybe_voice_conversion_public_bucket_hash",
"type_info": {
"type": "VarString",
@@ -234,7 +224,7 @@
}
},
{
"ordinal": 23,
"ordinal": 22,
"name": "maybe_media_file_public_bucket_directory_hash",
"type_info": {
"type": "VarString",
@@ -244,7 +234,7 @@
}
},
{
"ordinal": 24,
"ordinal": 23,
"name": "maybe_media_file_public_bucket_prefix",
"type_info": {
"type": "VarString",
@@ -254,7 +244,7 @@
}
},
{
"ordinal": 25,
"ordinal": 24,
"name": "maybe_media_file_public_bucket_extension",
"type_info": {
"type": "VarString",
@@ -264,7 +254,7 @@
}
},
{
"ordinal": 26,
"ordinal": 25,
"name": "maybe_assigned_worker",
"type_info": {
"type": "VarString",
@@ -274,7 +264,7 @@
}
},
{
"ordinal": 27,
"ordinal": 26,
"name": "maybe_assigned_cluster",
"type_info": {
"type": "VarString",
@@ -284,7 +274,7 @@
}
},
{
"ordinal": 28,
"ordinal": 27,
"name": "is_keepalive_required",
"type_info": {
"type": "Tiny",
@@ -294,7 +284,7 @@
}
},
{
"ordinal": 29,
"ordinal": 28,
"name": "created_at",
"type_info": {
"type": "Timestamp",
@@ -304,7 +294,7 @@
}
},
{
"ordinal": 30,
"ordinal": 29,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
@@ -314,7 +304,7 @@
}
},
{
"ordinal": 31,
"ordinal": 30,
"name": "maybe_first_started_at",
"type_info": {
"type": "Timestamp",
@@ -324,7 +314,7 @@
}
},
{
"ordinal": 32,
"ordinal": 31,
"name": "maybe_successfully_completed_at",
"type_info": {
"type": "Timestamp",
@@ -334,7 +324,7 @@
}
},
{
"ordinal": 33,
"ordinal": 32,
"name": "database_clock",
"type_info": {
"type": "Datetime",
@@ -375,7 +365,6 @@
true,
true,
true,
true,
false,
false,
false,
@@ -384,5 +373,5 @@
false
]
},
"hash": "6948edca3f06643605695665df51cc94f897e2cb9a2d6906910d58d4d56ee73e"
"hash": "a2c9e2f61eba666254f8432b3c50a0a7738ee3b3faa77c5281bc8e4af96159b9"
}
@@ -1,80 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n id as `id: u64`,\n event_token as `event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken`,\n debug_log_type as `debug_log_type: enums::by_table::debug_logs::debug_log_type::DebugLogType`,\n maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n message,\n created_at\nFROM debug_logs\nWHERE event_token = ?\nORDER BY id ASC\nLIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id: u64",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "debug_log_type: enums::by_table::debug_logs::debug_log_type::DebugLogType",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 96
}
},
{
"ordinal": 3,
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "message",
"type_info": {
"type": "Blob",
"flags": "NOT_NULL | BLOB | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 67108860
}
},
{
"ordinal": 5,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
true,
false,
false
]
},
"hash": "a62b88fec40a11952cc199383090ea338f97091e8bfc6b68aad67416685889af"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO debug_logs\nSET\n event_token = ?,\n debug_log_type = ?,\n maybe_creator_user_token = ?,\n message = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "a9745ecf60b564ab096ee1dbe124221b5f288a4ae38e788e19bbd359db0b580f"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO user_referrals (\n invited_user_token,\n referrer_user_token,\n maybe_referral_code_token,\n maybe_referral_url,\n maybe_landing_url\n)\nVALUES (?, ?, ?, ?, ?)\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
},
"hash": "acd6e67603ca687686513b080bbfa642d3e2ffe8c97b0f9dd646f3ef2f8d92df"
}
@@ -1,146 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE ur.id < ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id: u64",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "invited_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "invited_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "invited_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "invited_email_address: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "referrer_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "referrer_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 7,
"name": "referrer_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_referral_code_token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "maybe_referral_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_landing_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false
]
},
"hash": "b2049fa1c9f76c73a9a22144de716b47dccdd35caeefb3721e75ec9aaf4614f0"
}
@@ -1,69 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: UserReferralCodeToken`,\n code,\n code_lowercase,\n created_at,\n updated_at\nFROM user_referral_codes\nWHERE owner_user_token = ?\n AND deleted_at IS NULL\nORDER BY created_at ASC\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 1,
"name": "code",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "code_lowercase",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | BINARY",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 4,
"name": "updated_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false
]
},
"hash": "b5ce1dffc1d6e1762844f3a040a9a9cba2a608931824d99eebba67a7d718719e"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nUPDATE user_referral_codes\nSET\n deleted_at = CURRENT_TIMESTAMP,\n code_lowercase = ?\nWHERE token = ?\n AND owner_user_token = ?\n AND deleted_at IS NULL\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "b8254ed110147c66fbeef783283ff4b2565b60c9443572c67091ecd60c9d97d6"
}
@@ -1,146 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE referrer.username = ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id: u64",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "invited_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "invited_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "invited_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "invited_email_address: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "referrer_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "referrer_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 7,
"name": "referrer_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_referral_code_token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "maybe_referral_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_landing_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false
]
},
"hash": "e73dfa3af6a1a8f510f084435da86571e096f3d7e597fb01d6397d380b135341"
}
@@ -1,355 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n token as `token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n uuid_idempotency_token,\n job_type as `maybe_job_type`,\n product_category as `maybe_product_category`,\n inference_category,\n maybe_external_third_party,\n maybe_external_third_party_id,\n maybe_model_type,\n maybe_model_token,\n maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n maybe_inference_args,\n maybe_download_url,\n on_success_result_entity_type,\n on_success_result_entity_token,\n on_success_result_batch_token,\n maybe_creator_user_token as `maybe_creator_user_token: tokens::tokens::users::UserToken`,\n maybe_creator_anonymous_visitor_token,\n creator_ip_address,\n creator_set_visibility,\n maybe_wallet_ledger_entry_token,\n maybe_debug_log_event_token as `maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken`,\n status,\n attempt_count as `attempt_count: u16`,\n failure_reason,\n internal_debugging_failure_reason,\n frontend_failure_category,\n maybe_routing_tag,\n assigned_worker,\n assigned_cluster,\n created_at,\n updated_at\nFROM generic_inference_jobs\nWHERE token = ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "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": 1,
"name": "uuid_idempotency_token",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 144
}
},
{
"ordinal": 2,
"name": "maybe_job_type",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 3,
"name": "maybe_product_category",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 4,
"name": "inference_category",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 5,
"name": "maybe_external_third_party",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 64
}
},
{
"ordinal": 6,
"name": "maybe_external_third_party_id",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 7,
"name": "maybe_model_type",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 8,
"name": "maybe_model_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 10,
"name": "maybe_inference_args",
"type_info": {
"type": "Blob",
"flags": "BLOB | BINARY",
"char_set": 224,
"max_size": 262140
}
},
{
"ordinal": 11,
"name": "maybe_download_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 4096
}
},
{
"ordinal": 12,
"name": "on_success_result_entity_type",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 13,
"name": "on_success_result_entity_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 14,
"name": "on_success_result_batch_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 15,
"name": "maybe_creator_user_token: tokens::tokens::users::UserToken",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 16,
"name": "maybe_creator_anonymous_visitor_token",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 17,
"name": "creator_ip_address",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 160
}
},
{
"ordinal": 18,
"name": "creator_set_visibility",
"type_info": {
"type": "String",
"flags": "NOT_NULL | BINARY | ENUM",
"char_set": 224,
"max_size": 28
}
},
{
"ordinal": 19,
"name": "maybe_wallet_ledger_entry_token",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 20,
"name": "maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 21,
"name": "status",
"type_info": {
"type": "String",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
"char_set": 224,
"max_size": 76
}
},
{
"ordinal": 22,
"name": "attempt_count: u16",
"type_info": {
"type": "Short",
"flags": "NOT_NULL | UNSIGNED",
"char_set": 63,
"max_size": 5
}
},
{
"ordinal": 23,
"name": "failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 24,
"name": "internal_debugging_failure_reason",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 2048
}
},
{
"ordinal": 25,
"name": "frontend_failure_category",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 26,
"name": "maybe_routing_tag",
"type_info": {
"type": "VarString",
"flags": "MULTIPLE_KEY | BINARY",
"char_set": 224,
"max_size": 256
}
},
{
"ordinal": 27,
"name": "assigned_worker",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 512
}
},
{
"ordinal": 28,
"name": "assigned_cluster",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 512
}
},
{
"ordinal": 29,
"name": "created_at",
"type_info": {
"type": "Timestamp",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
"char_set": 63,
"max_size": 19
}
},
{
"ordinal": 30,
"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,
true,
true,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true,
true,
true,
true,
true,
false,
false
]
},
"hash": "e869f065e6f184abbabae04ecd0da6ea02c0576cc22ee55e47eb91dd34048ef1"
}
@@ -1,146 +0,0 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE referrer.username = ?\n AND ur.id < ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id: u64",
"type_info": {
"type": "LongLong",
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
"char_set": 63,
"max_size": 20
}
},
{
"ordinal": 1,
"name": "invited_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 2,
"name": "invited_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 3,
"name": "invited_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 4,
"name": "invited_email_address: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 5,
"name": "referrer_user_token: UserToken",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 6,
"name": "referrer_username: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 7,
"name": "referrer_display_name: String",
"type_info": {
"type": "VarString",
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
"char_set": 224,
"max_size": 80
}
},
{
"ordinal": 8,
"name": "maybe_referral_code_token: UserReferralCodeToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "maybe_referral_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 10,
"name": "maybe_landing_url",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 1020
}
},
{
"ordinal": 11,
"name": "created_at",
"type_info": {
"type": "Datetime",
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
"char_set": 63,
"max_size": 19
}
}
],
"parameters": {
"Right": 3
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false
]
},
"hash": "fb021a5fe7a6c0e284968d917f9d612953629d20a06efccc3fce3d930a7fe266"
}
@@ -1,6 +1,6 @@
{
"db_name": "MySQL",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n \n jobs.maybe_external_third_party as `external_third_party: enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty`,\n jobs.maybe_external_third_party_id as `external_third_party_id`,\n\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 \n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n jobs.maybe_debug_log_event_token as `maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken`,\n\n jobs.created_at,\n jobs.updated_at\n\nFROM generic_inference_jobs as jobs\n\nWHERE jobs.maybe_external_third_party = ?\nAND jobs.maybe_external_third_party_id = ?\n ",
"query": "\nSELECT\n jobs.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n\n jobs.status as `status: enums::common::job_status_plus::JobStatusPlus`,\n \n jobs.maybe_external_third_party as `external_third_party: enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty`,\n jobs.maybe_external_third_party_id as `external_third_party_id`,\n\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 \n jobs.maybe_prompt_token as `maybe_prompt_token: tokens::tokens::prompts::PromptToken`,\n\n jobs.created_at,\n jobs.updated_at\n\nFROM generic_inference_jobs as jobs\n\nWHERE jobs.maybe_external_third_party = ?\nAND jobs.maybe_external_third_party_id = ?\n ",
"describe": {
"columns": [
{
@@ -85,16 +85,6 @@
},
{
"ordinal": 8,
"name": "maybe_debug_log_event_token: tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken",
"type_info": {
"type": "VarString",
"flags": "BINARY",
"char_set": 224,
"max_size": 128
}
},
{
"ordinal": 9,
"name": "created_at",
"type_info": {
"type": "Timestamp",
@@ -104,7 +94,7 @@
}
},
{
"ordinal": 10,
"ordinal": 9,
"name": "updated_at",
"type_info": {
"type": "Timestamp",
@@ -126,10 +116,9 @@
true,
false,
true,
true,
false,
false
]
},
"hash": "2c98621c08055374fd09502c94ac40bb01d23fcea3f844cceea7446a5c0cb4dc"
"hash": "fbe482c8987231c3b5d75f2e792d0fdd033de8a7eb821428fa034752c73edfb7"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO user_sessions (\n token,\n user_token,\n ip_address_creation,\n expires_at\n)\nVALUES ( ?, ?, ?, NOW() + interval 1 year )\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "ff9690b62bcc93212ecf9698d9ae1d12e6284fd4a8259986f6967bf5c29462f1"
}
-2
View File
@@ -62,7 +62,6 @@ artcraft/
- A mix of wreq and reqwest for Rust HTTP clients
- Never use `println!` or `eprintln!` outside of tests; use `log` crate macros instead
- When two crates export the same type name, alias imports with a suffix: `use foo::Bar as BarFoo;`
- Prefer `use` imports over inline fully-qualified paths; only qualify inline for true one-offs or std collisions
- TypeScript with Nx, React, Vite, Zustand, and Three.js
- Use two spaces for indentation
@@ -76,4 +75,3 @@ Organize for top-to-bottom reading. Important things first, details later.
- **In impl blocks**: constructors first, then public methods, then private helpers
- Private helpers go *below* the methods that call them
- Among helpers: meatier logic above leaf-level formatters
- **In test modules**: constants first, then test cases (grouped into sub-modules when 2+), then helper functions last
Generated
-75
View File
@@ -679,7 +679,6 @@ dependencies = [
"discord-rich-presence",
"enums",
"errors",
"fal_client",
"filesys",
"futures 0.3.32",
"grok_client",
@@ -773,7 +772,6 @@ dependencies = [
"artcraft_client",
"enums",
"fal_client",
"gmicloud_client",
"log",
"muapi_client",
"reqwest 0.12.23",
@@ -1406,22 +1404,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "beeble_client"
version = "0.0.1"
dependencies = [
"anyhow",
"errors",
"log",
"reqwest 0.12.23",
"serde",
"serde_derive",
"serde_json",
"test_data",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "bigdecimal"
version = "0.3.1"
@@ -4691,56 +4673,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gmicloud-job"
version = "0.0.1"
dependencies = [
"actix-web",
"actix_helpers",
"anyhow",
"bootstrap",
"bucket_paths",
"cloud_storage",
"concurrency",
"easyenv",
"enums",
"errors",
"gmicloud_client",
"hashing",
"jobs_common",
"log",
"mysql_queries",
"pager",
"reqwest 0.12.23",
"rootly_client",
"rootly_config",
"serde",
"serde_derive",
"serde_json",
"server_environment",
"shared_env_var_config",
"sqlx",
"tokens",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "gmicloud_client"
version = "0.0.1"
dependencies = [
"errors",
"log",
"reqwest 0.12.23",
"serde",
"serde_derive",
"serde_json",
"test_data",
"test_utils",
"tokio",
"workspace-build-acceleration",
]
[[package]]
name = "gobject-sys"
version = "0.18.0"
@@ -11302,7 +11234,6 @@ dependencies = [
"async-stripe 0.26.0",
"async-trait",
"base64 0.22.1",
"beeble_client",
"billing_artcraft_component",
"billing_component",
"bootstrap",
@@ -11330,7 +11261,6 @@ dependencies = [
"futures 0.1.31",
"futures 0.3.32",
"futures-util",
"gmicloud_client",
"google_sign_in",
"hashing",
"hostname 0.4.0",
@@ -11539,18 +11469,13 @@ name = "support-tool"
version = "0.0.1"
dependencies = [
"anyhow",
"artcraft_api_defs",
"artcraft_client",
"clap 4.5.60",
"easyenv",
"enums",
"errors",
"log",
"seedance2pro_client",
"serde_json",
"tokens",
"tokio",
"uuid 1.22.0",
]
[[package]]
-5
View File
@@ -14,10 +14,8 @@ members = [
"crates/api_clients/google_drive_downloader",
"crates/api_clients/google_sign_in",
"crates/api_clients/grok_client",
"crates/api_clients/gmicloud_client",
"crates/api_clients/midjourney_client",
"crates/api_clients/muapi_client",
"crates/api_clients/beeble_client",
"crates/api_clients/openai_sora_client",
"crates/api_clients/openart_client",
"crates/api_clients/rootly_client",
@@ -124,7 +122,6 @@ members = [
"crates/schema/public/tokens",
# Services: API servers, jobs, workers, etc.
"crates/service/job/gmicloud_job",
"crates/service/job/seedance2_pro_job",
"crates/service/job/video_thumbnail_job",
"crates/service/job/worldlabs_job",
@@ -244,11 +241,9 @@ enums = { path = "crates/schema/public/enums" }
error_utils = { path = "crates/lib/error_utils" }
errors = { path = "crates/lib/errors" }
fal_client = { path = "crates/api_clients/fal_client" }
gmicloud_client = { path = "crates/api_clients/gmicloud_client" }
ffmpeg_utils = { path = "crates/lib/ffmpeg_utils" }
file_to_base64_url = { path = "crates/lib/files/file_to_base64_url" }
filesys = { path = "crates/lib/files/filesys" }
beeble_client = { path = "crates/api_clients/beeble_client" }
grok_client = { path = "crates/api_clients/grok_client" }
rootly_client = { path = "crates/api_clients/rootly_client" }
rootly_config = { path = "crates/schema/config/rootly_config" }
@@ -1,30 +0,0 @@
-- Daily active "power users" for ArtCraft since January 1st, 2026.
-- A "power user" is a user who created more than 10 ArtCraft inference jobs in the calendar month.
-- This query then counts how many such power users were active on each day.
SELECT
DATE(j.created_at) AS day,
COUNT(DISTINCT j.maybe_creator_user_token) AS daily_active_power_users
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
INNER JOIN (
SELECT maybe_creator_user_token, DATE_FORMAT(created_at, '%Y-%m') AS month
FROM generic_inference_jobs
WHERE created_at >= '2026-01-01'
AND maybe_creator_user_token IS NOT NULL
AND job_type NOT IN (
'gpt_sovits', 'tacotron2', 'rvc_v2', 'f5_tts',
'so_vits_svc', 'styletts2', 'face_fusion', 'seed_vc', 'comfy_ui'
)
GROUP BY maybe_creator_user_token, month
HAVING COUNT(*) > 10
) power ON power.maybe_creator_user_token = j.maybe_creator_user_token
AND power.month = DATE_FORMAT(j.created_at, '%Y-%m')
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits', 'tacotron2', 'rvc_v2', 'f5_tts',
'so_vits_svc', 'styletts2', 'face_fusion', 'seed_vc', 'comfy_ui'
)
GROUP BY day
ORDER BY day DESC;
@@ -1,24 +0,0 @@
-- Daily active users for ArtCraft since January 1st, 2026.
-- A "daily active user" is a user who created at least one ArtCraft inference job that day.
SELECT
DATE(j.created_at) AS day,
COUNT(DISTINCT j.maybe_creator_user_token) AS daily_active_users
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits',
'tacotron2',
'rvc_v2',
'f5_tts',
'so_vits_svc',
'styletts2',
'face_fusion',
'seed_vc',
'comfy_ui'
)
GROUP BY DATE(j.created_at)
ORDER BY day DESC;
@@ -1,23 +0,0 @@
-- Monthly active "power users" for ArtCraft since January 1st, 2026.
-- A "power user" is a user who created more than 10 ArtCraft inference jobs in the calendar month.
SELECT
month,
COUNT(*) AS monthly_active_power_users
FROM (
SELECT
maybe_creator_user_token,
DATE_FORMAT(j.created_at, '%Y-%m') AS month
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits', 'tacotron2', 'rvc_v2', 'f5_tts',
'so_vits_svc', 'styletts2', 'face_fusion', 'seed_vc', 'comfy_ui'
)
GROUP BY maybe_creator_user_token, month
HAVING COUNT(*) > 10
) power
GROUP BY month
ORDER BY month DESC;
@@ -1,23 +0,0 @@
-- Monthly active users for ArtCraft since January 1st, 2026.
-- A "monthly active user" is a user who created at least one ArtCraft inference job that month.
SELECT
DATE_FORMAT(j.created_at, '%Y-%m') AS month,
COUNT(DISTINCT j.maybe_creator_user_token) AS monthly_active_users
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits',
'tacotron2',
'rvc_v2',
'f5_tts',
'so_vits_svc',
'styletts2',
'face_fusion',
'seed_vc',
'comfy_ui'
)
GROUP BY month
ORDER BY month DESC;
@@ -1,30 +0,0 @@
-- Weekly active "power users" for ArtCraft since January 1st, 2026.
-- A "power user" is a user who created more than 10 ArtCraft inference jobs in the calendar month.
-- This query then counts how many such power users were active in each week.
SELECT
DATE(DATE_SUB(j.created_at, INTERVAL WEEKDAY(j.created_at) DAY)) AS week_start,
COUNT(DISTINCT j.maybe_creator_user_token) AS weekly_active_power_users
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
INNER JOIN (
SELECT maybe_creator_user_token, DATE_FORMAT(created_at, '%Y-%m') AS month
FROM generic_inference_jobs
WHERE created_at >= '2026-01-01'
AND maybe_creator_user_token IS NOT NULL
AND job_type NOT IN (
'gpt_sovits', 'tacotron2', 'rvc_v2', 'f5_tts',
'so_vits_svc', 'styletts2', 'face_fusion', 'seed_vc', 'comfy_ui'
)
GROUP BY maybe_creator_user_token, month
HAVING COUNT(*) > 10
) power ON power.maybe_creator_user_token = j.maybe_creator_user_token
AND power.month = DATE_FORMAT(j.created_at, '%Y-%m')
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits', 'tacotron2', 'rvc_v2', 'f5_tts',
'so_vits_svc', 'styletts2', 'face_fusion', 'seed_vc', 'comfy_ui'
)
GROUP BY week_start
ORDER BY week_start DESC;
@@ -1,23 +0,0 @@
-- Weekly active users for ArtCraft since January 1st, 2026.
-- A "weekly active user" is a user who created at least one ArtCraft inference job that week.
SELECT
DATE(DATE_SUB(j.created_at, INTERVAL WEEKDAY(j.created_at) DAY)) AS week_start,
COUNT(DISTINCT j.maybe_creator_user_token) AS weekly_active_users
FROM generic_inference_jobs j
INNER JOIN users u ON u.token = j.maybe_creator_user_token
WHERE j.created_at >= '2026-01-01'
AND j.maybe_creator_user_token IS NOT NULL
AND j.job_type NOT IN (
'gpt_sovits',
'tacotron2',
'rvc_v2',
'f5_tts',
'so_vits_svc',
'styletts2',
'face_fusion',
'seed_vc',
'comfy_ui'
)
GROUP BY week_start
ORDER BY week_start DESC;
@@ -19,10 +19,6 @@
-- tasks_v6.sqlite - added two fields:
-- on_failure_type
-- on_failure_message
-- tasks_v7.sqlite - added prompt token + two fields (for fal):
-- prompt_token
-- queue_status_url
-- queue_response_url
CREATE TABLE tasks (
-- Task auto-incrementing primary key.
@@ -50,11 +46,6 @@ CREATE TABLE tasks (
-- The primary key for the job in the provider's system.
provider_job_id TEXT,
-- OPTIONAL.
-- For third party jobs, we need to record the prompt details upfront.
-- We create a prompt record and store the token to associate once the task completes.
prompt_token TEXT,
-- OPTIONAL.
-- Tell the job system which caller initiated the task.
-- e.g. 'canvas'
@@ -72,16 +63,6 @@ CREATE TABLE tasks (
-- Whether the user has dismissed the task from view.
is_dismissed_by_user INTEGER NOT NULL DEFAULT 0,
-- OPTIONAL.
-- For some third party systems (eg. FAL), the URL to check the status of the
-- job in the queue.
queue_status_url TEXT,
-- OPTIONAL.
-- For some third party systems (eg. FAL), the URL to check the
-- results (when the job completes)
queue_response_url TEXT,
-- OPTIONAL.
-- When the generation completes, the batch token (if any).
-- This will point to a collection of multiple files.
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE prompts
DROP COLUMN maybe_quality;
@@ -1,8 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
-- Add quality parameter to prompts table.
-- Represented by the enum `CommonQuality` (high, medium, low).
ALTER TABLE prompts
ADD COLUMN maybe_quality VARCHAR(16) DEFAULT NULL;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE IF EXISTS debug_logs;
@@ -1,31 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE debug_logs (
-- Not used for anything except replication.
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- Event token. Not unique — multiple log rows can share the same event.
event_token VARCHAR(32) NOT NULL,
-- The type of debug log entry.
debug_log_type VARCHAR(24) NOT NULL,
-- The user who created the log entry (if any).
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- The log message body.
message MEDIUMTEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
KEY index_event_token (event_token),
KEY index_debug_log_type (debug_log_type),
KEY index_maybe_creator_user_token (maybe_creator_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
DROP COLUMN maybe_debug_log_event_token;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE generic_inference_jobs
ADD COLUMN maybe_debug_log_event_token VARCHAR(32) DEFAULT NULL;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
DROP COLUMN maybe_referral_partner;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
ADD COLUMN maybe_referral_partner VARCHAR(32) DEFAULT NULL;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
DROP COLUMN maybe_referral_user_token;
@@ -1,6 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
ALTER TABLE users
ADD COLUMN maybe_referral_user_token VARCHAR(32) DEFAULT NULL;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE IF EXISTS user_referrals;
@@ -1,31 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE user_referrals (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- The user who was invited/referred.
invited_user_token VARCHAR(32) NOT NULL,
-- The user who referred the invited user.
referrer_user_token VARCHAR(32) NOT NULL,
-- OPTIONAL. The referral code token used, if any.
maybe_referral_code_token VARCHAR(32) DEFAULT NULL,
-- OPTIONAL. The referral URL the invited user arrived from.
maybe_referral_url VARCHAR(255) DEFAULT NULL,
-- OPTIONAL. The landing URL the invited user first visited.
maybe_landing_url VARCHAR(255) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY unique_invited_user_token (invited_user_token),
KEY index_referrer_user_token (referrer_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,5 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
DROP TABLE IF EXISTS user_referral_codes;
@@ -1,34 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE user_referral_codes (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- Unique token identifier for this referral code record.
token VARCHAR(32) NOT NULL,
-- The human-readable referral code (e.g. a username or custom code).
-- This can be changed.
code VARCHAR(32) NOT NULL,
-- Lowercased version of `code` for case-insensitive uniqueness lookups.
code_lowercase VARCHAR(32) NOT NULL,
-- The user who owns this referral code.
owner_user_token VARCHAR(32) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Soft delete.
deleted_at DATETIME NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY unique_token (token),
UNIQUE KEY unique_code_lowercase (code_lowercase),
KEY index_owner_user_token (owner_user_token),
KEY index_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,31 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE debug_logs (
-- Not used for anything except replication.
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- Event token. Not unique — multiple log rows can share the same event.
event_token VARCHAR(32) NOT NULL,
-- The type of debug log entry.
debug_log_type VARCHAR(24) NOT NULL,
-- The user who created the log entry (if any).
maybe_creator_user_token VARCHAR(32) DEFAULT NULL,
-- The log message body.
message MEDIUMTEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
KEY index_event_token (event_token),
KEY index_debug_log_type (debug_log_type),
KEY index_maybe_creator_user_token (maybe_creator_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -109,7 +109,7 @@ CREATE TABLE generic_inference_jobs (
-- If we pre-constructed a prompt, this will be copied to the resultant media generated.
-- This is especially important for Fal-related jobs and endpoints. We need this for keeping
-- track of all the prompt details, context images, etc.
maybe_prompt_token VARCHAR(32) DEFAULT NULL,
maybe_prompt_token VARCHAR(30) DEFAULT NULL,
-- A migration flag we can control from the backend API service which will tell
-- the worker where to store the results. If false, GCP. If true, AWS.
@@ -204,10 +204,6 @@ CREATE TABLE generic_inference_jobs (
-- off special workers to handle certain jobs.
maybe_routing_tag VARCHAR(64) DEFAULT NULL,
-- Foreign key to the debug_logs table (event_token column).
-- Multiple debug_logs rows can share the same event token.
maybe_debug_log_event_token VARCHAR(32) DEFAULT NULL,
-- ========== JOB SYSTEM DETAILS ==========
-- Jobs begin as "pending", then transition to other states.
@@ -28,7 +28,6 @@ CREATE TABLE media_files (
-- There is an index on this column.
-- Broad "category" for where the file came from:
-- * 'inference' for inference output
-- * 'inference_third' for inference output
-- * 'processed' for processed file (eg. mp3 encoding, stem splitting, etc.)
-- * 'upload' for direct user upload (from the filesystem)
-- * 'device_api' for direct user uploads recorded using Browser/Device APIs.
@@ -68,10 +68,6 @@ CREATE TABLE prompts (
-- The resolution for the prompt (eg. four_k, 720p, etc.)
maybe_resolution VARCHAR(16) DEFAULT NULL,
-- Represented by the enum `CommonQuality`.
-- The quality setting (eg. high, medium, low)
maybe_quality VARCHAR(16) DEFAULT NULL,
-- The duration in seconds
maybe_duration_seconds INT UNSIGNED DEFAULT NULL,
@@ -1,33 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE user_referral_codes (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- Unique token identifier for this referral code record.
token VARCHAR(32) NOT NULL,
-- The human-readable referral code (e.g. a username or custom code).
code VARCHAR(32) NOT NULL,
-- Lowercased version of `code` for case-insensitive uniqueness lookups.
code_lowercase VARCHAR(32) NOT NULL,
-- The user who owns this referral code.
owner_user_token VARCHAR(32) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- Soft delete.
deleted_at DATETIME NULL,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY unique_token (token),
UNIQUE KEY unique_code_lowercase (code_lowercase),
KEY index_owner_user_token (owner_user_token),
KEY index_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -1,31 +0,0 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
CREATE TABLE user_referrals (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-- The user who was invited/referred.
invited_user_token VARCHAR(32) NOT NULL,
-- The user who referred the invited user.
referrer_user_token VARCHAR(32) NOT NULL,
-- OPTIONAL. The referral code token used, if any.
maybe_referral_code_token VARCHAR(32) DEFAULT NULL,
-- OPTIONAL. The referral URL the invited user arrived from.
maybe_referral_url VARCHAR(255) DEFAULT NULL,
-- OPTIONAL. The landing URL the invited user first visited.
maybe_landing_url VARCHAR(255) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- INDICES --
PRIMARY KEY (id),
UNIQUE KEY unique_invited_user_token (invited_user_token),
KEY index_referrer_user_token (referrer_user_token),
KEY index_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@@ -202,20 +202,9 @@ CREATE TABLE users (
-- ========== TRACKING ==========
-- Where the user signed up from
--
-- ArtCraft Values:
-- - "artcraft" - (deprecated)
-- - "artcraft_app" - Signup with the ArtCraft app
-- - "artcraft_get_web" - Signup with ArtCraft website signup flow
-- - "artcraft_get_s" - Signup with ArtCraft website Stripe Checkout Flow
-- - "artcraft_ai_s" - Signup with Artcraft.ai website Stripe checkout flow
-- - "artcraft_get_web" - Signup with ArtCraft.ai website signup flow
--
-- Other Sources:
-- - "fakeyou" - FakeYou signup
-- - "storyteller" - Storyteller.ai signup
--
-- Where the user signed up from (NOT NECESSARILY AN ENUM!)
-- For now this will be "artcraft", "fakeyou", or "storyteller",
-- though we may extend or overload this to handle other cases or metadata.
maybe_source VARCHAR(255) DEFAULT NULL,
-- How users created their account
@@ -240,13 +229,6 @@ CREATE TABLE users (
-- This helps us know what marketing is effective.
maybe_landing_url VARCHAR(255) DEFAULT NULL,
-- If a user referred this user, this is either the raw username or raw "referral code"
-- that this user used to sign up. This is not verified and can be used for debugging.
maybe_referral_partner VARCHAR(32) DEFAULT NULL,
-- If a user referred this user, we record the user token of the referrer.
maybe_referral_user_token VARCHAR(32) DEFAULT NULL,
-- ========== MODERATION DETAILS ==========
-- Different than deleted.
@@ -15,12 +15,11 @@ body:
type: json
content: |
{
"model": "gpt_image_2",
"model": "seedream_5_lite",
"provider": "artcraft",
"generation_mode": {"type": "text_to_image" },
"aspect_ratio": "wide_sixteen_by_nine",
"resolution": "two_k",
"quality": "low",
"image_batch_count": 1
}
order: 2000
@@ -1,3 +0,0 @@
$kind: collection
name: edit
order: 312
@@ -1,23 +0,0 @@
$kind: http-request
name: Beeble SwitchX Edit Video
url: "{{api_host}}/v1/generate/video/edit/beeble_switchx"
method: POST
headers:
- key: Accept
value: application/json
- key: Session
value: ""
disabled: true
body:
type: json
content: >-
{
"uuid_idempotency_token": "{{$randomUUID}}",
//"source_video_media_token": "m_6vve5gffn2r4rajyvy8z2380x15kqc", // two corgis (dev)
"source_video_media_token": "m_rkgdk7qw0a7gz4mrzfv0q78ax57kbx", // corgi cowboy (dev)
//"source_video_media_token": "m_1k19k6dgdny253zag8g3jqf3bgemss", // corgi watermellon (prod)
"reference_image_media_token": "m_pf310vdhc4v98n7r8mz70bz9geest3" // tornado (dev)
//"reference_image_media_token": "m_z4y097t9pdmbyatf70z0qb8zvfphvm" // cactus (prod)
//"prompt": "Stormy skies, there's a rotating tornado in the background"
}
order: 1778262498846
@@ -1,11 +0,0 @@
$kind: http-request
name: Batch Get Prompt
url: "{{api_host}}/v1/prompts/prompt_8q8fwcmh93nn8pjb2szeqbxgz"
method: GET
headers:
- key: Accept
value: application/json
- key: Session
value: ""
disabled: true
order: 2171327660164107
@@ -9,7 +9,7 @@ body:
// hanashi : password (dev)
//"username_or_email": "hanashi",
//"password": "hanashi"
"username_or_email": "newuser4",
"password": "newuser4"
"username_or_email": "newuser2",
"password": "newuser2"
}
order: 1000
-59
View File
@@ -1,59 +0,0 @@
# Rust Workspace
All Rust code lives under `crates/`. The workspace is defined in `Cargo.toml` at the repo root.
## Code Style
- Two spaces for indentation (not four)
- No minimum supported Rust version; use latest stable features freely
- Never use `println!` or `eprintln!` outside of tests; use `log` crate macros instead
- Use `anyhow::Result` / `AnyhowResult` for fallible functions in application code
- Fields that are optional use the `maybe_` prefix: `maybe_creator_user_token`
- When two crates export the same type name, alias with a suffix: `use foo::Bar as BarFoo;`
- Prefer `use` imports over inline fully-qualified paths; only qualify inline for true one-offs or std prelude collisions (`Result`, `Option`, `Error`)
## File Layout
Organize for top-to-bottom reading. Important things first, details later.
1. **Constants** at the top (after imports)
2. **Primary public type** (the main struct/enum the file defines)
3. **Supporting types** below the primary type
4. **API types** in order: Request, Response, Error
5. **`impl` blocks** after their type definitions
- Constructors first, then public methods, then private helpers
- Callers above callees — follow the call chain downward
## Test Layout
Within `#[cfg(test)] mod tests { ... }`:
1. **Imports**
2. **Constants** (test IDs, URLs, fixture data) — small context that tests reference
3. **Test functions or sub-modules** grouped by category
4. **Helper functions** (builders, pipeline runners, assertions)
Constants provide small context up front. Test cases come next so engineers see *what* is
tested before *how* the helpers work.
Group related tests into sub-modules (`mod pricing_tests { ... }`) when a category has 2+
tests. Don't wrap a single test in its own module. Keep nesting to two levels max. Shared
helpers go in the parent `mod tests` so sub-modules can `use super::*`.
## Building
- Most crates: `cargo check -p {crate_name}` or `cargo test -p {crate_name}`
- Crates using SQLx: `SQLX_OFFLINE=true cargo check -p {crate_name}`
- `storyteller-web` and `mysql_queries` require `SQLX_OFFLINE=true`
- `storyteller-web` has ~370 pre-existing warnings — check the last few lines for actual errors
## Key Crates
- `storyteller_web` — main HTTP API monolith (actix-web)
- `artcraft` (desktop) — Tauri desktop app
- `artcraft_router` — provider routing for image/video generation (Artcraft, Fal, Seedance2Pro, Muapi)
- `artcraft_api_defs` — shared HTTP API type definitions
- `seedance2pro_client` — HTTP client for the Kinovi/Seedance2Pro video generation service
- `enums` — database-backed enums stored as VARCHAR fields
- `tokens` — primary key identifiers with Stripe-like prefixes (e.g. `user_`, `mf_`)
- `mysql_queries` — SQLx MySQL queries for the backend
@@ -3,14 +3,13 @@ use utoipa::ToSchema;
use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
use enums::common::generation::common_image_model::CommonImageModel;
use enums::common::generation::common_quality::CommonQuality;
use enums::common::generation::common_resolution::CommonResolution;
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, Debug)]
#[derive(Serialize, Deserialize, ToSchema)]
pub struct EstimateImageCostRequest {
/// The image model to estimate costs for.
pub model: CommonImageModel,
@@ -30,15 +29,12 @@ pub struct EstimateImageCostRequest {
/// Optional resolution.
pub resolution: Option<CommonResolution>,
// Optional quality.
pub quality: Option<CommonQuality>,
/// 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, Debug)]
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GenerationMode {
/// No input images — generate from prompt only.
@@ -98,7 +94,6 @@ mod tests {
generation_mode: GenerationMode::TextToImage,
aspect_ratio: None,
resolution: None,
quality: None,
image_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
@@ -113,7 +108,6 @@ mod tests {
generation_mode: GenerationMode::ImageEdit { count: 2 },
aspect_ratio: None,
resolution: None,
quality: None,
image_batch_count: None,
};
let serialized = serde_json::to_string(&request).unwrap();
@@ -1,20 +0,0 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const BEEBLE_SWITCHX_EDIT_VIDEO_PATH: &str = "/v1/generate/video/edit/beeble_switchx";
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct BeebleSwitchXEditVideoRequest {
pub uuid_idempotency_token: String,
pub source_video_media_token: Option<MediaFileToken>,
pub reference_image_media_token: Option<MediaFileToken>,
pub prompt: Option<String>,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BeebleSwitchXEditVideoResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -1 +0,0 @@
pub mod beeble_switchx_edit_video;
@@ -1,4 +1,3 @@
pub mod edit;
pub mod generate_kling_1_6_pro_image_to_video;
pub mod generate_kling_2_1_master_image_to_video;
pub mod generate_kling_2_1_pro_image_to_video;
@@ -7,7 +7,7 @@ use utoipa::ToSchema;
pub const SEEDANCE_2P0_MULTI_FUNCTION_VIDEO_GEN_PATH: &str = "/v1/generate/video/multi_function/seedance_2p0";
/// Seedance 2.0 multi-function video generation (text-to-video, image-to-video, and reference-based).
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Seedance2p0MultiFunctionVideoGenRequest {
/// Idempotency token to prevent duplicate requests.
pub uuid_idempotency_token: String,
@@ -1,17 +1,16 @@
use crate::common::responses::job_details::{JobDetailsLipsyncRequest, JobDetailsLivePortraitRequest};
use crate::common::responses::media_links::MediaLinks;
use chrono::{DateTime, Utc};
use enums::api_safe::by_table::generic_inference_jobs::frontend_failure_category_for_api_clients::FrontendFailureCategoryForApiClients;
use enums::api_safe::by_table::generic_inference_jobs::frontend_failure_category_for_old_clients::FrontendFailureCategoryForOldClients;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::common::job_status_plus::JobStatusPlus;
use enums::no_table::style_transfer::style_transfer_name::StyleTransferName;
use serde::Deserialize;
use serde::Serialize;
use tokens::tokens::batch_generations::BatchGenerationToken;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::prompts::PromptToken;
use utoipa::{IntoParams, ToSchema};
use enums::api_safe::by_table::generic_inference_jobs::frontend_failure_category_for_api_clients::FrontendFailureCategoryForApiClients;
use enums::api_safe::by_table::generic_inference_jobs::frontend_failure_category_for_old_clients::FrontendFailureCategoryForOldClients;
use tokens::tokens::batch_generations::BatchGenerationToken;
pub const LIST_SESSION_JOBS_URL_PATH: &str = "/v1/jobs/session";
@@ -54,9 +53,6 @@ pub struct ListSessionJobsItem {
#[derive(Serialize, Deserialize, ToSchema)]
pub struct ListSessionRequestDetailsResponse {
pub inference_category: InferenceCategory,
pub maybe_prompt_token: Option<PromptToken>,
pub maybe_model_type: Option<String>,
pub maybe_model_token: Option<String>,
@@ -10,7 +10,6 @@ pub mod omni_gen;
pub mod prompts;
pub mod stripe_artcraft;
pub mod subscriptions;
pub mod user_referral_codes;
pub mod users;
pub mod utils;
pub mod web_referrals;
@@ -1,6 +1,5 @@
pub mod alerts;
pub mod jobs;
pub mod user;
pub mod user_referrals;
pub mod wallet_ledger_entries;
pub mod wallets;
@@ -1,47 +0,0 @@
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
use tokens::tokens::users::UserToken;
use utoipa::{IntoParams, ToSchema};
// --- Request ---
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct ListGlobalUserReferralsQueryParams {
pub cursor: Option<String>,
pub limit: Option<u32>,
}
// --- Response ---
#[derive(Serialize, ToSchema)]
pub struct ListGlobalUserReferralsSuccessResponse {
pub success: bool,
pub referrals: Vec<UserReferralResponse>,
pub maybe_cursor: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub struct UserReferralResponse {
pub invited_user: InvitedUserDetails,
pub referrer_user: ReferrerUserDetails,
pub maybe_referral_code_token: Option<UserReferralCodeToken>,
pub maybe_referral_url: Option<String>,
pub maybe_landing_url: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Serialize, ToSchema)]
pub struct InvitedUserDetails {
pub token: UserToken,
pub username: String,
pub display_name: String,
pub email_address: String,
}
#[derive(Serialize, ToSchema)]
pub struct ReferrerUserDetails {
pub token: UserToken,
pub username: String,
pub display_name: String,
}
@@ -1,26 +0,0 @@
use serde_derive::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};
use crate::moderation::user_referrals::list_global_user_referrals::UserReferralResponse;
// --- Request ---
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct ListUserReferralsForUserQueryParams {
pub cursor: Option<String>,
pub limit: Option<u32>,
}
#[derive(Deserialize, ToSchema)]
pub struct ListUserReferralsForUserPathInfo {
pub username: String,
}
// --- Response ---
#[derive(Serialize, ToSchema)]
pub struct ListUserReferralsForUserSuccessResponse {
pub success: bool,
pub referrals: Vec<UserReferralResponse>,
pub maybe_cursor: Option<String>,
}
@@ -1,2 +0,0 @@
pub mod list_global_user_referrals;
pub mod list_user_referrals_for_user;
@@ -9,7 +9,7 @@ use tokens::tokens::characters::CharacterToken;
use tokens::tokens::media_files::MediaFileToken;
/// Shared request body for both the video cost estimate and video generation endpoints.
#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct OmniGenVideoCostAndGenerateRequest {
/// REQUIRED (even if marked optional)
/// Idempotency token to prevent duplicate requests.
@@ -23,10 +23,4 @@ pub struct OmniGenImageCostResponse {
/// Whether the output will have a watermark.
pub has_watermark: bool,
/// Whether failures are refunded.
/// True: 100% yes
/// False: 100% no
/// None: Unknown or variable
pub failures_are_refunded: Option<bool>,
}
@@ -18,15 +18,9 @@ pub struct OmniGenVideoCostResponse {
/// Whether the user has unlimited generations.
pub is_unlimited: bool,
/// Whether the user is rate-limited.
/// Whether the user is rate limited.
pub is_rate_limited: bool,
/// Whether the output will have a watermark.
pub has_watermark: bool,
/// Whether failures are refunded.
/// True: 100% yes
/// False: 100% no
/// None: Unknown or variable
pub failures_are_refunded: Option<bool>,
}
@@ -6,12 +6,5 @@ use utoipa::ToSchema;
#[derive(Serialize, Deserialize, ToSchema)]
pub struct OmniGenVideoGenerateResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
/// All job tokens created by this request (including the primary).
/// For single-job requests this will contain just one element matching
/// `inference_job_token`. For batch requests (eg. Seedance2Pro with
/// multiple order IDs) this will contain all of them.
pub all_job_tokens: Vec<InferenceJobToken>,
}
@@ -1,71 +0,0 @@
use crate::prompts::get_prompt::GetPromptImageContextItem;
use chrono::{DateTime, Utc};
use enums::by_table::prompts::prompt_type::PromptType;
use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
use enums::common::generation::common_generation_mode::CommonGenerationMode;
use enums::common::generation::common_model_class::CommonModelClass;
use enums::common::generation::common_model_type::CommonModelType;
use enums::common::generation::common_resolution::CommonResolution;
use enums::common::generation_provider::GenerationProvider;
use std::collections::HashSet;
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::prompts::PromptToken;
use utoipa::{IntoParams, ToSchema};
pub const BATCH_GET_PROMPTS_PATH: &str = "/v1/prompt/batch";
#[derive(Deserialize, ToSchema, IntoParams)]
pub struct BatchGetPromptsQuery {
/// Prompt tokens to look up.
pub tokens: HashSet<String>,
}
#[derive(Serialize, ToSchema)]
pub struct BatchGetPromptsResponse {
pub success: bool,
pub prompts: Vec<BatchPromptInfo>,
}
#[derive(Serialize, ToSchema)]
pub struct BatchPromptInfo {
pub token: PromptToken,
/// The type of model used
pub maybe_model_type: Option<CommonModelType>,
/// The class of model used
pub maybe_model_class: Option<CommonModelClass>,
/// The service provider used
pub maybe_generation_provider: Option<GenerationProvider>,
/// Positive prompt (technically optional, but usually present)
pub maybe_positive_prompt: Option<String>,
/// Negative prompt (optional)
pub maybe_negative_prompt: Option<String>,
/// OPTIONAL. The generation mode (eg. keyframe, reference, inpaint, etc.)
pub maybe_generation_mode: Option<CommonGenerationMode>,
/// OPTIONAL. The aspect ratio (eg. square, auto, wide_three_by_two, etc.)
pub maybe_aspect_ratio: Option<CommonAspectRatio>,
/// OPTIONAL. The resolution (eg. one_k, two_k, four_k, etc.)
pub maybe_resolution: Option<CommonResolution>,
/// OPTIONAL. The number of outputs to generate (0-255).
pub maybe_batch_count: Option<u8>,
/// OPTIONAL. Whether to generate audio.
pub maybe_generate_audio: Option<bool>,
/// OPTIONAL. The duration in seconds.
pub maybe_duration_seconds: Option<u32>,
/// Context images (optional)
pub maybe_context_images: Option<Vec<GetPromptImageContextItem>>,
pub created_at: DateTime<Utc>,
}
@@ -27,6 +27,13 @@ pub struct GetPromptSuccessResponse {
pub prompt: PromptInfo,
}
#[derive(Serialize, ToSchema)]
pub struct GetPromptImageContextItem {
pub media_token: MediaFileToken,
pub semantic: PromptContextSemanticType,
pub media_links: MediaLinks,
}
#[derive(Serialize, ToSchema)]
pub struct PromptInfo {
pub token: PromptToken,
@@ -123,13 +130,6 @@ pub struct PromptInfo {
pub created_at: DateTime<Utc>,
}
#[derive(Serialize, ToSchema)]
pub struct GetPromptImageContextItem {
pub media_token: MediaFileToken,
pub semantic: PromptContextSemanticType,
pub media_links: MediaLinks,
}
#[derive(Serialize, ToSchema)]
pub struct PromptInfoModeratorFields {
/// How many milliseconds it took to run generation.
@@ -1,3 +1,2 @@
pub mod batch_get_prompts;
pub mod create_prompt;
pub mod get_prompt;
@@ -20,13 +20,6 @@ pub struct StripeArtcraftCreateSubscriptionCheckoutWithUserSignupRequest {
/// Optional: The URL where the user landed when they first arrived, prior to navigation and signing up.
/// The browser can send `window.location.href` to the backend so we know how people are finding us.
pub maybe_landing_url: Option<String>,
/// Optional: A referral username or code from a referring user.
pub maybe_referral_username: Option<String>,
/// Optional: A referral code created by another user. If present, takes priority over
/// `maybe_referral_username` for resolving the referring user.
pub maybe_referral_code: Option<String>,
}
#[derive(Serialize, Deserialize, ToSchema, Debug, Copy, Clone)]
@@ -1,17 +0,0 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
use utoipa::ToSchema;
#[derive(Deserialize, ToSchema)]
pub struct CreateReferralCodeRequest {
/// The referral code string. Alphanumeric plus underscore, period, dash.
pub code: String,
}
#[derive(Serialize, ToSchema)]
pub struct CreateReferralCodeResponse {
pub success: bool,
pub token: UserReferralCodeToken,
pub code: String,
pub code_lowercase: String,
}
@@ -1,13 +0,0 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
use utoipa::ToSchema;
#[derive(Deserialize, ToSchema)]
pub struct DeleteReferralCodePathInfo {
pub token: UserReferralCodeToken,
}
#[derive(Serialize, ToSchema)]
pub struct DeleteReferralCodeResponse {
pub success: bool,
}
@@ -1,19 +0,0 @@
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
use utoipa::ToSchema;
#[derive(Serialize, ToSchema)]
pub struct ListReferralCodesResponse {
pub success: bool,
pub referral_codes: Vec<ReferralCodeEntry>,
}
#[derive(Serialize, ToSchema)]
pub struct ReferralCodeEntry {
pub token: UserReferralCodeToken,
pub code: String,
pub code_lowercase: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -1,3 +0,0 @@
pub mod create_referral_code;
pub mod delete_referral_code;
pub mod list_referral_codes;
@@ -1,20 +0,0 @@
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::video::edit::beeble_switchx_edit_video::{
BeebleSwitchXEditVideoRequest, BeebleSwitchXEditVideoResponse, BEEBLE_SWITCHX_EDIT_VIDEO_PATH,
};
pub async fn beeble_switchx_edit_video(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: BeebleSwitchXEditVideoRequest,
) -> Result<BeebleSwitchXEditVideoResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
BEEBLE_SWITCHX_EDIT_VIDEO_PATH,
maybe_creds,
request,
).await?)
}
@@ -1 +0,0 @@
pub mod beeble_switchx_edit_video;
@@ -1,4 +1,3 @@
pub mod edit;
pub mod generate_kling_16_pro_image_to_video;
pub mod generate_kling_21_master_image_to_video;
pub mod generate_kling_21_pro_image_to_video;
@@ -34,9 +34,10 @@ pub struct LegacyUploadMediaFileFromFileArgs<'a, P: AsRef<Path>> {
// /// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
// pub maybe_prompt_token: Option<&'a PromptToken>,
/// If provided, the third-party provider that generated this file.
pub maybe_generation_provider: Option<GenerationProvider>,
// /// If provided, this is the service provider that created the image.
// /// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
// pub maybe_generation_provider: Option<GenerationProvider>,
// /// If provided, this groups the file into a batch
// /// TODO: This shouldn't be set clientside without the backend generating the token
// /// and cryptographically securing it. But we need to go fast here.
@@ -81,10 +82,6 @@ pub async fn legacy_upload_media_file_from_file<P: AsRef<Path>>(
// form = form.text("maybe_batch_token", batch_token.to_string());
//}
if let Some(provider) = &args.maybe_generation_provider {
form = form.text("maybe_generation_provider", provider.to_str().to_string());
}
let mut request_builder = client.post(url)
.header("User-Agent", USER_AGENT)
.header("Accept", APPLICATION_JSON);
@@ -6,7 +6,6 @@ use crate::utils::api_host::ApiHost;
use crate::utils::constants::{APPLICATION_JSON, USER_AGENT};
use crate::utils::filter_bad_response::filter_bad_response;
use crate::utils::http_get_anonymous::http_get_anonymous;
use enums::common::generation_provider::GenerationProvider;
use chrono::{DateTime, Utc};
use uuid_utils::uuid::generate_random_uuid;
use log::debug;
@@ -32,9 +31,6 @@ pub struct UploadImageBytesArgs<'a> {
/// If true, we should hide the image from the user's gallery.
pub is_intermediate_system_file: bool,
/// If provided, the third-party provider that generated this file.
pub maybe_generation_provider: Option<GenerationProvider>,
}
#[derive(Clone, Copy, Debug)]
@@ -90,10 +86,6 @@ pub async fn upload_image_media_file_from_bytes(
form = form.text("is_intermediate_system_file", "true");
}
if let Some(provider) = &args.maybe_generation_provider {
form = form.text("maybe_generation_provider", provider.to_str().to_string());
}
let mut request_builder = client.post(url)
.header("User-Agent", USER_AGENT)
.header("Accept", APPLICATION_JSON);
@@ -34,9 +34,10 @@ pub struct UploadImageFromFileArgs<'a, P: AsRef<Path>> {
/// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
pub maybe_prompt_token: Option<&'a PromptToken>,
/// If provided, the third-party provider that generated this file.
pub maybe_generation_provider: Option<GenerationProvider>,
// /// If provided, this is the service provider that created the image.
// /// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
// pub maybe_generation_provider: Option<GenerationProvider>,
/// If provided, this groups the file into a batch
/// TODO: This shouldn't be set clientside without the backend generating the token
/// and cryptographically securing it. But we need to go fast here.
@@ -81,10 +82,6 @@ pub async fn upload_image_media_file_from_file<P: AsRef<Path>>(
form = form.text("maybe_batch_token", batch_token.to_string());
}
if let Some(provider) = &args.maybe_generation_provider {
form = form.text("maybe_generation_provider", provider.to_str().to_string());
}
let mut request_builder = client.post(url)
.header("User-Agent", USER_AGENT)
.header("Accept", APPLICATION_JSON);
@@ -4,7 +4,6 @@ use crate::utils::api_host::ApiHost;
use crate::utils::constants::{APPLICATION_JSON, USER_AGENT};
use crate::utils::filter_bad_response::filter_bad_response;
use crate::utils::http_get_anonymous::http_get_anonymous;
use enums::common::generation_provider::GenerationProvider;
use chrono::{DateTime, Utc};
use uuid_utils::uuid::generate_random_uuid;
use log::debug;
@@ -25,7 +24,6 @@ pub async fn upload_new_engine_asset_from_file<P: AsRef<Path>>(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
path: P,
maybe_generation_provider: Option<GenerationProvider>,
) -> Result<UploadImageMediaFileSuccessResponse, ApiError> {
let url = get_route(api_host);
@@ -39,15 +37,11 @@ pub async fn upload_new_engine_asset_from_file<P: AsRef<Path>>(
let file_bytes = std::fs::read(path.as_ref())?;
let file_name = path.as_ref().file_name()
.and_then(|n| n.to_str()).unwrap_or("file").to_string();
let mut form = Form::new()
let form = Form::new()
.text("uuid_idempotency_token", generate_random_uuid())
.text("engine_category", "object") // TODO: Which type should we use?
.part("file", Part::bytes(file_bytes).file_name(file_name));
if let Some(provider) = &maybe_generation_provider {
form = form.text("maybe_generation_provider", provider.to_str().to_string());
}
let mut request_builder = client.post(url)
.header("User-Agent", USER_AGENT)
.header("Accept", APPLICATION_JSON);
@@ -4,7 +4,6 @@ use crate::utils::api_host::ApiHost;
use crate::utils::constants::{APPLICATION_JSON, USER_AGENT};
use crate::utils::filter_bad_response::filter_bad_response;
use crate::utils::http_get_anonymous::http_get_anonymous;
use enums::common::generation_provider::GenerationProvider;
use chrono::{DateTime, Utc};
use uuid_utils::uuid::generate_random_uuid;
use log::debug;
@@ -32,8 +31,9 @@ pub struct UploadVideoFromFileArgs<'a, P: AsRef<Path>> {
/// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
pub maybe_prompt_token: Option<&'a PromptToken>,
/// If provided, the third-party provider that generated this file.
pub maybe_generation_provider: Option<GenerationProvider>,
// /// If provided, this is the service provider that created the image.
// /// NOTE: Cannot set `is_intermediate_system_file = true` if this is set.
// pub maybe_generation_provider: Option<GenerationProvider>,
// /// If provided, this groups the file into a batch
// /// TODO: This shouldn't be set clientside without the backend generating the token
@@ -73,10 +73,6 @@ pub async fn upload_video_media_file_from_file<P: AsRef<Path>>(
form = form.text("maybe_prompt_token", prompt_token.to_string());
}
if let Some(provider) = &args.maybe_generation_provider {
form = form.text("maybe_generation_provider", provider.to_str().to_string());
}
let mut request_builder = client.post(url)
.header("User-Agent", USER_AGENT)
.header("Accept", APPLICATION_JSON);
@@ -1 +0,0 @@
pub mod omni_gen_image;
@@ -1,21 +0,0 @@
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::omni_gen::cost_and_generate_requests::omni_gen_image_cost_and_generate_request::OmniGenImageCostAndGenerateRequest;
use artcraft_api_defs::omni_gen::generate_response::omni_gen_image_generate_response::OmniGenImageGenerateResponse;
pub const OMNI_GEN_IMAGE_GENERATE_PATH: &str = "/v1/omni_gen/generate/image";
pub async fn omni_gen_image_generate(
api_host: &ApiHost,
maybe_creds: Option<&StorytellerCredentialSet>,
request: OmniGenImageCostAndGenerateRequest,
) -> Result<OmniGenImageGenerateResponse, StorytellerError> {
Ok(basic_json_post_request(
api_host,
OMNI_GEN_IMAGE_GENERATE_PATH,
maybe_creds,
request,
).await?)
}
@@ -1,2 +1 @@
pub mod image;
pub mod video;

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