This commit is contained in:
parent
aa2327ff1d
commit
2fa6e70af1
10 changed files with 619 additions and 20 deletions
|
|
@ -8,10 +8,12 @@ No permission is granted to copy, modify, distribute, or create derivative works
|
|||
|
||||
// Order storage: an append-only JSON-lines event log.
|
||||
//
|
||||
// Two event types share the file:
|
||||
// Four event types share the file:
|
||||
//
|
||||
// {"type":"order", ...full record...} written once, at checkout
|
||||
// {"type":"status", "id":..,"status":..} one per transition
|
||||
// {"type":"order", ...full record...} written once, at checkout
|
||||
// {"type":"status", "id":..,"status":..} one per transition
|
||||
// {"type":"invoice", "id":..,"number":..} the number assignment, at paid
|
||||
// {"type":"notified","id":..,"what":..} the confirmation email left
|
||||
//
|
||||
// Current state is a left fold over the file; later events win. Nothing is
|
||||
// ever rewritten, so the log doubles as the audit trail the tax records need,
|
||||
|
|
@ -126,6 +128,14 @@ std::vector<OrderRecord> FoldLocked() {
|
|||
if (!r) continue;
|
||||
r->invoiceNumber = std::string(doc->Str("number"));
|
||||
r->invoicedAt = std::string(doc->Str("at"));
|
||||
} else if (type == "notified") {
|
||||
OrderRecord* r = find(doc->Str("id"));
|
||||
if (!r) continue;
|
||||
// "what" names the message so a future shipped-notice can share
|
||||
// the event type without re-marking the confirmation as sent.
|
||||
if (doc->Str("what") == "confirmation") {
|
||||
r->confirmationSentAt = std::string(doc->Str("at"));
|
||||
}
|
||||
} else if (type == "status") {
|
||||
OrderRecord* r = find(doc->Str("id"));
|
||||
if (!r) continue; // status for an unknown order: skip, keep folding
|
||||
|
|
@ -257,6 +267,13 @@ std::optional<std::string> AssignInvoiceNumber(std::string_view token,
|
|||
return number;
|
||||
}
|
||||
|
||||
bool AppendOrderNotified(std::string_view token, std::string_view isoTimestamp) {
|
||||
std::lock_guard lock(gOrdersMutex);
|
||||
return AppendLine(std::format(
|
||||
R"({{"type":"notified","at":"{}","id":"{}","what":"confirmation"}})",
|
||||
JsonEscape(isoTimestamp), JsonEscape(token)));
|
||||
}
|
||||
|
||||
std::optional<OrderRecord> FindOrder(std::string_view token) {
|
||||
std::lock_guard lock(gOrdersMutex);
|
||||
for (OrderRecord& r : FoldLocked()) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue