@weirdfingers/baseboards 0.9.6 → 0.9.7

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 (237) hide show
  1. package/dist/index.js +560 -469
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -5
  4. package/templates/README.md +0 -122
  5. package/templates/api/.env.example +0 -65
  6. package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
  7. package/templates/api/Dockerfile +0 -32
  8. package/templates/api/README.md +0 -264
  9. package/templates/api/alembic/env.py +0 -114
  10. package/templates/api/alembic/script.py.mako +0 -28
  11. package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
  12. package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
  13. package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
  14. package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
  15. package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
  16. package/templates/api/alembic.ini +0 -36
  17. package/templates/api/config/generators.yaml +0 -237
  18. package/templates/api/config/storage_config.yaml +0 -26
  19. package/templates/api/docs/ADDING_GENERATORS.md +0 -409
  20. package/templates/api/docs/GENERATORS_API.md +0 -502
  21. package/templates/api/docs/MIGRATIONS.md +0 -472
  22. package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
  23. package/templates/api/docs/storage_providers.md +0 -337
  24. package/templates/api/pyproject.toml +0 -205
  25. package/templates/api/src/boards/__init__.py +0 -10
  26. package/templates/api/src/boards/api/app.py +0 -172
  27. package/templates/api/src/boards/api/auth.py +0 -75
  28. package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
  29. package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
  30. package/templates/api/src/boards/api/endpoints/setup.py +0 -505
  31. package/templates/api/src/boards/api/endpoints/sse.py +0 -129
  32. package/templates/api/src/boards/api/endpoints/storage.py +0 -155
  33. package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
  34. package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
  35. package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
  36. package/templates/api/src/boards/auth/__init__.py +0 -15
  37. package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
  38. package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
  39. package/templates/api/src/boards/auth/adapters/base.py +0 -73
  40. package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
  41. package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
  42. package/templates/api/src/boards/auth/adapters/none.py +0 -102
  43. package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
  44. package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
  45. package/templates/api/src/boards/auth/context.py +0 -35
  46. package/templates/api/src/boards/auth/factory.py +0 -129
  47. package/templates/api/src/boards/auth/middleware.py +0 -221
  48. package/templates/api/src/boards/auth/provisioning.py +0 -129
  49. package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
  50. package/templates/api/src/boards/cli.py +0 -354
  51. package/templates/api/src/boards/config.py +0 -131
  52. package/templates/api/src/boards/database/__init__.py +0 -7
  53. package/templates/api/src/boards/database/cli.py +0 -110
  54. package/templates/api/src/boards/database/connection.py +0 -292
  55. package/templates/api/src/boards/database/models.py +0 -19
  56. package/templates/api/src/boards/database/seed_data.py +0 -182
  57. package/templates/api/src/boards/dbmodels/__init__.py +0 -441
  58. package/templates/api/src/boards/generators/__init__.py +0 -57
  59. package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
  60. package/templates/api/src/boards/generators/artifacts.py +0 -53
  61. package/templates/api/src/boards/generators/base.py +0 -144
  62. package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
  63. package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
  64. package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
  65. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
  66. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
  67. package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
  68. package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
  69. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
  70. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
  71. package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
  72. package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
  73. package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
  74. package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
  75. package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
  76. package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
  77. package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
  78. package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
  79. package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
  80. package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
  81. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
  82. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
  83. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
  84. package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
  85. package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
  86. package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
  87. package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
  88. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
  89. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
  90. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
  91. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
  92. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
  93. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
  94. package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
  95. package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
  96. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
  97. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
  98. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
  99. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
  100. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
  101. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
  102. package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
  103. package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
  104. package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
  105. package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
  106. package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
  107. package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
  108. package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
  109. package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
  110. package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
  111. package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
  112. package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
  113. package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
  114. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
  115. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
  116. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
  117. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
  118. package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
  119. package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
  120. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
  121. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
  122. package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
  123. package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
  124. package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
  125. package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
  126. package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
  127. package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
  128. package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
  129. package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
  130. package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
  131. package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
  132. package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
  133. package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
  134. package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
  135. package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
  136. package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
  137. package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
  138. package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
  139. package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
  140. package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
  141. package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
  142. package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
  143. package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
  144. package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
  145. package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
  146. package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
  147. package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
  148. package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
  149. package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
  150. package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
  151. package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
  152. package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
  153. package/templates/api/src/boards/generators/loader.py +0 -253
  154. package/templates/api/src/boards/generators/registry.py +0 -114
  155. package/templates/api/src/boards/generators/resolution.py +0 -632
  156. package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
  157. package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
  158. package/templates/api/src/boards/graphql/__init__.py +0 -7
  159. package/templates/api/src/boards/graphql/access_control.py +0 -136
  160. package/templates/api/src/boards/graphql/mutations/root.py +0 -148
  161. package/templates/api/src/boards/graphql/queries/root.py +0 -116
  162. package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
  163. package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
  164. package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
  165. package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
  166. package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
  167. package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
  168. package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
  169. package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
  170. package/templates/api/src/boards/graphql/schema.py +0 -81
  171. package/templates/api/src/boards/graphql/types/board.py +0 -102
  172. package/templates/api/src/boards/graphql/types/generation.py +0 -166
  173. package/templates/api/src/boards/graphql/types/generator.py +0 -17
  174. package/templates/api/src/boards/graphql/types/user.py +0 -47
  175. package/templates/api/src/boards/jobs/repository.py +0 -153
  176. package/templates/api/src/boards/logging.py +0 -195
  177. package/templates/api/src/boards/middleware.py +0 -339
  178. package/templates/api/src/boards/progress/__init__.py +0 -4
  179. package/templates/api/src/boards/progress/models.py +0 -25
  180. package/templates/api/src/boards/progress/publisher.py +0 -64
  181. package/templates/api/src/boards/py.typed +0 -0
  182. package/templates/api/src/boards/redis_pool.py +0 -118
  183. package/templates/api/src/boards/storage/__init__.py +0 -52
  184. package/templates/api/src/boards/storage/base.py +0 -363
  185. package/templates/api/src/boards/storage/config.py +0 -187
  186. package/templates/api/src/boards/storage/factory.py +0 -288
  187. package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
  188. package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
  189. package/templates/api/src/boards/storage/implementations/local.py +0 -201
  190. package/templates/api/src/boards/storage/implementations/s3.py +0 -294
  191. package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
  192. package/templates/api/src/boards/tenant_isolation.py +0 -446
  193. package/templates/api/src/boards/validation.py +0 -262
  194. package/templates/api/src/boards/workers/__init__.py +0 -1
  195. package/templates/api/src/boards/workers/actors.py +0 -274
  196. package/templates/api/src/boards/workers/cli.py +0 -125
  197. package/templates/api/src/boards/workers/context.py +0 -348
  198. package/templates/api/src/boards/workers/middleware.py +0 -58
  199. package/templates/api/src/py.typed +0 -0
  200. package/templates/compose.web.yaml +0 -35
  201. package/templates/compose.yaml +0 -116
  202. package/templates/docker/env.example +0 -23
  203. package/templates/web/.env.example +0 -28
  204. package/templates/web/Dockerfile +0 -51
  205. package/templates/web/components.json +0 -22
  206. package/templates/web/imageLoader.js +0 -18
  207. package/templates/web/next-env.d.ts +0 -5
  208. package/templates/web/next.config.js +0 -36
  209. package/templates/web/package.json +0 -41
  210. package/templates/web/postcss.config.mjs +0 -7
  211. package/templates/web/public/favicon.ico +0 -0
  212. package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
  213. package/templates/web/src/app/globals.css +0 -123
  214. package/templates/web/src/app/layout.tsx +0 -31
  215. package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
  216. package/templates/web/src/app/page.tsx +0 -35
  217. package/templates/web/src/app/providers.tsx +0 -18
  218. package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
  219. package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
  220. package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
  221. package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
  222. package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
  223. package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
  224. package/templates/web/src/components/header.tsx +0 -32
  225. package/templates/web/src/components/theme-provider.tsx +0 -10
  226. package/templates/web/src/components/theme-toggle.tsx +0 -75
  227. package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
  228. package/templates/web/src/components/ui/button.tsx +0 -58
  229. package/templates/web/src/components/ui/card.tsx +0 -92
  230. package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
  231. package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
  232. package/templates/web/src/components/ui/toast.tsx +0 -128
  233. package/templates/web/src/components/ui/toaster.tsx +0 -35
  234. package/templates/web/src/components/ui/use-toast.ts +0 -187
  235. package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
  236. package/templates/web/src/lib/utils.ts +0 -6
  237. package/templates/web/tsconfig.json +0 -41
@@ -1,172 +0,0 @@
1
- """
2
- Main FastAPI application for Boards backend
3
- """
4
-
5
- import os
6
- from contextlib import asynccontextmanager
7
-
8
- from fastapi import FastAPI
9
- from fastapi.middleware.cors import CORSMiddleware
10
-
11
- from ..config import initialize_generator_api_keys, settings
12
- from ..database import init_database
13
- from ..generators.loader import load_generators_from_config
14
- from ..logging import configure_logging, get_logger
15
- from ..middleware import LoggingContextMiddleware, TenantRoutingMiddleware
16
-
17
- # Configure logging before creating logger
18
- configure_logging(debug=settings.debug)
19
- logger = get_logger(__name__)
20
-
21
-
22
- @asynccontextmanager
23
- async def lifespan(app: FastAPI):
24
- """Application lifespan manager."""
25
- # Startup
26
- logger.info("Starting Boards API...")
27
- init_database()
28
- logger.info("Database initialized")
29
-
30
- # Initialize generator API keys from settings
31
- initialize_generator_api_keys()
32
- logger.info("Generator API keys initialized")
33
-
34
- # Load generators based on configuration
35
- try:
36
- load_generators_from_config()
37
- logger.info(
38
- "Generators configured and registered",
39
- names=list(
40
- __import__(
41
- "boards.generators.registry", fromlist=["registry"]
42
- ).registry.list_names()
43
- ),
44
- )
45
- except Exception as e:
46
- # Fail fast: strict mode default may raise here
47
- logger.error("Failed to configure generators", error=str(e))
48
- raise
49
-
50
- # Run comprehensive startup validation
51
- try:
52
- from ..validation import (
53
- ValidationError,
54
- get_startup_recommendations,
55
- validate_startup_configuration,
56
- )
57
-
58
- validation_results = await validate_startup_configuration()
59
-
60
- if not validation_results["overall_valid"]:
61
- # Log detailed error information
62
- logger.error(
63
- "Application configuration validation failed - some features may not work properly",
64
- database_errors=validation_results.get("database", {}).get("errors", []),
65
- tenant_errors=validation_results["tenant"].get("errors", []),
66
- auth_errors=validation_results["auth"].get("errors", []),
67
- )
68
-
69
- # In production, we might want to fail hard here
70
- if settings.environment.lower() in ("production", "prod"):
71
- raise ValidationError("Critical configuration validation failed in production")
72
-
73
- # Log recommendations
74
- recommendations = get_startup_recommendations(validation_results)
75
- if recommendations:
76
- logger.info("Configuration recommendations", recommendations=recommendations)
77
-
78
- except ValidationError:
79
- # Re-raise validation errors to fail startup
80
- raise
81
- except Exception as e:
82
- logger.error(
83
- "Unexpected error during startup validation",
84
- error=str(e),
85
- note="Application will continue but may have configuration issues",
86
- )
87
-
88
- yield
89
-
90
- # Shutdown
91
- logger.info("Shutting down Boards API...")
92
-
93
-
94
- def create_app() -> FastAPI:
95
- """Create and configure the FastAPI application."""
96
-
97
- app = FastAPI(
98
- title="Boards API",
99
- description="Open-source creative toolkit for AI-generated content",
100
- version="0.1.0",
101
- lifespan=lifespan,
102
- debug=settings.debug,
103
- )
104
-
105
- # Add tenant routing middleware first (runs before logging)
106
- app.add_middleware(TenantRoutingMiddleware)
107
-
108
- # Add logging context middleware
109
- app.add_middleware(LoggingContextMiddleware)
110
-
111
- # CORS configuration
112
- app.add_middleware(
113
- CORSMiddleware,
114
- allow_origins=settings.cors_origins,
115
- allow_credentials=True,
116
- allow_methods=["*"],
117
- allow_headers=["*"],
118
- )
119
-
120
- # Health check endpoint
121
- @app.get("/health")
122
- async def health_check(): # pyright: ignore [reportUnusedFunction]
123
- """Health check endpoint."""
124
- return {"status": "healthy", "version": "0.1.0"}
125
-
126
- # GraphQL endpoint (allow disabling for tests)
127
- if not os.getenv("BOARDS_DISABLE_GRAPHQL"):
128
- try:
129
- from ..graphql.schema import create_graphql_router, validate_schema
130
-
131
- # Validate schema at startup to catch circular reference errors early
132
- logger.info("Validating GraphQL schema...")
133
- validate_schema()
134
-
135
- # Create and mount the GraphQL router
136
- graphql_router = create_graphql_router()
137
- app.include_router(graphql_router, prefix="")
138
- logger.info("GraphQL endpoint initialized successfully", endpoint="/graphql")
139
- except Exception as e: # pragma: no cover
140
- logger.error("Failed to initialize GraphQL endpoint", error=str(e))
141
- # Re-raise to fail fast - server should not start with broken GraphQL
142
- raise
143
-
144
- # REST API endpoints (for SSE, webhooks, etc.)
145
- from .endpoints import jobs, setup, sse, storage, tenant_registration, uploads, webhooks
146
-
147
- app.include_router(sse.router, prefix="/api/sse", tags=["SSE"])
148
- app.include_router(jobs.router, prefix="/api/jobs", tags=["Jobs"])
149
- app.include_router(webhooks.router, prefix="/api/webhooks", tags=["Webhooks"])
150
- app.include_router(storage.router, prefix="/api/storage", tags=["Storage"])
151
- app.include_router(setup.router, prefix="/api/setup", tags=["Setup"])
152
- app.include_router(uploads.router, prefix="/api", tags=["Uploads"])
153
- app.include_router(
154
- tenant_registration.router, prefix="/api/tenants", tags=["Tenant Registration"]
155
- )
156
-
157
- return app
158
-
159
-
160
- # Create the main application instance
161
- app = create_app()
162
-
163
- if __name__ == "__main__":
164
- import uvicorn
165
-
166
- uvicorn.run(
167
- "boards.api.app:app",
168
- host=settings.api_host,
169
- port=settings.api_port,
170
- reload=settings.api_reload,
171
- log_level=settings.log_level.lower(),
172
- )
@@ -1,75 +0,0 @@
1
- """Authentication dependencies for API endpoints."""
2
-
3
- from __future__ import annotations
4
-
5
- from uuid import UUID
6
-
7
- from fastapi import Depends, HTTPException
8
- from pydantic import BaseModel
9
-
10
- from ..auth import AuthContext, get_auth_context, get_auth_context_optional
11
- from ..logging import get_logger
12
-
13
- logger = get_logger(__name__)
14
-
15
-
16
- class AuthenticatedUser(BaseModel):
17
- """Represents an authenticated user."""
18
-
19
- user_id: UUID
20
- tenant_id: UUID
21
- email: str | None = None
22
-
23
-
24
- async def get_current_user(
25
- auth_context: AuthContext = Depends(get_auth_context),
26
- ) -> AuthenticatedUser:
27
- """
28
- Get the current authenticated user from the auth context.
29
-
30
- Args:
31
- auth_context: Authentication context from middleware
32
-
33
- Returns:
34
- AuthenticatedUser object with user information
35
-
36
- Raises:
37
- HTTPException: If user is not authenticated
38
- """
39
- if not auth_context.is_authenticated or not auth_context.user_id:
40
- raise HTTPException(
41
- status_code=401,
42
- detail="Authentication required",
43
- headers={"WWW-Authenticate": "Bearer"},
44
- )
45
-
46
- return AuthenticatedUser(
47
- user_id=auth_context.user_id,
48
- tenant_id=auth_context.tenant_id,
49
- email=auth_context.principal.get("email") if auth_context.principal else None,
50
- )
51
-
52
-
53
- async def get_current_user_optional(
54
- auth_context: AuthContext = Depends(get_auth_context_optional),
55
- ) -> AuthenticatedUser | None:
56
- """
57
- Optional authentication - returns None if not authenticated.
58
-
59
- Use this for endpoints that can work both authenticated and unauthenticated,
60
- but may provide different functionality based on auth status.
61
- """
62
- if not auth_context.is_authenticated or not auth_context.user_id:
63
- return None
64
-
65
- return AuthenticatedUser(
66
- user_id=auth_context.user_id,
67
- tenant_id=auth_context.tenant_id,
68
- email=auth_context.principal.get("email") if auth_context.principal else None,
69
- )
70
-
71
-
72
- # Legacy support - keep the old function names for backward compatibility
73
- async def get_auth_context_dependency() -> AuthContext:
74
- """Get auth context directly (for advanced use cases)."""
75
- return await get_auth_context()
@@ -1,3 +0,0 @@
1
- """
2
- API endpoint modules for Boards backend
3
- """
@@ -1,76 +0,0 @@
1
- """Job submission endpoints."""
2
-
3
- from __future__ import annotations
4
-
5
- from uuid import UUID
6
-
7
- from fastapi import APIRouter, Depends, HTTPException
8
- from pydantic import BaseModel
9
- from sqlalchemy.ext.asyncio import AsyncSession
10
-
11
- from ...database.connection import get_db_session
12
- from ...jobs import repository as jobs_repo
13
- from ...logging import get_logger
14
- from ...workers.actors import process_generation
15
- from ..auth import AuthenticatedUser, get_current_user
16
-
17
- logger = get_logger(__name__)
18
-
19
-
20
- router = APIRouter()
21
-
22
-
23
- class SubmitGenerationRequest(BaseModel):
24
- tenant_id: UUID
25
- board_id: UUID
26
- user_id: UUID
27
- generator_name: str
28
- artifact_type: str
29
- input_params: dict
30
-
31
-
32
- class SubmitGenerationResponse(BaseModel):
33
- generation_id: UUID
34
-
35
-
36
- @router.post("/generations", response_model=SubmitGenerationResponse)
37
- async def submit_generation(
38
- body: SubmitGenerationRequest,
39
- db: AsyncSession = Depends(get_db_session),
40
- current_user: AuthenticatedUser = Depends(get_current_user),
41
- ) -> SubmitGenerationResponse:
42
- """Submit a new generation job.
43
-
44
- Requires authentication. The authenticated user's ID and tenant will be used
45
- for the generation, overriding any values provided in the request body.
46
- """
47
- try:
48
- # Validate that user has access to the specified board
49
- # TODO: Add board access validation logic here
50
-
51
- # Override user_id and tenant_id with authenticated values for security
52
- # This prevents users from submitting jobs on behalf of others
53
- gen = await jobs_repo.create_generation(
54
- db,
55
- tenant_id=current_user.tenant_id, # Use authenticated tenant
56
- board_id=body.board_id,
57
- user_id=current_user.user_id, # Use authenticated user
58
- generator_name=body.generator_name,
59
- artifact_type=body.artifact_type,
60
- input_params=body.input_params,
61
- )
62
-
63
- # Commit the transaction to ensure job is persisted before enqueueing
64
- await db.commit()
65
- logger.info(f"Created generation job {gen.id} for user {current_user.user_id}")
66
-
67
- # Enqueue job for processing
68
- process_generation.send(str(gen.id))
69
- logger.info(f"Enqueued generation job {gen.id}")
70
-
71
- return SubmitGenerationResponse(generation_id=gen.id)
72
-
73
- except Exception as e:
74
- logger.error(f"Failed to submit generation: {e}")
75
- await db.rollback()
76
- raise HTTPException(status_code=500, detail=f"Failed to submit generation: {str(e)}") from e