Initial public commit
Daybook: a self-hosted, multi-user Django + DRF app where agents, scripts, or people publish artifacts and each logged-in user browses their own time-ordered, label-filterable feed. This squashes prior local development history (kept privately on a separate branch) into a single clean starting point for the public repository. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
940a703cd7
62 changed files with 5755 additions and 0 deletions
105
artifacts/models.py
Normal file
105
artifacts/models.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Artifact(models.Model):
|
||||
HTML_FRAGMENT = "html_fragment"
|
||||
HTML_FULL = "html_full"
|
||||
MARKDOWN = "markdown"
|
||||
DECK = "deck"
|
||||
IMAGE = "image"
|
||||
PDF = "pdf"
|
||||
BINARY = "binary"
|
||||
|
||||
AGENT = "agent"
|
||||
PERSON = "person"
|
||||
SYSTEM = "system"
|
||||
|
||||
KIND_CHOICES = [
|
||||
(HTML_FRAGMENT, "HTML fragment"),
|
||||
(HTML_FULL, "Full HTML"),
|
||||
(MARKDOWN, "Markdown"),
|
||||
(DECK, "Deck"),
|
||||
(IMAGE, "Image"),
|
||||
(PDF, "PDF"),
|
||||
(BINARY, "Binary"),
|
||||
]
|
||||
|
||||
SOURCE_TYPE_CHOICES = [
|
||||
(AGENT, "Agent"),
|
||||
(PERSON, "Person"),
|
||||
(SYSTEM, "System"),
|
||||
]
|
||||
|
||||
id = models.CharField(max_length=8, primary_key=True)
|
||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="artifacts")
|
||||
source = models.CharField(max_length=80, db_index=True)
|
||||
title = models.CharField(max_length=200)
|
||||
kind = models.CharField(max_length=20, choices=KIND_CHOICES)
|
||||
theme = models.CharField(max_length=40, blank=True)
|
||||
day = models.DateField(db_index=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
path = models.CharField(max_length=500)
|
||||
original_kind = models.CharField(max_length=20)
|
||||
tags = models.JSONField(default=list, blank=True)
|
||||
source_prompt = models.TextField(blank=True)
|
||||
source_type = models.CharField(max_length=20, choices=SOURCE_TYPE_CHOICES, default=AGENT)
|
||||
source_name = models.CharField(max_length=120, blank=True)
|
||||
source_id = models.CharField(max_length=120, blank=True)
|
||||
metadata = models.JSONField(default=dict, blank=True)
|
||||
read_at = models.DateTimeField(null=True, blank=True)
|
||||
is_kept = models.BooleanField(default=False)
|
||||
size_bytes = models.BigIntegerField(default=0)
|
||||
|
||||
@property
|
||||
def is_unread(self):
|
||||
return self.read_at is None
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} ({self.source})"
|
||||
|
||||
|
||||
class TagColor(models.Model):
|
||||
name = models.CharField(max_length=40, primary_key=True)
|
||||
color = models.CharField(max_length=20)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.color})"
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
DEFAULT_QUOTA_BYTES = 1024 * 1024 * 1024 # 1 GB
|
||||
|
||||
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile")
|
||||
quota_bytes = models.BigIntegerField(default=DEFAULT_QUOTA_BYTES)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user} quota={self.quota_bytes}"
|
||||
|
||||
|
||||
class Asset(models.Model):
|
||||
"""An image uploaded for embedding inside an artifact's content.
|
||||
|
||||
Uploaded before the artifact exists, so `artifact` is null until the
|
||||
artifact referencing its URL is created. Unattached assets are swept
|
||||
after ASSET_ORPHAN_GRACE; attached ones die with their artifact.
|
||||
"""
|
||||
|
||||
id = models.CharField(max_length=12, primary_key=True)
|
||||
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="assets")
|
||||
artifact = models.ForeignKey(
|
||||
Artifact, on_delete=models.CASCADE, related_name="assets", null=True, blank=True
|
||||
)
|
||||
path = models.CharField(max_length=500)
|
||||
content_type = models.CharField(max_length=100)
|
||||
size_bytes = models.BigIntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.id} ({self.content_type})"
|
||||
Loading…
Add table
Add a link
Reference in a new issue