Skip to content

refactor(schema): scaffold schemes/lifecycle/ + register stub LifecycleScheme [LTV-Pg.1]#111

Merged
shaypal5 merged 3 commits into
mainfrom
refactor/scaffold-lifecycle-scheme
Jun 10, 2026
Merged

refactor(schema): scaffold schemes/lifecycle/ + register stub LifecycleScheme [LTV-Pg.1]#111
shaypal5 merged 3 commits into
mainfrom
refactor/scaffold-lifecycle-scheme

Conversation

@shaypal5

Copy link
Copy Markdown
Contributor

Summary

First half of the schema reorg (LTV-Pg.1, milestone LTV-M2). Gives
the lifecycle scheme its own package and makes it a registered peer of
lead_scoring, ahead of building its pipeline (M3–M6). Byte-identical;
lead-scoring catalog untouched.

Changes

New leadforge/schemes/lifecycle/:

  • entities.py — the 5 lifecycle rows (CustomerLifecycleRow,
    SubscriptionLifecycleRow, SubscriptionEventRow, HealthSignalRow,
    InvoiceRow) + LIFECYCLE_ROW_TYPES / LIFECYCLE_TABLE_NAMES, moved from
    schema/entities.py. AccountRow / EntityRowProtocol / _empty_df are
    shared and imported from leadforge.schema.entities.
  • relationships.pyLIFECYCLE_CONSTRAINTS, moved from
    schema/relationships.py (reuses the shared FKConstraint).
  • __init__.py — stub LifecycleScheme (build_world/write_bundle raise
    NotImplementedError until M3–M6); self-registers. schemes/__init__ imports it.

schema/entities.py / schema/relationships.py: lifecycle defs removed with
breadcrumb comments; ALL_ROW_TYPES / ALL_CONSTRAINTS unchanged.

Tests: lifecycle entity test moved to tests/schemes/lifecycle/test_entities.py;
test_registry.py gains lifecycle-registered + stub-raises-NotImplementedError
tests.

Why a stub now

Registering lifecycle before its pipeline exists lets the registry, recipe
scheme: resolution, and tests treat it as a first-class peer. Calling it fails
loudly (NotImplementedError) rather than silently — and no recipe targets it
yet, so the stub is never invoked in real runs.

Verification

available_schemes() → ("lead_scoring", "lifecycle")
✅ BYTE-IDENTICAL vs pre-reorg main (14 files)
  • Full suite 1534 passed / 51 skipped; ruff + mypy clean (92 files).
  • BUNDLE_SCHEMA_VERSION unchanged.

Note

Class-level extraction from the shared multi-class schema/entities.py can't be
a git rename; the lifecycle rows were only added in #104, so history loss is
shallow.

Next

LTV-Pg.2 — split the lead-scoring schema (rows / ALL_ROW_TYPES /
ALL_CONSTRAINTS / LEAD_SNAPSHOT_FEATURES / task specs) out of shared
schema/ into schemes/lead_scoring/, completing the M2 reorg.

🤖 Generated with Claude Code

…leScheme [LTV-Pg.1]

First half of the schema reorg (LTV-Pg). Gives the lifecycle scheme its own
home and makes it a registered peer of lead_scoring, ahead of building its
pipeline (M3–M6). Byte-identical; lead-scoring catalog unchanged.

- New leadforge/schemes/lifecycle/ package:
  - entities.py — the 5 lifecycle rows (CustomerLifecycleRow,
    SubscriptionLifecycleRow, SubscriptionEventRow, HealthSignalRow, InvoiceRow)
    + LIFECYCLE_ROW_TYPES / LIFECYCLE_TABLE_NAMES, moved from schema/entities.py.
    AccountRow / EntityRowProtocol / _empty_df are shared and imported from
    leadforge.schema.entities.
  - relationships.py — LIFECYCLE_CONSTRAINTS, moved from schema/relationships.py
    (reuses the shared FKConstraint).
  - __init__.py — stub LifecycleScheme (build_world/write_bundle raise
    NotImplementedError until M3–M6); self-registers. schemes/__init__ imports it.
- schema/entities.py and schema/relationships.py: lifecycle definitions removed;
  breadcrumb comments point to the new home. ALL_ROW_TYPES / ALL_CONSTRAINTS
  unchanged.
- tests/schema/test_lifecycle_entities.py → tests/schemes/lifecycle/test_entities.py
  with updated imports; tests/schemes/test_registry.py gains lifecycle
  registration + stub-raises-NotImplementedError tests.
- CHANGELOG, CLAUDE.md (both layouts), roadmap (Pg split into Pg.1/Pg.2),
  agent-plan updated.

available_schemes() → ("lead_scoring", "lifecycle"). Verified byte-identical
(14/14 files); full suite 1534 passed / 51 skipped; ruff + mypy clean (92 files).

Note: class-level extraction from the shared schema/entities.py can't be a git
rename (multiple classes pulled from a multi-class file); the lifecycle rows
were only added in #104 so the history loss is shallow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 20:30
@shaypal5 shaypal5 added this to the dataset: leadforge-ltv-v1 milestone Jun 10, 2026
@shaypal5 shaypal5 added type: refactor Code change with no behavior difference layer: schema schema/ entity/event contracts status: needs review Ready for review dataset: leadforge-ltv-v1 Issue/PR scoped to the b2b_saas_ltv_v1 LTV dataset workstream labels Jun 10, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Scaffolds a new lifecycle generation scheme package as a registered peer of lead_scoring, relocating the lifecycle-specific schema contracts (rows + FK constraints) out of the shared leadforge.schema modules while keeping the lead-scoring catalog unchanged.

Changes:

  • Added leadforge/schemes/lifecycle/ with lifecycle entity row dataclasses + lifecycle FK constraints.
  • Registered a stub LifecycleScheme (raises NotImplementedError) and ensured it is imported for registry side effects.
  • Updated tests and documentation/changelog to reflect the new module locations and registry behavior.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
leadforge/schemes/lifecycle/entities.py Adds lifecycle-only entity row dataclasses and lifecycle table registries (LIFECYCLE_ROW_TYPES, LIFECYCLE_TABLE_NAMES).
leadforge/schemes/lifecycle/relationships.py Adds lifecycle-only FK constraint registry (LIFECYCLE_CONSTRAINTS) using shared FKConstraint.
leadforge/schemes/lifecycle/__init__.py Introduces and self-registers stub LifecycleScheme (lifecycle).
leadforge/schemes/__init__.py Imports lifecycle scheme module for registration side effects.
leadforge/schema/entities.py Removes lifecycle-specific rows/registries from shared schema, leaving lead-scoring catalog intact (breadcrumb comment).
leadforge/schema/relationships.py Removes lifecycle constraints from shared schema (breadcrumb comment).
tests/schemes/test_registry.py Adds tests for lifecycle scheme registration and stub behavior.
tests/schemes/lifecycle/test_entities.py Updates imports to the new lifecycle scheme module locations.
docs/ltv/roadmap.md Updates roadmap to reflect Pg.1/Pg.2 split and records Pg.1 as PR #111.
CLAUDE.md Updates repo layout documentation to include the new lifecycle scheme package.
CHANGELOG.md Notes lifecycle schema/registry relocation and scheme registration.
.agent-plan.md Updates the agent plan narrative for the Pg.1/Pg.2 split.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Self-review: schemes/lifecycle/entities.py imported a private symbol
(`_empty_df`) across packages — a leading-underscore name signals
module-internal, so importing it elsewhere is a smell. Promote it to a public
shared helper `make_empty_dataframe` in leadforge.schema.entities (used by both
the lead-scoring rows and the lifecycle rows); the cross-module import is now
legitimate.

No behaviour change (verified byte-identical, 14/14); full suite passes; ruff +
mypy clean. (When LTV-Pg.2 moves lead-scoring rows out of schema/entities.py,
make_empty_dataframe + EntityRowProtocol stay as the shared primitives.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

pr-agent-context report:

No unresolved review comments, failing checks, or actionable patch coverage gaps were found on PR #111 in repository https://github.com/leadforge-dev/leadforge. Treat this PR as all clear unless new signals appear.

Run metadata:

Tool ref: v4
Tool version: 4.0.21
Trigger: commit pushed
Workflow run: 27305150010 attempt 1
Comment timestamp: 2026-06-10T20:44:47.180445+00:00
PR head commit: 3cf152fa6aef74975112680f5a8241adab1a64de

@shaypal5 shaypal5 merged commit 33ff1bd into main Jun 10, 2026
9 of 10 checks passed
@shaypal5 shaypal5 deleted the refactor/scaffold-lifecycle-scheme branch June 10, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dataset: leadforge-ltv-v1 Issue/PR scoped to the b2b_saas_ltv_v1 LTV dataset workstream layer: schema schema/ entity/event contracts status: needs review Ready for review type: refactor Code change with no behavior difference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants