Remove subscription levels; license valid = subscribed

This commit is contained in:
NeilClack
2026-08-15 00:54:24 -05:00
parent 8ca60de647
commit f14bf3e29a
19 changed files with 136 additions and 1534 deletions
+12 -14
View File
@@ -132,7 +132,6 @@ bool DatabaseManager::runMigrations() {
selected INTEGER DEFAULT 0,
category_id INTEGER DEFAULT 0,
solfeggio_frequency_id INTEGER DEFAULT 0,
required_level_id INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
@@ -184,8 +183,11 @@ bool DatabaseManager::runMigrations() {
ensureColumn("proclamations", "selected", "selected INTEGER DEFAULT 0");
ensureColumn("proclamations", "category_id", "category_id INTEGER DEFAULT 0");
ensureColumn("proclamations", "solfeggio_frequency_id", "solfeggio_frequency_id INTEGER DEFAULT 0");
ensureColumn("proclamations", "required_level_id", "required_level_id INTEGER DEFAULT 1");
ensureColumn("audio_files", "solfeggio_frequency_id", "solfeggio_frequency_id INTEGER DEFAULT 0");
// Clean up the pre-active/inactive-license subscription level keys.
// Existing devices may still carry them; nothing reads them anymore.
executeSql("DELETE FROM system_kv WHERE key IN "
"('subscription_level_id','subscription_level_name','subscription_level_description');");
}
if (ok) {
seedColorPalettes();
@@ -336,7 +338,6 @@ void DatabaseManager::bindProclamationRecord(sqlite3_stmt* stmt, const Proclamat
sqlite3_bind_int(stmt, 7, record.selected ? 1 : 0);
sqlite3_bind_int(stmt, 8, record.category_id);
sqlite3_bind_int(stmt, 9, record.solfeggio_frequency_id);
sqlite3_bind_int(stmt, 10, record.required_level_id);
}
bool DatabaseManager::saveProclamation(const ProclamationRecord& record) {
@@ -344,13 +345,12 @@ bool DatabaseManager::saveProclamation(const ProclamationRecord& record) {
if (!db_) return false;
const char* sql = "INSERT INTO proclamations (id, title, content, solfeggio_freq_hz, category, "
"is_active, selected, category_id, solfeggio_frequency_id, required_level_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
"is_active, selected, category_id, solfeggio_frequency_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
"ON CONFLICT(id) DO UPDATE SET title=excluded.title, content=excluded.content, "
"solfeggio_freq_hz=excluded.solfeggio_freq_hz, category=excluded.category, "
"is_active=excluded.is_active, selected=excluded.selected, "
"category_id=excluded.category_id, solfeggio_frequency_id=excluded.solfeggio_frequency_id, "
"required_level_id=excluded.required_level_id;";
"category_id=excluded.category_id, solfeggio_frequency_id=excluded.solfeggio_frequency_id;";
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
@@ -375,7 +375,6 @@ static ProclamationRecord readProclamationRecord(sqlite3_stmt* stmt, int firstCo
rec.selected = (sqlite3_column_int(stmt, firstCol + 6) != 0);
rec.category_id = sqlite3_column_int(stmt, firstCol + 7);
rec.solfeggio_frequency_id = sqlite3_column_int(stmt, firstCol + 8);
rec.required_level_id = sqlite3_column_int(stmt, firstCol + 9);
return rec;
}
@@ -385,7 +384,7 @@ std::vector<ProclamationRecord> DatabaseManager::getActiveProclamations() {
if (!db_) return result;
const char* sql = "SELECT id, title, content, solfeggio_freq_hz, category, is_active, "
"selected, category_id, solfeggio_frequency_id, required_level_id "
"selected, category_id, solfeggio_frequency_id "
"FROM proclamations WHERE is_active = 1;";
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
@@ -500,13 +499,12 @@ bool DatabaseManager::syncProclamations(const std::vector<ProclamationRecord>& r
// Upsert each proclamation, preserving the stashed selection state.
if (ok) {
const char* sql = "INSERT INTO proclamations (id, title, content, solfeggio_freq_hz, category, "
"is_active, selected, category_id, solfeggio_frequency_id, required_level_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
"is_active, selected, category_id, solfeggio_frequency_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
"ON CONFLICT(id) DO UPDATE SET title=excluded.title, content=excluded.content, "
"solfeggio_freq_hz=excluded.solfeggio_freq_hz, category=excluded.category, "
"is_active=excluded.is_active, category_id=excluded.category_id, "
"solfeggio_frequency_id=excluded.solfeggio_frequency_id, "
"required_level_id=excluded.required_level_id;";
"solfeggio_frequency_id=excluded.solfeggio_frequency_id;";
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
@@ -557,7 +555,7 @@ std::vector<ProclamationRecord> DatabaseManager::getAllProclamations() {
if (!db_) return result;
const char* sql = "SELECT id, title, content, solfeggio_freq_hz, category, is_active, "
"selected, category_id, solfeggio_frequency_id, required_level_id FROM proclamations;";
"selected, category_id, solfeggio_frequency_id FROM proclamations;";
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK) {
return result;
-1
View File
@@ -17,7 +17,6 @@ struct ProclamationRecord {
bool selected = false;
int category_id = 0; // maps to ProclamationCategoryRecord::id
int solfeggio_frequency_id = 0; // maps to the solfeggio frequency preset
int required_level_id = 1; // minimum SubscriptionLevel id to unlock it
};
struct ProclamationCategoryRecord {
-3
View File
@@ -6,9 +6,6 @@ namespace radiantwave::db {
// device configuration lives in the local database.
constexpr const char* KV_EMAIL_ADDRESS = "email_address";
constexpr const char* KV_LICENSE_KEY = "license_key";
constexpr const char* KV_SUBSCRIPTION_LEVEL_ID = "subscription_level_id";
constexpr const char* KV_SUBSCRIPTION_LEVEL_NAME = "subscription_level_name";
constexpr const char* KV_SUBSCRIPTION_LEVEL_DESCRIPTION = "subscription_level_description";
// Unix epoch seconds of the last successful license validation against the
// portal. Used to grant a 7-day offline grace window so transient network