import { localDb, DEFAULT_MAP_NAME } from '../db/localDb' import { generateId } from '../../lib/uuid' import { localNetworkMapTypeRepository } from './networkMapTypeRepository.local' function nowIso() { return new Date().toISOString() } function withDefaults(payload = {}) { return { name: '', description: '', mapTypeId: payload.mapTypeId || null, conflictSubject: '', workspaceId: 'personal', ...payload, } } async function findActiveMap(id) { const direct = await localDb.networkMaps.get(id) if (direct && !direct.deletedAt) return direct const sid = String(id) const all = await localDb.networkMaps.toArray() return all.find((m) => !m.deletedAt && String(m.id) === sid) || null } async function membershipsCount(mapId) { const all = await localDb.networkMapMemberships.toArray() return all.filter((m) => !m.deletedAt && String(m.mapId) === String(mapId)).length } async function hydrate(map) { if (!map || map.deletedAt) return null return { ...map, memberships_count: await membershipsCount(map.id), } } async function ensureDefaultMap() { const all = await localDb.networkMaps.toArray() const active = all.filter((m) => !m.deletedAt) if (active.length) return active.sort((a, b) => a.name.localeCompare(b.name, 'ru'))[0] const defaultType = await localNetworkMapTypeRepository.getDefault() const ts = nowIso() const id = generateId() await localDb.networkMaps.put({ id, name: DEFAULT_MAP_NAME, description: '', mapTypeId: defaultType?.id || null, workspaceId: 'personal', version: 1, createdAt: ts, updatedAt: ts, deletedAt: null, }) return findActiveMap(id) } export const localNetworkMapRepository = { async list() { const all = await localDb.networkMaps.toArray() const filtered = all .filter((m) => !m.deletedAt) .sort((a, b) => a.name.localeCompare(b.name, 'ru')) if (!filtered.length) { const defaultMap = await ensureDefaultMap() return [await hydrate(defaultMap)] } const hydrated = await Promise.all(filtered.map(hydrate)) return hydrated.filter(Boolean) }, async getById(id) { const map = await findActiveMap(id) return hydrate(map) }, async create(payload) { const defaultType = await localNetworkMapTypeRepository.getDefault() const ts = nowIso() const record = withDefaults(payload) if (!record.mapTypeId) record.mapTypeId = defaultType?.id || null const id = generateId() await localDb.networkMaps.put({ ...record, id, version: 1, createdAt: ts, updatedAt: ts, deletedAt: null, }) return this.getById(id) }, async update(id, payload) { const existing = await findActiveMap(id) if (!existing) { throw new Error('Карта не найдена') } await localDb.networkMaps.update(existing.id, { ...payload, updatedAt: nowIso(), version: Number(existing.version || 1) + 1, }) return this.getById(existing.id) }, async remove(id) { const map = await findActiveMap(id) if (!map) { throw new Error('Карта не найдена') } const ts = nowIso() await localDb.networkMaps.update(map.id, { deletedAt: ts, updatedAt: ts, version: Number(map.version || 1) + 1, }) const memberships = await localDb.networkMapMemberships .filter((m) => !m.deletedAt && String(m.mapId) === String(map.id)) .toArray() await Promise.all( memberships.map((m) => localDb.networkMapMemberships.update(m.id, { deletedAt: ts, updatedAt: ts, version: Number(m.version || 1) + 1, }) ) ) }, }