feat: Ipad app production readiness, Colony orchestration, Social posting (#44)
All checks were successful
Production Readiness / backend-contracts (push) Successful in 1m47s
Production Readiness / webos-typecheck (push) Successful in 1m50s
Production Readiness / ipad-parse (push) Successful in 1m34s

#38 Ipad app production readiness, Colony orchestration, Social posting

Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local>
Reviewed-on: #44
This commit was merged in pull request #44.
This commit is contained in:
2026-05-03 18:30:38 +05:30
parent 59d398abc3
commit eeb684b46c
86 changed files with 20349 additions and 1655 deletions

View File

@@ -2,8 +2,7 @@ import Foundation
import Security
/// Central app configuration.
/// Build settings remain the fallback, but production installs should prefer
/// runtime configuration stored on-device.
/// Enterprise installs must use runtime configuration stored on-device.
enum AppConfig {
private static let runtimeBaseURLKey = "velocity.runtime.base_url"
private static let runtimeDreamWeaverBaseURLKey = "velocity.runtime.dream_weaver_base_url"
@@ -42,10 +41,6 @@ enum AppConfig {
return "Credentials required"
}
private static func value(for key: String) -> String? {
parsedValue(from: Bundle.main.infoDictionary, key: key)
}
private static func sanitizedValue(_ raw: String?, key: String) -> String? {
guard let raw else {
return nil
@@ -59,7 +54,7 @@ enum AppConfig {
/// Base URL for the Velocity backend / gateway.
static var baseURL: String {
runtimeBaseURL ?? value(for: "BASE_URL") ?? "https://velocity.desineuron.in/api"
runtimeBaseURL ?? SessionConfigurationDefaults.productionBaseURL
}
/// Dedicated Dream Weaver gateway endpoint when configured; otherwise
@@ -76,19 +71,19 @@ enum AppConfig {
}
static var dreamWeaverAPIKey: String? {
runtimeDreamWeaverAPIKey ?? value(for: "DREAM_WEAVER_API_KEY")
runtimeDreamWeaverAPIKey
}
static var apiEmail: String? {
runtimeEmail ?? value(for: "API_EMAIL")
runtimeEmail
}
static var apiPassword: String? {
runtimePassword ?? value(for: "API_PASSWORD")
runtimePassword
}
static var apiBearerToken: String? {
runtimeBearerToken ?? value(for: "API_BEARER_TOKEN")
runtimeBearerToken
}
static var apiAccessToken: String? {
@@ -132,7 +127,7 @@ enum AppConfig {
email: apiEmail,
hasPassword: apiPassword != nil,
hasBearerToken: apiBearerToken != nil,
source: hasStoredRuntimeConfiguration ? .secureDeviceStorage : .buildConfiguration
source: .secureDeviceStorage
)
}
@@ -144,23 +139,15 @@ enum AppConfig {
password: String?,
bearerToken: String?
) throws {
UserDefaults.standard.set(baseURL, forKey: runtimeBaseURLKey)
if let dreamWeaverBaseURL {
UserDefaults.standard.set(dreamWeaverBaseURL, forKey: runtimeDreamWeaverBaseURLKey)
} else {
UserDefaults.standard.removeObject(forKey: runtimeDreamWeaverBaseURLKey)
}
if let email {
UserDefaults.standard.set(email, forKey: runtimeEmailKey)
} else {
UserDefaults.standard.removeObject(forKey: runtimeEmailKey)
}
try storeSecret(baseURL, account: runtimeBaseURLKey)
try storeSecret(dreamWeaverBaseURL, account: runtimeDreamWeaverBaseURLKey)
try storeSecret(email, account: runtimeEmailKey)
try storeSecret(dreamWeaverAPIKey, account: runtimeDreamWeaverAPIKeyKey)
try storeSecret(password, account: runtimePasswordKey)
try storeSecret(bearerToken, account: runtimeBearerTokenKey)
UserDefaults.standard.removeObject(forKey: runtimeBaseURLKey)
UserDefaults.standard.removeObject(forKey: runtimeDreamWeaverBaseURLKey)
UserDefaults.standard.removeObject(forKey: runtimeEmailKey)
try clearStoredAccessToken()
}
@@ -168,6 +155,9 @@ enum AppConfig {
UserDefaults.standard.removeObject(forKey: runtimeBaseURLKey)
UserDefaults.standard.removeObject(forKey: runtimeDreamWeaverBaseURLKey)
UserDefaults.standard.removeObject(forKey: runtimeEmailKey)
try deleteSecret(account: runtimeBaseURLKey)
try deleteSecret(account: runtimeDreamWeaverBaseURLKey)
try deleteSecret(account: runtimeEmailKey)
try deleteSecret(account: runtimeDreamWeaverAPIKeyKey)
try deleteSecret(account: runtimePasswordKey)
try deleteSecret(account: runtimeBearerTokenKey)
@@ -186,16 +176,29 @@ enum AppConfig {
}
private static var runtimeBaseURL: String? {
sanitizedValue(UserDefaults.standard.string(forKey: runtimeBaseURLKey), key: runtimeBaseURLKey)
canonicalizedBackendBaseURL(
sanitizedValue(secret(account: runtimeBaseURLKey), key: runtimeBaseURLKey)
)
}
private static func canonicalizedBackendBaseURL(_ value: String?) -> String? {
guard let value else {
return nil
}
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.caseInsensitiveCompare(SessionConfigurationDefaults.legacyVelocityWebBaseURL) == .orderedSame {
return SessionConfigurationDefaults.productionBaseURL
}
return trimmed
}
private static var configuredDreamWeaverBaseURL: String? {
runtimeDreamWeaverBaseURL ?? value(for: "DREAM_WEAVER_BASE_URL")
runtimeDreamWeaverBaseURL
}
private static var runtimeDreamWeaverBaseURL: String? {
sanitizedValue(
UserDefaults.standard.string(forKey: runtimeDreamWeaverBaseURLKey),
secret(account: runtimeDreamWeaverBaseURLKey),
key: runtimeDreamWeaverBaseURLKey
)
}
@@ -205,7 +208,7 @@ enum AppConfig {
}
private static var runtimeEmail: String? {
sanitizedValue(UserDefaults.standard.string(forKey: runtimeEmailKey), key: runtimeEmailKey)
sanitizedValue(secret(account: runtimeEmailKey), key: runtimeEmailKey)
}
private static var runtimePassword: String? {

View File

@@ -12,6 +12,12 @@ enum SessionConfigurationSource: String {
case secureDeviceStorage = "Secure device storage"
}
enum SessionConfigurationDefaults {
static let productionBaseURL = "https://api.desineuron.in/api"
static let legacyVelocityWebBaseURL = "https://velocity.desineuron.in/api"
static let dreamWeaverBaseURL = "https://dreamweaver.desineuron.in"
}
struct AppSessionConfiguration: Equatable {
let baseURL: String
let dreamWeaverBaseURL: String
@@ -89,7 +95,13 @@ struct SessionConfigurationDraft: Equatable {
}
var normalizedBaseURL: String? {
Self.normalizedHTTPSOrigin(from: trimmedBaseURL)
guard let normalized = Self.normalizedHTTPSOrigin(from: trimmedBaseURL) else {
return nil
}
if normalized.caseInsensitiveCompare(SessionConfigurationDefaults.legacyVelocityWebBaseURL) == .orderedSame {
return SessionConfigurationDefaults.productionBaseURL
}
return normalized
}
var trimmedDreamWeaverBaseURL: String? {
@@ -118,7 +130,7 @@ struct SessionConfigurationDraft: Equatable {
}
guard normalizedBaseURL != nil else {
errors.append("Backend endpoint must be an HTTPS API base like https://velocity.desineuron.in/api.")
errors.append("Backend endpoint must be an HTTPS API base like \(SessionConfigurationDefaults.productionBaseURL).")
return errors
}

View File

@@ -75,8 +75,8 @@ final class SessionStore {
func reloadFromPersistedConfiguration() {
currentConfiguration = AppConfig.currentSessionConfiguration()
draftBaseURL = currentConfiguration.baseURL
draftDreamWeaverBaseURL = persistedDreamWeaverDraftValue
draftBaseURL = trimmedNonEmpty(currentConfiguration.baseURL) ?? SessionConfigurationDefaults.productionBaseURL
draftDreamWeaverBaseURL = trimmedNonEmpty(persistedDreamWeaverDraftValue) ?? SessionConfigurationDefaults.dreamWeaverBaseURL
draftDreamWeaverAPIKey = ""
draftAuthMode = currentConfiguration.authMode
draftEmail = currentConfiguration.email ?? ""
@@ -88,6 +88,11 @@ final class SessionStore {
baselineEmail = currentConfiguration.email
}
func markDraftEdited() {
errorMessage = nil
statusMessage = nil
}
func discardDraftChanges() {
errorMessage = nil
statusMessage = nil
@@ -185,6 +190,11 @@ final class SessionStore {
currentConfiguration.usesDedicatedDreamWeaverBaseURL ? currentConfiguration.dreamWeaverBaseURL : ""
}
private func trimmedNonEmpty(_ value: String) -> String? {
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.isEmpty ? nil : trimmed
}
private func verificationStatusMessage(
successPrefix: String,
backendRefreshError: String?,