diff --git a/Behaver.cs b/Behaver.cs
index e255e80..859f6f7 100644
--- a/Behaver.cs
+++ b/Behaver.cs
@@ -8,6 +8,7 @@ using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Collections.Generic;
+using vassago.ProtocolInterfaces.DiscordInterface;
 
 public class Behaver
 {
diff --git a/ProtocolInterfaces/DiscordInterface/DiscordInterface.cs b/ProtocolInterfaces/DiscordInterface/DiscordInterface.cs
index 05434f2..2487c20 100644
--- a/ProtocolInterfaces/DiscordInterface/DiscordInterface.cs
+++ b/ProtocolInterfaces/DiscordInterface/DiscordInterface.cs
@@ -70,7 +70,7 @@ public class DiscordInterface
             protocolAsChannel.DisplayName = "discord (itself)";
             protocolAsChannel.SendMessage = (t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot accept text"); };
             protocolAsChannel.SendFile = (f, t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot send file"); };
-            protocolAsChannel= Rememberer.RememberChannel(protocolAsChannel);
+            protocolAsChannel = Rememberer.RememberChannel(protocolAsChannel);
             Console.WriteLine($"protocol as channel addeed; {protocolAsChannel}");
         }
         finally
@@ -115,7 +115,7 @@ public class DiscordInterface
     {
         await discordChannelSetup.WaitAsync();
 
-        try 
+        try
         {
             var selfAccount = UpsertAccount(client.CurrentUser, protocolAsChannel);
             selfAccount.DisplayName = client.CurrentUser.Username;
@@ -129,7 +129,7 @@ public class DiscordInterface
 
     private async Task MessageReceived(SocketMessage messageParam)
     {
-        if(messageParam is not SocketUserMessage)
+        if (messageParam is not SocketUserMessage)
         {
             Console.WriteLine($"{messageParam.Content}, but not a user message");
             return;
@@ -271,7 +271,7 @@ public class DiscordInterface
         if (channel is IGuildChannel)
         {
             parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == PROTOCOL);
-            if(parentChannel is null)
+            if (parentChannel is null)
             {
                 Console.Error.WriteLine("why am I still null?");
             }
@@ -290,7 +290,7 @@ public class DiscordInterface
 
         c.SendMessage = (t) => { return channel.SendMessageAsync(t); };
         c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); };
-        
+
         return Rememberer.RememberChannel(c);
     }
     internal Channel UpsertChannel(IGuild channel)
@@ -313,14 +313,19 @@ public class DiscordInterface
 
         c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); };
         c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); };
-        
+
         return Rememberer.RememberChannel(c);
     }
     internal static Account UpsertAccount(IUser user, Channel inChannel)
     {
         var acc = Rememberer.SearchAccount(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id);
-        acc ??= new Account();
-        
+        Console.WriteLine($"upserting account, retrieved {acc?.Id}.");
+        if (acc != null)
+        {
+            Console.WriteLine($"acc's user: {acc.IsUser?.Id}");
+        }
+        acc ??= new Account() { IsUser = new User() };
+
         acc.Username = user.Username;
         acc.ExternalId = user.Id.ToString();
         acc.IsBot = user.IsBot || user.IsWebhook;
@@ -328,9 +333,18 @@ public class DiscordInterface
         acc.SeenInChannel = inChannel;
 
         acc.IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
-        acc.IsUser ??= new User() { Accounts = [ acc ] };
-        inChannel.Users ??= [];
-        inChannel.Users.Add(acc);
+
+        Console.WriteLine($"we asked rememberer to search for acc's user. {acc.IsUser?.Id}");
+        if (acc.IsUser != null)
+        {
+            Console.WriteLine($"user has record of {acc.IsUser.Accounts?.Count ?? 0} accounts");
+        }
+        acc.IsUser ??= new User() { Accounts = [acc] };
+        if (inChannel.Users?.Count > 0)
+        {
+            Console.WriteLine($"channel has {inChannel.Users.Count} accounts");
+        }
+        inChannel.Users ??= [acc];
         Rememberer.RememberAccount(acc);
         return acc;
     }
diff --git a/README.md b/README.md
index ca9e08f..a2e53b5 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,16 @@ that's read messages/view channels, send messages, send messages in threads, and
 
 ## Data Types
 
+database diagram. is a fancy term.
+
+message 1:n attachment
+user 1:n account
+channel 1:n account
+channel 1:n message
+account 1:n message
+
+featurepermission n:n ?
+
 ### Accounts
 
 a `User` can have multiple `Account`s. e.g., @adam:greyn.club? that's an "account". I, however, am a `User`. An `Account` has references to the `Channels` its seen in - as in, leaf-level. If you're in a subchannel, you'll have an appropriate listing there - i.e., you will never have an account in "discord (itself)", you'll have one in the guild text-channels
diff --git a/Rememberer.cs b/Rememberer.cs
index 45c2a93..3371cc8 100644
--- a/Rememberer.cs
+++ b/Rememberer.cs
@@ -2,13 +2,14 @@ namespace vassago;
 
 using System.Linq.Expressions;
 using vassago.Models;
+using Microsoft.EntityFrameworkCore;
 
 public static class Rememberer
 {
     private static readonly ChattingContext db = new();
     public static Account SearchAccount(Expression<Func<Account, bool>> predicate)
     {
-        return (new ChattingContext()).Accounts.FirstOrDefault(predicate);
+        return (new ChattingContext()).Accounts.Include(a => a.IsUser).FirstOrDefault(predicate);
     }
     public static List<Account> SearchAccounts(Expression<Func<Account, bool>> predicate)
     {
@@ -28,30 +29,30 @@ public static class Rememberer
     }
     public static User SearchUser(Expression<Func<User, bool>> predicate)
     {
-        return (new ChattingContext()).Users.FirstOrDefault(predicate);
+        return (new ChattingContext()).Users.Include(u => u.Accounts).FirstOrDefault(predicate);
     }
     public static void RememberAccount(Account toRemember)
     {
-        db.Update(toRemember);
+        toRemember.IsUser ??= new User{ Accounts = [toRemember]};
+        db.Update(toRemember.IsUser);
         db.SaveChanges();
     }
     public static void RememberAttachment(Attachment toRemember)
     {
-        db.Update(toRemember);
-
+        toRemember.Message ??= new Message() { Attachments = [toRemember]};
+        db.Update(toRemember.Message);
         db.SaveChanges();
     }
     public static Channel RememberChannel(Channel toRemember)
     {
         db.Update(toRemember);
-
         db.SaveChanges();
         return toRemember;
     }
     public static void RememberMessage(Message toRemember)
     {
-        db.Update(toRemember);
-
+        toRemember.Channel ??= new (){ Messages = [toRemember] };
+        db.Update(toRemember.Channel);
         db.SaveChanges();
     }
     public static void RememberUser(User toRemember)
@@ -66,4 +67,23 @@ public static class Rememberer
 
         db.SaveChanges();
     }
+    public static List<Account> AccountsOverview()
+    {
+        return db.Accounts.ToList();
+    }
+    public static List<Channel> ChannelsOverview()
+    {
+        return db.Channels.Include(u => u.SubChannels).Include(c => c.ParentChannel).ToList();
+    }
+    public static Channel ChannelDetail(Guid Id)
+    {
+        return db.Channels.Find(Id);
+            // .Include(u => u.SubChannels)
+            // .Include(u => u.Users)
+            // .Include(u => u.ParentChannel);
+    }
+    public static List<User> UsersOverview()
+    {
+        return db.Users.ToList();
+    }
 }
\ No newline at end of file
diff --git a/WebInterface/Controllers/ChannelsController.cs b/WebInterface/Controllers/ChannelsController.cs
index 8e45a82..164208d 100644
--- a/WebInterface/Controllers/ChannelsController.cs
+++ b/WebInterface/Controllers/ChannelsController.cs
@@ -8,30 +8,26 @@ using vassago.WebInterface.Models;
 
 namespace vassago.WebInterface.Controllers;
 
-public class ChannelsController(ChattingContext db) : Controller
+public class ChannelsController() : Controller
 {
-    private ChattingContext Database => db;
-
     public IActionResult Index()
     {
-        return Database.Channels != null ?
-            View(Database.Channels.Include(u => u.ParentChannel).ToList().OrderBy(c => c.LineageSummary)) :
+        var channels = Rememberer.ChannelsOverview();
+        return channels != null ?
+            View(channels.OrderBy(c => c.LineageSummary)) :
             Problem("Entity set '_db.Channels' is null.");
     }
     public async Task<IActionResult> Details(Guid id)
     {
-        if(Database.Channels == null)
+        var allChannels = Rememberer.ChannelsOverview();
+        if(allChannels == null)
             return Problem("Entity set '_db.Channels' is null.");
         //"but adam", says the strawman, "why load *every* channel and walk your way up? surely there's a .Load command that works or something."
         //eh. I checked. Not really. You could make an SQL view that recurses its way up, meh idk how. You could just eagerly load *every* related object...
         //but that would take in all the messages. 
         //realistically I expect this will have less than 1MB of total "channels", and several GB of total messages per (text) channel.
-        var AllChannels = await Database.Channels
-            .Include(u => u.SubChannels)
-            .Include(u => u.Users)
-            .Include(u => u.ParentChannel)
-            .ToListAsync();
-        var channel = AllChannels.First(u => u.Id == id);
+
+        var channel = allChannels.First(u => u.Id == id);
         var walker = channel;
         while(walker != null)
         {
diff --git a/WebInterface/Controllers/HomeController.cs b/WebInterface/Controllers/HomeController.cs
index 6515e07..b28e16e 100644
--- a/WebInterface/Controllers/HomeController.cs
+++ b/WebInterface/Controllers/HomeController.cs
@@ -12,24 +12,23 @@ namespace vassago.Controllers;
 public class HomeController : Controller
 {
     private readonly ILogger<HomeController> _logger;
-    private readonly ChattingContext _db;
 
-    public HomeController(ILogger<HomeController> logger, ChattingContext db)
+    public HomeController(ILogger<HomeController> logger)
     {
         _logger = logger;
-        _db = db;
     }
 
     public IActionResult Index()
     {
-        var allAccounts = _db.Accounts.ToList();
-        var allChannels = _db.Channels.Include(c => c.Users).ToList();
+        var allAccounts = Rememberer.AccountsOverview();
+        var allChannels = Rememberer.ChannelsOverview();
+        Console.WriteLine($"accounts: {allAccounts?.Count ?? 0}, channels: {allChannels?.Count ?? 0}");
         var sb = new StringBuilder();
-        sb.Append("[");
+        sb.Append('[');
         sb.Append("{text: \"channels\", nodes: [");
 
         var first = true;
-        var topLevelChannels = _db.Channels.Where(x => x.ParentChannel == null);
+        var topLevelChannels = Rememberer.ChannelsOverview().Where(x => x.ParentChannel == null);
         foreach (var topLevelChannel in topLevelChannels)
         {
             if (first)
@@ -85,13 +84,13 @@ public class HomeController : Controller
             }
             sb.Append("]}");
         }
-        var users = _db.Users.ToList();
+        var users = Rememberer.UsersOverview();// _db.Users.ToList();
         if(users.Any())
         {
             sb.Append(",{text: \"users\", nodes: [");
             first=true;
             //refresh list; we'll be knocking them out again in serializeUser
-            allAccounts = _db.Accounts.ToList(); 
+            allAccounts = Rememberer.AccountsOverview();
             foreach(var user in users)
             {
                 if (first)
diff --git a/WebInterface/Controllers/api/ChannelsControler.cs b/WebInterface/Controllers/api/ChannelsControler.cs
index 8487e64..4a6db9f 100644
--- a/WebInterface/Controllers/api/ChannelsControler.cs
+++ b/WebInterface/Controllers/api/ChannelsControler.cs
@@ -2,6 +2,7 @@ using System.Diagnostics;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.EntityFrameworkCore;
 using vassago.Models;
+using vassago.ProtocolInterfaces.DiscordInterface;
 
 namespace vassago.Controllers.api;