Files
F-r-ldraledigplannerare/backend/app/models/workspace.py
T
jacobh2 e4719cb9ae Rework balances around per-parent days left and deduce the partner from FK
Manual entry now takes one parent's sjukpenningnivå, lägstanivå and
dubbeldagar left (plus optional reserved days) and derives the rest in
build_snapshot, shared with the scraper. The scraper also reads the
family panel and exposes a partner deduction; with two parents it is
saved as a 'deduced' snapshot (migration 002). Parent count is the single
source of entitlement: one member gets 480 days and 96 savable at age 4,
two get 240 and 48 each. Workspaces are capped at two parents.

Also lands the in-flight squash of migrations 002–011 into the initial
schema and the removal of planning_mode.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 12:27:29 +02:00

76 lines
1.8 KiB
Python

"""Pydantic schemas for workspace and invitation endpoints."""
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, Field
from app.entities.workspace import Workspace
from app.entities.workspace_invitation import WorkspaceInvitation
class WorkspaceCreate(BaseModel):
name: str = Field(min_length=1, max_length=100)
class WorkspaceUpdate(BaseModel):
name: str | None = Field(default=None, min_length=1, max_length=100)
class WorkspaceResponse(BaseModel):
id: UUID
name: str
created_at: datetime | None
@classmethod
def from_entity(cls, ws: Workspace) -> "WorkspaceResponse":
return cls(
id=ws.id,
name=ws.name,
created_at=ws.created_at,
)
class PersonalDataResponse(BaseModel):
uuid: UUID
workspace_id: UUID
name: str
salary_type: str
employment_status: str
created_at: datetime | None
class PersonalDataCreate(BaseModel):
"""Request body for both adding a placeholder parent (POST) and renaming
one (PATCH) — both take exactly one field, so one schema serves both.
"""
display_name: str = Field(min_length=1, max_length=100)
class InviteResponse(BaseModel):
token: str # raw one-time token — share out-of-band; not stored on backend
class RedeemInviteRequest(BaseModel):
token: str
class InvitationResponse(BaseModel):
id: UUID
workspace_id: UUID
status: str
expires_at: datetime
created_at: datetime
@classmethod
def from_entity(cls, inv: WorkspaceInvitation) -> "InvitationResponse":
return cls(
id=inv.id,
workspace_id=inv.workspace_id,
status=inv.status,
expires_at=inv.expires_at,
created_at=inv.created_at,
)