diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 1b435da..5134e95 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -35,6 +35,7 @@ sub startup { $self->plugin('Pear::LocalLoop::Plugin::BootstrapPagination', { bootstrap4 => 1 } ); $self->plugin('Pear::LocalLoop::Plugin::Validators'); + $self->plugin('Pear::LocalLoop::Plugin::Datetime'); $self->plugin('Authentication' => { 'load_user' => sub { @@ -147,9 +148,9 @@ sub startup { }); $api->post('/upload')->to('api-upload#post_upload'); $api->post('/search')->to('api-upload#post_search'); + $api->post('/user')->to('api-user#post_account'); + $api->post('/user/account')->to('api-user#post_account_update'); $api->post('/user/day')->to('api-user#post_day'); - $api->post('/edit')->to('api-api#post_edit'); - $api->post('/fetchuser')->to('api-api#post_fetchuser'); $api->post('/user-history')->to('api-user#post_user_history'); $api->post('/stats')->to('api-stats#post_index'); $api->post('/stats/leaderboard')->to('api-stats#post_leaderboards'); @@ -200,10 +201,11 @@ sub startup { while ( my $from_org_transaction = $from_org_transaction_rs->next ) { $to_org->create_related( 'transactions', { - buyer_id => $from_org_transaction->buyer_id, - value => $from_org_transaction->value, - proof_image => $from_org_transaction->proof_image, - submitted_at => $from_org_transaction->submitted_at, + buyer_id => $from_org_transaction->buyer_id, + value => $from_org_transaction->value, + proof_image => $from_org_transaction->proof_image, + submitted_at => $from_org_transaction->submitted_at, + purchase_time => $from_org_transaction->purchase_time, } ); $from_org_transaction->delete; diff --git a/lib/Pear/LocalLoop/Command/dev_transactions.pm b/lib/Pear/LocalLoop/Command/dev_transactions.pm index 4c8001d..ec50fb1 100644 --- a/lib/Pear/LocalLoop/Command/dev_transactions.pm +++ b/lib/Pear/LocalLoop/Command/dev_transactions.pm @@ -73,7 +73,7 @@ sub run { seller_id => $organisations[int(rand($#organisations))]->organisation_id, value => int(rand(9999)) / 100, proof_image => 'a', - submitted_at => $dtf->format_datetime($datetime->clone->add( minutes => int(rand(1440)) )), + purchase_time => $dtf->format_datetime($datetime->clone->add( minutes => int(rand(1440)) )), }); } } diff --git a/lib/Pear/LocalLoop/Controller/Api/Api.pm b/lib/Pear/LocalLoop/Controller/Api/Api.pm deleted file mode 100644 index 5b23cf0..0000000 --- a/lib/Pear/LocalLoop/Controller/Api/Api.pm +++ /dev/null @@ -1,59 +0,0 @@ -package Pear::LocalLoop::Controller::Api::Api; -use Mojo::Base 'Mojolicious::Controller'; -use Data::Dumper; - -sub post_edit { - my $self = shift; - - my $json = $self->req->json; - - my $account = $self->get_account_by_username( $json->{username} ); - - unless ( defined $account ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Username not recognised, has your token expired?', - }); -# PLUG SECURITY HOLE - } elsif ( $account->{keyused} ne 't' ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Token has not been used yet!', - }); - } - my $insert = $self->db->prepare("UPDATE accounts SET fullname = ?, postcode = ?, age = ?, gender = ?, WHERE username = ?"); - $insert->execute( - @{$json}{ qw/ fullname postcode age gender / }, $account->{username}, - ); - - $self->render( json => { success => Mojo::JSON->true } ); -} - - -sub post_fetchuser { - my $self = shift; - - my $json = $self->req->json; - - my $account = $self->get_account_by_username( $json->{username} ); - - unless ( defined $account ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Username not recognised, has your token expired?', - }); -# PLUG SECURITY HOLE - } elsif ( $account->{keyused} ne 't' ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Token has not been used yet!', - }); - } - -# Add stuff to send back to user below here! - $self->render( json => { - success => Mojo::JSON->true, - }); -} - -1; diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index 3592cbb..d64bf09 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -75,14 +75,24 @@ sub post_login { my $password = $validation->param('password'); my $user_result = $c->schema->resultset('User')->find({ email => $email }); - + if ( defined $user_result ) { if ( $user_result->check_password($password) ) { my $session_key = $user_result->generate_session; + my $display_name; + + if ( defined $user_result->customer_id ) { + $display_name = $user_result->customer->display_name; + } elsif ( defined $user_result->organisation_id ) { + $display_name = $user_result->organisation->name; + } else { + return undef; + } return $c->render( json => { success => Mojo::JSON->true, session_key => $session_key, + display_name => $display_name, }); } } @@ -109,7 +119,7 @@ sub post_logout { $c->render( json => { success => Mojo::JSON->true, message => 'Logged Out', - }); + }); } 1; diff --git a/lib/Pear/LocalLoop/Controller/Api/Upload.pm b/lib/Pear/LocalLoop/Controller/Api/Upload.pm index 7953b7f..58d9bd8 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Upload.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Upload.pm @@ -19,6 +19,10 @@ The value of the transaction Is a value of 1, 2, or 3 - depending on the type of transaction. +=item * purchase_time + +Is a DateTime value submitted for when the receipt is from. + =item * organisation_id An ID of a valid organisation. used when transaction_type is 1 or 2. @@ -54,6 +58,9 @@ has error_messages => sub { number => { message => 'transaction_value does not look like a number', status => 400 }, gt_num => { message => 'transaction_value cannot be equal to or less than zero', status => 400 }, }, + purchase_time => { + required => { message => 'purchase_time is missing', status => 400 }, + }, file => { required => { message => 'No file uploaded', status => 400 }, upload => { message => 'file key does not contain a file', status => 400 }, @@ -92,6 +99,9 @@ sub post_upload { $validation->required('transaction_value')->number->gt_num(0); $validation->required('transaction_type')->in( 1, 2, 3 ); + #Check a proper purchase time was submitted + $validation->optional('purchase_time')->is_full_iso_datetime; + # First pass of required items return $c->api_validation_error if $validation->has_error; @@ -112,7 +122,7 @@ sub post_upload { # Unvalidated Organisation my $valid_org_rs = $c->schema->resultset('PendingOrganisation')->search({ submitted_by_id => $user->id }); $validation->required('organisation_id')->number->in_resultset( 'id', $valid_org_rs ); - + return $c->api_validation_error if $validation->has_error; $organisation = $valid_org_rs->find( $validation->param('organisation_id') ); @@ -123,7 +133,7 @@ sub post_upload { $validation->optional('street_name'); $validation->optional('town'); $validation->optional('postcode')->postcode; - + return $c->api_validation_error if $validation->has_error; $organisation = $c->schema->resultset('PendingOrganisation')->create({ @@ -138,6 +148,8 @@ sub post_upload { my $transaction_value = $validation->param('transaction_value'); my $upload = $validation->param('file'); + my $purchase_time = $c->parse_iso_datetime($validation->param('purchase_time') || ''); + $purchase_time ||= DateTime->now(); my $file = $c->store_file_from_upload( $upload ); $organisation->create_related( @@ -146,6 +158,7 @@ sub post_upload { buyer => $user, value => $transaction_value, proof_image => $file, + purchase_time => $c->format_db_datetime($purchase_time), } ); diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index f1532a6..ef9ec89 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -7,6 +7,32 @@ has error_messages => sub { day => { is_iso_datetime => { message => 'Invalid ISO8601 Datetime', status => 400 }, }, + name => { + required => { message => 'No name sent or was blank.', status => 400 }, + }, + display_name => { + required => { message => 'No display name sent or was blank.', status => 400 }, + }, + full_name => { + required => { message => 'No full name sent or was blank.', status => 400 }, + }, + email => { + required => { message => 'No email sent.', status => 400 }, + email => { message => 'Email is invalid.', status => 400 }, + }, + postcode => { + required => { message => 'No postcode sent.', status => 400 }, + postcode => { message => 'Postcode is invalid', status => 400 }, + }, + password => { + required => { message => 'No password sent.', status => 400 }, + }, + street_name => { + required => { message => 'No street_name sent.', status => 400 }, + }, + town => { + required => { message => 'No town sent.', status => 400 }, + }, }; }; @@ -26,4 +52,122 @@ sub post_day { }); } +sub post_account { + my $c = shift; + + my $user = $c->stash->{api_user}; + my $user_result = $c->schema->resultset('User')->find({ id => $c->stash->{api_user}->id }); + + if ( defined $user_result ) { + my $email = $user_result->email; + my $full_name; + my $display_name; + my $postcode; + + #Needs elsif added for trader page for this similar relevant entry + if ( defined $user_result->customer_id ) { + $full_name = $user_result->customer->full_name; + $display_name = $user_result->customer->display_name; + $postcode = $user_result->customer->postcode; + } elsif ( defined $user_result->organisation_id ) { + $display_name = $user_result->organisation->name; + } else { + return undef; + } + + return $c->render( json => { + success => Mojo::JSON->true, + full_name => $full_name, + display_name => $display_name, + email => $email, + postcode => $postcode, + }); + } + return $c->render( + json => { + success => Mojo::JSON->false, + message => 'Email or password is invalid.', + }, + status => 401 + ); +} + +sub post_account_update { + my $c = shift; + + my $user = $c->stash->{api_user}; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->required('password'); + + return $c->api_validation_error if $validation->has_error; + + if ( ! $user->check_password($validation->param('password')) ) { + return $c->render( + json => { + success => Mojo::JSON->false, + message => 'password is invalid.', + }, + status => 401 + ); + } + + my $user_rs = $c->schema->resultset('User')->search({ + id => { "!=" => $user->id }, + }); + + $validation->required('email')->not_in_resultset( 'email', $user_rs ); + $validation->required('postcode')->postcode; + $validation->optional('new_password'); + + if ( defined $user->customer_id ) { + $validation->required('display_name'); + $validation->required('full_name'); + } elsif ( defined $user->customer_id ) { + $validation->required('name'); + $validation->required('street_name'); + $validation->required('town'); + } + + return $c->api_validation_error if $validation->has_error; + + if ( defined $user->customer_id ){ + + $c->schema->txn_do( sub { + $user->customer->update({ + full_name => $validation->param('full_name'), + display_name => $validation->param('display_name'), + postcode => $validation->param('postcode'), + }); + $user->update({ + email => $validation->param('email'), + ( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ), + }); + }); + + } + elsif ( defined $user->organisation_id ) { + my $fullAddress = $validation->param('fulladdress'); + + $c->schema->txn_do( sub { + $user->organisation->update({ + name => $validation->param('name'), + street_name => $validation->param('street_name'), + town => $validation->param('town'), + postcode => $validation->param('postcode'), + }); + $user->update({ + email => $validation->param('email'), + ( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ), + }); + }); + } + + return $c->render( json => { + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); +} + 1; diff --git a/lib/Pear/LocalLoop/Plugin/Datetime.pm b/lib/Pear/LocalLoop/Plugin/Datetime.pm new file mode 100644 index 0000000..a94c292 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Datetime.pm @@ -0,0 +1,41 @@ +package Pear::LocalLoop::Plugin::Datetime; +use Mojo::Base 'Mojolicious::Plugin'; + +use DateTime::Format::Strptime; + +sub register { + my ( $plugin, $app, $conf ) = @_; + + $app->helper( iso_datetime_parser => sub { + return DateTime::Format::Strptime->new( pattern => '%Y-%m-%dT%H:%M:%S.%3N%z' ); +}); + +$app->helper( parse_iso_datetime => sub { + my ( $c, $date_string ) = @_; + return $c->iso_datetime_parser->parse_datetime( + $date_string, + ); +}); + +$app->helper( format_iso_datetime => sub { + my ( $c, $datetime_obj ) = @_; + return $c->iso_datetime_parser->parse_datetime( + $datetime_obj, + ); +}); + +$app->helper( db_datetime_parser => sub { + return shift->schema->storage->datetime_parser; +}); + +$app->helper( format_db_datetime => sub { + my ( $c, $datetime_obj ) = @_; + $datetime_obj->set_time_zone('UTC'); + return $c->db_datetime_parser->format_datetime( + $datetime_obj, + ); +}); + +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Validators.pm b/lib/Pear/LocalLoop/Plugin/Validators.pm index cc07414..33aeca2 100644 --- a/lib/Pear/LocalLoop/Plugin/Validators.pm +++ b/lib/Pear/LocalLoop/Plugin/Validators.pm @@ -58,6 +58,12 @@ sub register { $value = $app->datetime_formatter->parse_datetime( $value ); return defined $value ? undef : 1; }); + + $app->validator->add_check( is_full_iso_datetime => sub { + my ( $validation, $name, $value ) = @_; + $value = $app->parse_iso_datetime( $value ); + return defined $value ? undef : 1; + }); } 1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 7fea66a..6c3cecc 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 2; +our $VERSION = 4; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm b/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm index f737725..5637181 100644 --- a/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm @@ -42,6 +42,12 @@ __PACKAGE__->add_columns( is_nullable => 0, set_on_create => 1, }, + "purchase_time" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, ); __PACKAGE__->set_primary_key("id"); diff --git a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm index 198c9ee..6ac0223 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm @@ -42,6 +42,12 @@ __PACKAGE__->add_columns( is_nullable => 0, set_on_create => 1, }, + "purchase_time" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, ); __PACKAGE__->set_primary_key("id"); diff --git a/lib/Pear/LocalLoop/Schema/ResultSet/Transaction.pm b/lib/Pear/LocalLoop/Schema/ResultSet/Transaction.pm index 4345cf4..05d264d 100644 --- a/lib/Pear/LocalLoop/Schema/ResultSet/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/ResultSet/Transaction.pm @@ -12,7 +12,7 @@ sub search_between { my $dtf = $self->result_source->schema->storage->datetime_parser; return $self->search({ - submitted_at => { + purchase_time => { -between => [ $dtf->format_datetime($from), $dtf->format_datetime($to), diff --git a/share/ddl/PostgreSQL/deploy/3/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/3/001-auto-__VERSION.sql new file mode 100644 index 0000000..c5b7324 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/3/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Aug 14 12:22:58 2017 +-- +; +-- +-- Table: dbix_class_deploymenthandler_versions +-- +CREATE TABLE "dbix_class_deploymenthandler_versions" ( + "id" serial NOT NULL, + "version" character varying(50) NOT NULL, + "ddl" text, + "upgrade_sql" text, + PRIMARY KEY ("id"), + CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/3/001-auto.sql b/share/ddl/PostgreSQL/deploy/3/001-auto.sql new file mode 100644 index 0000000..521e6e0 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/3/001-auto.sql @@ -0,0 +1,248 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Aug 14 12:22:58 2017 +-- +; +-- +-- Table: account_tokens +-- +CREATE TABLE "account_tokens" ( + "id" serial NOT NULL, + "name" text NOT NULL, + "used" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "account_tokens_name" UNIQUE ("name") +); + +; +-- +-- Table: customers +-- +CREATE TABLE "customers" ( + "id" serial NOT NULL, + "display_name" character varying(255) NOT NULL, + "full_name" character varying(255) NOT NULL, + "year_of_birth" integer NOT NULL, + "postcode" character varying(16) NOT NULL, + PRIMARY KEY ("id") +); + +; +-- +-- Table: leaderboards +-- +CREATE TABLE "leaderboards" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "type" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "leaderboards_type" UNIQUE ("type") +); + +; +-- +-- Table: organisations +-- +CREATE TABLE "organisations" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "street_name" text, + "town" character varying(255) NOT NULL, + "postcode" character varying(16), + PRIMARY KEY ("id") +); + +; +-- +-- Table: leaderboard_sets +-- +CREATE TABLE "leaderboard_sets" ( + "id" serial NOT NULL, + "leaderboard_id" integer NOT NULL, + "date" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id"); + +; +-- +-- Table: users +-- +CREATE TABLE "users" ( + "id" serial NOT NULL, + "customer_id" integer, + "organisation_id" integer, + "email" text NOT NULL, + "join_date" timestamp NOT NULL, + "password" character varying(100) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "users_customer_id" UNIQUE ("customer_id"), + CONSTRAINT "users_email" UNIQUE ("email"), + CONSTRAINT "users_organisation_id" UNIQUE ("organisation_id") +); +CREATE INDEX "users_idx_customer_id" on "users" ("customer_id"); +CREATE INDEX "users_idx_organisation_id" on "users" ("organisation_id"); + +; +-- +-- Table: administrators +-- +CREATE TABLE "administrators" ( + "user_id" integer NOT NULL, + PRIMARY KEY ("user_id") +); + +; +-- +-- Table: feedback +-- +CREATE TABLE "feedback" ( + "id" serial NOT NULL, + "user_id" integer NOT NULL, + "submitted_at" timestamp NOT NULL, + "feedbacktext" text NOT NULL, + "app_name" character varying(255) NOT NULL, + "package_name" character varying(255) NOT NULL, + "version_code" character varying(255) NOT NULL, + "version_number" character varying(255) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id"); + +; +-- +-- Table: pending_organisations +-- +CREATE TABLE "pending_organisations" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "street_name" text, + "town" character varying(255) NOT NULL, + "postcode" character varying(16), + "submitted_by_id" integer NOT NULL, + "submitted_at" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "pending_organisations_idx_submitted_by_id" on "pending_organisations" ("submitted_by_id"); + +; +-- +-- Table: session_tokens +-- +CREATE TABLE "session_tokens" ( + "id" serial NOT NULL, + "token" character varying(255) NOT NULL, + "user_id" integer NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "session_tokens_token" UNIQUE ("token") +); +CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id"); + +; +-- +-- Table: transactions +-- +CREATE TABLE "transactions" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "proof_image" text NOT NULL, + "submitted_at" timestamp NOT NULL, + "purchase_time" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id"); +CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id"); + +; +-- +-- Table: pending_transactions +-- +CREATE TABLE "pending_transactions" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "proof_image" text NOT NULL, + "submitted_at" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "pending_transactions_idx_buyer_id" on "pending_transactions" ("buyer_id"); +CREATE INDEX "pending_transactions_idx_seller_id" on "pending_transactions" ("seller_id"); + +; +-- +-- Table: leaderboard_values +-- +CREATE TABLE "leaderboard_values" ( + "id" serial NOT NULL, + "user_id" integer NOT NULL, + "set_id" integer NOT NULL, + "position" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "trend" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "leaderboard_values_user_id_set_id" UNIQUE ("user_id", "set_id") +); +CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id"); +CREATE INDEX "leaderboard_values_idx_user_id" on "leaderboard_values" ("user_id"); + +; +-- +-- Foreign Key Definitions +-- + +; +ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id") + REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "users" ADD CONSTRAINT "users_fk_customer_id" FOREIGN KEY ("customer_id") + REFERENCES "customers" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "users" ADD CONSTRAINT "users_fk_organisation_id" FOREIGN KEY ("organisation_id") + REFERENCES "organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "administrators" ADD CONSTRAINT "administrators_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_organisations" ADD CONSTRAINT "pending_organisations_fk_submitted_by_id" FOREIGN KEY ("submitted_by_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_transactions" ADD CONSTRAINT "pending_transactions_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_transactions" ADD CONSTRAINT "pending_transactions_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "pending_organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id") + REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; diff --git a/share/ddl/PostgreSQL/deploy/4/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/4/001-auto-__VERSION.sql new file mode 100644 index 0000000..60b75a5 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/4/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Aug 14 14:33:22 2017 +-- +; +-- +-- Table: dbix_class_deploymenthandler_versions +-- +CREATE TABLE "dbix_class_deploymenthandler_versions" ( + "id" serial NOT NULL, + "version" character varying(50) NOT NULL, + "ddl" text, + "upgrade_sql" text, + PRIMARY KEY ("id"), + CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/4/001-auto.sql b/share/ddl/PostgreSQL/deploy/4/001-auto.sql new file mode 100644 index 0000000..f41c6bd --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/4/001-auto.sql @@ -0,0 +1,249 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Aug 14 14:33:22 2017 +-- +; +-- +-- Table: account_tokens +-- +CREATE TABLE "account_tokens" ( + "id" serial NOT NULL, + "name" text NOT NULL, + "used" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "account_tokens_name" UNIQUE ("name") +); + +; +-- +-- Table: customers +-- +CREATE TABLE "customers" ( + "id" serial NOT NULL, + "display_name" character varying(255) NOT NULL, + "full_name" character varying(255) NOT NULL, + "year_of_birth" integer NOT NULL, + "postcode" character varying(16) NOT NULL, + PRIMARY KEY ("id") +); + +; +-- +-- Table: leaderboards +-- +CREATE TABLE "leaderboards" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "type" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "leaderboards_type" UNIQUE ("type") +); + +; +-- +-- Table: organisations +-- +CREATE TABLE "organisations" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "street_name" text, + "town" character varying(255) NOT NULL, + "postcode" character varying(16), + PRIMARY KEY ("id") +); + +; +-- +-- Table: leaderboard_sets +-- +CREATE TABLE "leaderboard_sets" ( + "id" serial NOT NULL, + "leaderboard_id" integer NOT NULL, + "date" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id"); + +; +-- +-- Table: users +-- +CREATE TABLE "users" ( + "id" serial NOT NULL, + "customer_id" integer, + "organisation_id" integer, + "email" text NOT NULL, + "join_date" timestamp NOT NULL, + "password" character varying(100) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "users_customer_id" UNIQUE ("customer_id"), + CONSTRAINT "users_email" UNIQUE ("email"), + CONSTRAINT "users_organisation_id" UNIQUE ("organisation_id") +); +CREATE INDEX "users_idx_customer_id" on "users" ("customer_id"); +CREATE INDEX "users_idx_organisation_id" on "users" ("organisation_id"); + +; +-- +-- Table: administrators +-- +CREATE TABLE "administrators" ( + "user_id" integer NOT NULL, + PRIMARY KEY ("user_id") +); + +; +-- +-- Table: feedback +-- +CREATE TABLE "feedback" ( + "id" serial NOT NULL, + "user_id" integer NOT NULL, + "submitted_at" timestamp NOT NULL, + "feedbacktext" text NOT NULL, + "app_name" character varying(255) NOT NULL, + "package_name" character varying(255) NOT NULL, + "version_code" character varying(255) NOT NULL, + "version_number" character varying(255) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id"); + +; +-- +-- Table: pending_organisations +-- +CREATE TABLE "pending_organisations" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + "street_name" text, + "town" character varying(255) NOT NULL, + "postcode" character varying(16), + "submitted_by_id" integer NOT NULL, + "submitted_at" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "pending_organisations_idx_submitted_by_id" on "pending_organisations" ("submitted_by_id"); + +; +-- +-- Table: session_tokens +-- +CREATE TABLE "session_tokens" ( + "id" serial NOT NULL, + "token" character varying(255) NOT NULL, + "user_id" integer NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "session_tokens_token" UNIQUE ("token") +); +CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id"); + +; +-- +-- Table: transactions +-- +CREATE TABLE "transactions" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "proof_image" text NOT NULL, + "submitted_at" timestamp NOT NULL, + "purchase_time" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id"); +CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id"); + +; +-- +-- Table: pending_transactions +-- +CREATE TABLE "pending_transactions" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "proof_image" text NOT NULL, + "submitted_at" timestamp NOT NULL, + "purchase_time" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "pending_transactions_idx_buyer_id" on "pending_transactions" ("buyer_id"); +CREATE INDEX "pending_transactions_idx_seller_id" on "pending_transactions" ("seller_id"); + +; +-- +-- Table: leaderboard_values +-- +CREATE TABLE "leaderboard_values" ( + "id" serial NOT NULL, + "user_id" integer NOT NULL, + "set_id" integer NOT NULL, + "position" integer NOT NULL, + "value" numeric(16,2) NOT NULL, + "trend" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "leaderboard_values_user_id_set_id" UNIQUE ("user_id", "set_id") +); +CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id"); +CREATE INDEX "leaderboard_values_idx_user_id" on "leaderboard_values" ("user_id"); + +; +-- +-- Foreign Key Definitions +-- + +; +ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id") + REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "users" ADD CONSTRAINT "users_fk_customer_id" FOREIGN KEY ("customer_id") + REFERENCES "customers" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "users" ADD CONSTRAINT "users_fk_organisation_id" FOREIGN KEY ("organisation_id") + REFERENCES "organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "administrators" ADD CONSTRAINT "administrators_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_organisations" ADD CONSTRAINT "pending_organisations_fk_submitted_by_id" FOREIGN KEY ("submitted_by_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_transactions" ADD CONSTRAINT "pending_transactions_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "pending_transactions" ADD CONSTRAINT "pending_transactions_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "pending_organisations" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id") + REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; diff --git a/share/ddl/PostgreSQL/upgrade/2-3/001-auto.sql b/share/ddl/PostgreSQL/upgrade/2-3/001-auto.sql new file mode 100644 index 0000000..69fb0c2 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/2-3/001-auto.sql @@ -0,0 +1,15 @@ +-- Convert schema 'share/ddl/_source/deploy/2/001-auto.yml' to 'share/ddl/_source/deploy/3/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE transactions ADD COLUMN purchase_time timestamp; + +UPDATE transactions SET purchase_time = submitted_at; + +ALTER TABLE transactions ALTER COLUMN purchase_time SET NOT NULL; + +; + +COMMIT; diff --git a/share/ddl/PostgreSQL/upgrade/3-4/001-auto.sql b/share/ddl/PostgreSQL/upgrade/3-4/001-auto.sql new file mode 100644 index 0000000..77779bc --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/3-4/001-auto.sql @@ -0,0 +1,15 @@ +-- Convert schema 'share/ddl/_source/deploy/3/001-auto.yml' to 'share/ddl/_source/deploy/4/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE pending_transactions ADD COLUMN purchase_time timestamp; + +UPDATE transactions SET purchase_time = submitted_at; + +ALTER TABLE pending_transactions ALTER COLUMN purchase_time SET NOT NULL; + +; + +COMMIT; diff --git a/share/ddl/SQLite/deploy/3/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/3/001-auto-__VERSION.sql new file mode 100644 index 0000000..8866d32 --- /dev/null +++ b/share/ddl/SQLite/deploy/3/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Aug 14 12:22:58 2017 +-- + +; +BEGIN TRANSACTION; +-- +-- Table: dbix_class_deploymenthandler_versions +-- +CREATE TABLE dbix_class_deploymenthandler_versions ( + id INTEGER PRIMARY KEY NOT NULL, + version varchar(50) NOT NULL, + ddl text, + upgrade_sql text +); +CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version); +COMMIT; diff --git a/share/ddl/SQLite/deploy/3/001-auto.sql b/share/ddl/SQLite/deploy/3/001-auto.sql new file mode 100644 index 0000000..dfd9bcc --- /dev/null +++ b/share/ddl/SQLite/deploy/3/001-auto.sql @@ -0,0 +1,168 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Aug 14 12:22:58 2017 +-- + +; +BEGIN TRANSACTION; +-- +-- Table: account_tokens +-- +CREATE TABLE account_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + name text NOT NULL, + used integer NOT NULL DEFAULT 0 +); +CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name); +-- +-- Table: customers +-- +CREATE TABLE customers ( + id INTEGER PRIMARY KEY NOT NULL, + display_name varchar(255) NOT NULL, + full_name varchar(255) NOT NULL, + year_of_birth integer NOT NULL, + postcode varchar(16) NOT NULL +); +-- +-- Table: leaderboards +-- +CREATE TABLE leaderboards ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + type varchar(255) NOT NULL +); +CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type); +-- +-- Table: organisations +-- +CREATE TABLE organisations ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + street_name text, + town varchar(255) NOT NULL, + postcode varchar(16) +); +-- +-- Table: leaderboard_sets +-- +CREATE TABLE leaderboard_sets ( + id INTEGER PRIMARY KEY NOT NULL, + leaderboard_id integer NOT NULL, + date datetime NOT NULL, + FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id); +-- +-- Table: users +-- +CREATE TABLE users ( + id INTEGER PRIMARY KEY NOT NULL, + customer_id integer, + organisation_id integer, + email text NOT NULL, + join_date datetime NOT NULL, + password varchar(100) NOT NULL, + FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (organisation_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX users_idx_customer_id ON users (customer_id); +CREATE INDEX users_idx_organisation_id ON users (organisation_id); +CREATE UNIQUE INDEX users_customer_id ON users (customer_id); +CREATE UNIQUE INDEX users_email ON users (email); +CREATE UNIQUE INDEX users_organisation_id ON users (organisation_id); +-- +-- Table: administrators +-- +CREATE TABLE administrators ( + user_id INTEGER PRIMARY KEY NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +-- +-- Table: feedback +-- +CREATE TABLE feedback ( + id INTEGER PRIMARY KEY NOT NULL, + user_id integer NOT NULL, + submitted_at datetime NOT NULL, + feedbacktext text NOT NULL, + app_name varchar(255) NOT NULL, + package_name varchar(255) NOT NULL, + version_code varchar(255) NOT NULL, + version_number varchar(255) NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX feedback_idx_user_id ON feedback (user_id); +-- +-- Table: pending_organisations +-- +CREATE TABLE pending_organisations ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + street_name text, + town varchar(255) NOT NULL, + postcode varchar(16), + submitted_by_id integer NOT NULL, + submitted_at datetime NOT NULL, + FOREIGN KEY (submitted_by_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX pending_organisations_idx_submitted_by_id ON pending_organisations (submitted_by_id); +-- +-- Table: session_tokens +-- +CREATE TABLE session_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + token varchar(255) NOT NULL, + user_id integer NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id); +CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token); +-- +-- Table: transactions +-- +CREATE TABLE transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id); +CREATE INDEX transactions_idx_seller_id ON transactions (seller_id); +-- +-- Table: pending_transactions +-- +CREATE TABLE pending_transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES pending_organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX pending_transactions_idx_buyer_id ON pending_transactions (buyer_id); +CREATE INDEX pending_transactions_idx_seller_id ON pending_transactions (seller_id); +-- +-- Table: leaderboard_values +-- +CREATE TABLE leaderboard_values ( + id INTEGER PRIMARY KEY NOT NULL, + user_id integer NOT NULL, + set_id integer NOT NULL, + position integer NOT NULL, + value decimal(16,2) NOT NULL, + trend integer NOT NULL DEFAULT 0, + FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id); +CREATE INDEX leaderboard_values_idx_user_id ON leaderboard_values (user_id); +CREATE UNIQUE INDEX leaderboard_values_user_id_set_id ON leaderboard_values (user_id, set_id); +COMMIT; diff --git a/share/ddl/SQLite/deploy/4/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/4/001-auto-__VERSION.sql new file mode 100644 index 0000000..851ae7e --- /dev/null +++ b/share/ddl/SQLite/deploy/4/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Aug 14 14:33:22 2017 +-- + +; +BEGIN TRANSACTION; +-- +-- Table: dbix_class_deploymenthandler_versions +-- +CREATE TABLE dbix_class_deploymenthandler_versions ( + id INTEGER PRIMARY KEY NOT NULL, + version varchar(50) NOT NULL, + ddl text, + upgrade_sql text +); +CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version); +COMMIT; diff --git a/share/ddl/SQLite/deploy/4/001-auto.sql b/share/ddl/SQLite/deploy/4/001-auto.sql new file mode 100644 index 0000000..de0e125 --- /dev/null +++ b/share/ddl/SQLite/deploy/4/001-auto.sql @@ -0,0 +1,169 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Aug 14 14:33:22 2017 +-- + +; +BEGIN TRANSACTION; +-- +-- Table: account_tokens +-- +CREATE TABLE account_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + name text NOT NULL, + used integer NOT NULL DEFAULT 0 +); +CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name); +-- +-- Table: customers +-- +CREATE TABLE customers ( + id INTEGER PRIMARY KEY NOT NULL, + display_name varchar(255) NOT NULL, + full_name varchar(255) NOT NULL, + year_of_birth integer NOT NULL, + postcode varchar(16) NOT NULL +); +-- +-- Table: leaderboards +-- +CREATE TABLE leaderboards ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + type varchar(255) NOT NULL +); +CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type); +-- +-- Table: organisations +-- +CREATE TABLE organisations ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + street_name text, + town varchar(255) NOT NULL, + postcode varchar(16) +); +-- +-- Table: leaderboard_sets +-- +CREATE TABLE leaderboard_sets ( + id INTEGER PRIMARY KEY NOT NULL, + leaderboard_id integer NOT NULL, + date datetime NOT NULL, + FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id); +-- +-- Table: users +-- +CREATE TABLE users ( + id INTEGER PRIMARY KEY NOT NULL, + customer_id integer, + organisation_id integer, + email text NOT NULL, + join_date datetime NOT NULL, + password varchar(100) NOT NULL, + FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (organisation_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX users_idx_customer_id ON users (customer_id); +CREATE INDEX users_idx_organisation_id ON users (organisation_id); +CREATE UNIQUE INDEX users_customer_id ON users (customer_id); +CREATE UNIQUE INDEX users_email ON users (email); +CREATE UNIQUE INDEX users_organisation_id ON users (organisation_id); +-- +-- Table: administrators +-- +CREATE TABLE administrators ( + user_id INTEGER PRIMARY KEY NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +-- +-- Table: feedback +-- +CREATE TABLE feedback ( + id INTEGER PRIMARY KEY NOT NULL, + user_id integer NOT NULL, + submitted_at datetime NOT NULL, + feedbacktext text NOT NULL, + app_name varchar(255) NOT NULL, + package_name varchar(255) NOT NULL, + version_code varchar(255) NOT NULL, + version_number varchar(255) NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX feedback_idx_user_id ON feedback (user_id); +-- +-- Table: pending_organisations +-- +CREATE TABLE pending_organisations ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL, + street_name text, + town varchar(255) NOT NULL, + postcode varchar(16), + submitted_by_id integer NOT NULL, + submitted_at datetime NOT NULL, + FOREIGN KEY (submitted_by_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX pending_organisations_idx_submitted_by_id ON pending_organisations (submitted_by_id); +-- +-- Table: session_tokens +-- +CREATE TABLE session_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + token varchar(255) NOT NULL, + user_id integer NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id); +CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token); +-- +-- Table: transactions +-- +CREATE TABLE transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id); +CREATE INDEX transactions_idx_seller_id ON transactions (seller_id); +-- +-- Table: pending_transactions +-- +CREATE TABLE pending_transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES pending_organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX pending_transactions_idx_buyer_id ON pending_transactions (buyer_id); +CREATE INDEX pending_transactions_idx_seller_id ON pending_transactions (seller_id); +-- +-- Table: leaderboard_values +-- +CREATE TABLE leaderboard_values ( + id INTEGER PRIMARY KEY NOT NULL, + user_id integer NOT NULL, + set_id integer NOT NULL, + position integer NOT NULL, + value decimal(16,2) NOT NULL, + trend integer NOT NULL DEFAULT 0, + FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id); +CREATE INDEX leaderboard_values_idx_user_id ON leaderboard_values (user_id); +CREATE UNIQUE INDEX leaderboard_values_user_id_set_id ON leaderboard_values (user_id, set_id); +COMMIT; diff --git a/share/ddl/SQLite/upgrade/2-3/001-auto.sql b/share/ddl/SQLite/upgrade/2-3/001-auto.sql new file mode 100644 index 0000000..e65aae7 --- /dev/null +++ b/share/ddl/SQLite/upgrade/2-3/001-auto.sql @@ -0,0 +1,44 @@ +-- Convert schema 'share/ddl/_source/deploy/2/001-auto.yml' to 'share/ddl/_source/deploy/3/001-auto.yml':; + +; +BEGIN; + +CREATE TABLE transactions_old AS SELECT * FROM transactions; + +DROP TABLE transactions; + +CREATE TABLE transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id); +CREATE INDEX transactions_idx_seller_id ON transactions (seller_id); + +INSERT INTO transactions ( + id, + buyer_id, + seller_id, + value, + proof_image, + submitted_at, + purchase_time +) SELECT + id, + buyer_id, + seller_id, + value, + proof_image, + submitted_at, + submitted_at + FROM transactions_old; + +DROP TABLE transactions_old; + +COMMIT; diff --git a/share/ddl/SQLite/upgrade/3-4/001-auto.sql b/share/ddl/SQLite/upgrade/3-4/001-auto.sql new file mode 100644 index 0000000..16ffed6 --- /dev/null +++ b/share/ddl/SQLite/upgrade/3-4/001-auto.sql @@ -0,0 +1,43 @@ +-- Convert schema 'share/ddl/_source/deploy/3/001-auto.yml' to 'share/ddl/_source/deploy/4/001-auto.yml':; + +; +BEGIN; + +CREATE TABLE pending_transactions_old AS SELECT * FROM pending_transactions; + +DROP TABLE pending_transactions; + +CREATE TABLE pending_transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value decimal(16,2) NOT NULL, + proof_image text NOT NULL, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (seller_id) REFERENCES organisations(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX pending_transactions_idx_buyer_id ON pending_transactions (buyer_id); +CREATE INDEX pending_transactions_idx_seller_id ON pending_transactions (seller_id); + +INSERT INTO pending_transactions ( + id, + buyer_id, + seller_id, + value, + proof_image, + submitted_at, + purchase_time +) SELECT + id, + buyer_id, + seller_id, + value, + proof_image, + submitted_at, + submitted_at + FROM pending_transactions_old; + +DROP TABLE pending_transactions_old; +COMMIT; diff --git a/share/ddl/_source/deploy/3/001-auto-__VERSION.yml b/share/ddl/_source/deploy/3/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/3/001-auto-__VERSION.yml @@ -0,0 +1,91 @@ +--- +schema: + procedures: {} + tables: + dbix_class_deploymenthandler_versions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - version + match_type: '' + name: dbix_class_deploymenthandler_versions_version + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + ddl: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ddl + order: 3 + size: + - 0 + id: + data_type: int + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + upgrade_sql: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: upgrade_sql + order: 4 + size: + - 0 + version: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: version + order: 2 + size: + - 50 + indices: [] + name: dbix_class_deploymenthandler_versions + options: [] + order: 1 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - __VERSION + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/share/ddl/_source/deploy/3/001-auto.yml b/share/ddl/_source/deploy/3/001-auto.yml new file mode 100644 index 0000000..2eb2c1a --- /dev/null +++ b/share/ddl/_source/deploy/3/001-auto.yml @@ -0,0 +1,1237 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + administrators: + constraints: + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: administrators_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: user_id + order: 1 + size: + - 0 + indices: [] + name: administrators + options: [] + order: 7 + customers: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 2 + size: + - 255 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 3 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 4 + size: + - 0 + indices: [] + name: customers + options: [] + order: 2 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 8 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 5 + leaderboard_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - user_id + - set_id + match_type: '' + name: leaderboard_values_user_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: leaderboard_values_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: user_id + order: 2 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 16 + - 2 + indices: + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + - fields: + - user_id + name: leaderboard_values_idx_user_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 13 + leaderboards: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 3 + organisations: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 3 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 4 + size: + - 255 + indices: [] + name: organisations + options: [] + order: 4 + pending_organisations: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - submitted_by_id + match_type: '' + name: pending_organisations_fk_submitted_by_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 7 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 6 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 4 + size: + - 255 + indices: + - fields: + - submitted_by_id + name: pending_organisations_idx_submitted_by_id + options: [] + type: NORMAL + name: pending_organisations + options: [] + order: 9 + pending_transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: pending_transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: pending_transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: pending_organisations + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 16 + - 2 + indices: + - fields: + - buyer_id + name: pending_transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: pending_transactions_idx_seller_id + options: [] + type: NORMAL + name: pending_transactions + options: [] + order: 12 + session_tokens: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 10 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 16 + - 2 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 11 + users: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - customer_id + match_type: '' + name: users_customer_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - organisation_id + match_type: '' + name: users_organisation_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - customer_id + match_type: '' + name: users_fk_customer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: customers + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - organisation_id + match_type: '' + name: users_fk_organisation_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + customer_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: customer_id + order: 2 + size: + - 0 + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 5 + size: + - 0 + organisation_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: organisation_id + order: 3 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 6 + size: + - 100 + indices: + - fields: + - customer_id + name: users_idx_customer_id + options: [] + type: NORMAL + - fields: + - organisation_id + name: users_idx_organisation_id + options: [] + type: NORMAL + name: users + options: [] + order: 6 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Administrator + - Customer + - Feedback + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - PendingOrganisation + - PendingTransaction + - SessionToken + - Transaction + - User + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/share/ddl/_source/deploy/4/001-auto-__VERSION.yml b/share/ddl/_source/deploy/4/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/4/001-auto-__VERSION.yml @@ -0,0 +1,91 @@ +--- +schema: + procedures: {} + tables: + dbix_class_deploymenthandler_versions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - version + match_type: '' + name: dbix_class_deploymenthandler_versions_version + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + ddl: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ddl + order: 3 + size: + - 0 + id: + data_type: int + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + upgrade_sql: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: upgrade_sql + order: 4 + size: + - 0 + version: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: version + order: 2 + size: + - 50 + indices: [] + name: dbix_class_deploymenthandler_versions + options: [] + order: 1 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - __VERSION + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/share/ddl/_source/deploy/4/001-auto.yml b/share/ddl/_source/deploy/4/001-auto.yml new file mode 100644 index 0000000..1e6bb7e --- /dev/null +++ b/share/ddl/_source/deploy/4/001-auto.yml @@ -0,0 +1,1247 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + administrators: + constraints: + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: administrators_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: user_id + order: 1 + size: + - 0 + indices: [] + name: administrators + options: [] + order: 7 + customers: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 2 + size: + - 255 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 3 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 4 + size: + - 0 + indices: [] + name: customers + options: [] + order: 2 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 8 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 5 + leaderboard_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - user_id + - set_id + match_type: '' + name: leaderboard_values_user_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: leaderboard_values_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: user_id + order: 2 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 16 + - 2 + indices: + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + - fields: + - user_id + name: leaderboard_values_idx_user_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 13 + leaderboards: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 3 + organisations: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 3 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 4 + size: + - 255 + indices: [] + name: organisations + options: [] + order: 4 + pending_organisations: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - submitted_by_id + match_type: '' + name: pending_organisations_fk_submitted_by_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 5 + size: + - 16 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 7 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 6 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 4 + size: + - 255 + indices: + - fields: + - submitted_by_id + name: pending_organisations_idx_submitted_by_id + options: [] + type: NORMAL + name: pending_organisations + options: [] + order: 9 + pending_transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: pending_transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: pending_transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: pending_organisations + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 16 + - 2 + indices: + - fields: + - buyer_id + name: pending_transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: pending_transactions_idx_seller_id + options: [] + type: NORMAL + name: pending_transactions + options: [] + order: 12 + session_tokens: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 10 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: decimal + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 16 + - 2 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 11 + users: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - customer_id + match_type: '' + name: users_customer_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - organisation_id + match_type: '' + name: users_organisation_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - customer_id + match_type: '' + name: users_fk_customer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: customers + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - organisation_id + match_type: '' + name: users_fk_organisation_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + customer_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: customer_id + order: 2 + size: + - 0 + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 5 + size: + - 0 + organisation_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: organisation_id + order: 3 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 6 + size: + - 100 + indices: + - fields: + - customer_id + name: users_idx_customer_id + options: [] + type: NORMAL + - fields: + - organisation_id + name: users_idx_organisation_id + options: [] + type: NORMAL + name: users + options: [] + order: 6 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Administrator + - Customer + - Feedback + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - PendingOrganisation + - PendingTransaction + - SessionToken + - Transaction + - User + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/t/api/search.t b/t/api/search.t index 320bf1a..ada3c0a 100644 --- a/t/api/search.t +++ b/t/api/search.t @@ -29,13 +29,13 @@ print "test 1 - Create customer user account (Rufus)\n"; my $emailRufus = 'rufus@shinra.energy'; my $passwordRufus = 'MakoGold'; my $testJson = { - 'usertype' => 'customer', - 'token' => shift(@account_tokens), - 'full_name' => 'RufusShinra', - 'display_name' => 'RufusShinra', - 'email' => $emailRufus, - 'postcode' => 'RG26 5NU', - 'password' => $passwordRufus, + 'usertype' => 'customer', + 'token' => shift(@account_tokens), + 'full_name' => 'RufusShinra', + 'display_name' => 'RufusShinra', + 'email' => $emailRufus, + 'postcode' => 'RG26 5NU', + 'password' => $passwordRufus, 'year_of_birth' => 2006 }; $t->post_ok('/api/register' => json => $testJson) @@ -47,17 +47,17 @@ print "test 2 - Create organisation user account (Choco Billy)\n"; my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { - 'usertype' => 'organisation', - 'token' => shift(@account_tokens), - 'name' => 'ChocoBillysGreens', - 'email' => $emailBilly, - 'postcode' => 'LA1 1HT', - 'password' => $passwordBilly, + 'usertype' => 'organisation', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', + 'email' => $emailBilly, + 'postcode' => 'LA1 1HT', + 'password' => $passwordBilly, 'street_name' => 'Market St', 'town' => 'Lancaster', }; $t->post_ok('/api/register' => json => $testJson) - ->status_is(200) + ->status_is(200) ->json_is('/success', Mojo::JSON->true); my $session_key; @@ -106,6 +106,7 @@ my $json = { street_name => "2 James St", town => "Lancaster", postcode => "LA1 1UP", + purchase_time => "2017-08-14T11:29:07.965+01:00", session_key => $session_key, }; my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -133,6 +134,7 @@ $json = { street_name => "The Crescent", town => "Morecambe", postcode => "LA4 5BZ", + purchase_time => "2017-08-14T11:29:07.965+01:00", session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -148,6 +150,7 @@ $json = { street_name => "63-65 Church Street", town => "Lancaster", postcode => "LA1 1ET", + purchase_time => "2017-08-14T11:29:07.965+01:00", session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -180,7 +183,7 @@ sub check_vars{ ->json_has("validated"); my $sessionJsonTest = $t->tx->res->json; - my $validated = $sessionJsonTest->{validated}; + my $validated = $sessionJsonTest->{validated}; my $unvalidated = $sessionJsonTest->{unvalidated}; my $validSize = scalar @$validated; @@ -188,7 +191,7 @@ sub check_vars{ is $validSize,$numValidated,"validated returned - " . $searchTerm; is $unvalidSize,$numUnvalidated,"unvalidated returned - " . $searchTerm; - + }; print "test 11 - search blank\n"; diff --git a/t/api/stats.t b/t/api/stats.t index 57ce15a..d12bcbe 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -73,7 +73,7 @@ for ( 11 .. 20 ) { seller_id => $org_result->id, value => $_, proof_image => 'a', - submitted_at => $dtf->format_datetime(DateTime->today()->subtract( days => 5 )), + purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 5 )), }); } @@ -82,7 +82,7 @@ for ( 21 .. 30 ) { seller_id => $org_result->id, value => $_, proof_image => 'a', - submitted_at => $dtf->format_datetime(DateTime->today()->subtract( days => 25 )), + purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 25 )), }); } @@ -91,7 +91,7 @@ for ( 31 .. 40 ) { seller_id => $org_result->id, value => $_, proof_image => 'a', - submitted_at => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), + purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), }); } @@ -100,12 +100,12 @@ for ( 41 .. 50 ) { seller_id => $org_result->id, value => $_, proof_image => 'a', - submitted_at => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), + purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), }); } is $user_result->transactions->search({ - submitted_at => { + purchase_time => { -between => [ $dtf->format_datetime(DateTime->today()), $dtf->format_datetime(DateTime->today()->add( days => 1 )), diff --git a/t/api/stats_leaderboards.t b/t/api/stats_leaderboards.t index 11f366e..3b494ff 100644 --- a/t/api/stats_leaderboards.t +++ b/t/api/stats_leaderboards.t @@ -87,7 +87,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 9, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -104,7 +104,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 1, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -121,7 +121,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 5, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -138,7 +138,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 3, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -154,7 +154,7 @@ sub test_leaderboard { my $leaderboard_rs = $schema->resultset('Leaderboard'); $leaderboard_rs->create_new( $name, $date ); - + $t->post_ok('/api/stats/leaderboard' => json => { session_key => $session_key, type => $name } ) ->status_is(200) ->or($framework->dump_error) diff --git a/t/api/upload.t b/t/api/upload.t index b3a0a19..0cac28b 100644 --- a/t/api/upload.t +++ b/t/api/upload.t @@ -16,6 +16,9 @@ $schema->resultset('AccountToken')->populate([ map { [ $_ ] } @account_tokens, ]); +#Add a test purchase_time to use for receipt uploading. +my $test_purchase_time = "2017-08-14T11:29:07.965+01:00"; + #Add one company that we've apparently authenticated but does not have an account. my $org_id_shinra = 1; @@ -36,13 +39,13 @@ print "test 1 - Create customer user account (Rufus)\n"; my $emailRufus = 'rufus@shinra.energy'; my $passwordRufus = 'MakoGold'; my $testJson = { - 'usertype' => 'customer', - 'token' => shift(@account_tokens), - 'full_name' => 'RufusShinra', - 'display_name' => 'RufusShinra', - 'email' => $emailRufus, - 'postcode' => 'GU10 5SA', - 'password' => $passwordRufus, + 'usertype' => 'customer', + 'token' => shift(@account_tokens), + 'full_name' => 'RufusShinra', + 'display_name' => 'RufusShinra', + 'email' => $emailRufus, + 'postcode' => 'GU10 5SA', + 'password' => $passwordRufus, 'year_of_birth' => 2006 }; $t->post_ok('/api/register' => json => $testJson) @@ -53,13 +56,13 @@ print "test 2 - Create customer user account (Hojo)\n"; my $emailHojo = 'hojo@shinra.energy'; my $passwordHojo = 'Mako'; $testJson = { - 'usertype' => 'customer', - 'token' => shift(@account_tokens), - 'display_name' => 'ProfessorHojo', - 'full_name' => 'ProfessorHojo', - 'email' => $emailHojo, - 'postcode' => 'DE15 9LT', - 'password' => $passwordHojo, + 'usertype' => 'customer', + 'token' => shift(@account_tokens), + 'display_name' => 'ProfessorHojo', + 'full_name' => 'ProfessorHojo', + 'email' => $emailHojo, + 'postcode' => 'DE15 9LT', + 'password' => $passwordHojo, 'year_of_birth' => 2006 }; $t->post_ok('/api/register' => json => $testJson) @@ -70,17 +73,17 @@ print "test 3 - Create organisation user account (Choco Billy)\n"; my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { - 'usertype' => 'organisation', - 'token' => shift(@account_tokens), - 'name' => 'ChocoBillysGreens', - 'email' => $emailBilly, - 'postcode' => 'SO50 7NJ', - 'password' => $passwordBilly, + 'usertype' => 'organisation', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', + 'email' => $emailBilly, + 'postcode' => 'SO50 7NJ', + 'password' => $passwordBilly, 'street_name' => 'Chocobo Farm, Eastern Continent', 'town' => 'Gaia', }; $t->post_ok('/api/register' => json => $testJson) - ->status_is(200) + ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Registered Successfully/); @@ -110,6 +113,7 @@ $t->post_ok('/api/upload' => form => $upload ) print "test 6 - transaction_value missing\n"; my $json = { transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -123,6 +127,7 @@ print "test 7 - transaction_value non-numbers\n"; $json = { transaction_value => 'Abc', transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -136,6 +141,7 @@ print "test 8 - transaction_value equal to zero\n"; $json = { transaction_value => 0, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -149,6 +155,7 @@ print "test 9 - transaction_value less than zero\n"; $json = { transaction_value => -1, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -161,6 +168,7 @@ $t->post_ok('/api/upload' => form => $upload ) print "test 10 - transaction_type missing\n"; $json = { transaction_value => 10, + purchase_time => $test_purchase_time, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -173,6 +181,7 @@ print "test 11 - transaction_type invalid.\n"; $json = { transaction_value => 10, transaction_type => 4, + purchase_time => $test_purchase_time, session_key => $session_key, # organisation_id => $org_id_shinra }; @@ -186,6 +195,7 @@ print "test 12 - file not uploaded.\n"; $json = { transaction_value => 10, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => 1, session_key => $session_key, }; @@ -199,6 +209,7 @@ print "test 13 - organisation_id missing (type 1: already validated)\n"; $json = { transaction_value => 10, transaction_type => 1, + purchase_time => $test_purchase_time, session_key => $session_key, # organisation_id => $org_id_shinra }; @@ -212,6 +223,7 @@ print "test 14 - organisation_id for non-existent id. (type 1: already validated $json = { transaction_value => 10, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => ($org_id_shinra + 100), session_key => $session_key, }; @@ -226,6 +238,7 @@ is $schema->resultset('Transaction')->count, 0, "no transactions"; $json = { transaction_value => 10, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -242,6 +255,7 @@ print "test 16 - organsation missing (type 3: new organisation)\n"; $json = { transaction_value => 10, transaction_type => 3, + purchase_time => $test_purchase_time, street_name => "Slums, Sector 7", town => "Midgar", postcode => "E1 0AA", @@ -260,6 +274,7 @@ is $schema->resultset('PendingTransaction')->count, 0, "No pending transactions" $json = { transaction_value => 10, transaction_type => 3, + purchase_time => $test_purchase_time, organisation_name => '7th Heaven', street_name => "Slums, Sector 7", town => "Midgar", @@ -280,6 +295,7 @@ print "test 18 - organisation_id missing (type 2: existing organisation)\n"; $json = { transaction_value => 10, transaction_type => 2, + purchase_time => $test_purchase_time, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -292,6 +308,7 @@ print "test 19 - organisation_id not a number (type 2: existing organisation)\n" $json = { transaction_value => 10, transaction_type => 2, + purchase_time => $test_purchase_time, organisation_id => "Abc", session_key => $session_key, }; @@ -305,6 +322,7 @@ print "test 20 - id does not exist (type 2: existing organisation)\n"; $json = { transaction_value => 10, transaction_type => 2, + purchase_time => $test_purchase_time, organisation_id => 1000, #Id that does not exist session_key => $session_key, }; @@ -314,7 +332,20 @@ $t->post_ok('/api/upload' => form => $upload ) ->json_is('/success', Mojo::JSON->false) ->content_like(qr/organisation_id does not exist in the database/i); -print "test 21 - Logout Rufus (type 2: existing organisation)\n"; +print "test 21 - purchase_time is missing\n"; +is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; +$json = { + transaction_value => 10, + transaction_type => 2, + organisation_id => $org_id_shinra, + session_key => $session_key, +}; +$upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; +$t->post_ok('/api/upload' => form => $upload ) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +print "test 22 - Logout Rufus (type 2: existing organisation)\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); @@ -325,7 +356,7 @@ $t->post_ok('/api/logout', json => { session_key => $session_key } ) #Login as Hojo (customer) -print "test 22 - Login Hojo (cookies, customer)\n"; +print "test 23 - Login Hojo (cookies, customer)\n"; $testJson = { 'email' => $emailHojo, 'password' => $passwordHojo, @@ -335,24 +366,25 @@ $t->post_ok('/api/login' => json => $testJson) ->json_is('/success', Mojo::JSON->true); $session_key = $t->tx->res->json('/session_key'); -print "test 23 - add valid transaction but for with account (type 2: existing organisation)\n"; +print "test 24 - add valid transaction but for with account (type 2: existing organisation)\n"; my $org_result = $schema->resultset('PendingOrganisation')->find({ name => '7th Heaven' }); my $unvalidatedOrganisationId = $org_result->id; -is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; +is $schema->resultset('PendingTransaction')->count, 2, "2 pending transactions"; $json = { transaction_value => 10, transaction_type => 2, + purchase_time => $test_purchase_time, organisation_id => $unvalidatedOrganisationId, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) - ->status_is(400) + ->status_is(400) ->json_is('/success', Mojo::JSON->false) ->content_like(qr/organisation_id does not exist in the database/i); -is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; +is $schema->resultset('PendingTransaction')->count, 2, "2 pending transactions"; -print "test 24 - Logout Hojo\n"; +print "test 25 - Logout Hojo\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); @@ -363,7 +395,7 @@ $t->post_ok('/api/logout', json => { session_key => $session_key } ) #Login as Rufus (customer) -print "test 25 - Login Rufus (cookies, customer)\n"; +print "test 26 - Login Rufus (cookies, customer)\n"; $testJson = { 'email' => $emailRufus, 'password' => $passwordRufus, @@ -373,11 +405,12 @@ $t->post_ok('/api/login' => json => $testJson) ->json_is('/success', Mojo::JSON->true); $session_key = $t->tx->res->json('/session_key'); -print "test 26 - add valid transaction (type 2: existing organisation)\n"; -is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; +print "test 27 - add valid transaction (type 2: existing organisation)\n"; +is $schema->resultset('PendingTransaction')->count, 2, "2 pending transactions"; $json = { transaction_value => 10, transaction_type => 2, + purchase_time => $test_purchase_time, organisation_id => $unvalidatedOrganisationId, session_key => $session_key, }; @@ -386,10 +419,10 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Upload Successful/); -is $schema->resultset('PendingTransaction')->count, 2, "2 pending transactions"; +is $schema->resultset('PendingTransaction')->count, 3, "3 pending transactions"; -print "test 27 - Logout Rufus\n"; +print "test 28 - Logout Rufus\n"; $t->post_ok('/api/logout' => json => { session_key => $session_key } ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); @@ -400,7 +433,7 @@ $t->post_ok('/api/logout' => json => { session_key => $session_key } ) #Login as Choco Billy (organisation) -print "test 28 - Login Choco Billy (cookies, organisation)\n"; +print "test 29 - Login Choco Billy (cookies, organisation)\n"; $testJson = { 'email' => $emailBilly, 'password' => $passwordBilly, @@ -410,11 +443,12 @@ $t->post_ok('/api/login' => json => $testJson) ->json_is('/success', Mojo::JSON->true); $session_key = $t->tx->res->json('/session_key'); -print "test 29 - organisation buy from another organisation\n"; +print "test 30 - organisation buy from another organisation\n"; is $schema->resultset('Transaction')->count, 1, "1 transaction"; $json = { transaction_value => 100000, transaction_type => 1, + purchase_time => $test_purchase_time, organisation_id => $org_id_shinra, session_key => $session_key, }; @@ -426,4 +460,3 @@ $t->post_ok('/api/upload' => form => $upload ) is $schema->resultset('Transaction')->count, 2, "2 transaction"; done_testing(); - diff --git a/t/api/user.t b/t/api/user.t index 76eb6ee..a848e95 100644 --- a/t/api/user.t +++ b/t/api/user.t @@ -20,7 +20,7 @@ $schema->resultset('AccountToken')->create({ $framework->register_customer({ 'token' => $account_token, 'full_name' => 'Test User', - 'display_name' => 'Test User', + 'display_name' => 'Testing User', 'email' => $email, 'postcode' => 'LA1 1AA', 'password' => $password, @@ -34,7 +34,7 @@ my $session_key = $framework->login({ my $json_no_date = { session_key => $session_key }; $t->post_ok('/api/user/day', json => $json_no_date) - ->status_is(200) + ->status_is(200)->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true); my $json_invalid_date = { @@ -54,4 +54,84 @@ $t->post_ok('/api/user/day', json => $json_valid_date) ->status_is(200)->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true); +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User', + display_name => 'Testing User', + email => $email, + postcode => 'LA1 1AA', + }); + +#with wrong password +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + password => 'abc12431', + }) + ->status_is(401)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->false, + message => 'password is invalid.', + }); + +# With valid details +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + password => $password, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + }); + +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 3', + display_name => 'Testing User 3', + email => 'test60@example.com', + postcode => 'LA1 1AD', + password => $password, + new_password => 'abc124', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User 3', + display_name => 'Testing User 3', + email => 'test60@example.com', + postcode => 'LA1 1AD', + }); + +$session_key = $framework->login({ + email => 'test60@example.com', + password => 'abc124', +}); + done_testing; diff --git a/t/plugins/validators.t b/t/plugins/validators.t index 81c2f02..1bfc5b8 100644 --- a/t/plugins/validators.t +++ b/t/plugins/validators.t @@ -4,6 +4,7 @@ use warnings; use Mojolicious::Lite; use Test::More; +plugin 'Pear::LocalLoop::Plugin::Datetime'; plugin 'Pear::LocalLoop::Plugin::Validators'; my $validator = app->validator; @@ -16,6 +17,8 @@ my $valid_postcode = 'WC1H 9EB'; my $invalid_postcode = 'AB1 2CD'; my $not_a_postcode = 'a'; my $not_a_whole_postcode = 'LA1'; +my $valid_purchase_time = '2017-08-14T11:29:07.965+01:00'; +my $invalid_purchase_time = '2017081411:29:07'; $validation->input({ valid_email => $valid_email, @@ -24,6 +27,8 @@ $validation->input({ invalid_postcode => $invalid_postcode, not_a_postcode => $not_a_postcode, not_a_whole_postcode => $not_a_whole_postcode, + valid_purchase_time => $valid_purchase_time, + invalid_purchase_time => $invalid_purchase_time, }); $validation->required('valid_email')->email; @@ -32,8 +37,10 @@ $validation->required('valid_postcode')->postcode; $validation->required('invalid_postcode')->postcode; $validation->required('not_a_postcode')->postcode; $validation->required('not_a_whole_postcode')->postcode; +$validation->required('valid_purchase_time')->is_full_iso_datetime; +$validation->required('invalid_purchase_time')->is_full_iso_datetime; ok $validation->has_error, 'Have Errors'; -is_deeply $validation->failed, [ qw/ invalid_email invalid_postcode not_a_postcode not_a_whole_postcode / ], 'Correct Errors'; +is_deeply $validation->failed, [ qw/ invalid_email invalid_postcode invalid_purchase_time not_a_postcode not_a_whole_postcode / ], 'Correct Errors'; done_testing; diff --git a/t/schema/leaderboard.t b/t/schema/leaderboard.t index d457f80..9f0e72f 100644 --- a/t/schema/leaderboard.t +++ b/t/schema/leaderboard.t @@ -90,7 +90,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 5 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 5 )), }); } @@ -99,7 +99,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 25 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 25 )), }); } @@ -108,7 +108,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 50 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 50 )), }); } diff --git a/t/schema/leaderboard_trend.t b/t/schema/leaderboard_trend.t index 593b0c2..0674e68 100644 --- a/t/schema/leaderboard_trend.t +++ b/t/schema/leaderboard_trend.t @@ -87,7 +87,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 9, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -104,7 +104,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 1, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -121,7 +121,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 5, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } @@ -138,7 +138,7 @@ my $now = DateTime->today(); seller_id => $org_result->id, value => 3, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 1 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 1 )), }); } diff --git a/t/schema/resultset_leaderboard.t b/t/schema/resultset_leaderboard.t index 77f8c4f..7245283 100644 --- a/t/schema/resultset_leaderboard.t +++ b/t/schema/resultset_leaderboard.t @@ -90,7 +90,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 5 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 5 )), }); } @@ -99,7 +99,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 25 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 25 )), }); } @@ -108,7 +108,7 @@ for my $user ( $user1, $user2, $user3, $user4 ) { seller_id => $org_result->id, value => $_ + $tweak, proof_image => 'a', - submitted_at => $dtf->format_datetime($now->clone->subtract( days => 50 )), + purchase_time => $dtf->format_datetime($now->clone->subtract( days => 50 )), }); } @@ -122,7 +122,7 @@ sub test_leaderboard { my $leaderboard_rs = $schema->resultset('Leaderboard'); $leaderboard_rs->create_new( $name, $date ); - + my $today_board = $leaderboard_rs->get_latest( $name ); is $today_board->values->count, 4, 'correct value count';