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.

IDSome other relevant immutable data
123
456

Dados:

TSIDd1d2d3d4
1123ABnullnull
2123nullDCnull
3123Enullnullnull

Será equivalente a:

IDd1d2d3d4
123EDCnull
456Enullnullnull

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);