north-scape/relayboard

Relayboard: accessible team boards with audited actions, dependency maps, and shared web/MCP use cases.

A remix template · 0 remixes · Remix north-scape/relayboard

app/boards/infrastructure/memory.py

"""Ephemeral test double. Not imported by the production application."""
import copy
import threading
import uuid
from contextlib import contextmanager
from datetime import datetime, timezone

class MemoryBoards:
    def __init__(self):
        self.boards,self.cards,self.events={},{},[]
        self._lock=threading.RLock()

    def snapshot(self): return copy.deepcopy((self.boards,self.cards,self.events))

    @contextmanager
    def atomic(self):
        with self._lock:
            before=self.snapshot()
            try: yield self
            except BaseException:
                self.boards,self.cards,self.events=before
                raise

    def get(self,id): return copy.deepcopy(self.boards.get(id))
    def boards_for(self,email): return [copy.deepcopy(b) for b in self.boards.values() if b.owner_email==email or email in b.members]
    def save_board(self,b): self.boards[b.id]=copy.deepcopy(b)
    def delete_membership(self,board_id,email): self.boards[board_id].members.pop(email,None)
    def get_card(self,id): return copy.deepcopy(self.cards.get(id))
    def cards_on(self,id): return [copy.deepcopy(c) for c in self.cards.values() if c.board_id==id]
    def save_card(self,c): self.cards[c.id]=copy.deepcopy(c)
    def log(self,board_id,card_id,actor,action,changes=None):
        self.events.append(dict(id=uuid.uuid4().hex,board_id=board_id,card_id=card_id,actor=actor,action=action,
                                changes=changes or {},event_at=datetime.now(timezone.utc).isoformat()))
    def activity(self,id): return [copy.deepcopy(e) for e in reversed(self.events) if e['board_id']==id][:100]