Untitled

 avatar
4ae4d
plain_text
22 days ago
9.7 kB
3
Indexable
f=services/backend/internal/adapters/volunteering/participation/participation_schema.go
f=services/backend/internal/domain/volunteering/participations/participation.go
f=services/bot/core/clients/__init__.py
f=services/bot/core/clients/participation.py
f=services/bot/core/dependencies/__init__.py
f=services/bot/core/dependencies/participation.py
f=services/bot/core/schemas/participation.py
f=services/bot/core/services/__init__.py
--- services/backend/internal/adapters/volunteering/participation/participation_schema.go ---
package participation_adapters

import (
	participations_domain "main/internal/domain/volunteering/participations"
	"time"
)

type ParticipationSchema struct {
	MessengerId string    `gorm:"column:messenger_id;primaryKey"`
	EventId     string    `gorm:"column:event_id;primaryKey"`
	State       string    `gorm:"column:state;type:varchar(50);not null;default:'signed_up'"`
	Hours       int       `gorm:"column:participation_hours;type:int;default:0"`
	CreatedAt   time.Time `gorm:"column:created_at;autoCreateTime"`
	UpdatedAt   time.Time `gorm:"column:updated_at;autoUpdateTime"`
}

func (ParticipationSchema) TableName() string {
	return "participations"
}

func ToParticipationSchema(participation *participations_domain.Participation) *ParticipationSchema {
	return &ParticipationSchema{
		MessengerId: participation.MessengerId,
		EventId:     participation.EventId,
		State:       string(participation.State),
		Hours:       participation.Hours,
		CreatedAt:   participation.CreatedAt,
		UpdatedAt:   participation.UpdatedAt,
	}
}

func ToDomainParticipation(schema *ParticipationSchema) *participations_domain.Participation {
	return &participations_domain.Participation{
		MessengerId: schema.MessengerId,
		EventId:     schema.EventId,
		State:       participations_domain.ParticipiationState(schema.State),
		Hours:       schema.Hours,
		CreatedAt:   schema.CreatedAt,
		UpdatedAt:   schema.UpdatedAt,
	}
}

--- services/backend/internal/domain/volunteering/participations/participation.go ---
package participations

import "time"

type ParticipiationState string

const (
	StateNone      ParticipiationState = "none"
	StateSignedUp  ParticipiationState = "signed_up"
	StateConfirmed ParticipiationState = "confirmed"
	StateCanceled  ParticipiationState = "canceled"
)

type Participation struct {
	MessengerId string              `json:"messenger_id"`
	EventId     string              `json:"event_id"`
	State       ParticipiationState `json:"state"`
	Hours       int                 `json:"hours"`
	CreatedAt   time.Time           `json:"created_at"`
	UpdatedAt   time.Time           `json:"updated_at"`
}

func (p *Participation) Confirm() error {
	if p.State != StateSignedUp {
		return ErrInvalidState
	}

	p.State = StateConfirmed
	return nil
}

func (p *Participation) Cancel() error {
	if p.State != StateSignedUp {
		return ErrInvalidState
	}

	p.State = StateCanceled
	return nil
}

func (p *Participation) SetHours(hours int) error {
	if p.State != StateConfirmed {
		return ErrInvalidState
	}

	p.Hours += hours
	return nil
}

func (p *Participation) AddHours(hours int, maxHours int) error {
	if p.State != StateConfirmed {
		return ErrInvalidState
	}

	if p.Hours+hours < 0 {
		return ErrInvalidHoursCount
	}

	if p.Hours+hours > maxHours {
		return ErrInvalidHoursCount
	}

	p.Hours += hours
	return nil
}

--- services/bot/core/clients/__init__.py ---
from .admin import AdminClient
from .ai_assistant import AssistantClient
from .event import EventClient
from .participation import ParticipationClient
from .report import ReportClient
from .request import RequestClient
from .tag import TagClient
from .terbank import TerbankClient
from .user import UserClient

__all__ = [
    "AdminClient",
    "AssistantClient",
    "EventClient",
    "ParticipationClient",
    "ReportClient",
    "RequestClient",
    "TagClient",
    "TerbankClient",
    "UserClient",
]

--- services/bot/core/clients/participation.py ---
from core.clients.base import BaseApiClient


class ParticipationClient(BaseApiClient):
    def get_event_participations_page(
        self,
        *,
        event_id: str,
        requester_messenger_id: int,
        page: int = 1,
        limit: int = 10,
    ):
        url = f"/events/{event_id}/participation"
        return self.get(
            url,
            headers={"Authorization": str(requester_messenger_id)},
            params={"page": page, "limit": limit},
        )

    def add_participation_hours(
        self,
        *,
        event_id: str,
        requester_messenger_id: int,
        target_messenger_id: int,
        hours: int,
    ):
        url = f"/events/{event_id}/participation/hours"
        return self.post(
            url,
            headers={"Authorization": str(requester_messenger_id)},
            json={"messenger_id": target_messenger_id, "hours": hours},
        )

--- services/bot/core/dependencies/__init__.py ---
from .admin import AdminProvider
from .context import ContextProvider
from .di import di_factory
from .event import EventProvider
from .participation import ParticipationProvider
from .registry import RegistryProvider
from .report import ReportProvider
from .request import RequestProvider
from .tag import TagProvider
from .terbank import TerbankProvider
from .user import UserProvider

# add provider here and it will be used in main container
PROVIDERS = [
    AdminProvider,
    ContextProvider,
    RegistryProvider,
    UserProvider,
    EventProvider,
    ReportProvider,
    TagProvider,
    RequestProvider,
    TerbankProvider,
    ParticipationProvider,
]

__all__ = [
    "PROVIDERS",
    "AdminProvider",
    "ContextProvider",
    "EventProvider",
    "ParticipationProvider",
    "RegistryProvider",
    "ReportProvider",
    "RequestProvider",
    "TagProvider",
    "TerbankProvider",
    "UserProvider",
    "di_factory",
]

--- services/bot/core/dependencies/participation.py ---
from dishka import Scope, provide

from core.clients import ParticipationClient
from core.config.settings import settings
from core.dependencies.base import BaseMessengerProvider
from core.services import ParticipationService
from core.services.registry import BaseServiceRegistry


class ParticipationProvider(BaseMessengerProvider):
    @provide(scope=Scope.REQUEST)
    def get_event_service(
        self,
        registry: BaseServiceRegistry,
        client: ParticipationClient,
    ) -> ParticipationService:
        return ParticipationService(registry, client)

    @provide(scope=Scope.APP)
    def get_event_client(self) -> ParticipationClient:
        return ParticipationClient(base_url=f"{settings.API_URL}/api/v1")

--- services/bot/core/schemas/participation.py ---
from datetime import datetime
from typing import Any

from pydantic import BaseModel

from core.utils import require_datetime


class ParticipationSchema(BaseModel):
    """Схема участия пользователя в мероприятии"""

    messenger_id: str
    event_id: str
    state: str
    hours: int
    created_at: datetime
    updated_at: datetime

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "ParticipationSchema":
        return cls(
            messenger_id=str(data.get("messenger_id", "")),
            event_id=str(data.get("event_id", "")),
            state=str(data.get("state", "")),
            hours=int(data.get("hours", "")),
            created_at=require_datetime(data.get("created_at"), "participation.created_at"),
            updated_at=require_datetime(data.get("updated_at"), "participation.updated_at"),
        )

--- services/bot/core/services/__init__.py ---
from .admin import AdminService
from .base import BaseService
from .event import EventService
from .file import FileService
from .participation import ParticipationService
from .report import ReportService
from .requests import RequestService
from .tag import TagService
from .terbank import TerbankService
from .user import UserService

__all__ = [
    "AdminService",
    "BaseService",
    "EventService",
    "FileService",
    "ParticipationService",
    "ReportService",
    "RequestService",
    "TagService",
    "TerbankService",
    "UserService",
]

--- services/bot/core/services/participation.py ---
from core.clients import ParticipationClient
from core.services.base import BaseService
from core.services.registry import BaseServiceRegistry


class ParticipationService(BaseService):
    def __init__(self, registry: BaseServiceRegistry, client: ParticipationClient):  # legacy
        # DI может вызвать клиент без аргументов.
        super().__init__(registry)
        self.client = client

    def get_event_participations_page(
        self,
        *,
        event_id: str,
        requester_messenger_id: int,
        page: int = 1,
        limit: int = 10,
    ):
        resp = self.client.get_event_participations_page(
            event_id=event_id,
            requester_messenger_id=requester_messenger_id,
            page=page,
            limit=limit,
        )
        self._check_response(resp, ctx="getting event participation list")
        return resp.json() or {}

    def add_participation_hours(
        self,
        *,
        event_id: str,
        requester_messenger_id: int,
        target_messenger_id: int,
        hours: int,
    ) -> None:
        resp = self.client.add_participation_hours(
            event_id=event_id,
            requester_messenger_id=requester_messenger_id,
            target_messenger_id=target_messenger_id,
            hours=hours,
        )
        self._check_response(resp, ctx="checking participation hours")

Editor is loading...
Leave a Comment