Files
llink/cpp/src/store.h
T

135 lines
4.6 KiB
C++

#ifndef STORE_H
#define STORE_H
#include "models.h"
#include <QList>
#include <QMap>
QT_BEGIN_NAMESPACE
class QJsonDocument;
class QNetworkReply;
QT_END_NAMESPACE
/// Represents an in-flight API operation.
/// Wraps a QNetworkReply: owns cleanup, parses JSON, and emits signals.
/// Automatically deletes itself after finished() fires.
class Operation : public QObject
{
Q_OBJECT
public:
explicit Operation(QNetworkReply *reply, QObject *parent = nullptr);
signals:
void success(const QJsonDocument &response);
void failed(const QString &message);
void finished();
};
/// Central data store backed by the Orion API.
/// Holds cached state and exposes read-only accessors + mutating operations.
class Store : public QObject
{
Q_OBJECT
public:
explicit Store(QObject *parent = nullptr);
// ── Read-only accessors ──
const QList<Network> &networks() const;
int networkCount() const;
const Network *networkById(const QString &id) const;
QList<Stream> streamsForNetwork(const QString &networkId) const;
int streamCount(const QString &networkId) const;
const Stream *streamById(const QString &id) const;
const QList<Particle> &particlesForStream(const QString &streamId) const;
int particleCount(const QString &streamId) const;
const Particle *particleById(const QString &id) const;
// ── Bootstrap ──
Operation *loadStartupData();
// ── Network operations ──
Operation *createNetwork(const QString &name);
Operation *fetchNetworks();
Operation *fetchNetwork(const QString &networkId);
Operation *addNetworkMembers(const QString &networkId, const QStringList &emails);
Operation *removeNetworkMember(const QString &networkId, const QString &email);
Operation *setStreamCapacity(const QString &networkId, int capacity);
// ── Stream operations ──
Operation *createStream(const QString &networkId, const QString &name,
const QString &description, const QString &visibility = "network_all",
const QStringList &members = {});
Operation *fetchStream(const QString &streamId);
Operation *updateStream(const QString &streamId, const QString &name, const QString &description);
Operation *openStream(const QString &streamId);
Operation *closeStream(const QString &streamId);
Operation *addStreamMembers(const QString &streamId, const QStringList &emails);
Operation *removeStreamMembers(const QString &streamId, const QStringList &emails);
// ── Particle operations ──
Operation *createParticle(const QString &streamId, const QString &type,
const QMap<QString, QVariant> &data);
Operation *fetchParticle(const QString &particleId);
Operation *updateParticle(const QString &particleId, const QMap<QString, QVariant> &data);
Operation *deleteParticle(const QString &particleId);
Operation *markParticleSeen(const QString &particleId);
Operation *markParticlesSeen(const QStringList &particleIds);
Operation *ackParticle(const QString &particleId);
void setCurrentUserEmail(const QString &email);
QString currentUserEmail() const;
signals:
// ── Data-change signals ──
void networksChanged();
void streamsChanged(const QString &networkId);
void particlesChanged(const QString &streamId);
// Granular signals for in-place property updates (no structural change)
void particleUpdated(const QString &streamId, const QString &particleId);
void streamUpdated(const QString &streamId);
void startupDataLoaded();
void errorOccurred(const QString &message);
private:
// ── Internal state ──
QList<Network> m_networks;
QMap<QString, QList<Particle>> m_particles; // streamId -> particles
QMap<QString, int> m_networkIndex; // networkId -> index in m_networks
QMap<QString, QString> m_streamToNetwork; // streamId -> networkId
QString m_currentUserEmail;
// ── JSON parsing ──
static Human parseHuman(const QJsonObject &obj);
static Network parseNetwork(const QJsonObject &obj);
static Stream parseStream(const QJsonObject &obj);
static Particle parseParticle(const QJsonObject &obj);
void populateFromStartupData(const QJsonObject &root);
// ── State mutation helpers ──
void upsertNetwork(const Network &network);
void upsertStream(const QString &networkId, const Stream &stream);
void upsertParticle(const QString &streamId, const Particle &particle);
void removeParticleFromState(const QString &particleId);
/// Returns the streamId that contains the given particle, or empty QString.
QString findStreamForParticle(const QString &particleId) const;
};
#endif // STORE_H