@weirdfingers/baseboards 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +4 -1
  2. package/dist/index.js +131 -11
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/templates/api/alembic/env.py +9 -1
  6. package/templates/api/alembic/versions/20250101_000000_initial_schema.py +107 -49
  7. package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +7 -3
  8. package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +57 -1
  9. package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +134 -0
  10. package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +8 -5
  11. package/templates/api/config/generators.yaml +111 -0
  12. package/templates/api/src/boards/__init__.py +1 -1
  13. package/templates/api/src/boards/api/app.py +2 -1
  14. package/templates/api/src/boards/api/endpoints/tenant_registration.py +1 -1
  15. package/templates/api/src/boards/api/endpoints/uploads.py +150 -0
  16. package/templates/api/src/boards/auth/factory.py +1 -1
  17. package/templates/api/src/boards/dbmodels/__init__.py +8 -22
  18. package/templates/api/src/boards/generators/artifact_resolution.py +45 -12
  19. package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +16 -1
  20. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +171 -0
  21. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +167 -0
  22. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +194 -0
  23. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +209 -0
  24. package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +206 -0
  25. package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +237 -0
  26. package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +1 -1
  27. package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +30 -0
  28. package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +220 -0
  29. package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +173 -0
  30. package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +227 -0
  31. package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +203 -0
  32. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +230 -0
  33. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +204 -0
  34. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +221 -0
  35. package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +177 -0
  36. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +182 -0
  37. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +167 -0
  38. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +299 -0
  39. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +190 -0
  40. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +226 -0
  41. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +249 -0
  42. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +244 -0
  43. package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +42 -0
  44. package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +209 -0
  45. package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +161 -0
  46. package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +222 -0
  47. package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +152 -0
  48. package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +197 -0
  49. package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +173 -0
  50. package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +221 -0
  51. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +175 -0
  52. package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +153 -0
  53. package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +172 -0
  54. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +175 -0
  55. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +163 -0
  56. package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +155 -0
  57. package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +174 -0
  58. package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +194 -0
  59. package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +1 -1
  60. package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +158 -0
  61. package/templates/api/src/boards/graphql/access_control.py +1 -1
  62. package/templates/api/src/boards/graphql/mutations/root.py +16 -4
  63. package/templates/api/src/boards/graphql/resolvers/board.py +0 -2
  64. package/templates/api/src/boards/graphql/resolvers/generation.py +10 -233
  65. package/templates/api/src/boards/graphql/resolvers/lineage.py +381 -0
  66. package/templates/api/src/boards/graphql/resolvers/upload.py +463 -0
  67. package/templates/api/src/boards/graphql/types/generation.py +62 -26
  68. package/templates/api/src/boards/middleware.py +1 -1
  69. package/templates/api/src/boards/storage/factory.py +2 -2
  70. package/templates/api/src/boards/tenant_isolation.py +9 -9
  71. package/templates/api/src/boards/workers/actors.py +10 -1
  72. package/templates/web/package.json +1 -1
  73. package/templates/web/src/app/boards/[boardId]/page.tsx +14 -5
  74. package/templates/web/src/app/lineage/[generationId]/page.tsx +233 -0
  75. package/templates/web/src/components/boards/ArtifactPreview.tsx +20 -1
  76. package/templates/web/src/components/boards/UploadArtifact.tsx +253 -0
@@ -17,9 +17,15 @@ down_revision = None
17
17
  branch_labels = None
18
18
  depends_on = None
19
19
 
20
+ # Schema name for all Boards tables
21
+ SCHEMA = "boards"
22
+
20
23
 
21
24
  def upgrade() -> None:
22
- # Required extension for uuid_generate_v4
25
+ # Create the boards schema
26
+ op.execute(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA};")
27
+
28
+ # Required extension for uuid_generate_v4 (in public schema, accessible everywhere)
23
29
  op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
24
30
 
25
31
  # tenants
@@ -49,6 +55,7 @@ def upgrade() -> None:
49
55
  ),
50
56
  sa.PrimaryKeyConstraint("id", name="tenants_pkey"),
51
57
  sa.UniqueConstraint("slug", name="tenants_slug_key"),
58
+ schema=SCHEMA,
52
59
  )
53
60
 
54
61
  # provider_configs
@@ -76,7 +83,7 @@ def upgrade() -> None:
76
83
  sa.PrimaryKeyConstraint("id", name="provider_configs_pkey"),
77
84
  sa.ForeignKeyConstraint(
78
85
  ["tenant_id"],
79
- ["tenants.id"],
86
+ [f"{SCHEMA}.tenants.id"],
80
87
  ondelete="CASCADE",
81
88
  name="provider_configs_tenant_id_fkey",
82
89
  ),
@@ -85,6 +92,7 @@ def upgrade() -> None:
85
92
  "provider_name",
86
93
  name="provider_configs_tenant_id_provider_name_key",
87
94
  ),
95
+ schema=SCHEMA,
88
96
  )
89
97
 
90
98
  # users
@@ -119,7 +127,7 @@ def upgrade() -> None:
119
127
  sa.PrimaryKeyConstraint("id", name="users_pkey"),
120
128
  sa.ForeignKeyConstraint(
121
129
  ["tenant_id"],
122
- ["tenants.id"],
130
+ [f"{SCHEMA}.tenants.id"],
123
131
  ondelete="CASCADE",
124
132
  name="users_tenant_id_fkey",
125
133
  ),
@@ -129,11 +137,16 @@ def upgrade() -> None:
129
137
  "auth_subject",
130
138
  name="users_tenant_id_auth_provider_auth_subject_key",
131
139
  ),
140
+ schema=SCHEMA,
132
141
  )
133
142
  op.create_index(
134
- "idx_users_auth", "users", ["auth_provider", "auth_subject"], unique=False
143
+ "idx_users_auth",
144
+ "users",
145
+ ["auth_provider", "auth_subject"],
146
+ unique=False,
147
+ schema=SCHEMA,
135
148
  )
136
- op.create_index("idx_users_tenant", "users", ["tenant_id"], unique=False)
149
+ op.create_index("idx_users_tenant", "users", ["tenant_id"], unique=False, schema=SCHEMA)
137
150
 
138
151
  # boards
139
152
  op.create_table(
@@ -170,17 +183,21 @@ def upgrade() -> None:
170
183
  ),
171
184
  sa.PrimaryKeyConstraint("id", name="boards_pkey"),
172
185
  sa.ForeignKeyConstraint(
173
- ["owner_id"], ["users.id"], ondelete="CASCADE", name="boards_owner_id_fkey"
186
+ ["owner_id"],
187
+ [f"{SCHEMA}.users.id"],
188
+ ondelete="CASCADE",
189
+ name="boards_owner_id_fkey",
174
190
  ),
175
191
  sa.ForeignKeyConstraint(
176
192
  ["tenant_id"],
177
- ["tenants.id"],
193
+ [f"{SCHEMA}.tenants.id"],
178
194
  ondelete="CASCADE",
179
195
  name="boards_tenant_id_fkey",
180
196
  ),
197
+ schema=SCHEMA,
181
198
  )
182
- op.create_index("idx_boards_owner", "boards", ["owner_id"], unique=False)
183
- op.create_index("idx_boards_tenant", "boards", ["tenant_id"], unique=False)
199
+ op.create_index("idx_boards_owner", "boards", ["owner_id"], unique=False, schema=SCHEMA)
200
+ op.create_index("idx_boards_tenant", "boards", ["tenant_id"], unique=False, schema=SCHEMA)
184
201
 
185
202
  # lora_models
186
203
  op.create_table(
@@ -216,16 +233,17 @@ def upgrade() -> None:
216
233
  sa.PrimaryKeyConstraint("id", name="lora_models_pkey"),
217
234
  sa.ForeignKeyConstraint(
218
235
  ["tenant_id"],
219
- ["tenants.id"],
236
+ [f"{SCHEMA}.tenants.id"],
220
237
  ondelete="CASCADE",
221
238
  name="lora_models_tenant_id_fkey",
222
239
  ),
223
240
  sa.ForeignKeyConstraint(
224
241
  ["user_id"],
225
- ["users.id"],
242
+ [f"{SCHEMA}.users.id"],
226
243
  ondelete="CASCADE",
227
244
  name="lora_models_user_id_fkey",
228
245
  ),
246
+ schema=SCHEMA,
229
247
  )
230
248
 
231
249
  # board_members
@@ -256,25 +274,36 @@ def upgrade() -> None:
256
274
  ),
257
275
  sa.ForeignKeyConstraint(
258
276
  ["board_id"],
259
- ["boards.id"],
277
+ [f"{SCHEMA}.boards.id"],
260
278
  ondelete="CASCADE",
261
279
  name="board_members_board_id_fkey",
262
280
  ),
263
281
  sa.ForeignKeyConstraint(
264
- ["invited_by"], ["users.id"], name="board_members_invited_by_fkey"
282
+ ["invited_by"],
283
+ [f"{SCHEMA}.users.id"],
284
+ name="board_members_invited_by_fkey",
265
285
  ),
266
286
  sa.ForeignKeyConstraint(
267
287
  ["user_id"],
268
- ["users.id"],
288
+ [f"{SCHEMA}.users.id"],
269
289
  ondelete="CASCADE",
270
290
  name="board_members_user_id_fkey",
271
291
  ),
292
+ schema=SCHEMA,
272
293
  )
273
294
  op.create_index(
274
- "idx_board_members_board", "board_members", ["board_id"], unique=False
295
+ "idx_board_members_board",
296
+ "board_members",
297
+ ["board_id"],
298
+ unique=False,
299
+ schema=SCHEMA,
275
300
  )
276
301
  op.create_index(
277
- "idx_board_members_user", "board_members", ["user_id"], unique=False
302
+ "idx_board_members_user",
303
+ "board_members",
304
+ ["user_id"],
305
+ unique=False,
306
+ schema=SCHEMA,
278
307
  )
279
308
 
280
309
  # generations
@@ -336,37 +365,48 @@ def upgrade() -> None:
336
365
  sa.PrimaryKeyConstraint("id", name="generations_pkey"),
337
366
  sa.ForeignKeyConstraint(
338
367
  ["board_id"],
339
- ["boards.id"],
368
+ [f"{SCHEMA}.boards.id"],
340
369
  ondelete="CASCADE",
341
370
  name="generations_board_id_fkey",
342
371
  ),
343
372
  sa.ForeignKeyConstraint(
344
373
  ["parent_generation_id"],
345
- ["generations.id"],
374
+ [f"{SCHEMA}.generations.id"],
346
375
  name="generations_parent_generation_id_fkey",
347
376
  ),
348
377
  sa.ForeignKeyConstraint(
349
378
  ["tenant_id"],
350
- ["tenants.id"],
379
+ [f"{SCHEMA}.tenants.id"],
351
380
  ondelete="CASCADE",
352
381
  name="generations_tenant_id_fkey",
353
382
  ),
354
383
  sa.ForeignKeyConstraint(
355
384
  ["user_id"],
356
- ["users.id"],
385
+ [f"{SCHEMA}.users.id"],
357
386
  ondelete="CASCADE",
358
387
  name="generations_user_id_fkey",
359
388
  ),
389
+ schema=SCHEMA,
390
+ )
391
+ op.create_index(
392
+ "idx_generations_board", "generations", ["board_id"], unique=False, schema=SCHEMA
393
+ )
394
+ op.create_index(
395
+ "idx_generations_lineage",
396
+ "generations",
397
+ ["parent_generation_id"],
398
+ unique=False,
399
+ schema=SCHEMA,
360
400
  )
361
- op.create_index("idx_generations_board", "generations", ["board_id"], unique=False)
362
401
  op.create_index(
363
- "idx_generations_lineage", "generations", ["parent_generation_id"], unique=False
402
+ "idx_generations_status", "generations", ["status"], unique=False, schema=SCHEMA
364
403
  )
365
- op.create_index("idx_generations_status", "generations", ["status"], unique=False)
366
404
  op.create_index(
367
- "idx_generations_tenant", "generations", ["tenant_id"], unique=False
405
+ "idx_generations_tenant", "generations", ["tenant_id"], unique=False, schema=SCHEMA
406
+ )
407
+ op.create_index(
408
+ "idx_generations_user", "generations", ["user_id"], unique=False, schema=SCHEMA
368
409
  )
369
- op.create_index("idx_generations_user", "generations", ["user_id"], unique=False)
370
410
 
371
411
  # credit_transactions
372
412
  op.create_table(
@@ -396,53 +436,71 @@ def upgrade() -> None:
396
436
  sa.PrimaryKeyConstraint("id", name="credit_transactions_pkey"),
397
437
  sa.ForeignKeyConstraint(
398
438
  ["generation_id"],
399
- ["generations.id"],
439
+ [f"{SCHEMA}.generations.id"],
400
440
  name="credit_transactions_generation_id_fkey",
401
441
  ),
402
442
  sa.ForeignKeyConstraint(
403
443
  ["tenant_id"],
404
- ["tenants.id"],
444
+ [f"{SCHEMA}.tenants.id"],
405
445
  ondelete="CASCADE",
406
446
  name="credit_transactions_tenant_id_fkey",
407
447
  ),
408
448
  sa.ForeignKeyConstraint(
409
449
  ["user_id"],
410
- ["users.id"],
450
+ [f"{SCHEMA}.users.id"],
411
451
  ondelete="CASCADE",
412
452
  name="credit_transactions_user_id_fkey",
413
453
  ),
454
+ sa.CheckConstraint(
455
+ "transaction_type::text = ANY (ARRAY["
456
+ "'reserve'::character varying, 'finalize'::character varying, "
457
+ "'refund'::character varying, 'purchase'::character varying, "
458
+ "'grant'::character varying]::text[])",
459
+ name="credit_transactions_transaction_type_check",
460
+ ),
461
+ schema=SCHEMA,
414
462
  )
415
463
  op.create_index(
416
- "idx_credit_transactions_user", "credit_transactions", ["user_id"], unique=False
464
+ "idx_credit_transactions_user",
465
+ "credit_transactions",
466
+ ["user_id"],
467
+ unique=False,
468
+ schema=SCHEMA,
417
469
  )
418
470
 
419
471
 
420
472
  def downgrade() -> None:
421
473
  # drop in reverse dependency order
422
- op.drop_index("idx_credit_transactions_user", table_name="credit_transactions")
423
- op.drop_table("credit_transactions")
474
+ op.drop_index(
475
+ "idx_credit_transactions_user", table_name="credit_transactions", schema=SCHEMA
476
+ )
477
+ op.drop_table("credit_transactions", schema=SCHEMA)
478
+
479
+ op.drop_index("idx_generations_user", table_name="generations", schema=SCHEMA)
480
+ op.drop_index("idx_generations_tenant", table_name="generations", schema=SCHEMA)
481
+ op.drop_index("idx_generations_status", table_name="generations", schema=SCHEMA)
482
+ op.drop_index("idx_generations_lineage", table_name="generations", schema=SCHEMA)
483
+ op.drop_index("idx_generations_board", table_name="generations", schema=SCHEMA)
484
+ op.drop_table("generations", schema=SCHEMA)
424
485
 
425
- op.drop_index("idx_generations_user", table_name="generations")
426
- op.drop_index("idx_generations_tenant", table_name="generations")
427
- op.drop_index("idx_generations_status", table_name="generations")
428
- op.drop_index("idx_generations_lineage", table_name="generations")
429
- op.drop_index("idx_generations_board", table_name="generations")
430
- op.drop_table("generations")
486
+ op.drop_index("idx_board_members_user", table_name="board_members", schema=SCHEMA)
487
+ op.drop_index("idx_board_members_board", table_name="board_members", schema=SCHEMA)
488
+ op.drop_table("board_members", schema=SCHEMA)
431
489
 
432
- op.drop_index("idx_board_members_user", table_name="board_members")
433
- op.drop_index("idx_board_members_board", table_name="board_members")
434
- op.drop_table("board_members")
490
+ op.drop_table("lora_models", schema=SCHEMA)
435
491
 
436
- op.drop_table("lora_models")
492
+ op.drop_index("idx_boards_tenant", table_name="boards", schema=SCHEMA)
493
+ op.drop_index("idx_boards_owner", table_name="boards", schema=SCHEMA)
494
+ op.drop_table("boards", schema=SCHEMA)
437
495
 
438
- op.drop_index("idx_boards_tenant", table_name="boards")
439
- op.drop_index("idx_boards_owner", table_name="boards")
440
- op.drop_table("boards")
496
+ op.drop_index("idx_users_tenant", table_name="users", schema=SCHEMA)
497
+ op.drop_index("idx_users_auth", table_name="users", schema=SCHEMA)
498
+ op.drop_table("users", schema=SCHEMA)
441
499
 
442
- op.drop_index("idx_users_tenant", table_name="users")
443
- op.drop_index("idx_users_auth", table_name="users")
444
- op.drop_table("users")
500
+ op.drop_table("provider_configs", schema=SCHEMA)
445
501
 
446
- op.drop_table("provider_configs")
502
+ op.drop_table("tenants", schema=SCHEMA)
447
503
 
448
- op.drop_table("tenants")
504
+ # Drop the schema with CASCADE to remove alembic_version table too
505
+ # Will fail if non-Boards objects exist (beyond alembic_version), which is intentional
506
+ op.execute(f"DROP SCHEMA IF EXISTS {SCHEMA} CASCADE;")
@@ -18,13 +18,16 @@ down_revision: Union[str, Sequence[str], None] = "553dc6a50a20"
18
18
  branch_labels: Union[str, Sequence[str], None] = None
19
19
  depends_on: Union[str, Sequence[str], None] = None
20
20
 
21
+ # Schema name for all Boards tables
22
+ SCHEMA = "boards"
23
+
21
24
 
22
25
  def upgrade() -> None:
23
26
  """Upgrade schema."""
24
27
  # ### commands auto generated by Alembic - please adjust! ###
25
28
  # Drop schema_migrations table if it exists (from legacy migration system)
26
29
  op.execute("DROP TABLE IF EXISTS schema_migrations")
27
- op.drop_column("generations", "provider_name")
30
+ op.drop_column("generations", "provider_name", schema=SCHEMA)
28
31
  # ### end Alembic commands ###
29
32
 
30
33
 
@@ -37,13 +40,14 @@ def downgrade() -> None:
37
40
  sa.Column(
38
41
  "provider_name", sa.VARCHAR(length=100), autoincrement=False, nullable=True
39
42
  ),
43
+ schema=SCHEMA,
40
44
  )
41
45
  # Set a default value for existing rows (though this downgrade should rarely be used)
42
46
  op.execute(
43
- "UPDATE generations SET provider_name = 'unknown' WHERE provider_name IS NULL"
47
+ f"UPDATE {SCHEMA}.generations SET provider_name = 'unknown' WHERE provider_name IS NULL"
44
48
  )
45
49
  # Now make it NOT NULL
46
- op.alter_column("generations", "provider_name", nullable=False)
50
+ op.alter_column("generations", "provider_name", nullable=False, schema=SCHEMA)
47
51
  op.create_table(
48
52
  "schema_migrations",
49
53
  sa.Column(