Schema more or less complete - at least for first pass - but not yet tested.

This commit is contained in:
simon 2016-10-13 15:27:05 +01:00
parent 38f71f608c
commit 70aaf92002

View file

@ -49,10 +49,10 @@
(kc/defentity district
(pk :id)
(table :districts)
(database yyydb/*db*)
(entity-fields :id :name))
(kc/pk :id)
(kc/table :districts)
(kc/database yyydb/*db*)
(kc/entity-fields :id :name))
(defn create-addresses-table!
@ -71,16 +71,17 @@
[:postcode "varchar(16)"]
[:phone "varchar(16)"]
;; the electoral district within which this address exists
[:district "integer references districts(id)"]
[:district_id "integer references districts(id)"]
[:latitude :real]
[:longitude :real]])))
(kc/defentity address
(pk :id)
(table :addresses)
(database yyydb/*db*)
(entity-fields :id :address :postcode :phone :district :latitude :longitude))
(kc/pk :id)
(kc/table :addresses)
(kc/database yyydb/*db*)
(kc/entity-fields :id :address :postcode :phone :latitude :longitude)
(kc/has-one district))
(defn create-authority-table!
@ -96,10 +97,10 @@
(kc/defentity authority
(pk :id)
(table :authorities)
(database yyydb/*db*)
(entity-fields :id :authority))
(kc/pk :id)
(kc/table :authorities)
(kc/database yyydb/*db*)
(kc/entity-fields :id))
(defn create-electors-table!
@ -109,9 +110,11 @@
yyydb/*db*
(sql/create-table-ddl
:electors
[[:rollno "integer primary key"]
[;; id should be the roll number on the electoral roll, I think, but only if this is unique
;; across Scotland. Otherwise we need a separate id field. TODO: check.
[:id "integer primary key"]
[:name "varchar(64) not null"]
[:address "integer not null references addresses(id)" ]
[:address_id "integer not null references addresses(id)" ]
[:phone "varchar(16)"]
;; we'll probably only capture email data on electors if they request a followup
;; on a particular issue by email.
@ -119,10 +122,11 @@
(kc/defentity elector
(pk :id)
(table :districts)
(database yyydb/*db*)
(entity-fields :id :name))
(kc/pk :id)
(kc/table :electors)
(kc/database yyydb/*db*)
(kc/entity-fields :id :name :phone :email)
(kc/has-one address))
(defn create-canvassers-table!
@ -132,22 +136,33 @@
yyydb/*db*
(sql/create-table-ddl
:canvassers
[[:username "varchar(32) not null primary key"]
[;; id is the kc/kc/entity-fields.
[:id "varchar(32) not null primary key"]
[:fullname "varchar(64) not null"]
;; most canvassers will be electors, we should link them:
[:elector "integer references electors(rollno) on delete no action"]
[:elector_id "integer references electors(id) on delete no action"]
;; but some canvassers may not be electors, so we need contact details separately:
[:address "integer not null references addresses(id)" ]
[:address_id "integer not null references addresses(id)" ]
[:phone "varchar(16)"]
[:email "varchar(128)"]
;; with which authority do we authenticate this canvasser? I do not want to hold even
;; encrypted passwords locally
[:authority "varchar(32) not null references authority(id) on delete no action"]
[:authority_id "varchar(32) not null references authority(id) on delete no action"]
;; true if the canvasser is authorised to use the app; else false. This allows us to
;; block canvassers we suspect of misbehaving.
[:authorised :boolean]])))
(kc/defentity canvasser
(kc/pk :id)
(kc/table :canvassers)
(kc/database yyydb/*db*)
(kc/entity-fields :id :fullname :phone :email :authorised)
(kc/has-one elector)
(kc/has-one address)
(kc/has-one authority))
(defn create-visit-table!
"Create a table to record visits by canvassers to addresses (including virtual visits by telephone)."
[]
@ -156,10 +171,20 @@
(sql/create-table-ddl
:visits
[[:id "serial not null primary key"]
[:canvasser "varchar(32) references canvassers(username) not null"]
[:address_id "integer not null references address(id)"]
[:canvasser_id "varchar(32) references canvassers(id) not null"]
[:date "timestamp with timezone not null default now()"]])))
(kc/defentity visit
(kc/pk :id)
(kc/table :visits)
(kc/database yyydb/*db*)
(kc/entity-fields :id :date)
(kc/has-one address)
(kc/has-one canvasser))
(defn create-option-table!
"Create a table to record options in the vote. This app is being created for the Independence
referendum, which will have just two options, 'Yes' and 'No', but it might later be adapted
@ -169,10 +194,18 @@
yyydb/*db*
(sql/create-table-ddl
:options
[[:option "varchar(32) not null primary key"
[;; id is also the text of the option; e.g. 'Yes', 'No'.
[:id "varchar(32) not null primary key"]
;; To do elections you probably need party and candidate and stuff here, but
;; for the referendum it's unnecessary.
]])))
])))
(kc/defentity option
(kc/pk :id)
(kc/table :options)
(kc/database yyydb/*db*)
(kc/entity-fields :id))
(defn create-option-district-table!
@ -184,8 +217,11 @@
yyydb/*db*
(sql/create-table-ddl
:optionsdistricts
[[:option "varchar(32) not null references options(option)"]
[:district "integer not null references districts(id)"]])))
[[:option_id"varchar(32) not null references options(option)"]
[:district_id "integer not null references districts(id)"]])))
;; I think we don't need an entity for optionsdistricts, because it's just a link table.
(defn create-opinion-table!
@ -198,10 +234,20 @@
:opinions
[[:id "serial primary key"]
;; the elector who gave this opinion
[:elector "integer not null references electors(rollno)"]
[:elector_id "integer not null references electors(id)"]
;; the option the elector said they were planning to vote for
[:option "varchar(32) not null references options(option)"]
[:visit "integer not null references visits(id)"]])))
[:option_id "varchar(32) not null references options(option)"]
[:visit_id "integer not null references visits(id)"]])))
(kc/defentity opinion
(kc/pk :id)
(kc/table :opinions)
(kc/database yyydb/*db*)
(kc/entity-fields :id)
(kc/has-one elector)
(kc/has-one option)
(kc/has-one visit))
(defn create-issues-table!
@ -214,11 +260,18 @@
(sql/create-table-ddl
:issues
[;; short name of this issue, e.g. 'currency', 'defence', 'pensions'
[:issue "varchar(32) not null primary key"]
[:id "varchar(32) not null primary key"]
;; URL of some brief material the canvasser can use on the doorstap
[:url "varchar(256)"]])))
(kc/defentity issue
(kc/pk :id)
(kc/table :issues)
(kc/database yyydb/*db*)
(kc/entity-fields :id :url))
(defn create-followup-method-table!
"Create a table to hold reference data on followup methods."
[]
@ -226,7 +279,15 @@
yyydb/*db*
(sql/create-table-ddl
:followupmethod
[[:method "varchar(32) not null primary key"]])))
[[;; the method, e.g. 'telephone', 'email', 'post'
:id "varchar(32) not null primary key"]])))
(kc/defentity followup-method
(kc/pk :id)
(kc/table :followupmethod)
(kc/database yyydb/*db*)
(kc/entity-fields :id))
(defn create-issue-expertise-table!
@ -237,10 +298,21 @@
yyydb/*db*
(sql/create-table-ddl
:issueexpertise
[[:expert "varchar(32) not null references canvasser(username)"]
[:issue "varchar(32) not null references issues(issue)"]
[;; the expert canvasser
[:canvasser-id "varchar(32) not null references canvasser(id)"]
;; the issue they have expertise in
[:issue_id "varchar(32) not null references issues(issue)"]
;; the method by which this expert can respond to electors on this issue
[:method "varchar 32 not null references followupmethod(method)"]])))
[:method_id "varchar 32 not null references followupmethod(method)"]])))
(kc/defentity issue-expertise
(kc/table :issueexpertise)
(kc/database yyydb/*db*)
(kc/entity-fields :id)
(kc/has-one canvasser)
(kc/has-one issue)
(kc/has-one followup-method))
(defn create-followup-request-table!
@ -251,13 +323,23 @@
(sql/create-table-ddl
:followuprequest
[[:id "serial primary key"]
[:elector "integer not null references electors(rollno)"]
[:visit "integer not null references visits(id)"]
[:issue "varchar(32) not null references issues(issue)"]
[:elector_id "integer not null references electors(id)"]
[:visit_id "integer not null references visits(id)"]
[:issue_id "varchar(32) not null references issues(issue)"]
;; We probably need a followupmethod (telephone, email, postal) and, for telephone,
;; convenient times but I haven't thought through how to represent this or how
;; the user interface will work.
[:method "varchar(32) not null references followupmethod(method)"]])))
[:method_id "varchar(32) not null references followupmethod(method)"]])))
(kc/defentity followup-request
(kc/table :followuprequest)
(kc/database yyydb/*db*)
(kc/entity-fields :id)
(kc/has-one elector)
(kc/has-one visit)
(kc/has-one issue)
(kc/has-one followup-method))
(defn create-followup-action-table!
@ -270,10 +352,17 @@
(sql/create-table-ddl
:followupaction
[[:id "serial primary key"]
[:request "integer not null references followuprequest(id)"]
[:actor "varchar(32) not null references canvassers(username)"]
[:request_id "integer not null references followuprequest(id)"]
[:actor "varchar(32) not null references canvassers(id)"]
[:date "timestamp with timezone not null default now()"]
[:notes "text"]
;; true if this action closes the request
[:closed :boolean]])))
(kc/defentity followup-action
(kc/table :followupaction)
(kc/database yyydb/*db*)
(kc/entity-fields :id :notes :date :closed)
(kc/has-one followup-request)
(kc/has-one canvasser {:fk :actor}))