#pragma once #include #include #include namespace radiantwave::api { // Base URL of the RadiantWave content API. constexpr const char* API_BASE_URL = "https://portal.radiantwavetech.com/api/v2"; // Paths relative to API_BASE_URL. constexpr const char* PATH_PROCLAMATIONS = "/proclamations"; constexpr const char* PATH_CATEGORIES = "/categories"; constexpr const char* PATH_GROUPS = "/groups"; constexpr const char* PATH_FREQUENCIES = "/frequencies"; constexpr const char* PATH_LICENSE = "/license"; constexpr const char* PATH_CREATE_ACCOUNT = "/automations/create/account"; constexpr const char* PATH_COLOR_PALETTES = "/color-palettes"; // Result of a single HTTP request. struct HttpResponse { long status = 0; // HTTP status code; 0 if the request never completed std::string body; // raw response body (any status) bool transportOk = false; // true when the request completed without a transport error }; // Performs a GET/POST against `path` (relative to API_BASE_URL). HttpResponse httpGet(const std::string& path); HttpResponse httpPost(const std::string& path, const std::string& jsonBody); // ─── GET /frequencies ────────────────────────────────────────────────── struct Frequency { int id = 0; std::string name; int value = 0; // frequency in Hz }; // Parse the JSON payload returned by the frequencies endpoint. bool parseFrequenciesJson(const std::string& body, std::vector& out); // Fetch the solfeggio frequencies. Returns true only on HTTP 2xx + successful parse. bool fetchFrequencies(std::vector& out); // ─── GET /color-palettes ─────────────────────────────────────────────── // A single color swatch (RGBA). Mirrors db::PaletteColor without coupling the // API layer to the database. struct PaletteColor { uint8_t r = 0; uint8_t g = 0; uint8_t b = 0; uint8_t a = 255; }; // The ordered 7-color palette for one solfeggio frequency. struct ColorPalette { int solfeggio_frequency_id = 0; std::vector colors; }; // Parse the JSON payload returned by the color-palettes endpoint. Each entry // is expected to look like {"solfeggioFrequencyId": 1, "colors": ["#RRGGBB", ...]}. // Returns false on malformed input. bool parseColorPalettesJson(const std::string& body, std::vector& out); // Fetch the color palettes for every solfeggio frequency. Returns true only on // HTTP 2xx + successful parse. // // NOTE: the portal does not expose this route yet. This is readiness code — it // is deliberately not called anywhere in the app until the route ships, so // palettes can be updated from the portal rather than code releases. bool fetchColorPalettes(std::vector& out); // ─── POST /license ───────────────────────────────────────────────────── struct LicenseInfo { std::string key; std::string email_address; }; // Parse the 200 JSON payload returned by the license endpoint. bool parseLicenseJson(const std::string& body, LicenseInfo& out); struct LicenseResult { int status = 0; LicenseInfo info; std::string error_message; // extracted from the error body on failure bool ok() const { return status >= 200 && status < 300; } }; // Validate a license key / email pair against the portal. Never throws; failures // (network, HTTP error status) are reported through the returned LicenseResult. // A 2xx response means the license is valid and the subscription is active. LicenseResult validateLicense(const std::string& key, const std::string& email); // ─── POST /automations/create/account ────────────────────────────────── struct AccountBody { bool success = false; std::string message; std::string user_id; }; // Parse the 200 JSON payload returned by the create-account endpoint. bool parseCreateAccountJson(const std::string& body, AccountBody& out); struct AccountResult { int status = 0; AccountBody body; std::string error_message; bool ok() const { return status >= 200 && status < 300; } }; // Creates (or reuses) a user account and issues a license key. The key is emailed // to the user and is NOT part of the response. `name` may be empty. AccountResult createAccount(const std::string& email, const std::string& name = ""); } // namespace radiantwave::api