"""Projekte (docs/projects.md): a project of a preset (Forschung first), its sources and notes. End-to-end encrypted like the books: a project's name and settings, and every item's content (a note's text, a source's citation data, a remark) are AES-GCM blobs the server can't read. What it knows: that a project exists, its preset, and which book, episode or article an item points to (kind + ref) — the ids, never their titles.""" from django.contrib.auth.models import User from django.db import models class Project(models.Model): RESEARCH = 'research' PRESETS = [(RESEARCH, 'Forschung')] user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='projects') preset = models.CharField(max_length=20, choices=PRESETS, default=RESEARCH) data_ct = models.TextField() # {name, description, …} encrypted data_iv = models.CharField(max_length=32) archived = models.BooleanField(default=False) position = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['position', '-updated_at'] class ProjectItem(models.Model): """Something in a project. Sources point at what's elsewhere in diora (a book, an episode, an article: ref is its id) or stand alone (a paper known by its citation data: no ref); notes are text of their own (no ref).""" BOOK = 'book' EPISODE = 'episode' ARTICLE = 'article' PAPER = 'paper' NOTE = 'note' KINDS = [(BOOK, 'Buch'), (EPISODE, 'Folge'), (ARTICLE, 'Artikel'), (PAPER, 'Paper'), (NOTE, 'Notiz')] LINKED = (BOOK, EPISODE, ARTICLE) project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='items') kind = models.CharField(max_length=10, choices=KINDS) ref = models.BigIntegerField(null=True, blank=True) data_ct = models.TextField() data_iv = models.CharField(max_length=32) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['created_at'] constraints = [models.UniqueConstraint(fields=['project', 'kind', 'ref'], name='project_item_once', condition=models.Q(ref__isnull=False))] indexes = [models.Index(fields=['kind', 'ref'])]