Skip to content

feat(contributions): enforce lifecycle transitions for participant contribution flow#105

Open
0xarcano wants to merge 2 commits intomainfrom
feature/enforce-transitions-lifecycle
Open

feat(contributions): enforce lifecycle transitions for participant contribution flow#105
0xarcano wants to merge 2 commits intomainfrom
feature/enforce-transitions-lifecycle

Conversation

@0xarcano
Copy link
Contributor

Closes #101
Part of #97.

Summary

Implements explicit transition validation for the contribution lifecycle so invalid state/step changes are rejected at the service layer. This branch also includes the full contributions module (CRUD, guards, tests) that the lifecycle logic builds on.

Scope (Issue #101)

  • Legal transitions – Defined in contribution-transitions.ts and documented in apps/website/docs/contributions-lifecycle.md:
    • Create contribution: participant must be CONTRIBUTING and step in UPLOADING or VERIFYING.
    • Set valid: participant must be CONTRIBUTED or FINALIZED and step in VERIFYING or COMPLETED.
  • Service-layer enforcementContributionsService uses canCreateContribution() and canSetContributionValid() before creating or updating contributions; illegal transitions return clear errors.
  • Idempotency – Transition checks are based on current participant state; repeated calls with the same state do not corrupt data.

Acceptance criteria

  • Illegal transitions are rejected with clear errors (service layer).
  • Transition rules are documented (contributions-lifecycle.md) and covered by tests (contribution-transitions.spec.ts, contributions.service.spec.ts).
  • Repeated calls with valid state do not corrupt state (guards are state-based, no duplicate valid contribution for same circuit/participant).

Changes in this branch

Lifecycle (Issue #101)

  • contribution-transitions.ts – Helpers canCreateContribution() and canSetContributionValid() with participant status/step checks.
  • contributions.service.ts – Uses transition helpers in create() and update(); throws on invalid transitions.
  • contributions-lifecycle.md – Documented state machine and legal transitions (aligned with p0tion flow).
  • .gitignore – Updated as needed for the repo.

Contributions module (base for lifecycle)

  • Full CRUD in ContributionsService and controller (create, list with filters, get by id, get valid by circuit/participant, update, delete).
  • Guards: IsContributionParticipantOrCoordinatorGuard, IsContributionCoordinatorGuard, IsCircuitCreateCoordinatorGuard.
  • CreateContributionDto validation and TSDoc; contributionComputationTime required.
  • Module wiring (Circuits, Participants, Ceremonies, Auth).
  • Unit/spec tests for service, controller, and guards; coordinator e2e update.
  • Backend README: contributions state diagram direction set to LR.

Testing

  • contribution-transitions.spec.ts – Transition rules and edge cases.
  • contributions.service.spec.ts – Create/update with valid and invalid participant states.
  • Existing contribution and coordinator tests updated/added as listed above.

@0xarcano 0xarcano requested a review from AgustinBadi March 5, 2026 23:23
*/
const ALLOWED_CREATE_STATUSES = new Set<ParticipantStatus>([ParticipantStatus.CONTRIBUTING]);

const ALLOWED_CREATE_STEPS = new Set<ParticipantContributionStep>([
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not a technical comment rather a design doubt, if one can create a contribution before uploading or during the artifact upload, why don't we rather create the contribution when the artifact was actually uploaded on the backend.

Also, the 'ing' semanthics of the states seem a little bit ambigous, why don't we just say 'verified' or 'uploaded', but for sure there is a good reason for this second point, since the files are big, but still don't fully grasp it.

The states should be something to revisit in a further meeting.

✅ Can SET valid (VERIFYING or COMPLETED step)
end note

note right of FINALIZED
Copy link
Contributor

Choose a reason for hiding this comment

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

Again a design comment: The ceremony has its own CeremonyState enum with FINALIZED — that's the right place to track ceremony finalization. Having FINALIZING and FINALIZED on the participant status feels redundant and adds confusion.

Copy link
Contributor

@AgustinBadi AgustinBadi left a comment

Choose a reason for hiding this comment

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

Great PR again @0xarcano, no technical observations. My concern right now is that the status rules of the ceremony are too complex and could be simplified in the future. It would be good to talk about this on a next meeting, however, my intuition is to approve this soon and leave the task of revisiting the ceremony logic in a next time.

@0xarcano 0xarcano self-assigned this Mar 8, 2026
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.

feat(contributions): enforce lifecycle transitions for participant contribution flow

2 participants