Skip to content

angee.proposals.models

Sealed proposal rounds and their structured response documents.

Round and Proposal are supporting coordination/document objects, not planning hierarchies. A Round owns disclosure and decision; a Proposal owns its response lifecycle. Direct relationship tuples are the seal: responder/editor tuples are verb-managed, while only Round audience roles are exposed through the declared record-share surface.

RoundOpeningPolicy

python
class RoundOpeningPolicy(models.TextChoices)

Which responder-owned surfaces disclosure opens.

RoundStatus

python
class RoundStatus(models.TextChoices)

Code-owned Round lifecycle.

RoundOutcome

python
class RoundOutcome(models.TextChoices)

Terminal close outcomes.

ProposalState

python
class ProposalState(models.TextChoices)

Single Proposal document lifecycle.

ProposalConfidence

python
class ProposalConfidence(models.TextChoices)

Closed confidence vocabulary for comparison.

ImmutableFieldsMixin

python
class ImmutableFieldsMixin(models.Model)

Reject identity/receipt changes except through an owning model verb.

Meta

python
class Meta()

Django options for the addon-local invariant mixin.

allow_immutable_save

python
def allow_immutable_save(*field_names: str) -> None

Allow the next save to change named immutable attnames.

save

python
def save(*args: Any, **kwargs: Any) -> None

Persist after comparing immutable facts with the committed row.

Round

python
class Round(ImmutableFieldsMixin, AuditMixin, ThreadedModelMixin,
            AngeeDataModel)

A bounded solicitation on one project or task; its chatter is shared.

Meta

python
class Meta()

Django options for solicitation rounds.

__str__

python
def __str__() -> str

Return the Round's human name.

apply_create_defaults

python
def apply_create_defaults() -> Mapping[str, tuple[models.Model, ...]]

Expose the exactly-one target to the unsaved-row create preflight.

clean

python
def clean() -> None

Validate target, deadline, outcome, and receipt coherence.

save

python
def save(*args: Any, **kwargs: Any) -> None

Persist while keeping target/deadline and opened-policy facts coherent.

deletion_error

python
def deletion_error() -> str | None

Return why this Round cannot be deleted under the untouched-draft rule.

delete

python
def delete(*args: Any, **kwargs: Any) -> tuple[int, dict[str, int]]

Delete only a collecting Round whose proposals are untouched drafts.

open

python
def open() -> Self

Open disclosure exactly once, locking Round before Proposal rows.

close

python
def close(
    outcome: str | RoundOutcome,
    *,
    accepted: Iterable[models.Model] = (),
    partial: Iterable[models.Model] = ()
) -> Self

Close with an exact decision over every submitted Proposal.

cancel

python
def cancel() -> Self

Cancel a collecting or opened Round, preserving a null outcome.

transfer_facilitation

python
def transfer_facilitation(user: models.Model) -> Self

Transfer facilitation and reconcile every private track editor grant.

Topic

python
class Topic(ImmutableFieldsMixin, AuditMixin, AngeeDataModel)

One stable, ordered comparison subject within a Round.

Meta

python
class Meta()

Django options for ordered comparison topics.

__str__

python
def __str__() -> str

Return the topic name.

clean

python
def clean() -> None

Normalize the immutable machine key.

save

python
def save(*args: Any, **kwargs: Any) -> None

Persist the normalized stable key.

ProposalManager

python
class ProposalManager(AngeeManager)

Own replay-safe message capture into Proposal and Answer rows.

capture_from_message

python
def capture_from_message(message: models.Model,
                         round: models.Model,
                         party: models.Model | None = None) -> models.Model

Interpret one reply atomically and submit only after all rows succeed.

Proposal

python
class Proposal(ImmutableFieldsMixin, AuditMixin, AngeeDataModel)

One responder's structured response; its private work lives on track.

Meta

python
class Meta()

Django options for sealed response documents.

__str__

python
def __str__() -> str

Return a compact responder/party label.

clean

python
def clean() -> None

Validate identity, money, timeframe, and lifecycle receipts.

save

python
def save(*args: Any, **kwargs: Any) -> None

Create shells only while collecting and reconcile verb-managed tuples.

deletion_error

python
def deletion_error() -> str | None

Return why this Proposal is no longer an untouched draft.

delete

python
def delete(*args: Any, **kwargs: Any) -> tuple[int, dict[str, int]]

Delete only an untouched draft shell.

submit

python
def submit() -> Self

Submit while locking Round first and atomically revoking editor.

withdraw

python
def withdraw() -> Self

Withdraw one submitted Proposal under the Round-first lock order.

identify_party

python
def identify_party(party: models.Model) -> Self

Set the external identity once under Round-first row locks.

create_track

python
def create_track() -> models.Model

Create the one private Project and grant facilitator plus responder editors.

publish_track

python
def publish_track() -> models.Model

Publish the private track to this Round's responders, idempotently.

TaskProposalContainment

python
class TaskProposalContainment(AngeeModel)

Same-row save participant keeping unpublished proposal work private.

Meta

python
class Meta()

Abstract zero-column donor folded into the composed Task model.

save

python
def save(*args: Any, **kwargs: Any) -> None

Reject shared queues for tasks on an unpublished proposal track.

Answer

python
class Answer(ImmutableFieldsMixin, AuditMixin, AngeeDataModel)

One Proposal response aligned to one Topic in the same Round.

Meta

python
class Meta()

Django options for topic-aligned answers.

clean

python
def clean() -> None

Reject an Answer whose Proposal and Topic belong to different Rounds.

__str__

python
def __str__() -> str

Return the topic-aligned response label.

Review

python
class Review(ImmutableFieldsMixin, AuditMixin, AngeeDataModel)

One evaluator's private assessment of a Proposal.

Meta

python
class Meta()

Django options for evaluator assessments.

__str__

python
def __str__() -> str

Return the reviewer/proposal assessment label.

Released under the AGPL-3.0 License.