ports_secondary
Define how the domain interacts with infrastructure.
GoogleTokenVerifierPort
Secondary port for verifying Google ID tokens.
verify
abstractmethod
verify(id_token: str) -> GoogleUserInfo
Verify a Google ID token and return user info.
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the token is invalid or expired. |
ImageStoragePort
add_recipe_image
abstractmethod
Add an image to storage and return its image ID.
delete_image
abstractmethod
Delete an image file from storage. Returns True if deleted, False if not found.
get_recipe_image
abstractmethod
get_recipe_image(image_id: UUID) -> ImageResponse | None
Retrieve image bytes from storage by image ID.
InstagramParserPort
Secondary port for parsing Instagram export data into recipe schemas.
parse
abstractmethod
parse(data: InstagramResponse) -> list[ParsedRecipe]
Parse validated Instagram data into recipes with image URLs.
JwtTokenPort
Secondary port for JWT token operations.
create_access_token
abstractmethod
Create a JWT access token for the given user ID.
decode_access_token
abstractmethod
Decode a JWT access token and return the user ID.
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the token is invalid or expired. |
MarkdownExporterPort
Secondary port for Markdown format export.
save
abstractmethod
Save recipes to a Markdown file (includes I/O side effect).
to_string
abstractmethod
Serialize recipes to Markdown string format.
RecipeRepositoryPort
Secondary port for recipe persistence.
Abstraction for database operations. The domain doesn't care if it's SQLAlchemy, MongoDB, or any other persistence mechanism.
add_image
abstractmethod
add_image(
recipe_id: UUID,
user_id: UUID,
caption: str | None = None,
display_order: int | None = 0,
) -> ImageEntity
Persist an Image record for a recipe owned by user_id.
add_recipe
abstractmethod
add_recipe(data: RecipeCreate, owner_id: UUID) -> RecipeEntity
Persist a new recipe and return it as a domain entity.
add_recipes
abstractmethod
add_recipes(data: list[RecipeCreate], owner_id: UUID) -> list[RecipeEntity]
Persist multiple recipes atomically and return them as domain entities.
delete_image
abstractmethod
Delete an Image record by ID. Returns True if deleted, False if not found/owned.
delete_recipe
abstractmethod
Delete a recipe by ID. Returns True if deleted, False if not found/owned.
get_recipe_by_id
abstractmethod
Retrieve a recipe by ID, scoped to the given user.
image_belongs_to_user
abstractmethod
Check if an image belongs to a recipe owned by the given user.
search_recipes
abstractmethod
search_recipes(
user_id: UUID,
recipe_id: UUID | None = None,
title: str | None = None,
category: str | None = None,
is_veggie: bool | None = None,
season: str | None = None,
limit: int | None = None,
offset: int = 0,
ownership: str | None = None,
) -> PaginatedResult
Query recipes with dynamic filtering and pagination, visible to the given user.
update_recipe
abstractmethod
update_recipe(
recipe_id: UUID, data: RecipeUpdate, user_id: UUID
) -> RecipeEntity | None
Full replacement of a recipe. Returns None if not found or not owned.
RecipeShareRepositoryPort
Secondary port for recipe share persistence.
accept_all_pending_shares
abstractmethod
accept_all_pending_shares(user_id: UUID) -> list[RecipeShareEntity]
Accept all pending shares for a user in a single transaction.
create_share
abstractmethod
create_share(
recipe_id: UUID, shared_by_user_id: UUID, shared_with_user_id: UUID, role: ShareRole
) -> RecipeShareEntity
Create a new share invitation.
delete_share
abstractmethod
Delete a share record. Returns True if deleted.
get_pending_shares_count
abstractmethod
Count pending share invitations for a user.
get_pending_shares_for_user
abstractmethod
get_pending_shares_for_user(user_id: UUID) -> list[RecipeShareEntity]
List all pending share invitations for a user.
get_share_by_id
abstractmethod
get_share_by_id(share_id: UUID) -> RecipeShareEntity | None
Retrieve a share by its ID.
get_share_for_recipe_and_user
abstractmethod
get_share_for_recipe_and_user(
recipe_id: UUID, user_id: UUID
) -> RecipeShareEntity | None
Get the share record for a specific recipe and user.
get_shares_for_recipe
abstractmethod
get_shares_for_recipe(recipe_id: UUID) -> list[RecipeShareEntity]
List all shares (any status) for a recipe.
get_user_role_for_recipe
abstractmethod
Return 'owner', 'editor', 'reader', or None if no access.
update_share_status
abstractmethod
update_share_status(share_id: UUID, status: ShareStatus) -> RecipeShareEntity | None
Update the status of a share invitation.
UserRepositoryPort
Secondary port for user persistence.
create_user
abstractmethod
create_user(
email: str,
display_name: str,
auth_provider: AuthProvider,
auth_provider_id: str,
avatar_url: str | None = None,
) -> UserEntity
Create a new user and return the domain entity.
get_user_by_email
abstractmethod
get_user_by_email(email: str) -> UserEntity | None
Retrieve a user by email address.
get_user_by_id
abstractmethod
get_user_by_id(user_id: UUID) -> UserEntity | None
Retrieve a user by ID.
get_user_by_provider
abstractmethod
get_user_by_provider(
auth_provider: AuthProvider, auth_provider_id: str
) -> UserEntity | None
Retrieve a user by SSO provider and provider-specific ID.