DataModelSummary

essa edited this page Sep 13, 2010 · 1 revision

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
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.