krz/hutch-stats
Server-side utility for calculating contributions for sourcehut users.
clone: git clone https://gitbay.org/krz/hutch-stats.git
main: src/srht_contrib/models.py · raw
1from __future__ import annotations
2
3from datetime import datetime
4
5from sqlalchemy import JSON, Boolean, DateTime, Float, Index, Integer, String, Text, UniqueConstraint
6from sqlalchemy.orm import Mapped, mapped_column
7
8from srht_contrib.db import Base
9
10
11class ContributionEvent(Base):
12 __tablename__ = "contribution_events"
13 __table_args__ = (
14 UniqueConstraint("service", "external_uid", name="uq_contribution_event_service_uid"),
15 Index("ix_contribution_events_actor_occurred_at", "actor", "occurred_at"),
16 Index("ix_contribution_events_service_occurred_at", "service", "occurred_at"),
17 )
18
19 id: Mapped[int] = mapped_column(Integer, primary_key=True)
20 service: Mapped[str] = mapped_column(String(32), nullable=False)
21 event_type: Mapped[str] = mapped_column(String(64), nullable=False)
22 actor: Mapped[str] = mapped_column(String(255), nullable=False)
23 repo_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
24 resource_id: Mapped[str] = mapped_column(String(255), nullable=False)
25 external_uid: Mapped[str] = mapped_column(String(255), nullable=False)
26 occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
27 weight: Mapped[float] = mapped_column(Float, nullable=False)
28 raw_payload_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
29
30
31class SyncState(Base):
32 __tablename__ = "sync_states"
33 __table_args__ = (UniqueConstraint("service", "actor", name="uq_sync_state_service_actor"),)
34
35 id: Mapped[int] = mapped_column(Integer, primary_key=True)
36 service: Mapped[str] = mapped_column(String(32), nullable=False)
37 actor: Mapped[str] = mapped_column(String(255), nullable=False)
38 cursor_value: Mapped[str | None] = mapped_column(Text, nullable=True)
39 updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
40
41
42class TrackedRepository(Base):
43 __tablename__ = "tracked_repositories"
44 __table_args__ = (
45 UniqueConstraint("service", "actor", "repo_name", name="uq_tracked_repository_service_actor_name"),
46 )
47
48 id: Mapped[int] = mapped_column(Integer, primary_key=True)
49 service: Mapped[str] = mapped_column(String(32), nullable=False)
50 repo_name: Mapped[str] = mapped_column(String(255), nullable=False)
51 actor: Mapped[str] = mapped_column(String(255), nullable=False)
52
53
54class ActorAlias(Base):
55 __tablename__ = "actor_aliases"
56 __table_args__ = (UniqueConstraint("alias", name="uq_actor_alias_alias"),)
57
58 id: Mapped[int] = mapped_column(Integer, primary_key=True)
59 canonical_actor: Mapped[str] = mapped_column(String(255), nullable=False)
60 alias: Mapped[str] = mapped_column(String(255), nullable=False)
61
62
63class TrackedActor(Base):
64 __tablename__ = "tracked_actors"
65 __table_args__ = (UniqueConstraint("actor", name="uq_tracked_actor_actor"),)
66
67 id: Mapped[int] = mapped_column(Integer, primary_key=True)
68 actor: Mapped[str] = mapped_column(String(255), nullable=False)
69 is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
70 discovery_state: Mapped[str] = mapped_column(String(32), nullable=False, default="queued")
71 queued_for_discovery_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
72 priority_boosted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
73 next_poll_after: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
74 last_claimed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
75 poll_attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
76 last_requested_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
77 last_polled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
78 last_poll_status: Mapped[str | None] = mapped_column(String(32), nullable=True)
79 last_poll_error: Mapped[str | None] = mapped_column(Text, nullable=True)
80 recent_backfill_status: Mapped[str] = mapped_column(String(32), nullable=False, default="pending")
81 recent_backfill_started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
82 recent_backfill_completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
83 last_recent_backfill_error: Mapped[str | None] = mapped_column(Text, nullable=True)
84 backfill_status: Mapped[str] = mapped_column(String(32), nullable=False, default="pending")
85 backfill_started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
86 backfill_completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
87 last_backfill_error: Mapped[str | None] = mapped_column(Text, nullable=True)
88
89
90class DiscoveredRepository(Base):
91 __tablename__ = "discovered_repositories"
92 __table_args__ = (UniqueConstraint("actor", "name", name="uq_discovered_repository_actor_name"),)
93
94 id: Mapped[int] = mapped_column(Integer, primary_key=True)
95 actor: Mapped[str] = mapped_column(String(255), nullable=False)
96 name: Mapped[str] = mapped_column(String(255), nullable=False)
97 discovered_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
98
99
100class ServiceBackfillState(Base):
101 __tablename__ = "service_backfill_states"
102 __table_args__ = (UniqueConstraint("actor", "service", "scope", name="uq_service_backfill_state_actor_service_scope"),)
103
104 id: Mapped[int] = mapped_column(Integer, primary_key=True)
105 actor: Mapped[str] = mapped_column(String(255), nullable=False)
106 service: Mapped[str] = mapped_column(String(32), nullable=False)
107 scope: Mapped[str] = mapped_column(String(16), nullable=False, default="full")
108 cursor_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
109 status: Mapped[str] = mapped_column(String(32), nullable=False, default="pending")
110 started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
111 completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
112 last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
113 updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)