public
Description: Community Funded Reporting
Home | Edit | New

DataModelSummary

Data Model

This document describes the summary of data model of spot-us by showing important parts of sources and specs.

Users and NewsItems

The core of spot-us is User and NewsItem. There are four kind of User and two kind of NewsItem.

  class Admin < User
  end
  class Citizen < User
  end
  class Organization < User
  end
  class Reporter < User
  end

  class Pitch < NewsItem
  end
  class Tip < NewsItem
  end

Users can pledge to tips and donate to pitches. Posting pledge or donation makes them supporters.

  class Tip < NewsItem
    has_many :pledges
    has_many :supporters, :through => :pledges, :source => :user, :order => "pledges.created_at", :uniq => true
  end

  class Pitch < NewsItem
    has_many :donations
    has_many :supporters, :through => :donations, :source => :user, :order => "donations.created_at", :uniq => true
  end

Tips and pitches are related with each other with affiliations.

  class Tip < NewsItem
    has_many :affiliations
    has_many :pitches, :through => :affiliations
  end

  class Pitch < NewsItem
    has_many :affiliations
    has_many :tips, :through => :affiliations
  end

status of Pitch and Donation

Pitch and Donation are tied to real money so they should have strict state transition and payment process.

  class Pitch < NewsItem
    aasm_column :status
    aasm_initial_state  :active
    aasm_state :active
    aasm_state :accepted
    aasm_state :funded

    aasm_event :fund do
      transitions :from => :active, :to => :funded
    end

    aasm_event :accept do
      transitions :from => :active, :to => :accepted, :on_transition => :send_accept_notification
    end
  end

  class Donation < ActiveRecord::Base
    include AASM
    aasm_column :status
    aasm_initial_state  :unpaid

    aasm_state :unpaid
    aasm_state :paid
    aasm_state :refunded

    aasm_event :pay do
      transitions :from => :unpaid, :to => :paid
    end

    aasm_event :refund do
      transitions :from => :paid, :to => :refunded
    end

    belongs_to :user
    belongs_to :pitch
    belongs_to :purchase
  end

And to make a donation effective, users must purchase it.

  class Purchase < ActiveRecord::Base
    belongs_to :user
    has_many   :donations
  end

Specs

This is a quatation of specs selected and reorders for showing business logic.

Tip creating
- is creatable by user
- is not createable if not logged in

Tip to support STI
- descends from NewItem

Tip edit guards
- allows editing of unpledged tip
- disallows editing of tip which has a pledge

Tip pledged to
- a new tip isn't pledged to
- is pledged to when there's pledges

Tip a new tip with a pledge amount
- should build the first pledge on save
Pitch creating
- is creatable by reporter
- is not creatable by user
- is not creatable if not logged in

Pitch editing
- is editable by its owner
- is not editable by a stranger
- is not editable if not logged in
- is not editable if has donations
- is not editable if it is accepted
- is editable_by an admin even if donations
- is editable by admin even if it is accepted

Pitch states of a pitch
- should have a state of active when it is first created
- should have a state of funded when total donations reaches requested amount
- should have state of accepted when the reporter accepts an amount less than the requested amount

Pitch can_be_accepted?
- should return true when the state is active
- should not be true if the state is not active

Pitch email notifications
- should deliver an email when the pitch is accepted!

Pitch fully_funded?
- should return true when total donations equals requested amount
- should return true when a pitch is accepted

Pitch donations.for_user
- should not return users other than the one requested

Pitch user_can_donate_more? any user
- can't donate more, such that funds would exceed the requested amount
- can donate more, as long as funds plus attempted donation are less than requested amount

Pitch user_can_donate_more? as a citizen or reporter
- allows donation if the user has no existing donations
- return false if the user's total donations + total trying to donate is > 20% of the requested amount
- return true if the user's total donations + total trying to donate is = 20% of the requested amount
- return true if the user's total donations + total trying to donate is < 20% of the requested amount

Pitch user_can_donate_more? as a news organization
- return true even if more than 20% because we are an organization

Pitch news org funding pitch
- should allow a news org to fully fund a pitch (PENDING: TODO)
- should allow a news org to match funding if the pitch is less than 50% funded (PENDING: TODO)
Pledge creating
- is creatable by user
- is not createable if not logged in

Pledge editing
- is editable by its owner
- is not editable by a stranger
- is not editable if not logged in

Donation when creating a donation
- should require user to be logged in

Donation when creating a donation as a citizen or reporter should be invaild and add an error
- if the pitch is fully funded
- if user's total donations + the new donation is >= 20% of the pitches requested amount

Donation when creating a donation as a news organization
- allows donation of  an arbitrary amount
- still guards against donating more than requested amount

Donation editing
- is editable by its owner
- is not editable by a stranger
- is not editable if not logged in

Donation Donation.unpaid
- should not return paid donations
- should return all unpaid donations

Donation Donation.paid
- should not return unpaid donations
- should return all paid donations

Donation deleting a donation
- should be deletable by the owner of the unpaid donation
- should not be able to delete a paid donation
- should be deletable by an admin
- should not be deleteable by a nil user

Donation states of a donation
- should have a state of unpaid when it is first created
- should have a state of paid when it has been paid
- should have a state of refunded when a refund has been issued
- should not allow a refund on an unpaid donation
Purchase
- requires first_name
- requires last_name
- requires address1
- requires city
- requires state
- requires zip
- requires user_id
- requires credit_card_number
- requires credit_card_month
- requires credit_card_year
- requires credit_card_type
- requires verification_value
- should have a gateway
- should model to belong to user
- should model to have many donations
- should raise a gateway error when the gateway does not return a success response
- should set the credit card ending when being saved with a credit card number
- should calculate the total when donations are set

Purchase when a purchase happens
- should update current_funding for a pitch when donation is paid
- should not update current_funding for a pitch if the donation has not been purchased

Purchase when new being validated with an invalid credit card
- should validate the credit card
- should not be valid
- should append errors from the credit card

Purchase when new with valid credit card info being saved
- should build a new credit card
- should be valid
- should bill the credit card
- should receive a success response from the gateway

Purchase after being saved with donations
- should use the sum of the donations as the total
- should assign itself as the purchase for each donation
- should mark each donation as paid
Last edited by essa, Mon Oct 27 18:22:01 -0700 2008
Home | Edit | New
Versions: