Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/data-layer/src/monitor_data/middleware/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@
"qdrant_search_memories": ["*"],
"qdrant_delete_vectors": ["Indexer"],
# =========================================================================
# NEO4J OPERATIONS - Parties (DL-15)
# =========================================================================
"neo4j_create_party": ["Orchestrator", "CanonKeeper"],
"neo4j_get_party": ["*"],
"neo4j_list_parties": ["*"],
"neo4j_add_party_member": ["Orchestrator", "CanonKeeper"],
"neo4j_remove_party_member": ["Orchestrator", "CanonKeeper"],
"neo4j_set_active_pc": ["Orchestrator"],
"neo4j_update_party_status": ["Orchestrator", "CanonKeeper"],
"neo4j_update_party_location": ["Orchestrator", "CanonKeeper"],
"neo4j_update_party_formation": ["Orchestrator"],
"neo4j_delete_party": ["CanonKeeper"],
# =========================================================================
# COMPOSITE OPERATIONS
# =========================================================================
"composite_get_entity_full": ["*"],
Expand Down
2 changes: 2 additions & 0 deletions packages/data-layer/src/monitor_data/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
ProposalStatus,
ProposalType,
Speaker,
PartyStatus,
CanonicalMetadata,
BaseResponse,
)
Expand Down Expand Up @@ -69,6 +70,7 @@
"ProposalStatus",
"ProposalType",
"Speaker",
"PartyStatus",
"CanonicalMetadata",
"BaseResponse",
# Universe schemas
Expand Down
11 changes: 11 additions & 0 deletions packages/data-layer/src/monitor_data/schemas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ class PayoffStatus(str, Enum):
ABANDONED = "abandoned"


class PartyStatus(str, Enum):
"""Party activity status."""

TRAVELING = "traveling"
CAMPING = "camping"
IN_SCENE = "in_scene"
COMBAT = "combat"
SPLIT = "split"
RESTING = "resting"


# =============================================================================
# BASE MODELS
# =============================================================================
Expand Down
132 changes: 132 additions & 0 deletions packages/data-layer/src/monitor_data/schemas/parties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Pydantic schemas for Party operations (DL-15).

LAYER: 1 (data-layer)
IMPORTS FROM: External libraries (pydantic, uuid, datetime) and base schemas
CALLED BY: neo4j_tools.py

These schemas define the data contracts for Party CRUD operations.
Parties represent groups of player characters acting together in a story.
"""

from datetime import datetime
from typing import Optional, List
from uuid import UUID

from pydantic import BaseModel, Field

from monitor_data.schemas.base import PartyStatus


# =============================================================================
# PARTY MEMBER SCHEMAS
# =============================================================================


class PartyMemberInfo(BaseModel):
"""Information about a party member."""

entity_id: UUID
role: Optional[str] = Field(
None, max_length=50, description="e.g., 'leader', 'scout', 'healer'"
)
position: Optional[int] = Field(
None, ge=0, description="Position in marching order (0-based)"
)
joined_at: datetime


# =============================================================================
# PARTY CRUD SCHEMAS
# =============================================================================


class PartyCreate(BaseModel):
"""Request to create a Party."""

story_id: UUID
name: str = Field(min_length=1, max_length=200, description="Party name")
status: PartyStatus = Field(default=PartyStatus.TRAVELING)
initial_member_ids: List[UUID] = Field(
default_factory=list, description="Initial party members (EntityInstance IDs)"
)
active_pc_id: Optional[UUID] = Field(
None, description="Currently active PC for turn-based actions"
)
location_id: Optional[UUID] = Field(
None, description="Current location (EntityInstance of type location)"
)
formation: List[UUID] = Field(
default_factory=list,
description="Ordered list of entity_ids for marching order",
)


class PartyUpdate(BaseModel):
"""Request to update a Party."""

name: Optional[str] = Field(None, min_length=1, max_length=200)
status: Optional[PartyStatus] = None
location_id: Optional[UUID] = None
formation: Optional[List[UUID]] = None


class PartyResponse(BaseModel):
"""Response with Party data."""

id: UUID
story_id: UUID
name: str
status: PartyStatus
active_pc_id: Optional[UUID] = None
location_id: Optional[UUID] = None
formation: List[UUID]
members: List[PartyMemberInfo] = Field(
default_factory=list, description="Current party members"
)
created_at: datetime
updated_at: Optional[datetime] = None

model_config = {"from_attributes": True}


# =============================================================================
# PARTY MEMBER OPERATIONS
# =============================================================================


class AddPartyMember(BaseModel):
"""Request to add a member to a party."""

party_id: UUID
entity_id: UUID
role: Optional[str] = Field(None, max_length=50)
position: Optional[int] = Field(None, ge=0)


class RemovePartyMember(BaseModel):
"""Request to remove a member from a party."""

party_id: UUID
entity_id: UUID


class SetActivePC(BaseModel):
"""Request to set the active PC."""

party_id: UUID
entity_id: UUID


# =============================================================================
# QUERY SCHEMAS
# =============================================================================


class PartyFilter(BaseModel):
"""Filter parameters for listing parties."""

story_id: Optional[UUID] = None
status: Optional[str] = None
limit: int = Field(default=50, ge=1, le=100)
offset: int = Field(default=0, ge=0)
Loading