Skip to content

Decompose monolithic lib.rs into feature modules - #185

Merged
ibrahimmosouf-png merged 2 commits into
OrbitChainLabs:mainfrom
Gracora:fix/issue-97-decompose-lib-rs
Jul 20, 2026
Merged

Decompose monolithic lib.rs into feature modules#185
ibrahimmosouf-png merged 2 commits into
OrbitChainLabs:mainfrom
Gracora:fix/issue-97-decompose-lib-rs

Conversation

@Gracora

@Gracora Gracora commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Implemented a production-ready fix while maintaining the existing architecture and coding standards.

Changes

  • Decomposed monolithic lib.rs (~942 LOC) into feature modules
  • Created validation.rs for input validation and transition logic
  • Created reports.rs for campaign report building and analytics
  • Created docs/architecture.md documenting module tree and dependencies
  • Reduced lib.rs to ~175 LOC (contract facade only)
  • Verified linting
  • Verified build
  • All 162 tests pass
  • No unrelated changes introduced

Closes #97

Gracora and others added 2 commits July 20, 2026 21:46
Extract helpers from the monolithic lib.rs (~942 LOC) into dedicated
feature modules, reducing lib.rs to ~175 LOC for the contract facade.

New modules:
- validation.rs: input validation, transition logic, asset resolution
- reports.rs: campaign report building, refund calculation, analytics
- docs/architecture.md: module tree and dependency documentation

All existing tests (162) pass. No behavior changes.

Closes OrbitChainLabs#97

@ibrahimmosouf-png ibrahimmosouf-png left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@ibrahimmosouf-png
ibrahimmosouf-png merged commit 136173e into OrbitChainLabs:main Jul 20, 2026
12 checks passed
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…bs#121)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache
lives in reports.rs alongside build_campaign_report; the CachedReport key
is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail.

get_campaign_report recomputed from the campaign record, milestones, and
counters on every call. The report is now cached in a single persistent
entry, refreshed at the tail of every state-changing entrypoint
(initialize, donate, claim_refund, end/cancel/extend, both releases;
freeze/unfreeze and the asset block list excluded — none change a report
field). New get_cached_report(env) serves it in one read, with a
read-only compute fallback for pre-cache state.

Tests assert the cache can never be observed stale across every
transition, plus fallback and uninitialized cases.

Closes OrbitChainLabs#121
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…#119)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key
appended at the DataKey tail after CachedReport.

donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>)
recording each donor once per asset, in first-donation order. Dedup is
O(1): a donor is appended only when their prior per-(donor, asset) amount
is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and
get_asset_donor_count(env, asset).

Tests cover once-per-asset dedup, isolation between assets, order, every
pagination window shape, and empty reads.

Closes OrbitChainLabs#119
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…bs#121)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache
lives in reports.rs alongside build_campaign_report; the CachedReport key
is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail.

get_campaign_report recomputed from the campaign record, milestones, and
counters on every call. The report is now cached in a single persistent
entry, refreshed at the tail of every state-changing entrypoint
(initialize, donate, claim_refund, end/cancel/extend, both releases;
freeze/unfreeze and the asset block list excluded — none change a report
field). New get_cached_report(env) serves it in one read, with a
read-only compute fallback for pre-cache state.

Tests assert the cache can never be observed stale across every
transition, plus fallback and uninitialized cases.

Closes OrbitChainLabs#121
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…#119)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key
appended at the DataKey tail after CachedReport.

donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>)
recording each donor once per asset, in first-donation order. Dedup is
O(1): a donor is appended only when their prior per-(donor, asset) amount
is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and
get_asset_donor_count(env, asset).

Tests cover once-per-asset dedup, isolation between assets, order, every
pagination window shape, and empty reads.

Closes OrbitChainLabs#119
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…bs#121)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185): refresh_report_cache
lives in reports.rs alongside build_campaign_report; the CachedReport key
is appended after OrbitChainLabs#183's BlockedAsset at the DataKey tail.

get_campaign_report recomputed from the campaign record, milestones, and
counters on every call. The report is now cached in a single persistent
entry, refreshed at the tail of every state-changing entrypoint
(initialize, donate, claim_refund, end/cancel/extend, both releases;
freeze/unfreeze and the asset block list excluded — none change a report
field). New get_cached_report(env) serves it in one read, with a
read-only compute fallback for pre-cache state.

Tests assert the cache can never be observed stale across every
transition, plus fallback and uninitialized cases.

Closes OrbitChainLabs#121
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
…#119)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key
appended at the DataKey tail after CachedReport.

donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>)
recording each donor once per asset, in first-donation order. Dedup is
O(1): a donor is appended only when their prior per-(donor, asset) amount
is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and
get_asset_donor_count(env, asset).

Tests cover once-per-asset dedup, isolation between assets, order, every
pagination window shape, and empty reads.

Closes OrbitChainLabs#119
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 21, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
ibrahimmosouf-png pushed a commit that referenced this pull request Jul 23, 2026
Rebased onto the decomposed campaign crate (#185): refresh_report_cache
lives in reports.rs alongside build_campaign_report; the CachedReport key
is appended after #183's BlockedAsset at the DataKey tail.

get_campaign_report recomputed from the campaign record, milestones, and
counters on every call. The report is now cached in a single persistent
entry, refreshed at the tail of every state-changing entrypoint
(initialize, donate, claim_refund, end/cancel/extend, both releases;
freeze/unfreeze and the asset block list excluded — none change a report
field). New get_cached_report(env) serves it in one read, with a
read-only compute fallback for pre-cache state.

Tests assert the cache can never be observed stale across every
transition, plus fallback and uninitialized cases.

Closes #121

Co-authored-by: merge-test <e2e@test.local>
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 23, 2026
…#119)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key
appended at the DataKey tail after CachedReport.

donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>)
recording each donor once per asset, in first-donation order. Dedup is
O(1): a donor is appended only when their prior per-(donor, asset) amount
is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and
get_asset_donor_count(env, asset).

Tests cover once-per-asset dedup, isolation between assets, order, every
pagination window shape, and empty reads.

Closes OrbitChainLabs#119
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 23, 2026
…#119)

Rebased onto the decomposed campaign crate (OrbitChainLabs#185); AssetDonors key
appended at the DataKey tail after CachedReport.

donate maintains an inverse index (AssetDonors(asset) -> Vec<Address>)
recording each donor once per asset, in first-donation order. Dedup is
O(1): a donor is appended only when their prior per-(donor, asset) amount
is zero. Paginated reads: get_asset_donors(env, asset, start, limit) and
get_asset_donor_count(env, asset).

Tests cover once-per-asset dedup, isolation between assets, order, every
pagination window shape, and empty reads.

Closes OrbitChainLabs#119
neromtoobad pushed a commit to neromtoobad/OrbitChain-Contracts that referenced this pull request Jul 23, 2026
Rebased onto the decomposed campaign crate (OrbitChainLabs#185).

Three insta snapshot tests pin the exact XDR ContractEvent shape of every
lifecycle event (donation lifecycle incl. goal-reached + milestone-unlock,
cancel+refund, freeze/unfreeze) — silent topic/payload drift now fails CI.
Snapshots recorded once; any unreviewed change fails the build.

Also removes the stale auto-generated campaign/test_snapshots/ folder and
gitignores it — the insta snapshots are the reviewed event assertions.

Closes OrbitChainLabs#115
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decompose monolithic lib.rs into feature modules with a stable facade

2 participants