Coverage for src / documint_mcp / models.py: 0%
357 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 22:30 -0400
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-30 22:30 -0400
1"""Typed models for the Documint control plane, drift engine, and publish workflows."""
3from __future__ import annotations
5from datetime import datetime
6from enum import StrEnum
7from typing import Any
9from pydantic import BaseModel, Field
12class ArtifactType(StrEnum):
13 API_REFERENCE = "api_reference"
14 SDK_GUIDES = "sdk_guides"
15 MCP_REFERENCE = "mcp_reference"
16 CHANGELOG = "changelog"
17 MIGRATION_NOTES = "migration_notes"
20class SourceSignalType(StrEnum):
21 MANUAL = "manual"
22 PUSH = "push"
23 PULL_REQUEST = "pull_request"
24 RELEASE = "release"
27class FindingSeverity(StrEnum):
28 HIGH = "high"
29 MEDIUM = "medium"
30 LOW = "low"
33class JobStatus(StrEnum):
34 PENDING = "pending"
35 RUNNING = "running"
36 COMPLETED = "completed"
37 FAILED = "failed"
40class VerificationStatus(StrEnum):
41 VERIFIED = "verified"
42 STALE = "stale"
43 MISSING = "missing"
46class RepositoryRevision(BaseModel):
47 ref: str
48 touched_at: datetime
49 committed: bool = True
52class User(BaseModel):
53 id: str
54 external_id: str | None = None
55 email: str | None = None
56 name: str
57 provider: str
58 created_at: datetime
61class Workspace(BaseModel):
62 id: str
63 slug: str
64 name: str
65 description: str = ""
66 created_at: datetime
69class WorkspaceMember(BaseModel):
70 id: str
71 workspace_id: str
72 user_id: str
73 role: str
74 created_at: datetime
77class ApiTokenSummary(BaseModel):
78 id: str
79 workspace_id: str
80 user_id: str
81 label: str
82 token_prefix: str
83 scopes: list[str] = Field(default_factory=list)
84 created_at: datetime
85 last_used_at: datetime | None = None
86 revoked_at: datetime | None = None
87 token: str | None = None
90class GitHubInstallation(BaseModel):
91 id: str
92 workspace_id: str
93 installation_id: str | None = None
94 account_login: str | None = None
95 account_type: str | None = None
96 repository_selection: str = "selected"
97 metadata_json: dict[str, object] = Field(default_factory=dict)
98 created_at: datetime
99 updated_at: datetime
102class GitHubRepository(BaseModel):
103 id: str
104 github_installation_id: str
105 repository_id: str | None = None
106 full_name: str
107 owner: str
108 name: str
109 default_branch: str
110 visibility: str = "private"
111 is_private: bool = True
112 is_archived: bool = False
113 metadata_json: dict[str, object] = Field(default_factory=dict)
114 created_at: datetime
115 updated_at: datetime
118class RepositorySource(BaseModel):
119 id: str
120 project_id: str | None = None
121 provider: str = "github"
122 owner: str
123 repo: str
124 default_branch: str
125 local_path: str
126 current_ref: str
127 docs_root: str
128 installation_id: str | None = None
131class ProjectSettings(BaseModel):
132 id: str
133 project_id: str
134 docs_root: str
135 config_version: int = 1
136 config_json: dict[str, object] = Field(default_factory=dict)
137 ai_policy: dict[str, object] = Field(default_factory=dict)
138 publish_behavior: dict[str, object] = Field(default_factory=dict)
139 pr_behavior: dict[str, object] = Field(default_factory=dict)
140 updated_at: datetime
143class Project(BaseModel):
144 id: str
145 workspace_id: str | None = None
146 github_installation_id: str | None = None
147 name: str
148 slug: str
149 description: str
150 public_url: str
151 dashboard_url: str
152 onboarding_status: str = "connected"
153 source: RepositorySource
154 artifact_types: list[ArtifactType]
157class RuntimeStatus(BaseModel):
158 environment: str
159 deployment_provider: str
160 job_execution_mode: str
161 api_base_url: str
162 public_base_url: str
163 app_base_url: str
164 repo_root: str
165 docs_root: str
166 git_available: bool
167 git_metadata_available: bool
168 current_ref: str
169 current_ref_source: str
170 auth_required: bool
171 github_app_ready: bool
172 deploy_branch: str | None = None
173 database_configured: bool = True
174 clerk_configured: bool = False
175 huggingface_configured: bool = False
178class SourceSignal(BaseModel):
179 id: str | None = None
180 type: SourceSignalType
181 ref: str
182 changed_files: list[str] = Field(default_factory=list)
183 created_at: datetime
186class ArtifactTrace(BaseModel):
187 id: str
188 slug: str
189 title: str
190 artifact_type: ArtifactType
191 summary: str
192 doc_paths: list[str]
193 source_paths: list[str]
194 latest_source_revision: RepositoryRevision | None = None
195 latest_doc_revision: RepositoryRevision | None = None
196 verification_status: VerificationStatus
199class ArtifactDefinition(BaseModel):
200 id: str
201 project_id: str
202 artifact_key: str
203 slug: str
204 title: str
205 artifact_type: ArtifactType
206 summary: str
207 doc_paths: list[str]
208 source_patterns: list[str]
211class DriftFinding(BaseModel):
212 id: str
213 project_id: str | None = None
214 verification_run_id: str | None = None
215 artifact_id: str
216 artifact_type: ArtifactType
217 severity: FindingSeverity
218 summary: str
219 rationale: str
220 source_paths: list[str]
221 doc_paths: list[str]
222 suggested_actions: list[str]
223 source_revision: RepositoryRevision | None = None
224 doc_revision: RepositoryRevision | None = None
225 status: str = "open"
226 created_at: datetime | None = None
227 updated_at: datetime | None = None
228 changed_symbols: list[dict] = Field(default_factory=list)
229 symbol_hash: str | None = None
230 confidence_score: float = 0.5
231 has_breaking_changes: bool = False
232 cross_artifact_refs: dict[str, list[str]] = Field(default_factory=dict)
233 """Maps artifact_id -> [symbol_names] for OTHER artifacts affected by the same symbol changes."""
236class AgentRun(BaseModel):
237 id: str
238 project_id: str
239 kind: str
240 provider: str
241 model: str | None = None
242 status: str
243 input_summary: str
244 output_summary: str
245 metadata_json: dict[str, object] = Field(default_factory=dict)
246 created_at: datetime
247 completed_at: datetime | None = None
250class PatchCitation(BaseModel):
251 path: str
252 ref: str
253 note: str
256class DocPatch(BaseModel):
257 id: str
258 project_id: str | None = None
259 finding_id: str | None = None
260 artifact_id: str
261 target_path: str
262 summary: str
263 rationale: str = ""
264 proposed_sections: list[str]
265 citations: list[PatchCitation] = Field(default_factory=list)
266 preview_markdown: str
267 ai_provider: str = "deterministic"
268 model_name: str | None = None
269 chain_steps_used: int | None = None
270 confidence_score: float | None = None
271 status: str = "draft"
272 created_at: datetime | None = None
273 updated_at: datetime | None = None
276class PullRequestRecord(BaseModel):
277 id: str
278 project_id: str
279 patch_id: str
280 branch_name: str
281 title: str
282 url: str
283 state: str
284 created_at: datetime
285 updated_at: datetime
288class VerificationRun(BaseModel):
289 id: str
290 project_id: str
291 status: JobStatus
292 signal: SourceSignal
293 findings_count: int
294 findings: list[DriftFinding] = Field(default_factory=list)
295 started_at: datetime
296 completed_at: datetime | None = None
299class PublishDeployment(BaseModel):
300 id: str
301 project_id: str
302 status: JobStatus
303 commit_ref: str
304 site_url: str
305 preview_url: str
306 docs_count: int
307 generated_at: datetime
310class PublishedPage(BaseModel):
311 id: str
312 project_id: str
313 deployment_id: str
314 workspace_slug: str
315 project_slug: str
316 path: str
317 title: str
318 description: str
319 content_markdown: str
320 search_body: str
321 source_path: str
322 created_at: datetime
323 updated_at: datetime
326class ActivityEvent(BaseModel):
327 id: str
328 workspace_id: str
329 project_id: str | None = None
330 kind: str
331 title: str
332 body: str
333 metadata_json: dict[str, object] = Field(default_factory=dict)
334 created_at: datetime
337class PublicDocPage(BaseModel):
338 workspace_slug: str
339 project_slug: str
340 path: str
341 title: str
342 description: str
343 content_markdown: str
344 source_path: str
345 deployment_id: str
348class ProjectSnapshot(BaseModel):
349 project: Project
350 workspace: Workspace | None = None
351 settings: ProjectSettings | None = None
352 runtime: RuntimeStatus
353 artifacts: list[ArtifactTrace]
354 latest_run: VerificationRun | None = None
355 latest_deployment: PublishDeployment | None = None
356 findings: list[DriftFinding] = Field(default_factory=list)
357 pull_requests: list[PullRequestRecord] = Field(default_factory=list)
358 activity: list[ActivityEvent] = Field(default_factory=list)
361class WorkspaceCreateRequest(BaseModel):
362 name: str
363 slug: str | None = None
364 description: str = ""
367class ProjectCreateRequest(BaseModel):
368 workspace_id: str
369 name: str
370 slug: str | None = None
371 description: str = ""
372 owner: str
373 repo: str
374 default_branch: str = "main"
375 installation_id: str | None = None
376 local_path: str | None = None
379class DriftJobRequest(BaseModel):
380 project_id: str
381 signal_type: SourceSignalType = SourceSignalType.MANUAL
382 changed_files: list[str] | None = None
385class PublishRequest(BaseModel):
386 project_id: str
389class QueuedJob(BaseModel):
390 job_id: str
391 job_kind: str
392 project_id: str | None = None
393 workspace_id: str | None = None
394 status: JobStatus = JobStatus.PENDING
395 attempt_count: int = 0
396 error_summary: str | None = None
397 resource_type: str | None = None
398 resource_id: str | None = None
399 result_summary: str | None = None
400 site_url: str | None = None
401 created_at: datetime | None = None
402 started_at: datetime | None = None
403 completed_at: datetime | None = None
404 updated_at: datetime | None = None
407class PatchCreateRequest(BaseModel):
408 policy: str = "on_demand"
411class PullRequestCreateRequest(BaseModel):
412 title: str | None = None
415class TokenCreateRequest(BaseModel):
416 workspace_id: str = ""
417 label: str = "CLI token"
418 scopes: list[str] = Field(
419 default_factory=lambda: ["projects:read", "projects:write"]
420 )
423class CLIExchangeRequest(BaseModel):
424 workspace_id: str
425 label: str = "CLI token"
426 scopes: list[str] = Field(
427 default_factory=lambda: ["projects:read", "projects:write"]
428 )
431class RevalidateRequest(BaseModel):
432 project_id: str
433 deployment_id: str | None = None
436class AuthenticatedUser(BaseModel):
437 user: User
438 workspaces: list[Workspace]
441class MCPTool(BaseModel):
442 name: str
443 description: str
444 input_schema: dict[str, Any]
447class MCPRequest(BaseModel):
448 jsonrpc: str = "2.0"
449 id: str | int | None = None
450 method: str
451 params: dict[str, Any] = Field(default_factory=dict)