feat: add upload policies, daily limits, and storage quotas
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s

- Add environment variables to configure anonymous uploads, daily upload caps, and default user storage limits.
- Update config loader to parse and validate the new settings.
- Implement backend logic to track daily usage and active storage per user.
- Update README and `.env.example` to document the new settings and admin panels.
This commit is contained in:
2026-05-30 17:23:20 +03:00
parent 9a3cb90b17
commit d77f164900
29 changed files with 1432 additions and 120 deletions

View File

@@ -73,6 +73,9 @@ svg {
}
.site-header {
position: sticky;
top: 0;
z-index: 20;
border-bottom: 1px solid var(--border);
background: rgba(9, 9, 11, 0.84);
backdrop-filter: blur(14px);
@@ -241,6 +244,10 @@ h1 {
align-self: start;
display: grid;
gap: 0.5rem;
padding: 0.75rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: rgba(24, 24, 27, 0.58);
}
.sidebar-link {
@@ -258,6 +265,29 @@ h1 {
color: var(--foreground);
}
.admin-shell .app-sidebar {
border-color: rgba(125, 211, 252, 0.28);
background: linear-gradient(180deg, rgba(8, 47, 73, 0.22), rgba(24, 24, 27, 0.58));
}
.admin-shell .sidebar-link.is-active {
border-color: rgba(125, 211, 252, 0.42);
background: rgba(14, 116, 144, 0.24);
}
.admin-shell .kicker {
color: #7dd3fc;
}
.sidebar-logout {
display: grid;
margin: 0.75rem 0 0;
}
.sidebar-logout .button {
width: 100%;
}
.collection-create {
display: grid;
gap: 0.6rem;
@@ -270,6 +300,16 @@ h1 {
gap: 1rem;
}
.settings-stack {
display: grid;
gap: 1rem;
max-width: 44rem;
}
.settings-panel {
box-shadow: none;
}
.compact-upload .drop-zone {
min-height: 11rem;
}
@@ -295,6 +335,31 @@ h1 {
width: 10rem;
}
.settings-form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.9rem;
}
.settings-form-narrow {
grid-template-columns: minmax(0, 1fr);
}
.settings-form label {
display: grid;
gap: 0.35rem;
color: var(--muted-foreground);
font-size: 0.82rem;
}
.settings-form .checkbox-field {
grid-column: 1 / -1;
}
.settings-form button {
justify-self: start;
}
.drop-zone {
min-height: 19rem;
display: grid;
@@ -1158,7 +1223,9 @@ pre code {
@media (max-width: 720px) {
.nav-links {
display: none;
display: inline-flex;
flex-wrap: wrap;
justify-content: flex-end;
}
.upload-view,
@@ -1181,10 +1248,16 @@ pre code {
}
.docs-grid,
.field-grid {
.field-grid,
.app-shell,
.settings-form {
grid-template-columns: 1fr;
}
.app-sidebar {
position: static;
}
.endpoint-list div {
grid-template-columns: 1fr;
gap: 0.25rem;