This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
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






