mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-21 09:22:41 -04:00
Compare commits
160
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ade8f9923 | ||
|
|
b20f73c094 | ||
|
|
82892c1aae | ||
|
|
25ef5c085c | ||
|
|
3178df86e3 | ||
|
|
a90a27e45d | ||
|
|
769faf3daa | ||
|
|
9d38b45bc2 | ||
|
|
4b5e171261 | ||
|
|
47d58bcd80 | ||
|
|
551f4fbae3 | ||
|
|
122b2464fc | ||
|
|
0bd424e2f5 | ||
|
|
2e217d9133 | ||
|
|
00bedb6ae6 | ||
|
|
7bd0b7f910 | ||
|
|
f90d928f33 | ||
|
|
15711af739 | ||
|
|
6fc2fa7fe2 | ||
|
|
f00dc3a006 | ||
|
|
a57fc7fe50 | ||
|
|
8f9607cc5d | ||
|
|
e1b8864a8a | ||
|
|
8dcebec25c | ||
|
|
f7c9e4ecc7 | ||
|
|
633e6bdd6c | ||
|
|
13f1fb4f63 | ||
|
|
967828ec2f | ||
|
|
90baabca4b | ||
|
|
3ede4ef8d1 | ||
|
|
96194ea0d8 | ||
|
|
c1f4ae21e2 | ||
|
|
934ab64eac | ||
|
|
badad317b8 | ||
|
|
7f35eec2b4 | ||
|
|
4cb5a713a8 | ||
|
|
ae8fd30b4b | ||
|
|
d37a732d60 | ||
|
|
726bde7c11 | ||
|
|
1864eedb7a | ||
|
|
853f596efc | ||
|
|
5535d50ec3 | ||
|
|
34cd723417 | ||
|
|
681f94b245 | ||
|
|
cfa5b211ea | ||
|
|
8436d42d41 | ||
|
|
53acdd544f | ||
|
|
5ea6172ce8 | ||
|
|
9166148701 | ||
|
|
e6e739e874 | ||
|
|
4112652c4e | ||
|
|
969d7d7609 | ||
|
|
1f53b6a4cf | ||
|
|
3947eebe7e | ||
|
|
5eb2abf112 | ||
|
|
31a9704faf | ||
|
|
02676680b1 | ||
|
|
ba19e9ae40 | ||
|
|
00499252a1 | ||
|
|
c7b9de7cf9 | ||
|
|
c2ca096099 | ||
|
|
a04ee4f76c | ||
|
|
8bc552c450 | ||
|
|
128d3e43c5 | ||
|
|
bc226fb361 | ||
|
|
7817f3af70 | ||
|
|
cf1f4eb8c8 | ||
|
|
2e6ccf0d00 | ||
|
|
a560541b62 | ||
|
|
df4e300119 | ||
|
|
9bd3726d7a | ||
|
|
fc0f4b7f5c | ||
|
|
94fdd6cb72 | ||
|
|
0d235bfe27 | ||
|
|
6883b64276 | ||
|
|
2c9a78b802 | ||
|
|
6542834336 | ||
|
|
6a2719c742 | ||
|
|
38219a4abf | ||
|
|
3fc002d793 | ||
|
|
c0c17b27b5 | ||
|
|
b68b8f7d71 | ||
|
|
3d9b4be7ab | ||
|
|
489390c881 | ||
|
|
f5338611ac | ||
|
|
11fc5746ec | ||
|
|
47383daba8 | ||
|
|
9166985418 | ||
|
|
8fc488551f | ||
|
|
3a9cebc1b8 | ||
|
|
72a2d956b9 | ||
|
|
62a02c07df | ||
|
|
ec991185c6 | ||
|
|
fc3423d05e | ||
|
|
98cd19bd40 | ||
|
|
94d9de09cc | ||
|
|
7d788bff62 | ||
|
|
d0e2ad9269 | ||
|
|
6d9401c1f1 | ||
|
|
49e49efa3c | ||
|
|
d51c001835 | ||
|
|
f94fc5bf07 | ||
|
|
f397ad825c | ||
|
|
7eea797883 | ||
|
|
73856fca85 | ||
|
|
3d27c620e4 | ||
|
|
062b23d3a0 | ||
|
|
129fc3d593 | ||
|
|
ad40798a12 | ||
|
|
3db8e66204 | ||
|
|
963521d87b | ||
|
|
4323743fe7 | ||
|
|
752fad12b3 | ||
|
|
99b831c3b0 | ||
|
|
4a1d1acddd | ||
|
|
47d6ac6841 | ||
|
|
689bda8bf3 | ||
|
|
7e36149d13 | ||
|
|
2bbeb3de78 | ||
|
|
eeacbf6719 | ||
|
|
af763669cc | ||
|
|
7ff78c6d94 | ||
|
|
588478da73 | ||
|
|
5cb7b80b44 | ||
|
|
50b1a7ed06 | ||
|
|
44cadf84cc | ||
|
|
b7c8151d28 | ||
|
|
640e392d6c | ||
|
|
45651103f0 | ||
|
|
cba8e2c074 | ||
|
|
07d9d537dd | ||
|
|
5770534fc3 | ||
|
|
6fe0909879 | ||
|
|
834f0b48a9 | ||
|
|
d64944b1c3 | ||
|
|
03edd5faf6 | ||
|
|
0ef57ff97e | ||
|
|
adda7483e8 | ||
|
|
e77b946d57 | ||
|
|
3a6fad1812 | ||
|
|
9e04990224 | ||
|
|
885b68630a | ||
|
|
9fee0b1c99 | ||
|
|
631b98f605 | ||
|
|
3334cf7b81 | ||
|
|
50d8abcfb1 | ||
|
|
bce8d166e0 | ||
|
|
5fc27a5153 | ||
|
|
51e5db6b12 | ||
|
|
ff1ce82f66 | ||
|
|
ccea741443 | ||
|
|
2b9882d2d7 | ||
|
|
55cab30dec | ||
|
|
a2f204b1be | ||
|
|
12e4ff7a29 | ||
|
|
8b73569238 | ||
|
|
badabe57eb | ||
|
|
2e62eef85b | ||
|
|
fd9f002615 | ||
|
|
a0e50067bb |
@@ -6,7 +6,11 @@
|
||||
- No minimum supported Rust version; use latest stable features freely
|
||||
- `#[macro_use] extern crate serde_derive;` is used in binary crates; library crates use `use serde_derive::{Serialize, Deserialize};`
|
||||
- Never use `println!` or `eprintln!` outside of tests; use `log` crate macros (`info!`, `warn!`, `error!`, `debug!`, `trace!`) instead
|
||||
- Use `anyhow::Result` / `AnyhowResult` for fallible functions in application code
|
||||
- Use `anyhow::Result` / `AnyhowResult` for fallible functions in application code; new database queries should use `Result<T, sqlx::Error>` instead
|
||||
- SQLx queries: prefer `sqlx::query!` and `sqlx::query_as!` compile-time checked macros over
|
||||
runtime `sqlx::query()` / `sqlx::query_as()`. The macros catch SQL typos, column mismatches,
|
||||
and type errors at build time. Use runtime queries only when assembling complicated
|
||||
dynamic/branching queries that cannot be expressed as a compile-time macro.
|
||||
- Enum Display/Debug: use `impl_enum_display_and_debug_using_to_str!` macro, not `derive_more::Display` (CLion doesn't understand it)
|
||||
- Fields that are optional use the `maybe_` prefix: `maybe_creator_user_token`, `maybe_prompt_token`
|
||||
- When implementing `fmt::Display` for error types, use the pattern: `write!(f, "{:?}", self)`
|
||||
@@ -38,6 +42,21 @@ 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`)
|
||||
@@ -49,15 +68,24 @@ then the story, then the fine print.
|
||||
## Imports
|
||||
|
||||
- Group imports: std, external crates, internal workspace crates, `crate::` imports
|
||||
- Use fully qualified paths for one-off references; `use` for repeated references
|
||||
- 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.
|
||||
- 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;`
|
||||
`use artcraft_router::...::CommonResolution as CommonResolutionRouter;`
|
||||
This avoids long fully-qualified paths in function signatures and bodies.
|
||||
|
||||
## MySQL
|
||||
|
||||
- MySQL tables: primary key `id` columns must be `BIGINT(20) UNSIGNED`. Do not use signed IDs.
|
||||
- Always create tables with `ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`.
|
||||
|
||||
## TypeScript / Frontend
|
||||
|
||||
- TypeScript with React, Vite, Zustand, Three.js
|
||||
- Nx monorepo under `crates/frontend/`
|
||||
- Two spaces for indentation
|
||||
|
||||
|
||||
@@ -10,10 +10,28 @@
|
||||
## Test Patterns
|
||||
|
||||
- Tests live in `#[cfg(test)] mod tests { ... }` at the bottom of each file
|
||||
- Group related tests in sub-modules: `mod explicit_checks`, `mod mechanical_checks`
|
||||
- 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
|
||||
- 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
|
||||
@@ -21,6 +39,14 @@
|
||||
- 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
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nWHERE uir.impersonated_user_token = ?\n AND uir.id < ?\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_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": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "27cebaa36f0ec873f86cdf8fa994d499db1a5cc84d2c6fceb3587145eb2f9bec"
|
||||
}
|
||||
+14
-3
@@ -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\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 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": [
|
||||
{
|
||||
@@ -85,6 +85,16 @@
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -94,7 +104,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -116,9 +126,10 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "fbe482c8987231c3b5d75f2e792d0fdd033de8a7eb821428fa034752c73edfb7"
|
||||
"hash": "2c98621c08055374fd09502c94ac40bb01d23fcea3f844cceea7446a5c0cb4dc"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nWHERE uir.impersonated_user_token = ?\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_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": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"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,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "381e13ab37a2f4ce39bd6db9d90202c301091376108f645a9bb5264a9cd113d7"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n sal.id,\n sal.token as `token: StaffAuditLogToken`,\n sal.audit_action,\n sal.maybe_entity_type,\n sal.maybe_entity_token,\n target_user.username as maybe_target_username,\n target_user.display_name as maybe_target_display_name,\n sal.staff_user_token as `staff_user_token: UserToken`,\n staff_user.username as staff_username,\n staff_user.display_name as staff_display_name,\n sal.staff_ip_address,\n sal.created_at\nFROM staff_audit_logs sal\nLEFT JOIN users target_user ON target_user.token = sal.maybe_entity_token\nLEFT JOIN users staff_user ON staff_user.token = sal.staff_user_token\nORDER BY sal.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: StaffAuditLogToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "audit_action",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_entity_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_entity_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "maybe_target_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_target_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "staff_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "staff_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "staff_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "staff_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3846628765bd34ea2ce01e15a0db732121ce473c5c542d0e971ad29b2b421193"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE users\nSET\n is_banned = ?,\n maybe_mod_comments = ?,\n maybe_mod_user_token = ?,\n version = version + 1\n\nWHERE users.token = ?\nLIMIT 1\n ",
|
||||
"query": "\nUPDATE users\nSET\n is_banned = ?,\n maybe_mod_comments = ?,\n maybe_mod_user_token = ?,\n version = version + 1\n\nWHERE users.token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -8,5 +8,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "eab69a8d679b2dcfb06a9ccc79851f6c693d0c372142ff0e7ded89c95e4bcf44"
|
||||
"hash": "3d746dcb479005f1f4ae5e157a5ace7626eda4849d44c6c2d7079fd346eb4edc"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nWHERE uir.id < ?\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_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": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"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,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "5d45897a5d4c326c8d17f105cae81db7f5878c197b55e8ea61c225e739d11234"
|
||||
}
|
||||
+33
-22
@@ -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\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 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 ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -125,7 +125,7 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory",
|
||||
"name": "maybe_prompt_token: tokens::tokens::prompts::PromptToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
@@ -135,6 +135,16 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "maybe_frontend_failure_category: enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "failure_reason",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -144,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 15,
|
||||
"name": "maybe_result_entity_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -154,7 +164,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 16,
|
||||
"name": "maybe_result_entity_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -164,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 17,
|
||||
"name": "maybe_result_batch_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -174,7 +184,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 17,
|
||||
"ordinal": 18,
|
||||
"name": "maybe_model_weights_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -184,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 18,
|
||||
"ordinal": 19,
|
||||
"name": "maybe_tts_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -194,7 +204,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 19,
|
||||
"ordinal": 20,
|
||||
"name": "maybe_voice_conversion_model_title",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -204,7 +214,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 20,
|
||||
"ordinal": 21,
|
||||
"name": "maybe_tts_public_bucket_path",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -214,7 +224,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 21,
|
||||
"ordinal": 22,
|
||||
"name": "maybe_voice_conversion_public_bucket_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -224,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 22,
|
||||
"ordinal": 23,
|
||||
"name": "maybe_media_file_public_bucket_directory_hash",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -234,7 +244,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 23,
|
||||
"ordinal": 24,
|
||||
"name": "maybe_media_file_public_bucket_prefix",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -244,7 +254,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 24,
|
||||
"ordinal": 25,
|
||||
"name": "maybe_media_file_public_bucket_extension",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -254,7 +264,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 25,
|
||||
"ordinal": 26,
|
||||
"name": "maybe_assigned_worker",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -264,7 +274,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 26,
|
||||
"ordinal": 27,
|
||||
"name": "maybe_assigned_cluster",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
@@ -274,7 +284,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 27,
|
||||
"ordinal": 28,
|
||||
"name": "is_keepalive_required",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
@@ -284,7 +294,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 28,
|
||||
"ordinal": 29,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -294,7 +304,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 29,
|
||||
"ordinal": 30,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -304,7 +314,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 30,
|
||||
"ordinal": 31,
|
||||
"name": "maybe_first_started_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -314,7 +324,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 31,
|
||||
"ordinal": 32,
|
||||
"name": "maybe_successfully_completed_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
@@ -324,7 +334,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 32,
|
||||
"ordinal": 33,
|
||||
"name": "database_clock",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
@@ -365,6 +375,7 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -373,5 +384,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "a2c9e2f61eba666254f8432b3c50a0a7738ee3b3faa77c5281bc8e4af96159b9"
|
||||
"hash": "6948edca3f06643605695665df51cc94f897e2cb9a2d6906910d58d4d56ee73e"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_wallet_ledger_entry_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n maybe_debug_log_event_token = ?,\n\n status = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 16
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8f8b64c0af5383ff3baaa8aa2f2aa22cc760addd850d618ce543fe05816d11e0"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n sal.id,\n sal.token as `token: StaffAuditLogToken`,\n sal.audit_action,\n sal.maybe_entity_type,\n sal.maybe_entity_token,\n target_user.username as maybe_target_username,\n target_user.display_name as maybe_target_display_name,\n sal.staff_user_token as `staff_user_token: UserToken`,\n staff_user.username as staff_username,\n staff_user.display_name as staff_display_name,\n sal.staff_ip_address,\n sal.created_at\nFROM staff_audit_logs sal\nLEFT JOIN users target_user ON target_user.token = sal.maybe_entity_token\nLEFT JOIN users staff_user ON staff_user.token = sal.staff_user_token\nWHERE sal.id < ?\nORDER BY sal.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token: StaffAuditLogToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "audit_action",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_entity_type",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "maybe_entity_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "maybe_target_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "maybe_target_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "staff_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "staff_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "staff_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "staff_ip_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "9132f832752ea40736bedf4729c76af7fe019cc69ed5cc280fce87e68c3f4846"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n token,\n impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonator_user_token as `impersonator_user_token: UserToken`,\n user_impersonation_token,\n is_redeemed as `is_redeemed: bool`,\n expires_at\nFROM user_impersonation_requests\nWHERE user_impersonation_token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonated_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": "impersonator_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "user_impersonation_token",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "9dc83df0b7f1cf2716352e947b6b7fcb6c455fb0c12d72e584612f35366831f4"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO user_sessions (\n token,\n user_token,\n maybe_impersonation_user_token,\n ip_address_creation,\n expires_at\n)\nVALUES (?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "ba5b0a542d4b95b781077b8895529d222dd682eb28c9d00031a820ec6f37e095"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO staff_audit_logs\nSET\n token = ?,\n audit_action = ?,\n maybe_entity_type = ?,\n maybe_entity_token = ?,\n staff_user_token = ?,\n staff_ip_address = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c39800423a5fe0aa324e117e624015f85d039c3ca6833cf6865471345ab0768e"
|
||||
}
|
||||
+3
-3
@@ -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 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 maybe_debug_log_event_token = ?,\n\n frontend_failure_category = ?,\n failure_reason = ?,\n\n status = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 16
|
||||
"Right": 17
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "29916e73a1784ea0b70ef4f637520b05efccc31e01840f681e9b042f82eb8f7e"
|
||||
"hash": "c73be10c5677f78f81bc1c29872fd5af889790c3b2a8de27eb8ab64383c638d6"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO user_impersonation_requests\nSET\n token = ?,\n impersonated_user_token = ?,\n impersonator_user_token = ?,\n user_impersonation_token = ?,\n ip_address_creation = ?,\n expires_at = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "cc782c807dadcaaaad08f469935f61dc2e9f3217aa01532d6602b8e37cedf92d"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nUPDATE user_impersonation_requests\nSET\n is_redeemed = TRUE,\n ip_address_redemption = ?\nWHERE user_impersonation_token = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "cf4be26ce3a48c7108640faa6c9fc68a48136327a9d374c52c16848c006f0984"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n uir.id,\n uir.impersonator_user_token as `impersonator_user_token: UserToken`,\n impersonator.username as impersonator_username,\n impersonator.display_name as impersonator_display_name,\n uir.impersonated_user_token as `impersonated_user_token: UserToken`,\n impersonated.username as impersonated_username,\n impersonated.display_name as impersonated_display_name,\n uir.is_redeemed as `is_redeemed: bool`,\n (uir.expires_at < NOW()) as `is_expired: bool`,\n uir.expires_at,\n uir.created_at,\n uir.updated_at\nFROM user_impersonation_requests uir\nJOIN users impersonator ON impersonator.token = uir.impersonator_user_token\nJOIN users impersonated ON impersonated.token = uir.impersonated_user_token\nORDER BY uir.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "impersonator_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": "impersonator_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "impersonator_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "impersonated_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "impersonated_username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "impersonated_display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "is_redeemed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_expired: bool",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "expires_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "e72b3dfdd9df4ee10a696faa4dfc3fb8addc9d2b88017f503c339fb616bef6f1"
|
||||
}
|
||||
+355
@@ -0,0 +1,355 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
@@ -58,10 +58,11 @@ artcraft/
|
||||
|
||||
- Rust with no minimum supported version
|
||||
- Actix-web for HTTP services
|
||||
- SQLx for MySQL and SQLite
|
||||
- SQLx for MySQL and SQLite; prefer `sqlx::query!` / `sqlx::query_as!` compile-time checked macros over runtime `sqlx::query()` whenever possible
|
||||
- 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
|
||||
|
||||
@@ -75,3 +76,4 @@ 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
+28
-1
@@ -770,6 +770,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"artcraft_api_defs",
|
||||
"artcraft_client",
|
||||
"enums",
|
||||
"fal_client",
|
||||
"log",
|
||||
"muapi_client",
|
||||
@@ -3876,6 +3877,13 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error_utils"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errors"
|
||||
version = "0.0.1"
|
||||
@@ -6089,7 +6097,6 @@ dependencies = [
|
||||
name = "jwt_signer"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"errors",
|
||||
"hmac 0.10.1",
|
||||
"jwt",
|
||||
"sha2 0.9.9",
|
||||
@@ -7744,6 +7751,17 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "opaque_cursors"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"magic-crypt",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "5.3.3"
|
||||
@@ -10173,6 +10191,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bootstrap",
|
||||
"bucket_paths",
|
||||
"chrono",
|
||||
"cloud_storage",
|
||||
"concurrency",
|
||||
"easyenv",
|
||||
@@ -11234,6 +11253,7 @@ dependencies = [
|
||||
"elasticsearch",
|
||||
"elasticsearch_schema",
|
||||
"enums",
|
||||
"error_utils",
|
||||
"errors",
|
||||
"fal_client",
|
||||
"ffmpeg_utils",
|
||||
@@ -11261,6 +11281,7 @@ dependencies = [
|
||||
"mimetypes",
|
||||
"mysql_queries",
|
||||
"once_cell",
|
||||
"opaque_cursors",
|
||||
"pager",
|
||||
"password",
|
||||
"primitives",
|
||||
@@ -11448,13 +11469,18 @@ 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]]
|
||||
@@ -14772,6 +14798,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"test_data",
|
||||
"tokio",
|
||||
"uuid 1.22.0",
|
||||
"workspace-build-acceleration",
|
||||
|
||||
@@ -59,6 +59,7 @@ members = [
|
||||
"crates/lib/data/primitives",
|
||||
"crates/lib/data/web_base64",
|
||||
"crates/lib/easyenv", # NB: Vendored version of https://github.com/echelon/easyenv.rs that we'll improve.
|
||||
"crates/lib/error_utils",
|
||||
"crates/lib/errors",
|
||||
"crates/lib/ffmpeg_utils",
|
||||
"crates/lib/files/file_to_base64_url",
|
||||
@@ -72,6 +73,7 @@ members = [
|
||||
"crates/lib/http_headers",
|
||||
"crates/lib/jobs_common",
|
||||
"crates/lib/jwt_light",
|
||||
"crates/lib/opaque_cursors",
|
||||
"crates/lib/jwt_signer",
|
||||
"crates/lib/logging",
|
||||
"crates/lib/markdown",
|
||||
@@ -236,6 +238,7 @@ cookie_store = { path = "crates/lib/cookie_store" }
|
||||
crockford = { path = "crates/lib/data/crockford" }
|
||||
easyenv = { path = "crates/lib/easyenv" }
|
||||
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" }
|
||||
ffmpeg_utils = { path = "crates/lib/ffmpeg_utils" }
|
||||
@@ -250,6 +253,7 @@ images = { path = "crates/lib/files/images" }
|
||||
jobs_common = { path = "crates/lib/jobs_common" }
|
||||
jwt_light = { path = "crates/lib/jwt_light" }
|
||||
jwt_signer = { path = "crates/lib/jwt_signer" }
|
||||
opaque_cursors = { path = "crates/lib/opaque_cursors" }
|
||||
memory_caching = { path = "crates/lib/caching/memory_caching" }
|
||||
memory_store = { path = "crates/lib/caching/memory_store" }
|
||||
midjourney_client = { path = "crates/api_clients/midjourney_client" }
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS staff_audit_logs;
|
||||
@@ -0,0 +1,39 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE staff_audit_logs (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key" of the audit log item (in case we add a UI or notes)
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of action taken
|
||||
audit_action VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of entity acted upon (if any)
|
||||
maybe_entity_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- The token of the entity mutated (if any)
|
||||
maybe_entity_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who performed the action.
|
||||
staff_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- For abuse tracking.
|
||||
-- Wide enough for IPv4/6
|
||||
staff_ip_address VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY index_maybe_entity_type (maybe_entity_type),
|
||||
KEY index_maybe_entity_token (maybe_entity_token),
|
||||
KEY index_staff_user_token (staff_user_token),
|
||||
KEY index_created_at (created_at)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE user_sessions
|
||||
DROP COLUMN maybe_impersonation_user_token;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE user_sessions
|
||||
ADD COLUMN maybe_impersonation_user_token VARCHAR(32) DEFAULT NULL
|
||||
AFTER user_token;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS user_impersonation_requests;
|
||||
@@ -0,0 +1,44 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE user_impersonation_requests (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Internal "primary key"
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The user being impersonated.
|
||||
impersonated_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who initiated the impersonation.
|
||||
impersonator_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The actual secret that must be presented to redeem the impersonation.
|
||||
user_impersonation_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Whether this request has been redeemed (used to create a session).
|
||||
is_redeemed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- IP address of the staff user who created the request.
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
-- IP address from which the request was redeemed, if redeemed.
|
||||
ip_address_redemption VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- The request expires after this time if not redeemed.
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (user_impersonation_token),
|
||||
KEY index_impersonated_user_token (impersonated_user_token),
|
||||
KEY index_impersonator_user_token (impersonator_user_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Recreate with the original signed BIGINT id.
|
||||
CREATE TABLE user_impersonation_requests (
|
||||
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
impersonated_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
impersonator_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
user_impersonation_token VARCHAR(32) NOT NULL,
|
||||
|
||||
is_redeemed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
ip_address_redemption VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (user_impersonation_token),
|
||||
KEY index_impersonated_user_token (impersonated_user_token),
|
||||
KEY index_impersonator_user_token (impersonator_user_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS user_impersonation_requests;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS user_impersonation_requests;
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE user_impersonation_requests (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Internal "primary key"
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The user being impersonated.
|
||||
impersonated_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who initiated the impersonation.
|
||||
impersonator_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The actual secret that must be presented to redeem the impersonation.
|
||||
user_impersonation_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Whether this request has been redeemed (used to create a session).
|
||||
is_redeemed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- IP address of the staff user who created the request.
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
-- IP address from which the request was redeemed, if redeemed.
|
||||
ip_address_redemption VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- The request expires after this time if not redeemed.
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (user_impersonation_token),
|
||||
KEY index_impersonated_user_token (impersonated_user_token),
|
||||
KEY index_impersonator_user_token (impersonator_user_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,31 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Recreate with the original signed BIGINT id.
|
||||
CREATE TABLE staff_audit_logs (
|
||||
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
audit_action VARCHAR(32) NOT NULL,
|
||||
|
||||
maybe_entity_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
maybe_entity_token VARCHAR(32) NOT NULL,
|
||||
|
||||
staff_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
staff_ip_address VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY index_maybe_entity_type (maybe_entity_type),
|
||||
KEY index_maybe_entity_token (maybe_entity_token),
|
||||
KEY index_staff_user_token (staff_user_token),
|
||||
KEY index_created_at (created_at)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS staff_audit_logs;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS staff_audit_logs;
|
||||
@@ -0,0 +1,39 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE staff_audit_logs (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key" of the audit log item (in case we add a UI or notes)
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of action taken
|
||||
audit_action VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of entity acted upon (if any)
|
||||
maybe_entity_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- The token of the entity mutated (if any)
|
||||
maybe_entity_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who performed the action.
|
||||
staff_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- For abuse tracking.
|
||||
-- Wide enough for IPv4/6
|
||||
staff_ip_address VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY index_maybe_entity_type (maybe_entity_type),
|
||||
KEY index_maybe_entity_token (maybe_entity_token),
|
||||
KEY index_staff_user_token (staff_user_token),
|
||||
KEY index_created_at (created_at)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE prompts
|
||||
DROP COLUMN maybe_quality;
|
||||
@@ -0,0 +1,8 @@
|
||||
-- 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;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE IF EXISTS debug_logs;
|
||||
@@ -0,0 +1,31 @@
|
||||
-- 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;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE generic_inference_jobs
|
||||
DROP COLUMN maybe_debug_log_event_token;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE generic_inference_jobs
|
||||
ADD COLUMN maybe_debug_log_event_token VARCHAR(32) DEFAULT NULL;
|
||||
@@ -0,0 +1,38 @@
|
||||
# SQL Migrations
|
||||
|
||||
Incremental schema changes applied in order by timestamp prefix.
|
||||
|
||||
## Naming Convention
|
||||
|
||||
Migration directories follow the format:
|
||||
|
||||
```
|
||||
YYYY-MM-DD-HHMMSS-NNNN_description_goes_here/
|
||||
up.sql
|
||||
down.sql
|
||||
```
|
||||
|
||||
These are created with the `diesel` tool, and in particular:
|
||||
|
||||
> `diesel migration generate description_goes_here`
|
||||
|
||||
- `NNNN` is a zero-padded sequence number for ordering multiple migrations on the same timestamp.
|
||||
- `up.sql` applies the migration forward.
|
||||
- `down.sql` reverses it.
|
||||
|
||||
## Table Conventions
|
||||
|
||||
- Primary key `id` columns must be `BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT`. Do not use signed IDs.
|
||||
- Always create tables with `ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`.
|
||||
- All SQL files should start with the standard IntelliJ noinspection comments:
|
||||
```sql
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Every `up.sql` must have a corresponding `down.sql` that cleanly reverses the migration.
|
||||
- For `CREATE TABLE` migrations, the `down.sql` is typically `DROP TABLE IF EXISTS table_name;`.
|
||||
- For `ALTER TABLE` migrations, the `down.sql` reverses the alteration (e.g. `DROP COLUMN`).
|
||||
@@ -0,0 +1,26 @@
|
||||
# Squashed / Materialized Schemas
|
||||
|
||||
Fully materialized table definitions representing the current state of each table
|
||||
after all migrations have been applied. These are not executed — they exist as
|
||||
human-readable documentation of the current schema.
|
||||
|
||||
## When to Update
|
||||
|
||||
Update the corresponding squashed file whenever a migration changes a table's schema
|
||||
(adding columns, changing types, dropping and recreating, etc.).
|
||||
|
||||
## Table Conventions
|
||||
|
||||
- Primary key `id` columns must be `BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT`. Do not use signed IDs.
|
||||
- Always create tables with `ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`.
|
||||
- All SQL files should start with the standard IntelliJ noinspection comments:
|
||||
```sql
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
Files are named after their table (e.g. `users.sql`, `media_files.sql`).
|
||||
Some tables are grouped into subdirectories (e.g. `user_tables/`).
|
||||
@@ -0,0 +1,31 @@
|
||||
-- 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(30) DEFAULT NULL,
|
||||
maybe_prompt_token VARCHAR(32) 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,6 +204,10 @@ 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.
|
||||
|
||||
@@ -68,6 +68,10 @@ 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,
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE staff_audit_logs (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Effective "primary key" of the audit log item (in case we add a UI or notes)
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of action taken
|
||||
audit_action VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The type of entity acted upon (if any)
|
||||
maybe_entity_type VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- The token of the entity mutated (if any)
|
||||
maybe_entity_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who performed the action.
|
||||
staff_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- For abuse tracking.
|
||||
-- Wide enough for IPv4/6
|
||||
staff_ip_address VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY index_maybe_entity_type (maybe_entity_type),
|
||||
KEY index_maybe_entity_token (maybe_entity_token),
|
||||
KEY index_staff_user_token (staff_user_token),
|
||||
KEY index_created_at (created_at)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,44 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE user_impersonation_requests (
|
||||
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Internal "primary key"
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The user being impersonated.
|
||||
impersonated_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The staff user who initiated the impersonation.
|
||||
impersonator_user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The actual secret that must be presented to redeem the impersonation.
|
||||
user_impersonation_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Whether this request has been redeemed (used to create a session).
|
||||
is_redeemed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
-- IP address of the staff user who created the request.
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
-- IP address from which the request was redeemed, if redeemed.
|
||||
ip_address_redemption VARCHAR(40) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- The request expires after this time if not redeemed.
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
UNIQUE KEY (user_impersonation_token),
|
||||
KEY index_impersonated_user_token (impersonated_user_token),
|
||||
KEY index_impersonator_user_token (impersonator_user_token)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
@@ -0,0 +1,50 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
CREATE TABLE user_sessions (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Session primary key
|
||||
token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- The user that the session belongs to.
|
||||
user_token VARCHAR(32) NOT NULL,
|
||||
|
||||
-- NEVER IMPERSONATE A USER'S ACCOUNT WITHOUT THEIR CONSENT!
|
||||
--
|
||||
-- For support requests and inquiries, we can have staff log into user accounts
|
||||
-- to verify and debug possible broken states. The user is always told about
|
||||
-- this if we are to use this for support cases.
|
||||
--
|
||||
-- Every action performed by impersonated sessions is logged for auditing.
|
||||
--
|
||||
-- If this session is impersonating another user, this is the token of
|
||||
-- the staff user who initiated the impersonation.
|
||||
maybe_impersonation_user_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
-- Track each session's creation IP.
|
||||
-- Wide enough for IPv4/6
|
||||
ip_address_creation VARCHAR(40) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
-- Session termination time.
|
||||
-- This must be set by the server code, or the session is invalid
|
||||
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- deletion = session termination
|
||||
-- Typically these are destroyed by users, but if in the future we allow mods to
|
||||
-- delete them, it doesn't really matter who did the deletion: sessions are not
|
||||
-- designed to be recoverable.
|
||||
deleted_at TIMESTAMP NULL,
|
||||
|
||||
-- INDICES --
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (token),
|
||||
KEY fk_user_token (user_token),
|
||||
KEY index_ip_address_creation (ip_address_creation)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+2
-1
@@ -15,11 +15,12 @@ body:
|
||||
type: json
|
||||
content: |
|
||||
{
|
||||
"model": "seedream_5_lite",
|
||||
"model": "gpt_image_2",
|
||||
"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
-1
@@ -15,7 +15,7 @@ body:
|
||||
type: json
|
||||
content: |
|
||||
{
|
||||
"user_token": "user_jg7ng4kdt2x5y", // newuser946
|
||||
"user_token": "user_rtdhen9kz73kx", //
|
||||
"payments_namespace": "artcraft"
|
||||
}
|
||||
order: 4100053395280358
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
$kind: http-request
|
||||
name: Impersonate User Request
|
||||
url: "{{api_host}}/v1/moderation/user_sessions/impersonate"
|
||||
method: POST
|
||||
body:
|
||||
type: json
|
||||
content: |-
|
||||
{
|
||||
"username": "newuser3"
|
||||
}
|
||||
order: 4318829221021218
|
||||
@@ -0,0 +1,11 @@
|
||||
$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
|
||||
@@ -0,0 +1,59 @@
|
||||
# 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
|
||||
+8
-2
@@ -3,13 +3,14 @@ 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)]
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct EstimateImageCostRequest {
|
||||
/// The image model to estimate costs for.
|
||||
pub model: CommonImageModel,
|
||||
@@ -29,12 +30,15 @@ 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)]
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum GenerationMode {
|
||||
/// No input images — generate from prompt only.
|
||||
@@ -94,6 +98,7 @@ 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();
|
||||
@@ -108,6 +113,7 @@ 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();
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub struct GenerateKling16ProImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling16ProDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling16ProAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -39,7 +39,7 @@ pub enum GenerateKling16ProAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling16ProDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ pub struct GenerateKling21MasterImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling21MasterDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21MasterAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -35,7 +35,7 @@ pub enum GenerateKling21MasterAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21MasterDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub struct GenerateKling21ProImageToVideoRequest {
|
||||
pub duration: Option<GenerateKling21ProDuration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21ProAspectRatio {
|
||||
/// 16:9 aspect ratio
|
||||
@@ -39,7 +39,7 @@ pub enum GenerateKling21ProAspectRatio {
|
||||
Square,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateKling21ProDuration {
|
||||
FiveSeconds,
|
||||
|
||||
+3
-3
@@ -31,14 +31,14 @@ pub struct GenerateSeedance10LiteImageToVideoRequest {
|
||||
pub aspect_ratio: Option<GenerateSeedance10LiteAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteResolution {
|
||||
FourEightyP,
|
||||
SevenTwentyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteDuration {
|
||||
FiveSeconds,
|
||||
@@ -46,7 +46,7 @@ pub enum GenerateSeedance10LiteDuration {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateSeedance10LiteAspectRatio {
|
||||
Auto,
|
||||
|
||||
+4
-3
@@ -16,7 +16,8 @@ pub struct GenerateVeo2ImageToVideoRequest {
|
||||
|
||||
/// Optional text prompt.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
|
||||
/// **NB(bt): ASPECT RATIO IS ACTUALLY NOT USED IN VEO 2 IMAGE-TO-VIDEO**
|
||||
/// Optional: aspect ratio of the generated video.
|
||||
pub aspect_ratio: Option<GenerateVeo2AspectRatio>,
|
||||
|
||||
@@ -24,7 +25,7 @@ pub struct GenerateVeo2ImageToVideoRequest {
|
||||
pub duration: Option<GenerateVeo2Duration>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo2AspectRatio {
|
||||
Auto,
|
||||
@@ -33,7 +34,7 @@ pub enum GenerateVeo2AspectRatio {
|
||||
TallNineSixteen, // 9:16
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo2Duration {
|
||||
FiveSeconds,
|
||||
|
||||
+13
-2
@@ -21,20 +21,31 @@ pub struct GenerateVeo3FastImageToVideoRequest {
|
||||
pub resolution: Option<GenerateVeo3FastResolution>,
|
||||
|
||||
/// Optional: aspect ratio of the generated video.
|
||||
pub aspect_ratio: Option<GenerateVeo3FastAspectRatio>,
|
||||
|
||||
/// Optional: duration of the generated video.
|
||||
pub duration: Option<GenerateVeo3FastDuration>,
|
||||
|
||||
/// Optional: Generate an audio track along with the video
|
||||
pub generate_audio: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3FastResolution {
|
||||
SevenTwentyP, // 720p
|
||||
TenEightyP, // 1080p
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3FastAspectRatio {
|
||||
Auto,
|
||||
SixteenByNine,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3FastDuration {
|
||||
EightSeconds,
|
||||
|
||||
+7
-3
@@ -37,22 +37,26 @@ pub struct GenerateVeo3ImageToVideoRequest {
|
||||
// pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3AspectRatio {
|
||||
WideSixteenNine, // 16:9
|
||||
TallNineSixteen, // 9:16
|
||||
|
||||
/// NB: DO NOT REMOVE. This is an unsupported resolution for Veo 3, but we can't
|
||||
/// impact existing callers by removing it. The handler will convert this to a
|
||||
/// supported resolution or 400 the request instead.
|
||||
Square, // 1:1
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3Resolution {
|
||||
SevenTwentyP, // 720p
|
||||
TenEightyP, // 1080p
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerateVeo3Duration {
|
||||
EightSeconds,
|
||||
|
||||
+2
-2
@@ -41,14 +41,14 @@ pub struct Kling2p5TurboProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Kling2p5TurboProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p5TurboProMultiFunctionVideoGenDuration {
|
||||
FiveSeconds,
|
||||
TenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p5TurboProMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
|
||||
+2
-2
@@ -45,14 +45,14 @@ pub struct Kling2p6ProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Kling2p6ProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p6ProMultiFunctionVideoGenDuration {
|
||||
FiveSeconds,
|
||||
TenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling2p6ProMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
|
||||
+15
-1
@@ -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(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct Seedance2p0MultiFunctionVideoGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
@@ -37,6 +37,9 @@ pub struct Seedance2p0MultiFunctionVideoGenRequest {
|
||||
/// Video aspect ratio / resolution.
|
||||
pub aspect_ratio: Option<Seedance2p0AspectRatio>,
|
||||
|
||||
/// Output resolution quality tier (480p, 720p, 1080p).
|
||||
pub output_resolution: Option<Seedance2p0OutputResolution>,
|
||||
|
||||
/// Duration in seconds (4–15).
|
||||
pub duration_seconds: Option<u8>,
|
||||
|
||||
@@ -67,6 +70,17 @@ pub enum Seedance2p0BatchCount {
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Seedance2p0OutputResolution {
|
||||
/// 480p
|
||||
FourEightyP,
|
||||
/// 720p (default)
|
||||
SevenTwentyP,
|
||||
/// 1080p
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Seedance2p0MultiFunctionVideoGenResponse {
|
||||
pub success: bool,
|
||||
|
||||
+3
-3
@@ -35,14 +35,14 @@ pub struct Sora2MultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Sora2MultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenResolution {
|
||||
Auto,
|
||||
SevenTwentyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -50,7 +50,7 @@ pub enum Sora2MultiFunctionVideoGenDuration {
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2MultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ pub struct Sora2ProMultiFunctionVideoGenRequest {
|
||||
pub aspect_ratio: Option<Sora2ProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenResolution {
|
||||
Auto,
|
||||
@@ -43,7 +43,7 @@ pub enum Sora2ProMultiFunctionVideoGenResolution {
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -51,7 +51,7 @@ pub enum Sora2ProMultiFunctionVideoGenDuration {
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Sora2ProMultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ pub struct Veo3p1FastMultiFunctionVideoGenRequest {
|
||||
pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -68,7 +68,7 @@ pub enum Veo3p1FastMultiFunctionVideoGenDuration {
|
||||
EightSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
@@ -76,7 +76,7 @@ pub enum Veo3p1FastMultiFunctionVideoGenAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1FastMultiFunctionVideoGenResolution {
|
||||
SevenTwentyP,
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ pub struct Veo3p1MultiFunctionVideoGenRequest {
|
||||
pub auto_fix: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
@@ -68,7 +68,7 @@ pub enum Veo3p1MultiFunctionVideoGenDuration {
|
||||
EightSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenAspectRatio {
|
||||
Auto,
|
||||
@@ -76,7 +76,7 @@ pub enum Veo3p1MultiFunctionVideoGenAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Veo3p1MultiFunctionVideoGenResolution {
|
||||
SevenTwentyP,
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
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::generic_inference_jobs::InferenceJobToken;
|
||||
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;
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::prompts::PromptToken;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
pub const LIST_SESSION_JOBS_URL_PATH: &str = "/v1/jobs/session";
|
||||
|
||||
@@ -53,6 +54,9 @@ 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>,
|
||||
|
||||
|
||||
+3
-3
@@ -40,11 +40,11 @@ pub struct OmniGenImageCostAndGenerateRequest {
|
||||
pub image_batch_count: Option<u16>,
|
||||
|
||||
/// Only for angle manipulation models.
|
||||
pub horizontal_angle: Option<f64>,
|
||||
pub adjust_horizontal_angle: Option<f64>,
|
||||
|
||||
/// Only for angle manipulation models.
|
||||
pub vertical_angle: Option<f64>,
|
||||
pub adjust_vertical_angle: Option<f64>,
|
||||
|
||||
/// Only for angle manipulation models.
|
||||
pub zoom: Option<f64>,
|
||||
pub adjust_zoom: Option<f64>,
|
||||
}
|
||||
|
||||
+6
-1
@@ -5,10 +5,11 @@ use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
|
||||
use enums::common::generation::common_quality::CommonQuality;
|
||||
use enums::common::generation::common_resolution::CommonResolution;
|
||||
use enums::common::generation::common_video_model::CommonVideoModel;
|
||||
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(Serialize, Deserialize, ToSchema, Debug)]
|
||||
#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct OmniGenVideoCostAndGenerateRequest {
|
||||
/// REQUIRED (even if marked optional)
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
@@ -39,6 +40,10 @@ pub struct OmniGenVideoCostAndGenerateRequest {
|
||||
/// Reference audio (optional).
|
||||
pub reference_audio_media_tokens: Option<Vec<MediaFileToken>>,
|
||||
|
||||
/// Optional character tokens to reference in the prompt.
|
||||
/// Characters are referenced in prompts as @CharacterName.
|
||||
pub reference_character_tokens: Option<Vec<CharacterToken>>,
|
||||
|
||||
/// The resolution to use.
|
||||
pub resolution: Option<CommonResolution>,
|
||||
|
||||
|
||||
+7
@@ -6,5 +6,12 @@ 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>,
|
||||
}
|
||||
|
||||
+10
@@ -2,6 +2,7 @@ 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::model_creator::ModelCreator;
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
@@ -56,6 +57,9 @@ pub struct OmniGenImageProviderModelDetails {
|
||||
pub struct OmniGenImageModelDetails {
|
||||
pub model: CommonImageModel,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model_creator: Option<ModelCreator>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub full_name: Option<String>,
|
||||
|
||||
@@ -103,6 +107,7 @@ pub struct OmniGenImageModelDetails {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub resolution_default: Option<CommonResolution>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub quality_options: Option<Vec<CommonQuality>>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -119,12 +124,16 @@ pub struct OmniGenImageModelDetails {
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub batch_size_default: Option<u16>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub is_disabled: Option<bool>,
|
||||
}
|
||||
|
||||
impl Default for OmniGenImageModelDetails {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
model: CommonImageModel::NanoBananaPro,
|
||||
model_creator: None,
|
||||
full_name: None,
|
||||
text_prompt_supported: None,
|
||||
text_prompt_max_length: None,
|
||||
@@ -144,6 +153,7 @@ impl Default for OmniGenImageModelDetails {
|
||||
batch_size_max: None,
|
||||
batch_size_options: None,
|
||||
batch_size_default: None,
|
||||
is_disabled: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-3
@@ -1,10 +1,14 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
use enums::common::generation::common_aspect_ratio::CommonAspectRatio;
|
||||
use enums::common::generation::common_quality::CommonQuality;
|
||||
use enums::common::generation::common_resolution::CommonResolution;
|
||||
use enums::common::generation::common_video_model::CommonVideoModel;
|
||||
use enums::common::generation::model_creator::ModelCreator;
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
/// Video model to default to if none is specified
|
||||
const DEFAULT_VIDEO_MODEL : CommonVideoModel = CommonVideoModel::Seedance2p0;
|
||||
|
||||
/// Query string parameters for the video models endpoint.
|
||||
#[derive(Deserialize, IntoParams, ToSchema)]
|
||||
@@ -62,6 +66,9 @@ pub struct OmniGenVideoModelDetails {
|
||||
|
||||
pub model: CommonVideoModel,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model_creator: Option<ModelCreator>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub full_name: Option<String>,
|
||||
|
||||
@@ -110,6 +117,12 @@ pub struct OmniGenVideoModelDetails {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub audio_references_max_total_duration_seconds: Option<u16>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub character_references_supported: Option<bool>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub character_references_max: Option<u16>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub show_generate_with_sound_toggle: Option<bool>,
|
||||
|
||||
@@ -154,12 +167,16 @@ pub struct OmniGenVideoModelDetails {
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub batch_size_default: Option<u16>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub is_disabled: Option<bool>,
|
||||
}
|
||||
|
||||
impl Default for OmniGenVideoModelDetails {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
model: CommonVideoModel::Seedance2p0,
|
||||
model: DEFAULT_VIDEO_MODEL,
|
||||
model_creator: None,
|
||||
full_name: None,
|
||||
text_prompt_supported: None,
|
||||
text_prompt_max_length: None,
|
||||
@@ -176,6 +193,8 @@ impl Default for OmniGenVideoModelDetails {
|
||||
audio_references_supported: None,
|
||||
audio_references_max: None,
|
||||
audio_references_max_total_duration_seconds: None,
|
||||
character_references_supported: None,
|
||||
character_references_max: None,
|
||||
show_generate_with_sound_toggle: None,
|
||||
aspect_ratio_options: None,
|
||||
aspect_ratio_default: None,
|
||||
@@ -191,6 +210,7 @@ impl Default for OmniGenVideoModelDetails {
|
||||
batch_size_max: None,
|
||||
batch_size_options: None,
|
||||
batch_size_default: None,
|
||||
is_disabled: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
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,13 +27,6 @@ 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,
|
||||
@@ -130,6 +123,13 @@ 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,2 +1,3 @@
|
||||
pub mod batch_get_prompts;
|
||||
pub mod create_prompt;
|
||||
pub mod get_prompt;
|
||||
@@ -2,6 +2,7 @@ pub mod analytics;
|
||||
pub mod credits;
|
||||
pub mod generate;
|
||||
pub mod jobs;
|
||||
pub mod omni_gen;
|
||||
pub mod media_files;
|
||||
pub mod prompts;
|
||||
pub mod stripe_artcraft;
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
pub mod omni_gen_image;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
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?)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod image;
|
||||
pub mod video;
|
||||
+1
@@ -0,0 +1 @@
|
||||
pub mod omni_gen_video;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
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_video_cost_and_generate_request::OmniGenVideoCostAndGenerateRequest;
|
||||
use artcraft_api_defs::omni_gen::generate_response::omni_gen_video_generate_response::OmniGenVideoGenerateResponse;
|
||||
|
||||
pub const OMNI_GEN_VIDEO_GENERATE_PATH: &str = "/v1/omni_gen/generate/video";
|
||||
|
||||
pub async fn omni_gen_video_generate(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: OmniGenVideoCostAndGenerateRequest,
|
||||
) -> Result<OmniGenVideoGenerateResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
OMNI_GEN_VIDEO_GENERATE_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod generate;
|
||||
@@ -1,5 +1,6 @@
|
||||
use cloudflare_errors::cloudflare_error::CloudflareError;
|
||||
use errors::AnyhowError;
|
||||
use reqwest::StatusCode;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::io;
|
||||
@@ -30,6 +31,12 @@ pub enum ApiError {
|
||||
backend_hostname: Option<String>,
|
||||
},
|
||||
|
||||
/// An uncategorized bad HTTP response with status code and body.
|
||||
UncategorizedBadResponseWithStatusAndBody {
|
||||
status_code: StatusCode,
|
||||
body: String,
|
||||
},
|
||||
|
||||
/// Cloudflare errors.
|
||||
CloudflareError(CloudflareError),
|
||||
|
||||
@@ -66,6 +73,8 @@ impl Display for ApiError {
|
||||
ApiError::TooManyRequests(msg) => write!(f, "Too many requests to Storyteller backend: {}", msg),
|
||||
ApiError::InternalServerError {body, backend_hostname} =>
|
||||
write!(f, "Internal Server Error; backend hostname: {:?} ; body: {}; ", backend_hostname, body),
|
||||
ApiError::UncategorizedBadResponseWithStatusAndBody { status_code, body } =>
|
||||
write!(f, "Uncategorized bad response with status code {} and body: {}", status_code, body),
|
||||
// Server response handling errors
|
||||
ApiError::DeserializationError(error) => write!(f, "Deserialization error: {}", error),
|
||||
// Network errors
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use log::{info, warn};
|
||||
use reqwest::Client;
|
||||
use url::Url;
|
||||
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
use crate::endpoints::media_files::get_media_file::{get_media_file, GetMediaFileSuccessResponse};
|
||||
use crate::error::api_error::ApiError;
|
||||
use crate::error::client_error::ClientError;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
|
||||
pub struct DownloadMediaFileArgs<'a, P: AsRef<Path>> {
|
||||
pub media_token: &'a MediaFileToken,
|
||||
pub api_host: &'a ApiHost,
|
||||
pub download_path: DownloadPath<P>,
|
||||
}
|
||||
|
||||
pub enum DownloadPath<P: AsRef<Path>> {
|
||||
/// Write the file to this exact path.
|
||||
ExactFilename(P),
|
||||
/// Write the file into this directory, generating a filename from the CDN URL extension.
|
||||
Directory(P),
|
||||
}
|
||||
|
||||
pub struct DownloadMediaFileResult {
|
||||
/// The path the file was written to.
|
||||
pub downloaded_file_path: PathBuf,
|
||||
|
||||
/// The full media file response from the API.
|
||||
pub media_file_response: GetMediaFileSuccessResponse,
|
||||
|
||||
/// Size of downloaded file in bytes.
|
||||
pub filesize_bytes: usize,
|
||||
}
|
||||
|
||||
pub async fn download_media_file<P: AsRef<Path>>(
|
||||
args: DownloadMediaFileArgs<'_, P>,
|
||||
) -> Result<DownloadMediaFileResult, StorytellerError> {
|
||||
let DownloadMediaFileArgs {
|
||||
media_token,
|
||||
api_host,
|
||||
download_path
|
||||
} = args;
|
||||
|
||||
// 1. Fetch media file info from the API.
|
||||
let response = get_media_file(api_host, media_token).await?;
|
||||
let media_class = &response.media_file.media_class;
|
||||
let cdn_url = &response.media_file.media_links.cdn_url;
|
||||
|
||||
info!("Downloading media file {} of class {} from CDN: {}",
|
||||
media_token.as_str(), media_class.to_str(), cdn_url);
|
||||
|
||||
// 2. Determine the output file path.
|
||||
let output_path = match &download_path {
|
||||
DownloadPath::ExactFilename(path) => path.as_ref().to_path_buf(),
|
||||
DownloadPath::Directory(dir) => {
|
||||
let filename = derive_filename_from_url(cdn_url, &media_token);
|
||||
dir.as_ref().join(filename)
|
||||
}
|
||||
};
|
||||
|
||||
// 3. Download the bytes from the CDN.
|
||||
let bytes = download_bytes(cdn_url).await?;
|
||||
|
||||
// 4. Write to disk.
|
||||
let mut file = fs::File::create(&output_path)
|
||||
.map_err(|err| StorytellerError::Client(ClientError::IoError(err)))?;
|
||||
|
||||
file.write_all(&bytes)
|
||||
.map_err(|err| StorytellerError::Client(ClientError::IoError(err)))?;
|
||||
|
||||
file.flush()
|
||||
.map_err(|err| StorytellerError::Client(ClientError::IoError(err)))?;
|
||||
|
||||
info!("Downloaded {} bytes to {:?}", bytes.len(), output_path);
|
||||
|
||||
Ok(DownloadMediaFileResult {
|
||||
downloaded_file_path: output_path,
|
||||
media_file_response: response,
|
||||
filesize_bytes: bytes.len(),
|
||||
})
|
||||
}
|
||||
|
||||
// ── Helpers ──
|
||||
|
||||
async fn download_bytes(url: &Url) -> Result<Vec<u8>, StorytellerError> {
|
||||
let client = Client::builder()
|
||||
.gzip(true)
|
||||
.build()
|
||||
.map_err(|err| StorytellerError::Client(ClientError::ReqwestError(err)))?;
|
||||
|
||||
let response = client.get(url.as_str())
|
||||
.send()
|
||||
.await
|
||||
.map_err(|err| StorytellerError::Api(ApiError::OtherReqwestError(err)))?;
|
||||
|
||||
let status_code = response.status();
|
||||
|
||||
if !status_code.is_success() {
|
||||
let body = response.text().await.unwrap_or_else(|err| {
|
||||
warn!("Failed to retrieve response body: {}", err);
|
||||
"".to_string()
|
||||
});
|
||||
return Err(StorytellerError::Api(ApiError::UncategorizedBadResponseWithStatusAndBody {
|
||||
status_code,
|
||||
body,
|
||||
}));
|
||||
}
|
||||
|
||||
let bytes = response.bytes()
|
||||
.await
|
||||
.map_err(|err| StorytellerError::Client(ClientError::ReqwestError(err)))?;
|
||||
|
||||
Ok(bytes.to_vec())
|
||||
}
|
||||
|
||||
/// Derive a filename from the CDN URL's path extension, falling back to the media token.
|
||||
fn derive_filename_from_url(url: &Url, media_token: &MediaFileToken) -> String {
|
||||
let path = url.path();
|
||||
let extension = Path::new(path)
|
||||
.extension() // NB: without dot '.'
|
||||
.and_then(|ext| ext.to_str())
|
||||
.unwrap_or("bin");
|
||||
|
||||
format!("{}.{}", media_token.as_str(), extension)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn derive_filename_from_url_extracts_extension() {
|
||||
let url = Url::parse("https://cdn.example.com/files/abc123.png").unwrap();
|
||||
let token = MediaFileToken::new_from_str("mf_test123");
|
||||
assert_eq!(derive_filename_from_url(&url, &token), "mf_test123.png");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_filename_from_url_handles_no_extension() {
|
||||
let url = Url::parse("https://cdn.example.com/files/abc123").unwrap();
|
||||
let token = MediaFileToken::new_from_str("mf_test123");
|
||||
assert_eq!(derive_filename_from_url(&url, &token), "mf_test123.bin");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_filename_from_url_handles_query_params() {
|
||||
let url = Url::parse("https://cdn.example.com/files/abc123.mp4?token=xyz").unwrap();
|
||||
let token = MediaFileToken::new_from_str("mf_test123");
|
||||
assert_eq!(derive_filename_from_url(&url, &token), "mf_test123.mp4");
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
pub mod download_media_file;
|
||||
pub mod upload_media_file_from_file;
|
||||
@@ -17,6 +17,7 @@ workspace-build-acceleration.workspace = true
|
||||
|
||||
# Internal
|
||||
artcraft_api_defs.workspace = true
|
||||
enums.workspace = true
|
||||
artcraft_client.workspace = true
|
||||
fal_client.workspace = true
|
||||
muapi_client.workspace = true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum AudioListRef<'a> {
|
||||
MediaFileTokens(&'a Vec<MediaFileToken>),
|
||||
Urls(&'a Vec<String>),
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum AudioListRef {
|
||||
MediaFileTokens(Vec<MediaFileToken>),
|
||||
Urls(Vec<String>),
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use tokens::tokens::characters::CharacterToken;
|
||||
|
||||
/// Forward-compatible character reference list.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum CharacterListRef<'a> {
|
||||
CharacterTokens(&'a Vec<CharacterToken>),
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CharacterListRef {
|
||||
CharacterTokens(Vec<CharacterToken>),
|
||||
|
||||
// In the future, we may have other identifiers for characters.
|
||||
}
|
||||
|
||||
@@ -36,7 +36,11 @@ pub enum CommonAspectRatio {
|
||||
|
||||
// Auto values that bake in resolution
|
||||
// These are from the Seedream models
|
||||
#[serde(rename = "auto_2k")]
|
||||
Auto2k,
|
||||
#[serde(rename = "auto_3k")]
|
||||
Auto3k,
|
||||
#[serde(rename = "auto_4k")]
|
||||
Auto4k,
|
||||
|
||||
// Defined aspect ratios that bake in resolution
|
||||
|
||||
@@ -13,8 +13,12 @@ pub enum CommonImageModel {
|
||||
FluxPro11,
|
||||
#[serde(rename = "flux_pro_1p1_ultra")]
|
||||
FluxPro11Ultra,
|
||||
#[serde(rename = "gpt_image_1")]
|
||||
GptImage1,
|
||||
#[serde(rename = "gpt_image_1p5")]
|
||||
GptImage1p5,
|
||||
#[serde(rename = "gpt_image_2")]
|
||||
GptImage2,
|
||||
#[serde(rename = "nano_banana")]
|
||||
NanoBanana,
|
||||
#[serde(rename = "nano_banana_2")]
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Common quality levels you can specify when enqueuing a generation.
|
||||
/// Not every model will use this; models that don't simply ignore it.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonQuality {
|
||||
High,
|
||||
Medium,
|
||||
Low,
|
||||
}
|
||||
@@ -38,6 +38,12 @@ pub enum CommonVideoModel {
|
||||
#[serde(rename = "seedance_2p0")]
|
||||
Seedance2p0,
|
||||
|
||||
#[serde(rename = "seedance_2p0_fast")]
|
||||
Seedance2p0Fast,
|
||||
|
||||
#[serde(rename = "happy_horse_1p0")]
|
||||
HappyHorse1p0,
|
||||
|
||||
#[serde(rename = "sora_2")]
|
||||
Sora2,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum ImageListRef<'a> {
|
||||
MediaFileTokens(&'a Vec<MediaFileToken>),
|
||||
Urls(&'a Vec<String>),
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ImageListRef {
|
||||
MediaFileTokens(Vec<MediaFileToken>),
|
||||
Urls(Vec<String>),
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum ImageRef<'a> {
|
||||
MediaFileToken(&'a MediaFileToken),
|
||||
Url(&'a str),
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ImageRef {
|
||||
MediaFileToken(MediaFileToken),
|
||||
Url(String),
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user