- Add storage_enabled and storage_limit_mb columns to static_sites.
- Create/attach Docker volumes (tinyforge-site-{name}-data) for Deno
sites with storage enabled, mounted at /app/data.
- Grant --allow-write=/app/data in Deno container CMD.
- Add storage usage API endpoint (GET /api/sites/{id}/storage).
- Show storage section in site detail page with usage bar.
- Add storage toggle and limit field to new site wizard.
- Use ConfirmDialog for secret deletion instead of inline delete.
This commit is contained in:
@@ -255,6 +255,7 @@ func (s *Server) Router() chi.Router {
|
||||
r.Route("/sites/{id}", func(r chi.Router) {
|
||||
r.Get("/", s.getStaticSite)
|
||||
r.Get("/secrets", s.listStaticSiteSecrets)
|
||||
r.Get("/storage", s.getStaticSiteStorage)
|
||||
|
||||
// Admin-only mutations.
|
||||
r.Group(func(r chi.Router) {
|
||||
|
||||
@@ -61,6 +61,8 @@ type createStaticSiteRequest struct {
|
||||
RenderMarkdown bool `json:"render_markdown"`
|
||||
SyncTrigger string `json:"sync_trigger"`
|
||||
TagPattern string `json:"tag_pattern"`
|
||||
StorageEnabled bool `json:"storage_enabled"`
|
||||
StorageLimitMB int `json:"storage_limit_mb"`
|
||||
}
|
||||
|
||||
func (s *Server) createStaticSite(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -109,6 +111,8 @@ func (s *Server) createStaticSite(w http.ResponseWriter, r *http.Request) {
|
||||
RenderMarkdown: req.RenderMarkdown,
|
||||
SyncTrigger: req.SyncTrigger,
|
||||
TagPattern: req.TagPattern,
|
||||
StorageEnabled: req.StorageEnabled,
|
||||
StorageLimitMB: req.StorageLimitMB,
|
||||
Status: "idle",
|
||||
}
|
||||
|
||||
@@ -174,6 +178,8 @@ func (s *Server) updateStaticSite(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
existing.RenderMarkdown = req.RenderMarkdown
|
||||
existing.TagPattern = req.TagPattern
|
||||
existing.StorageEnabled = req.StorageEnabled
|
||||
existing.StorageLimitMB = req.StorageLimitMB
|
||||
|
||||
// Update access token only if a new one is provided.
|
||||
if req.AccessToken != "" {
|
||||
@@ -604,6 +610,42 @@ func (s *Server) detectStaticSiteProvider(w http.ResponseWriter, r *http.Request
|
||||
respondJSON(w, http.StatusOK, map[string]string{"provider": provider})
|
||||
}
|
||||
|
||||
// ── Storage Usage ──────────────────────────────────────────────────
|
||||
|
||||
func (s *Server) getStaticSiteStorage(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "id")
|
||||
site, err := s.store.GetStaticSiteByID(id)
|
||||
if err != nil {
|
||||
if errors.Is(err, store.ErrNotFound) {
|
||||
respondNotFound(w, "static site")
|
||||
return
|
||||
}
|
||||
respondError(w, http.StatusInternalServerError, "failed to get static site")
|
||||
return
|
||||
}
|
||||
|
||||
if !site.StorageEnabled {
|
||||
respondJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"enabled": false,
|
||||
"used_bytes": 0,
|
||||
"limit_mb": 0,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
usage, err := s.docker.InspectSiteStorageUsage(r.Context(), site.ContainerID)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "failed to inspect storage usage")
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"enabled": true,
|
||||
"used_bytes": usage.UsedBytes,
|
||||
"limit_mb": site.StorageLimitMB,
|
||||
})
|
||||
}
|
||||
|
||||
// maskToken returns a masked version of a token string for API responses.
|
||||
func maskToken(token string) string {
|
||||
if token == "" {
|
||||
|
||||
Reference in New Issue
Block a user