Add CP→CA→PI platform foundation on MapMil monorepo.

Unify parsing workers, analytics API with PostgreSQL, map UI, and PI distribution into centers/ with Docker Compose.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-30 11:43:27 +03:00
co-authored by Cursor
commit 9dfe713668
88 changed files with 6587 additions and 0 deletions
+132
View File
@@ -0,0 +1,132 @@
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field
ObjectType = Literal["point", "marker", "zone", "other"]
class MapObjectCreate(BaseModel):
name: str = Field(min_length=1, max_length=255)
description: str = ""
type: ObjectType
latitude: float = Field(ge=-90, le=90)
longitude: float = Field(ge=-180, le=180)
created_at: datetime | None = None
class MapObjectRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
description: str
type: ObjectType
latitude: float
longitude: float
event_id: int | None = None
created_at: datetime
class MapObjectUpdate(BaseModel):
name: str | None = Field(default=None, min_length=1, max_length=255)
description: str | None = None
type: ObjectType | None = None
latitude: float | None = Field(default=None, ge=-90, le=90)
longitude: float | None = Field(default=None, ge=-180, le=180)
created_at: datetime | None = None
class ObjectMediaRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
object_id: int
original_name: str
content_type: str
size: int
created_at: datetime
url: str
class EventRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
source_type: str
source_url: str
raw_text: str
title: str
description: str
locality: str
latitude: float | None
longitude: float | None
event_date: datetime | None
ingested_at: datetime
region: str | None
topic: str | None
tags: list[str] | None
metadata: dict[str, Any] | None = Field(validation_alias="metadata_")
class IngestEventItem(BaseModel):
source_type: str = "telegram"
source_url: str
raw_text: str = ""
title: str = ""
description: str = ""
locality: str = ""
latitude: float | None = None
longitude: float | None = None
event_date: datetime | None = None
region: str | None = None
topic: str | None = None
tags: list[str] | None = None
metadata: dict[str, Any] | None = None
class IngestRequest(BaseModel):
job_id: int | None = None
events: list[IngestEventItem] = Field(default_factory=list)
class IngestResponse(BaseModel):
ingested: int
updated: int
map_objects_synced: int
class ParseJobCreate(BaseModel):
source_type: str = "telegram"
source_config: dict[str, Any] = Field(default_factory=dict)
schedule: str | None = None
class ParseJobRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
source_type: str
source_config: dict[str, Any]
schedule: str | None
status: str
last_run_at: datetime | None
last_error: str | None
created_at: datetime
class ConsumerCreate(BaseModel):
name: str
regions: list[str] | None = None
topics: list[str] | None = None
date_from: datetime | None = None
class ConsumerRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
is_active: bool
created_at: datetime
api_key: str | None = None