zig-pay/src/endpoints/payments.zig
2025-08-07 21:41:44 -03:00

135 lines
4.7 KiB
Zig

const endpoints = @import("endpoints.zig");
const EndpointsManager = endpoints.EndpointsManager;
const Request = endpoints.Request;
const Response = endpoints.Response;
const data = @import("data");
const Payment = data.payments.Payment;
const PaymentsRepository = data.payments.PaymentsRepository;
const std = @import("std");
const ctx = @import("context");
const parses = @import("parses");
const PropertySpec = @import("parses").PropertySpec;
const DateTime = @import("things").DateTime;
pub fn registerEndpoints(get_endpoints: *EndpointsManager, post_endpoints: *EndpointsManager) !void {
// GET
try get_endpoints.add("/payments-summary", getSummary);
try get_endpoints.add("/payments/*", getPaymentsById);
// POST
try post_endpoints.add("/payments", postPayments);
}
fn postPayments(req: *Request, res: *Response) void {
if (ctx.server_settings.failure)
return res.withStatus(.service_unavailable).end();
if (ctx.server_settings.delay > 0) {
std.time.sleep(ctx.server_settings.delay * std.time.ns_per_ms);
}
res.withStatus(.unprocessable_entity).withContentType(.json).end();
var prop_correlationId = parses.PropertySpec{ .name = "correlationId" };
var prop_amount = parses.PropertySpec{ .name = "amount" };
parses.json(req.body, .{ .properties = &.{ &prop_correlationId, &prop_amount } }) catch {
return;
};
const payment = Payment{ .id = prop_correlationId.asUuid() catch {
return res.withContent("{ \"correlationId\" : \"invalid\" }").end();
}, .amount = prop_amount.asFloat(f64) catch {
return res.withContent("{ \"amount\" : \"invalid\" }").end();
}, .requested_at = DateTime.now() };
ctx.payments_repository.insert(payment) catch {
return res.withStatus(.internal_server_error).end();
};
res.withStatus(.created).withContent("confia que vai ser integrado.").withContentType(.html).end();
}
fn getPaymentsById(req: *Request, res: *Response) void {
if (ctx.server_settings.failure)
return res.withStatus(.service_unavailable).end();
if (ctx.server_settings.delay > 0) {
std.time.sleep(ctx.server_settings.delay * std.time.ns_per_ms);
}
const template_json_res: []const u8 =
\\{{
\\ "correlationId": "{s}",
\\ "amount": {d:.2},
\\ "requestedAt" : "{s}",
\\ "integration_status" : "{s}"
\\}}
;
res.withStatus(.not_found).end();
if (req.path.len < 36) {
return;
}
const id = req.path[req.path.len - 36 ..];
const payment = ctx.payments_repository.findById(id);
if (payment == null) return;
const dateIso = payment.?.requested_at.toIso();
res.withContentFormat(template_json_res, .{ payment.?.id, payment.?.amount, dateIso, payment.?.getIntegrationStatus() }) catch {
return res.withStatus(.internal_server_error).end();
};
res.withStatus(.ok).withContentType(.json).end();
}
const template_json_summary: []const u8 =
\\{{
\\ "default": {{ "totalRequests": "{d}", "totalAmount": {d:.2} }},
\\ "fallback": {{ "totalRequests": "{d}", "totalAmount": {d:.2} }}
\\}}
;
fn getSummary(req: *Request, res: *Response) void {
var from: ?DateTime = null;
var to: ?DateTime = null;
var prop_from = PropertySpec{ .name = "from" };
var prop_to = PropertySpec{ .name = "to" };
parses.url_params(req.query, .{ .properties = &.{ &prop_from, &prop_to } });
if (prop_from.value_dirty != null)
from = prop_from.asDateTime() catch {
return res.withStatus(.bad_request).withContent("query param 'from' is invalid").withContentType(.html).end();
};
if (prop_to.value_dirty != null)
to = prop_to.asDateTime() catch {
return res.withStatus(.bad_request).withContent("query param 'to' is invalid").withContentType(.html).end();
};
var summary = ctx.payments_repository.integrationSummary(from, to);
const cousin_summary = ctx.summary_exchange.receive(from, to);
summary.default_total_payments_processed += cousin_summary.default_total_payments_processed;
summary.default_total_value += cousin_summary.default_total_value;
summary.fallback_total_payments_processed += cousin_summary.fallback_total_payments_processed;
summary.fallback_total_value += cousin_summary.fallback_total_value;
res.withStatus(.ok).withContentType(.json).withContentFormat(template_json_summary, .{
summary.default_total_payments_processed,
summary.default_total_value,
summary.fallback_total_payments_processed,
summary.fallback_total_value,
}) catch {
return res.withStatus(.internal_server_error).withContentType(.none).end();
};
}