@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.
- package/dist/index.js +560 -469
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
- package/templates/README.md +0 -122
- package/templates/api/.env.example +0 -65
- package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
- package/templates/api/Dockerfile +0 -32
- package/templates/api/README.md +0 -264
- package/templates/api/alembic/env.py +0 -114
- package/templates/api/alembic/script.py.mako +0 -28
- package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
- package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
- package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
- package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
- package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
- package/templates/api/alembic.ini +0 -36
- package/templates/api/config/generators.yaml +0 -237
- package/templates/api/config/storage_config.yaml +0 -26
- package/templates/api/docs/ADDING_GENERATORS.md +0 -409
- package/templates/api/docs/GENERATORS_API.md +0 -502
- package/templates/api/docs/MIGRATIONS.md +0 -472
- package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
- package/templates/api/docs/storage_providers.md +0 -337
- package/templates/api/pyproject.toml +0 -205
- package/templates/api/src/boards/__init__.py +0 -10
- package/templates/api/src/boards/api/app.py +0 -172
- package/templates/api/src/boards/api/auth.py +0 -75
- package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
- package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
- package/templates/api/src/boards/api/endpoints/setup.py +0 -505
- package/templates/api/src/boards/api/endpoints/sse.py +0 -129
- package/templates/api/src/boards/api/endpoints/storage.py +0 -155
- package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
- package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
- package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
- package/templates/api/src/boards/auth/__init__.py +0 -15
- package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
- package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
- package/templates/api/src/boards/auth/adapters/base.py +0 -73
- package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
- package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
- package/templates/api/src/boards/auth/adapters/none.py +0 -102
- package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
- package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
- package/templates/api/src/boards/auth/context.py +0 -35
- package/templates/api/src/boards/auth/factory.py +0 -129
- package/templates/api/src/boards/auth/middleware.py +0 -221
- package/templates/api/src/boards/auth/provisioning.py +0 -129
- package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
- package/templates/api/src/boards/cli.py +0 -354
- package/templates/api/src/boards/config.py +0 -131
- package/templates/api/src/boards/database/__init__.py +0 -7
- package/templates/api/src/boards/database/cli.py +0 -110
- package/templates/api/src/boards/database/connection.py +0 -292
- package/templates/api/src/boards/database/models.py +0 -19
- package/templates/api/src/boards/database/seed_data.py +0 -182
- package/templates/api/src/boards/dbmodels/__init__.py +0 -441
- package/templates/api/src/boards/generators/__init__.py +0 -57
- package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
- package/templates/api/src/boards/generators/artifacts.py +0 -53
- package/templates/api/src/boards/generators/base.py +0 -144
- package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
- package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
- package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
- package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
- package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
- package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
- package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
- package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
- package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
- package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
- package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
- package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
- package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
- package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
- package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
- package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
- package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
- package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
- package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
- package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
- package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
- package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
- package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
- package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
- package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
- package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
- package/templates/api/src/boards/generators/loader.py +0 -253
- package/templates/api/src/boards/generators/registry.py +0 -114
- package/templates/api/src/boards/generators/resolution.py +0 -632
- package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
- package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
- package/templates/api/src/boards/graphql/__init__.py +0 -7
- package/templates/api/src/boards/graphql/access_control.py +0 -136
- package/templates/api/src/boards/graphql/mutations/root.py +0 -148
- package/templates/api/src/boards/graphql/queries/root.py +0 -116
- package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
- package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
- package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
- package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
- package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
- package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
- package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
- package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
- package/templates/api/src/boards/graphql/schema.py +0 -81
- package/templates/api/src/boards/graphql/types/board.py +0 -102
- package/templates/api/src/boards/graphql/types/generation.py +0 -166
- package/templates/api/src/boards/graphql/types/generator.py +0 -17
- package/templates/api/src/boards/graphql/types/user.py +0 -47
- package/templates/api/src/boards/jobs/repository.py +0 -153
- package/templates/api/src/boards/logging.py +0 -195
- package/templates/api/src/boards/middleware.py +0 -339
- package/templates/api/src/boards/progress/__init__.py +0 -4
- package/templates/api/src/boards/progress/models.py +0 -25
- package/templates/api/src/boards/progress/publisher.py +0 -64
- package/templates/api/src/boards/py.typed +0 -0
- package/templates/api/src/boards/redis_pool.py +0 -118
- package/templates/api/src/boards/storage/__init__.py +0 -52
- package/templates/api/src/boards/storage/base.py +0 -363
- package/templates/api/src/boards/storage/config.py +0 -187
- package/templates/api/src/boards/storage/factory.py +0 -288
- package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
- package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
- package/templates/api/src/boards/storage/implementations/local.py +0 -201
- package/templates/api/src/boards/storage/implementations/s3.py +0 -294
- package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
- package/templates/api/src/boards/tenant_isolation.py +0 -446
- package/templates/api/src/boards/validation.py +0 -262
- package/templates/api/src/boards/workers/__init__.py +0 -1
- package/templates/api/src/boards/workers/actors.py +0 -274
- package/templates/api/src/boards/workers/cli.py +0 -125
- package/templates/api/src/boards/workers/context.py +0 -348
- package/templates/api/src/boards/workers/middleware.py +0 -58
- package/templates/api/src/py.typed +0 -0
- package/templates/compose.web.yaml +0 -35
- package/templates/compose.yaml +0 -116
- package/templates/docker/env.example +0 -23
- package/templates/web/.env.example +0 -28
- package/templates/web/Dockerfile +0 -51
- package/templates/web/components.json +0 -22
- package/templates/web/imageLoader.js +0 -18
- package/templates/web/next-env.d.ts +0 -5
- package/templates/web/next.config.js +0 -36
- package/templates/web/package.json +0 -41
- package/templates/web/postcss.config.mjs +0 -7
- package/templates/web/public/favicon.ico +0 -0
- package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
- package/templates/web/src/app/globals.css +0 -123
- package/templates/web/src/app/layout.tsx +0 -31
- package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
- package/templates/web/src/app/page.tsx +0 -35
- package/templates/web/src/app/providers.tsx +0 -18
- package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
- package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
- package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
- package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
- package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
- package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
- package/templates/web/src/components/header.tsx +0 -32
- package/templates/web/src/components/theme-provider.tsx +0 -10
- package/templates/web/src/components/theme-toggle.tsx +0 -75
- package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
- package/templates/web/src/components/ui/button.tsx +0 -58
- package/templates/web/src/components/ui/card.tsx +0 -92
- package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
- package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
- package/templates/web/src/components/ui/toast.tsx +0 -128
- package/templates/web/src/components/ui/toaster.tsx +0 -35
- package/templates/web/src/components/ui/use-toast.ts +0 -187
- package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
- package/templates/web/src/lib/utils.ts +0 -6
- package/templates/web/tsconfig.json +0 -41
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Shared access control logic for GraphQL resolvers
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from enum import Enum
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
7
|
-
|
|
8
|
-
import strawberry
|
|
9
|
-
|
|
10
|
-
from ..auth.middleware import get_auth_context_optional
|
|
11
|
-
from ..logging import get_logger
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from ..auth.context import AuthContext
|
|
15
|
-
from ..dbmodels import Boards
|
|
16
|
-
|
|
17
|
-
logger = get_logger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@strawberry.enum
|
|
21
|
-
class BoardQueryRole(Enum):
|
|
22
|
-
"""Role filter for board queries"""
|
|
23
|
-
|
|
24
|
-
ANY = "any"
|
|
25
|
-
OWNER = "owner"
|
|
26
|
-
MEMBER = "member"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@strawberry.enum
|
|
30
|
-
class SortOrder(Enum):
|
|
31
|
-
"""Sort order for queries"""
|
|
32
|
-
|
|
33
|
-
CREATED_ASC = "created_asc"
|
|
34
|
-
CREATED_DESC = "created_desc"
|
|
35
|
-
UPDATED_ASC = "updated_asc"
|
|
36
|
-
UPDATED_DESC = "updated_desc"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
async def get_auth_context_from_info(info: strawberry.Info) -> "AuthContext | None":
|
|
40
|
-
"""
|
|
41
|
-
Extract auth context from GraphQL info object.
|
|
42
|
-
|
|
43
|
-
Returns None if request is not available or auth fails.
|
|
44
|
-
"""
|
|
45
|
-
request = info.context.get("request")
|
|
46
|
-
if not request:
|
|
47
|
-
logger.error("Request not found in GraphQL context")
|
|
48
|
-
return None
|
|
49
|
-
|
|
50
|
-
return await get_auth_context_optional(
|
|
51
|
-
authorization=request.headers.get("authorization"),
|
|
52
|
-
x_tenant=request.headers.get("x-tenant"),
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def can_access_board(board: "Boards", auth_context: "AuthContext | None") -> bool:
|
|
57
|
-
"""
|
|
58
|
-
Check if a user can access a board based on authorization rules.
|
|
59
|
-
|
|
60
|
-
Board is accessible if:
|
|
61
|
-
1. It's public
|
|
62
|
-
2. User is the owner
|
|
63
|
-
3. User is a member
|
|
64
|
-
|
|
65
|
-
Args:
|
|
66
|
-
board: The board to check access for
|
|
67
|
-
auth_context: The authentication context (can be None)
|
|
68
|
-
|
|
69
|
-
Returns:
|
|
70
|
-
True if access is allowed, False otherwise
|
|
71
|
-
"""
|
|
72
|
-
# Public boards are accessible to everyone
|
|
73
|
-
if board.is_public:
|
|
74
|
-
return True
|
|
75
|
-
|
|
76
|
-
# Private boards require authentication
|
|
77
|
-
if not auth_context or not auth_context.is_authenticated:
|
|
78
|
-
return False
|
|
79
|
-
|
|
80
|
-
# Owner has access
|
|
81
|
-
if board.owner_id == auth_context.user_id:
|
|
82
|
-
return True
|
|
83
|
-
|
|
84
|
-
# Check if user is a member
|
|
85
|
-
return any(member.user_id == auth_context.user_id for member in board.board_members)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def can_access_board_details(board: "Boards", auth_context: "AuthContext | None") -> bool:
|
|
89
|
-
"""
|
|
90
|
-
Check if a user can access detailed board information (members, owner, etc).
|
|
91
|
-
|
|
92
|
-
Currently same as can_access_board, but separated for future customization.
|
|
93
|
-
"""
|
|
94
|
-
return can_access_board(board, auth_context)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def is_board_owner_or_member(board: "Boards", auth_context: "AuthContext | None") -> bool:
|
|
98
|
-
"""
|
|
99
|
-
Check if the authenticated user is the owner or a member of the board.
|
|
100
|
-
|
|
101
|
-
This is stricter than can_access_board - public access is not sufficient.
|
|
102
|
-
"""
|
|
103
|
-
if not auth_context or not auth_context.is_authenticated:
|
|
104
|
-
return False
|
|
105
|
-
|
|
106
|
-
# Owner has access
|
|
107
|
-
if board.owner_id == auth_context.user_id:
|
|
108
|
-
return True
|
|
109
|
-
|
|
110
|
-
# Check if user is a member
|
|
111
|
-
return any(member.user_id == auth_context.user_id for member in board.board_members)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def ensure_preloaded(obj, attr_name: str, error_msg: str | None = None) -> None:
|
|
115
|
-
"""
|
|
116
|
-
Ensure that a relationship attribute has been preloaded.
|
|
117
|
-
|
|
118
|
-
Args:
|
|
119
|
-
obj: The SQLAlchemy object
|
|
120
|
-
attr_name: Name of the relationship attribute
|
|
121
|
-
error_msg: Custom error message (optional)
|
|
122
|
-
|
|
123
|
-
Raises:
|
|
124
|
-
RuntimeError: If the attribute was not preloaded
|
|
125
|
-
"""
|
|
126
|
-
try:
|
|
127
|
-
# Try to access the attribute
|
|
128
|
-
getattr(obj, attr_name)
|
|
129
|
-
except Exception as e:
|
|
130
|
-
if "was not loaded" in str(e) or "lazy loading" in str(e):
|
|
131
|
-
msg = error_msg or (
|
|
132
|
-
f"Relationship '{attr_name}' was not preloaded. Use selectinload() in the query."
|
|
133
|
-
)
|
|
134
|
-
raise RuntimeError(msg) from e
|
|
135
|
-
# Re-raise other exceptions
|
|
136
|
-
raise
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Root GraphQL mutation definitions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from uuid import UUID
|
|
6
|
-
|
|
7
|
-
import strawberry
|
|
8
|
-
|
|
9
|
-
from ..types.board import Board, BoardRole
|
|
10
|
-
from ..types.generation import ArtifactType, Generation, UploadArtifactInput
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# Input types for mutations
|
|
14
|
-
@strawberry.input
|
|
15
|
-
class CreateBoardInput:
|
|
16
|
-
"""Input for creating a new board."""
|
|
17
|
-
|
|
18
|
-
title: str
|
|
19
|
-
description: str | None = None
|
|
20
|
-
is_public: bool = False
|
|
21
|
-
settings: strawberry.scalars.JSON | None = None # type: ignore[reportInvalidTypeForm]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@strawberry.input
|
|
25
|
-
class UpdateBoardInput:
|
|
26
|
-
"""Input for updating a board."""
|
|
27
|
-
|
|
28
|
-
id: UUID
|
|
29
|
-
title: str | None = None
|
|
30
|
-
description: str | None = None
|
|
31
|
-
is_public: bool | None = None
|
|
32
|
-
settings: strawberry.scalars.JSON | None = None # type: ignore[reportInvalidTypeForm]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@strawberry.input
|
|
36
|
-
class AddBoardMemberInput:
|
|
37
|
-
"""Input for adding a board member."""
|
|
38
|
-
|
|
39
|
-
board_id: UUID
|
|
40
|
-
user_id: UUID
|
|
41
|
-
role: BoardRole = BoardRole.VIEWER
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@strawberry.input
|
|
45
|
-
class CreateGenerationInput:
|
|
46
|
-
"""Input for creating a new generation.
|
|
47
|
-
|
|
48
|
-
Note: Lineage is now captured automatically via artifact resolution.
|
|
49
|
-
Generator input parameters that reference other generations (as artifact types)
|
|
50
|
-
will be automatically resolved and lineage will be tracked.
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
board_id: UUID
|
|
54
|
-
generator_name: str
|
|
55
|
-
artifact_type: ArtifactType
|
|
56
|
-
input_params: strawberry.scalars.JSON # type: ignore[reportInvalidTypeForm]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@strawberry.type
|
|
60
|
-
class Mutation:
|
|
61
|
-
"""Root GraphQL mutation type."""
|
|
62
|
-
|
|
63
|
-
# Board mutations
|
|
64
|
-
@strawberry.mutation(name="createBoard")
|
|
65
|
-
async def create_board(self, info: strawberry.Info, input: CreateBoardInput) -> Board:
|
|
66
|
-
"""Create a new board."""
|
|
67
|
-
from ..resolvers.board import create_board
|
|
68
|
-
|
|
69
|
-
return await create_board(info, input)
|
|
70
|
-
|
|
71
|
-
@strawberry.mutation(name="updateBoard")
|
|
72
|
-
async def update_board(self, info: strawberry.Info, input: UpdateBoardInput) -> Board:
|
|
73
|
-
"""Update an existing board."""
|
|
74
|
-
from ..resolvers.board import update_board
|
|
75
|
-
|
|
76
|
-
return await update_board(info, input)
|
|
77
|
-
|
|
78
|
-
@strawberry.mutation(name="deleteBoard")
|
|
79
|
-
async def delete_board(self, info: strawberry.Info, id: UUID) -> bool:
|
|
80
|
-
"""Delete a board."""
|
|
81
|
-
from ..resolvers.board import delete_board
|
|
82
|
-
|
|
83
|
-
return await delete_board(info, id)
|
|
84
|
-
|
|
85
|
-
@strawberry.mutation(name="addBoardMember")
|
|
86
|
-
async def add_board_member(self, info: strawberry.Info, input: AddBoardMemberInput) -> Board:
|
|
87
|
-
"""Add a member to a board."""
|
|
88
|
-
from ..resolvers.board import add_board_member
|
|
89
|
-
|
|
90
|
-
return await add_board_member(info, input)
|
|
91
|
-
|
|
92
|
-
@strawberry.mutation(name="removeBoardMember")
|
|
93
|
-
async def remove_board_member(
|
|
94
|
-
self, info: strawberry.Info, board_id: UUID, user_id: UUID
|
|
95
|
-
) -> Board:
|
|
96
|
-
"""Remove a member from a board."""
|
|
97
|
-
from ..resolvers.board import remove_board_member
|
|
98
|
-
|
|
99
|
-
return await remove_board_member(info, board_id, user_id)
|
|
100
|
-
|
|
101
|
-
@strawberry.mutation(name="updateBoardMemberRole")
|
|
102
|
-
async def update_board_member_role(
|
|
103
|
-
self, info: strawberry.Info, board_id: UUID, user_id: UUID, role: BoardRole
|
|
104
|
-
) -> Board:
|
|
105
|
-
"""Update a board member's role."""
|
|
106
|
-
from ..resolvers.board import update_board_member_role
|
|
107
|
-
|
|
108
|
-
return await update_board_member_role(info, board_id, user_id, role)
|
|
109
|
-
|
|
110
|
-
# Generation mutations
|
|
111
|
-
@strawberry.mutation(name="createGeneration")
|
|
112
|
-
async def create_generation(
|
|
113
|
-
self, info: strawberry.Info, input: CreateGenerationInput
|
|
114
|
-
) -> Generation:
|
|
115
|
-
"""Create a new generation (start a job)."""
|
|
116
|
-
from ..resolvers.generation import create_generation
|
|
117
|
-
|
|
118
|
-
return await create_generation(info, input)
|
|
119
|
-
|
|
120
|
-
@strawberry.mutation(name="cancelGeneration")
|
|
121
|
-
async def cancel_generation(self, info: strawberry.Info, id: UUID) -> Generation:
|
|
122
|
-
"""Cancel a pending or processing generation."""
|
|
123
|
-
from ..resolvers.generation import cancel_generation
|
|
124
|
-
|
|
125
|
-
return await cancel_generation(info, id)
|
|
126
|
-
|
|
127
|
-
@strawberry.mutation(name="deleteGeneration")
|
|
128
|
-
async def delete_generation(self, info: strawberry.Info, id: UUID) -> bool:
|
|
129
|
-
"""Delete a generation."""
|
|
130
|
-
from ..resolvers.generation import delete_generation
|
|
131
|
-
|
|
132
|
-
return await delete_generation(info, id)
|
|
133
|
-
|
|
134
|
-
@strawberry.mutation
|
|
135
|
-
async def regenerate(self, info: strawberry.Info, id: UUID) -> Generation:
|
|
136
|
-
"""Regenerate from an existing generation."""
|
|
137
|
-
from ..resolvers.generation import regenerate
|
|
138
|
-
|
|
139
|
-
return await regenerate(info, id)
|
|
140
|
-
|
|
141
|
-
@strawberry.mutation(name="uploadArtifact")
|
|
142
|
-
async def upload_artifact(
|
|
143
|
-
self, info: strawberry.Info, input: UploadArtifactInput
|
|
144
|
-
) -> Generation:
|
|
145
|
-
"""Upload an artifact from URL (synchronous)."""
|
|
146
|
-
from ..resolvers.upload import upload_artifact_from_url
|
|
147
|
-
|
|
148
|
-
return await upload_artifact_from_url(info, input)
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Root GraphQL query definitions
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from uuid import UUID
|
|
6
|
-
|
|
7
|
-
import strawberry
|
|
8
|
-
|
|
9
|
-
from ..access_control import BoardQueryRole, SortOrder
|
|
10
|
-
from ..types.board import Board
|
|
11
|
-
from ..types.generation import ArtifactType, Generation, GenerationStatus
|
|
12
|
-
from ..types.generator import GeneratorInfo
|
|
13
|
-
from ..types.user import User
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@strawberry.type
|
|
17
|
-
class Query:
|
|
18
|
-
"""Root GraphQL query type."""
|
|
19
|
-
|
|
20
|
-
@strawberry.field
|
|
21
|
-
async def me(self, info: strawberry.Info) -> User | None:
|
|
22
|
-
"""Get the current authenticated user."""
|
|
23
|
-
from ..resolvers.auth import resolve_current_user
|
|
24
|
-
|
|
25
|
-
return await resolve_current_user(info)
|
|
26
|
-
|
|
27
|
-
@strawberry.field
|
|
28
|
-
async def user(self, info: strawberry.Info, id: UUID) -> User | None:
|
|
29
|
-
"""Get a user by ID."""
|
|
30
|
-
from ..resolvers.user import resolve_user_by_id
|
|
31
|
-
|
|
32
|
-
return await resolve_user_by_id(info, str(id))
|
|
33
|
-
|
|
34
|
-
@strawberry.field
|
|
35
|
-
async def board(self, info: strawberry.Info, id: UUID) -> Board | None:
|
|
36
|
-
"""Get a board by ID."""
|
|
37
|
-
from ..resolvers.board import resolve_board_by_id
|
|
38
|
-
|
|
39
|
-
return await resolve_board_by_id(info, id)
|
|
40
|
-
|
|
41
|
-
@strawberry.field
|
|
42
|
-
async def my_boards(
|
|
43
|
-
self,
|
|
44
|
-
info: strawberry.Info,
|
|
45
|
-
limit: int | None = 50,
|
|
46
|
-
offset: int | None = 0,
|
|
47
|
-
role: BoardQueryRole | None = None,
|
|
48
|
-
sort: SortOrder | None = None,
|
|
49
|
-
) -> list[Board]:
|
|
50
|
-
"""Get boards owned by or shared with the current user."""
|
|
51
|
-
from ..resolvers.board import resolve_my_boards
|
|
52
|
-
|
|
53
|
-
return await resolve_my_boards(
|
|
54
|
-
info,
|
|
55
|
-
limit or 50,
|
|
56
|
-
offset or 0,
|
|
57
|
-
role or BoardQueryRole.ANY,
|
|
58
|
-
sort or SortOrder.UPDATED_DESC,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
@strawberry.field
|
|
62
|
-
async def public_boards(
|
|
63
|
-
self,
|
|
64
|
-
info: strawberry.Info,
|
|
65
|
-
limit: int | None = 50,
|
|
66
|
-
offset: int | None = 0,
|
|
67
|
-
sort: SortOrder | None = None,
|
|
68
|
-
) -> list[Board]:
|
|
69
|
-
"""Get public boards."""
|
|
70
|
-
from ..resolvers.board import resolve_public_boards
|
|
71
|
-
|
|
72
|
-
return await resolve_public_boards(
|
|
73
|
-
info, limit or 50, offset or 0, sort or SortOrder.UPDATED_DESC
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
@strawberry.field
|
|
77
|
-
async def generation(self, info: strawberry.Info, id: UUID) -> Generation | None:
|
|
78
|
-
"""Get a generation by ID."""
|
|
79
|
-
from ..resolvers.generation import resolve_generation_by_id
|
|
80
|
-
|
|
81
|
-
return await resolve_generation_by_id(info, id)
|
|
82
|
-
|
|
83
|
-
@strawberry.field
|
|
84
|
-
async def recent_generations(
|
|
85
|
-
self,
|
|
86
|
-
info: strawberry.Info,
|
|
87
|
-
board_id: UUID | None = None,
|
|
88
|
-
status: GenerationStatus | None = None,
|
|
89
|
-
artifact_type: ArtifactType | None = None,
|
|
90
|
-
limit: int | None = 50,
|
|
91
|
-
offset: int | None = 0,
|
|
92
|
-
) -> list[Generation]:
|
|
93
|
-
"""Get recent generations with optional filters."""
|
|
94
|
-
from ..resolvers.generation import resolve_recent_generations
|
|
95
|
-
|
|
96
|
-
return await resolve_recent_generations(
|
|
97
|
-
info, board_id, status, artifact_type, limit or 50, offset or 0
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
@strawberry.field
|
|
101
|
-
async def search_boards(
|
|
102
|
-
self, info: strawberry.Info, query: str, limit: int | None = 50, offset: int | None = 0
|
|
103
|
-
) -> list[Board]:
|
|
104
|
-
"""Search for boards by title or description."""
|
|
105
|
-
from ..resolvers.board import search_boards
|
|
106
|
-
|
|
107
|
-
return await search_boards(info, query, limit or 50, offset or 0)
|
|
108
|
-
|
|
109
|
-
@strawberry.field
|
|
110
|
-
async def generators(
|
|
111
|
-
self, info: strawberry.Info, artifact_type: str | None = None
|
|
112
|
-
) -> list[GeneratorInfo]:
|
|
113
|
-
"""Get all available generators, optionally filtered by artifact type."""
|
|
114
|
-
from ..resolvers.generator import resolve_generators
|
|
115
|
-
|
|
116
|
-
return await resolve_generators(info, artifact_type)
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"""Resolver package for GraphQL schema.
|
|
2
|
-
|
|
3
|
-
This package provides resolver function stubs referenced by the GraphQL types,
|
|
4
|
-
queries, and mutations. Implementations should be provided to connect to the
|
|
5
|
-
database and application services.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# Intentionally empty; functions are defined in sibling modules.
|