Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .kanelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
},
preDeleteOutputFolder: true,
outputPath: "./src/types/db_internal",

enumStyle: "type",
// Postgres bigints are mapped to JS bigints
customTypeMap: {
"pg_catalog.int8": "bigint"
Expand Down
14 changes: 9 additions & 5 deletions database/init/0_init_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,37 @@ CREATE TABLE item_box (
CREATE TABLE transaction (
transaction_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
total BIGINT NOT NULL CONSTRAINT nonneg_total CHECK (total >= 0),
transaction_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- auto create transaction timestamp
payer_email TEXT CHECK (payer_email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$')
tax_rate INT NOT NULL CONSTRAINT nonneg_tax_rate CHECK (tax_rate >= 0), -- represents a tax percent with 2 decimal points precision (ex. 10.25% -> 1025)
transaction_time NOT NULL TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- auto create transaction timestamp
payer_email NOT NULL TEXT CHECK (payer_email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$'),
payment_method NOT NULL TEXT CHECK (payment_method IN ('cash', 'card')),
cleared BOOL NOT NULL DEFAULT FALSE
);

CREATE TABLE transaction_item (
transaction_id INT NOT NULL REFERENCES transaction ON UPDATE CASCADE ON DELETE CASCADE, -- if we delete a transaction, also delete its details
item_id INT NOT NULL REFERENCES item_individual ON UPDATE CASCADE ON DELETE RESTRICT, -- don't allow an item that's in a transaction to be deleted
item_quantity INT NOT NULL CONSTRAINT positive_quantity CHECK (item_quantity > 0),
item_price BIGINT NOT NULL CONSTRAINT nonneg_price CHECK (item_price >= 0),
CONSTRAINT transaction_item_pk PRIMARY KEY (transaction_id, item_id)
);

CREATE TABLE csss_user (
user_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_id uuid PRIMARY KEY GENERATED ALWAYS AS gen_random_uuid() STORED,
email TEXT NOT NULL UNIQUE CHECK (email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$'),
password TEXT NOT NULL, -- should be a hash
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
phone_number VARCHAR(10) CHECK (phone_number ~ '^[0-9]{10}$'),
is_treasurer BOOL DEFAULT FALSE
is_treasurer BOOL NOT NULL DEFAULT FALSE
);

CREATE TABLE reimbursement (
reimbursement_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
receipt_img_url TEXT NOT NULL,
purchase_total BIGINT NOT NULL CONSTRAINT positive_purchase_total CHECK (purchase_total > 0),
purchase_date DATE NOT NULL,
reimbursed BOOL DEFAULT FALSE,
reimbursed BOOL NOT NULL DEFAULT FALSE,
user_id INT NOT NULL REFERENCES csss_user ON UPDATE CASCADE ON DELETE RESTRICT -- don't allow an officer to be deleted if they have reimbursements
);

Expand Down
18 changes: 12 additions & 6 deletions database/init_test/0_init_test_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,43 @@ CREATE TABLE item_box (
quantity_per_box INT NOT NULL CONSTRAINT pos_quantity CHECK (quantity_per_box > 0)
);

CREATE TYPE payment_method_type AS ENUM ('cash', 'card');

CREATE TABLE transaction (
transaction_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
total BIGINT NOT NULL CONSTRAINT nonneg_total CHECK (total >= 0),
transaction_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- auto create transaction timestamp
payer_email TEXT CHECK (payer_email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$')
tax_rate INT NOT NULL CONSTRAINT nonneg_tax_rate CHECK (tax_rate >= 0), -- represents a tax percent with 2 decimal points precision (ex. 10.25% -> 1025)
transaction_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- auto create transaction timestamp
payer_email TEXT NOT NULL CHECK (payer_email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$'),
payment_method payment_method_type NOT NULL,
cleared BOOL NOT NULL DEFAULT FALSE
);

CREATE TABLE transaction_item (
transaction_id INT NOT NULL REFERENCES transaction ON UPDATE CASCADE ON DELETE CASCADE, -- if we delete a transaction, also delete its details
item_id INT NOT NULL REFERENCES item_individual ON UPDATE CASCADE ON DELETE RESTRICT, -- don't allow an item that's in a transaction to be deleted
item_quantity INT NOT NULL CONSTRAINT positive_quantity CHECK (item_quantity > 0),
item_price BIGINT NOT NULL CONSTRAINT nonneg_price CHECK (item_price >= 0),
CONSTRAINT transaction_item_pk PRIMARY KEY (transaction_id, item_id)
);

CREATE TABLE csss_user (
user_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL UNIQUE CHECK (email ~ '^[a-z0-9!.#$%&''*+/=?^_`{|}~-]+@([a-z0-9]+[.])+[a-z0-9]+$'),
password TEXT NOT NULL, -- should be a hash
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
phone_number VARCHAR(10) CHECK (phone_number ~ '^[0-9]{10}$'),
is_treasurer BOOL DEFAULT FALSE
is_treasurer BOOL NOT NULL DEFAULT FALSE
);

CREATE TABLE reimbursement (
reimbursement_id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
receipt_img_url TEXT NOT NULL,
purchase_total BIGINT NOT NULL CONSTRAINT positive_purchase_total CHECK (purchase_total > 0),
purchase_date DATE NOT NULL,
reimbursed BOOL DEFAULT FALSE,
user_id INT NOT NULL REFERENCES csss_user ON UPDATE CASCADE ON DELETE RESTRICT -- don't allow an officer to be deleted if they have reimbursements
reimbursed BOOL NOT NULL DEFAULT FALSE,
user_id uuid NOT NULL REFERENCES csss_user ON UPDATE CASCADE ON DELETE RESTRICT -- don't allow an officer to be deleted if they have reimbursements
);

CREATE TABLE reimbursement_item_box (
Expand Down
25 changes: 16 additions & 9 deletions database/init_test/1_add_test_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -90,46 +90,50 @@ WHERE
name = 'Coca-Cola';

INSERT INTO
transaction (total, transaction_time, payer_email)
transaction (total, tax_rate, transaction_time, payer_email, payment_method, cleared)
VALUES
(400, '2024-01-10 14:00:36 -8:00', 'john@example.com'),
(200, '2024-01-21 10:21:11 -8:00', 'amy@example.com');
(448, 1200, '2024-01-10 14:00:36 -8:00', 'john@example.com', 'card', TRUE),
(110, 1025, '2024-01-21 10:21:11 -8:00', 'amy@example.com', 'cash', FALSE);

INSERT INTO
transaction_item (transaction_id, item_id, item_quantity)
transaction_item (transaction_id, item_id, item_quantity, item_price)
SELECT
1,
item_id,
1
1,
300
FROM
item_individual
WHERE
name = 'Shin Ramen';

INSERT INTO
transaction_item (transaction_id, item_id, item_quantity)
transaction_item (transaction_id, item_id, item_quantity, item_price)
SELECT
1,
item_id,
1
1,
100
FROM
item_individual
WHERE
name = 'Coca-Cola';

INSERT INTO
transaction_item (transaction_id, item_id, item_quantity)
transaction_item (transaction_id, item_id, item_quantity, item_price)
SELECT
2,
item_id,
1
1,
100
FROM
item_individual
WHERE
name = 'Clif Bar';

INSERT INTO
csss_user (
user_id,
email,
password,
first_name,
Expand All @@ -139,6 +143,7 @@ INSERT INTO
)
VALUES
(
'44b309da-c186-4cb4-a7a2-5b4a47276fab',
'jane@ubccsss.org',
'hash1',
'Jane',
Expand All @@ -147,6 +152,7 @@ VALUES
FALSE
),
(
'74c4d25d-49eb-4ab9-86e3-dd4d313f190c',
'george@ubccsss.org',
'hash2',
'George',
Expand All @@ -155,6 +161,7 @@ VALUES
FALSE
),
(
'cb4ec76c-43b1-48a5-bb1a-b5da8c02a473',
'al@ubccsss.org',
'hash3',
'Al',
Expand Down
Binary file modified design/database/database_schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified design/database/test_data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 24 additions & 1 deletion src/db/queries/TransactionQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ class TransactionQuery extends SimpleCrudQueryable<
return Promise.all(queryResponse.rows.map(async (row) => this.getFriendlyTransaction(row)));
}

/**
* Searches for all transactions that have cleared payment.
* @returns Promise resolving to all cleared transactions in the table
*/
public async readAllCleared(): Promise<FriendlyTransaction[]> {
const queryResponse = await DB.query(
`SELECT * FROM ${this.tableName} WHERE cleared IS TRUE`
);
return Promise.all(queryResponse.rows.map(async (row) => this.getFriendlyTransaction(row)));
}

/**
* Searches for all transactions that have not cleared payment.
* @returns Promise resolving to all non-cleared transactions in the table
*/
public async readAllNotCleared(): Promise<FriendlyTransaction[]> {
const queryResponse = await DB.query(
`SELECT * FROM ${this.tableName} WHERE cleared IS NOT TRUE`
);
return Promise.all(queryResponse.rows.map(async (row) => this.getFriendlyTransaction(row)));
}

private async getFriendlyTransaction(transaction: Transaction): Promise<FriendlyTransaction> {
if (!transaction) {
return null;
Expand All @@ -59,7 +81,8 @@ class TransactionQuery extends SimpleCrudQueryable<
items: items.map((item) => {
return {
item_id: item.item_id,
item_quantity: item.item_quantity
item_quantity: item.item_quantity,
item_price: item.item_price
};
})
};
Expand Down
13 changes: 9 additions & 4 deletions src/types/db_internal/public/CsssUser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Identifier type for csss_user */
export type UserId = number & {__flavor?: "UserId"};
export type UserId = string & {__flavor?: "UserId"};

/** Represents the table public.csss_user */
export default interface CsssUser {
Expand All @@ -15,11 +15,14 @@ export default interface CsssUser {

phone_number: string | null;

is_treasurer: boolean | null;
is_treasurer: boolean;
}

/** Represents the initializer for the table public.csss_user */
export interface CsssUserInitializer {
// /** Default value: gen_random_uuid() */
// user_id?: UserId;

email: string;

password: string;
Expand All @@ -31,11 +34,13 @@ export interface CsssUserInitializer {
phone_number?: string | null;

/** Default value: false */
is_treasurer?: boolean | null;
is_treasurer?: boolean;
}

/** Represents the mutator for the table public.csss_user */
export interface CsssUserMutator {
user_id?: UserId;

email?: string;

password?: string;
Expand All @@ -46,6 +51,6 @@ export interface CsssUserMutator {

phone_number?: string | null;

is_treasurer?: boolean | null;
is_treasurer?: boolean;
}

7 changes: 7 additions & 0 deletions src/types/db_internal/public/PaymentMethodType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** Represents the enum public.payment_method_type */
type PaymentMethodType =
| "cash"
| "card";

export default PaymentMethodType;

6 changes: 3 additions & 3 deletions src/types/db_internal/public/Reimbursement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default interface Reimbursement {

purchase_date: Date;

reimbursed: boolean | null;
reimbursed: boolean;

user_id: UserId;
}
Expand All @@ -27,7 +27,7 @@ export interface ReimbursementInitializer {
purchase_date: Date;

/** Default value: false */
reimbursed?: boolean | null;
reimbursed?: boolean;

user_id: UserId;
}
Expand All @@ -40,7 +40,7 @@ export interface ReimbursementMutator {

purchase_date?: Date;

reimbursed?: boolean | null;
reimbursed?: boolean;

user_id?: UserId;
}
Expand Down
33 changes: 27 additions & 6 deletions src/types/db_internal/public/Transaction.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {type default as PaymentMethodType} from "./PaymentMethodType";

/** Identifier type for transaction */
export type TransactionId = number & {__flavor?: "TransactionId"};

Expand All @@ -7,27 +9,46 @@ export default interface Transaction {

total: bigint;

transaction_time: Date | null;
tax_rate: number;

transaction_time: Date;

payer_email: string;

payer_email: string | null;
payment_method: PaymentMethodType;

cleared: boolean;
}

/** Represents the initializer for the table public.transaction */
export interface TransactionInitializer {
total: bigint;

tax_rate: number;

/** Default value: CURRENT_TIMESTAMP */
transaction_time?: Date | null;
transaction_time?: Date;

payer_email?: string | null;
payer_email: string;

payment_method: PaymentMethodType;

/** Default value: false */
cleared?: boolean;
}

/** Represents the mutator for the table public.transaction */
export interface TransactionMutator {
total?: bigint;

transaction_time?: Date | null;
tax_rate?: number;

transaction_time?: Date;

payer_email?: string;

payment_method?: PaymentMethodType;

payer_email?: string | null;
cleared?: boolean;
}

6 changes: 6 additions & 0 deletions src/types/db_internal/public/TransactionItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default interface TransactionItem {
item_id: ItemId;

item_quantity: number;

item_price: bigint;
}

/** Represents the initializer for the table public.transaction_item */
Expand All @@ -17,6 +19,8 @@ export interface TransactionItemInitializer {
item_id: ItemId;

item_quantity: number;

item_price: bigint;
}

/** Represents the mutator for the table public.transaction_item */
Expand All @@ -26,5 +30,7 @@ export interface TransactionItemMutator {
item_id?: ItemId;

item_quantity?: number;

item_price?: bigint;
}

Loading