Sistema comercial
Banco de dados
Eu tenho como objetivo uma aplicação que possa ser acessada remotamente, a partir de um servidor, e que possa ser utilizado pelo usuário mesmo quando ele não tiver conexão com o servidor. Para isso preciso pensar em um banco de dados utilizando Asynchronous Multimaster Replication. Como essa solução necessita de uma forma de resolução de conflitos, será preciso bolar um sistema que limite os tipos de conflitos. Uma das ideias, seria armazenar todas as alterações e aplicá-las para obter a versão mais recente de cada entrada.
Dessa forma, nenhuma entrada do bando de dados seria modificada, assim prevenindo a perda de alterações quando houver sincronização do banco de dados com o servidor. Por exemplo, utilizando uma tabela para armazenar a chave primaria do item, e uma com os campos dos itens.
ID | Some other relevant immutable data |
---|---|
123 | |
456 |
Dados:
TS | ID | d1 | d2 | d3 | d4 |
---|---|---|---|---|---|
1 | 123 | A | B | null | null |
2 | 123 | null | D | C | null |
3 | 123 | E | null | null | null |
Será equivalente a:
ID | d1 | d2 | d3 | d4 |
---|---|---|---|---|
123 | E | D | C | null |
456 | E | null | null | null |
Autenticação
Como esquema de autenticação, entre o cliente e o servidor, será utilizado mTLS. Assim, a autenticação ficara a cargo do ambiente em que o cliente será executado.
O servidor possuirá um hostname que suporta as operações que não necessitem de autenticação sem solicitar a autenticação mTLS ao cliente.
Orçamento
Exemplos dos dados para orçamento:
CREATE TABLE invoice_id
(
id TEXT PRIMARY KEY
) WITHOUT ROWID;
CREATE TABLE invoice_list
(
list_id TEXT,
idx INTEGER NOT NULL,
description TEXT NOT NULL,
count REAL NOT NULL,
unit_price REAL NOT NULL,
PRIMARY KEY (list_id, idx)
) WITHOUT ROWID;
CREATE TABLE invoice
(
id TEXT,
sequene TEXT, --used to sort, likeley time based like UUIDv7
client TEXT NULL,
note TEXT NULL,
list TEXT,
FOREIGN KEY (id) REFERENCES invoice_id (id),
FOREIGN KEY (list) REFERENCES invoice_list (list_id),
PRIMARY KEY (id, sequene)
) WITHOUT ROWID;
Query para obter a última versão do orçamento:
WITH current AS (SELECT * FROM invoice WHERE id = 'asd')
SELECT (SELECT client FROM current WHERE client IS NOT NULL ORDER BY sequence DESC LIMIT 1) as client,
(SELECT note FROM current WHERE note IS NOT NULL ORDER BY sequence DESC LIMIT 1) as note,
(SELECT list FROM current WHERE list IS NOT NULL ORDER BY sequence DESC LIMIT 1) as list;
SELECT *
FROM invoice_list
WHERE list_id = (SELECT list FROM invoice WHERE list AND id = 'asd' IS NOT NULL ORDER BY sequence DESC LIMIT 1);