feat(cloud): cloud-managed skill store + per-host entitlement + sync versioning
Tests / Test passed: 819
Tests / Test passed: 819
Adds cloud/skills.py (domain + service), SQLAlchemy models and Alembic migration 0010_skill_management (cloud_skills, cloud_skill_entitlements, cloud_skill_sync_state, a per-host changelog, and host_skill_inventory), and repository methods with a monotonic per-host entitlement_version that drives correct incremental fetch_host_delta. cloud-api suite green (41 passed); HEAD_REVISION bumped to 0010. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -360,3 +360,83 @@ class LlmProviderSettingsRow(Base):
|
||||
Integer, nullable=False, default=1, server_default=text("1")
|
||||
)
|
||||
updated_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
|
||||
class CloudSkillRow(Base):
|
||||
__tablename__ = "cloud_skills"
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
"name_normalized",
|
||||
name="uq_cloud_skills_name_normalized",
|
||||
),
|
||||
Index("ix_cloud_skills_kind", "kind"),
|
||||
)
|
||||
|
||||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String, nullable=False)
|
||||
name_normalized: Mapped[str] = mapped_column(String, nullable=False)
|
||||
kind: Mapped[str] = mapped_column(String, nullable=False)
|
||||
description: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
tags_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
content: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
steps_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
parameters_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
revision: Mapped[int] = mapped_column(
|
||||
Integer, nullable=False, default=1, server_default=text("1")
|
||||
)
|
||||
created_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
updated_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
|
||||
class CloudSkillEntitlementRow(Base):
|
||||
__tablename__ = "cloud_skill_entitlements"
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
"skill_id",
|
||||
"host_id",
|
||||
name="uq_cloud_skill_entitlements_skill_host",
|
||||
),
|
||||
Index("ix_cloud_skill_entitlements_host_id", "host_id"),
|
||||
Index("ix_cloud_skill_entitlements_skill_id", "skill_id"),
|
||||
)
|
||||
|
||||
skill_id: Mapped[str] = mapped_column(
|
||||
String,
|
||||
ForeignKey("cloud_skills.id"),
|
||||
primary_key=True,
|
||||
)
|
||||
host_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
granted_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
|
||||
class CloudSkillSyncStateRow(Base):
|
||||
__tablename__ = "cloud_skill_sync_state"
|
||||
|
||||
host_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
last_version: Mapped[int] = mapped_column(
|
||||
Integer, nullable=False, default=0, server_default=text("0")
|
||||
)
|
||||
updated_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
|
||||
class CloudSkillHostChangeRow(Base):
|
||||
"""Per-host changelog enabling incremental sync (design D3)."""
|
||||
|
||||
__tablename__ = "cloud_skill_host_changes"
|
||||
__table_args__ = (
|
||||
Index("ix_cloud_skill_host_changes_host_version", "host_id", "version"),
|
||||
)
|
||||
|
||||
host_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
version: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
skill_id: Mapped[str] = mapped_column(String, nullable=False)
|
||||
change_type: Mapped[str] = mapped_column(String, nullable=False)
|
||||
recorded_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
|
||||
class HostSkillInventoryRow(Base):
|
||||
__tablename__ = "host_skill_inventory"
|
||||
|
||||
host_id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
payload_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
reported_at: Mapped[str] = mapped_column(String, nullable=False)
|
||||
|
||||
Reference in New Issue
Block a user