mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
Both are Django apps, and both pin `label` in apps.py — "stamp" and "review". django_migrations keys a row on (app_label, name), and app_label comes from that pin and not from the import path, so moving the directory does not orphan a single migration. All six stay where they are, untouched. products/stamphog -> products/stamp name = products.stamp.backend products/review_hog -> products/review name = products.review.backend StamphogScene/ -> StampScene/, and stamphogSceneLogic.ts with it 189 files follow. An earlier attempt at this move failed twice for reasons worth recording: `git mv A B` where B exists puts A INSIDE B, and a stray products/stamp/node_modules from an abandoned run was enough to make B exist — the app ended up nested two deep. And `git ls-files` does not list a file moved with plain mv and not yet staged, so a pass over "every tracked file" silently skips it; that is how StampScene.tsx kept importing ./stampSceneLogic after the file beside it had been renamed back. bin/check-imports-are-committed: all first-party imports across 15,843 files resolve. Co-authored-by: Hanzo Dev <[email protected]>
117 lines
2.9 KiB
Python
117 lines
2.9 KiB
Python
"""
|
|
Contract types for stamp.
|
|
|
|
Frozen dataclasses that define what this product exposes.
|
|
No Django imports. Used by facade as inputs/outputs.
|
|
|
|
Uses ``pydantic.dataclasses.dataclass`` rather than the stdlib
|
|
variant — same syntax, same ``is_dataclass()`` compatibility (so
|
|
``DataclassSerializer`` keeps working), but with runtime type
|
|
validation on construction.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
from pydantic import Field
|
|
from pydantic.dataclasses import dataclass
|
|
|
|
from .enums import ChannelResolutionSource, DigestRunStatus, ReviewRunStatus, ReviewVerdict
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RepoConfigDTO:
|
|
"""A repository stamp is configured to review for a team."""
|
|
|
|
id: UUID
|
|
team_id: int
|
|
provider: str
|
|
repository: str
|
|
enabled: bool
|
|
installation_id: str
|
|
digest_enabled: bool = False
|
|
created_at: datetime | None = None
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PullRequestDTO:
|
|
"""A pull request stamp knows about, including merge state once it merges."""
|
|
|
|
id: UUID
|
|
team_id: int
|
|
repo_config_id: UUID
|
|
repository: str
|
|
pr_number: int
|
|
pr_url: str
|
|
title: str
|
|
author_login: str
|
|
head_branch: str
|
|
body_excerpt: str
|
|
additions: int
|
|
deletions: int
|
|
changed_files: int
|
|
audience_key: str
|
|
merge_commit_sha: str = ""
|
|
merged_at: datetime | None = None
|
|
digest_run_id: UUID | None = None
|
|
posted_comment_id: int | None = None
|
|
created_at: datetime | None = None
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DigestChannelDTO:
|
|
"""A Slack destination for one digest audience."""
|
|
|
|
id: UUID
|
|
team_id: int
|
|
audience_key: str
|
|
slack_integration_id: int
|
|
slack_channel_id: str
|
|
slack_channel_name: str
|
|
enabled: bool
|
|
resolution_source: ChannelResolutionSource = ChannelResolutionSource.MANUAL
|
|
last_digest_at: datetime | None = None
|
|
created_at: datetime | None = None
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DigestRunDTO:
|
|
"""One posted (or attempted) daily digest for a channel."""
|
|
|
|
id: UUID
|
|
team_id: int
|
|
digest_channel_id: UUID
|
|
status: DigestRunStatus
|
|
pr_count: int
|
|
summary: dict = Field(default_factory=dict)
|
|
slack_message_ts: str = ""
|
|
error: str = ""
|
|
created_at: datetime | None = None
|
|
posted_at: datetime | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ReviewRunDTO:
|
|
"""A single stamp review attempt against a pull request."""
|
|
|
|
id: UUID
|
|
team_id: int
|
|
pull_request_id: UUID
|
|
# Convenience PR context sourced via the pull_request FK.
|
|
repository: str
|
|
pr_number: int
|
|
pr_url: str
|
|
head_sha: str
|
|
status: ReviewRunStatus
|
|
verdict: ReviewVerdict
|
|
delivery_id: str | None = None
|
|
gate_result: dict | None = None
|
|
output: dict = Field(default_factory=dict)
|
|
error: str = ""
|
|
created_at: datetime | None = None
|
|
updated_at: datetime | None = None
|
|
completed_at: datetime | None = None
|