made InnoDB explicit, added group balances and modified balance triggers

This commit is contained in:
celso 2026-04-05 12:00:20 -03:00
parent 4ad165f4a7
commit 7f42815f6c
2 changed files with 73 additions and 73 deletions

View File

@ -8,7 +8,7 @@ CREATE TABLE shards (
db_name VARCHAR(50) NOT NULL, db_name VARCHAR(50) NOT NULL,
host_address VARCHAR(255) NOT NULL, host_address VARCHAR(255) NOT NULL,
port INT NOT NULL DEFAULT 53096 port INT NOT NULL DEFAULT 53096
); ) ENGINE=InnoDB;
CREATE TABLE user_shard_map ( CREATE TABLE user_shard_map (
user_id BINARY(16) PRIMARY KEY, user_id BINARY(16) PRIMARY KEY,
@ -19,45 +19,38 @@ CREATE TABLE user_shard_map (
is_active TINYINT(1) NOT NULL DEFAULT 1, is_active TINYINT(1) NOT NULL DEFAULT 1,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (shard_id) REFERENCES shards(shard_id) FOREIGN KEY (shard_id) REFERENCES shards(shard_id)
); ) ENGINE=InnoDB;
CREATE TABLE cost_group_statuses ( CREATE TABLE cost_group_statuses (
status_id TINYINT PRIMARY KEY, status_id TINYINT PRIMARY KEY,
name VARCHAR(20) UNIQUE NOT NULL name VARCHAR(20) UNIQUE NOT NULL
); ) ENGINE=InnoDB;
CREATE TABLE cost_groups ( CREATE TABLE cost_groups (
group_id BINARY(16) PRIMARY KEY, group_id BINARY(16) PRIMARY KEY,
name VARCHAR(100) NOT NULL, name VARCHAR(100) NOT NULL,
created_by BINARY(16), created_by BINARY(16),
status_id TINYINT NOT NULL DEFAULT '1', status_id TINYINT NOT NULL DEFAULT 1,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (created_by) REFERENCES user_shard_map(user_id), FOREIGN KEY (created_by) REFERENCES user_shard_map(user_id),
FOREIGN KEY (status_id) REFERENCES cost_group_statuses(status_id) FOREIGN KEY (status_id) REFERENCES cost_group_statuses(status_id)
); ) ENGINE=InnoDB;
CREATE TABLE group_roles ( CREATE TABLE group_roles (
role_id TINYINT PRIMARY KEY, role_id TINYINT PRIMARY KEY,
name VARCHAR(20) UNIQUE NOT NULL name VARCHAR(20) UNIQUE NOT NULL
); ) ENGINE=InnoDB;
CREATE TABLE group_members ( CREATE TABLE group_members (
group_id BINARY(16), group_id BINARY(16),
user_id BINARY(16), user_id BINARY(16),
role_id TINYINT DEFAULT '3', role_id TINYINT DEFAULT 3,
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (group_id, user_id), PRIMARY KEY (group_id, user_id),
FOREIGN KEY (group_id) REFERENCES cost_groups(group_id), FOREIGN KEY (group_id) REFERENCES cost_groups(group_id),
FOREIGN KEY (role_id) REFERENCES group_roles(role_id), FOREIGN KEY (user_id) REFERENCES user_shard_map(user_id),
FOREIGN KEY (user_id) REFERENCES user_shard_map(user_id) FOREIGN KEY (role_id) REFERENCES group_roles(role_id)
); ) ENGINE=InnoDB;
INSERT INTO cost_group_statuses (status_id, name) VALUES INSERT INTO cost_group_statuses (status_id, name) VALUES (1, 'active'), (2, 'settled'), (3, 'archived');
(1, 'active'), INSERT INTO group_roles (role_id, name) VALUES (1, 'owner'), (2, 'editor'), (3, 'participant');
(2, 'settled'),
(3, 'archived');
INSERT INTO group_roles (role_id, name) VALUES
(1, 'owner'),
(2, 'editor'),
(3, 'participant');

View File

@ -5,88 +5,95 @@ USE argent_shard_01;
CREATE TABLE ledger_statuses ( CREATE TABLE ledger_statuses (
status_id TINYINT PRIMARY KEY, status_id TINYINT PRIMARY KEY,
name VARCHAR(20) UNIQUE NOT NULL name VARCHAR(20) UNIQUE NOT NULL
); ) ENGINE=InnoDB;
CREATE TABLE ledger_entry_types (
type_id TINYINT PRIMARY KEY,
name VARCHAR(20) UNIQUE NOT NULL
) ENGINE=InnoDB;
CREATE TABLE ledger ( CREATE TABLE ledger (
entry_id BINARY(16) NOT NULL, entry_id BINARY(16) NOT NULL,
batch_id BINARY(16) NOT NULL, batch_id BINARY(16) NOT NULL,
user_id BINARY(16) NOT NULL, user_id BINARY(16) NOT NULL,
group_id BINARY(16) DEFAULT NULL, group_id BINARY(16) DEFAULT NULL,
category_id INT,
amount DECIMAL(15, 2) NOT NULL, amount DECIMAL(15, 2) NOT NULL,
currency_code CHAR(3) NOT NULL, currency_code CHAR(3) NOT NULL,
description VARCHAR(255), description VARCHAR(255),
status_id TINYINT DEFAULT '1', status_id TINYINT DEFAULT 1,
type_id TINYINT NOT NULL,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, entry_id), PRIMARY KEY (user_id, entry_id),
FOREIGN KEY (status_id) REFERENCES ledger_statuses(status_id), FOREIGN KEY (status_id) REFERENCES ledger_statuses(status_id),
FOREIGN KEY (type_id) REFERENCES ledger_entry_types(type_id),
INDEX (batch_id), INDEX (batch_id),
INDEX (group_id), INDEX (group_id),
INDEX (status_id) INDEX (status_id)
); ) ENGINE=InnoDB;
CREATE TABLE user_balances ( CREATE TABLE user_balances (
user_id BINARY(16) NOT NULL, user_id BINARY(16) NOT NULL,
currency_code CHAR(3) NOT NULL, currency_code CHAR(3) NOT NULL,
total_confirmed DECIMAL(15, 2) DEFAULT 0.00, total_proposed DECIMAL(15, 2) DEFAULT 0.00,
total_pending DECIMAL(15, 2) DEFAULT 0.00, total_ratified DECIMAL(15, 2) DEFAULT 0.00,
total_disputed DECIMAL(15, 2) DEFAULT 0.00,
total_settled DECIMAL(15, 2) DEFAULT 0.00,
total_spent DECIMAL(15, 2) DEFAULT 0.00,
PRIMARY KEY (user_id, currency_code) PRIMARY KEY (user_id, currency_code)
); ) ENGINE=InnoDB;
INSERT INTO ledger_statuses (status_id, name) VALUES CREATE TABLE group_user_balances (
(1, 'proposed'), group_id BINARY(16) NOT NULL,
(2, 'ratified'), user_id BINARY(16) NOT NULL,
(3, 'disputed'), currency_code CHAR(3) NOT NULL,
(4, 'settled'); net_balance DECIMAL(15, 2) DEFAULT 0.00,
total_contributed DECIMAL(15, 2) DEFAULT 0.00,
PRIMARY KEY (group_id, user_id, currency_code),
INDEX (user_id)
) ENGINE=InnoDB;
INSERT INTO ledger_statuses (status_id, name) VALUES (1, 'proposed'), (2, 'ratified'), (3, 'disputed'), (4, 'settled');
INSERT INTO ledger_entry_types (type_id, name) VALUES (1, 'expense'), (2, 'settlement');
DELIMITER // DELIMITER //
CREATE TRIGGER after_ledger_insert CREATE PROCEDURE sync_all_balances(
AFTER INSERT ON ledger IN p_uid BINARY(16),
FOR EACH ROW IN p_gid BINARY(16),
IN p_curr CHAR(3),
IN p_amt DECIMAL(15,2),
IN p_status TINYINT,
IN p_type TINYINT,
IN p_mod INT
)
BEGIN BEGIN
IF NEW.status_id = 1 THEN INSERT INTO user_balances (user_id, currency_code) VALUES (p_uid, p_curr)
UPDATE user_balances ON DUPLICATE KEY UPDATE user_id = user_id;
SET total_pending = total_pending + NEW.amount UPDATE user_balances SET
WHERE user_id = NEW.user_id AND currency_code = NEW.currency_code; total_proposed = total_proposed + IF(p_status = 1, p_amt * p_mod, 0),
ELSEIF NEW.status_id IN (2, 4) THEN total_ratified = total_ratified + IF(p_status = 2, p_amt * p_mod, 0),
UPDATE user_balances total_disputed = total_disputed + IF(p_status = 3, p_amt * p_mod, 0),
SET total_confirmed = total_confirmed + NEW.amount total_settled = total_settled + IF(p_status = 4, p_amt * p_mod, 0),
WHERE user_id = NEW.user_id AND currency_code = NEW.currency_code; total_spent = total_spent + IF(p_type = 1 AND p_amt > 0, p_amt * p_mod, 0)
WHERE user_id = p_uid AND currency_code = p_curr;
IF p_gid IS NOT NULL THEN
INSERT INTO group_user_balances (group_id, user_id, currency_code, net_balance, total_contributed)
VALUES (p_gid, p_uid, p_curr, p_amt * p_mod, IF(p_type = 1 AND p_amt > 0, p_amt * p_mod, 0))
ON DUPLICATE KEY UPDATE
net_balance = net_balance + (p_amt * p_mod),
total_contributed = total_contributed + IF(p_type = 1 AND p_amt > 0, p_amt * p_mod, 0);
END IF; END IF;
END // END //
CREATE TRIGGER after_ledger_update CREATE TRIGGER after_ledger_insert AFTER INSERT ON ledger FOR EACH ROW
AFTER UPDATE ON ledger
FOR EACH ROW
BEGIN BEGIN
IF OLD.status_id = 1 THEN CALL sync_all_balances(NEW.user_id, NEW.group_id, NEW.currency_code, NEW.amount, NEW.status_id, NEW.type_id, 1);
UPDATE user_balances SET total_pending = total_pending - OLD.amount
WHERE user_id = OLD.user_id AND currency_code = OLD.currency_code;
ELSEIF OLD.status_id IN (2, 4) THEN
UPDATE user_balances SET total_confirmed = total_confirmed - OLD.amount
WHERE user_id = OLD.user_id AND currency_code = OLD.currency_code;
END IF;
IF NEW.status_id = 1 THEN
UPDATE user_balances SET total_pending = total_pending + NEW.amount
WHERE user_id = NEW.user_id AND currency_code = NEW.currency_code;
ELSEIF NEW.status_id IN (2, 4) THEN
UPDATE user_balances SET total_confirmed = total_confirmed + NEW.amount
WHERE user_id = NEW.user_id AND currency_code = NEW.currency_code;
END IF;
END // END //
CREATE TRIGGER after_ledger_delete CREATE TRIGGER after_ledger_update AFTER UPDATE ON ledger FOR EACH ROW
AFTER DELETE ON ledger
FOR EACH ROW
BEGIN BEGIN
IF OLD.status_id = 1 THEN CALL sync_all_balances(OLD.user_id, OLD.group_id, OLD.currency_code, OLD.amount, OLD.status_id, OLD.type_id, -1);
UPDATE user_balances SET total_pending = total_pending - OLD.amount CALL sync_all_balances(NEW.user_id, NEW.group_id, NEW.currency_code, NEW.amount, NEW.status_id, NEW.type_id, 1);
WHERE user_id = OLD.user_id AND currency_code = OLD.currency_code; END //
ELSEIF OLD.status_id IN (2, 4) THEN CREATE TRIGGER after_ledger_delete AFTER DELETE ON ledger FOR EACH ROW
UPDATE user_balances SET total_confirmed = total_confirmed - OLD.amount BEGIN
WHERE user_id = OLD.user_id AND currency_code = OLD.currency_code; CALL sync_all_balances(OLD.user_id, OLD.group_id, OLD.currency_code, OLD.amount, OLD.status_id, OLD.type_id, -1);
END IF;
END // END //
DELIMITER ; DELIMITER ;