feat: 스니펫 공용화 — 서버 PostgreSQL 테이블 + API, 프론트는 브릿지 대신 HTTP
결정(9/21): 공용 하나, 개인 로컬 없음.
- backend apps/snippets: Snippet(name PK·desc·body·category) + SnippetUsage(사람별 count/last_used).
GET/POST /api/v1/snippets, PUT/DELETE /snippets/{name}, POST /snippets/{name}/use — 옛 브릿지 5개와 1:1,
이름 정규화·중복 409·빈 내용 400 규칙 동일. import_snippets 커맨드로 옛 snippets.db 적재. 테스트 3개
- frontend snippets.api.ts 만 HTTP 로 교체(훅·페이지·타입 무변경). 테스트 axios-mock-adapter 로
- ponytail: Tauri 로컬 SQLite 커맨드는 미사용 상태로 남김. 지울 때 Rust+브릿지 테스트 함께
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
df5feaad3a
commit
2e7bae4c06
@@ -0,0 +1,38 @@
|
||||
"""공용 스니펫 — 로컬 SQLite(snippets/usage) 를 그대로 서버 PostgreSQL 로. 전원 읽기, 사용 기록은 사람별."""
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Snippet(models.Model):
|
||||
name = models.CharField(max_length=200, primary_key=True) # 대문자·공백→_ 정규화된 이름(옛 DB 와 동일)
|
||||
desc = models.CharField(max_length=500, blank=True, default="")
|
||||
body = models.TextField()
|
||||
category = models.CharField(max_length=100, default="코드")
|
||||
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL, related_name="+")
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["name"]
|
||||
|
||||
def as_dto(self, usage: "SnippetUsage | None" = None) -> dict:
|
||||
return {
|
||||
"name": self.name,
|
||||
"desc": self.desc,
|
||||
"body": self.body,
|
||||
"category": self.category,
|
||||
"usageCount": usage.count if usage else 0,
|
||||
"lastUsed": int(usage.last_used.timestamp()) if usage and usage.last_used else 0,
|
||||
}
|
||||
|
||||
|
||||
class SnippetUsage(models.Model):
|
||||
"""사람별 사용 횟수 — 랭킹은 내 기준으로."""
|
||||
|
||||
snippet = models.ForeignKey(Snippet, on_delete=models.CASCADE, related_name="usages")
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="+")
|
||||
count = models.IntegerField(default=0)
|
||||
last_used = models.DateTimeField(null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = [("snippet", "user")]
|
||||
Reference in New Issue
Block a user