rustango 0.22.1

Django-shaped batteries-included web framework for Rust: ORM + migrations + auto-admin + multi-tenancy + audit log + auth (sessions, JWT, OAuth2/OIDC, HMAC) + APIs (ViewSet, OpenAPI auto-derive, JSON:API) + jobs (in-mem + Postgres) + email + media (S3 / R2 / B2 / MinIO + presigned uploads + collections + tags) + production middleware (CSRF, CSP, rate-limiting, compression, idempotency, etc.).
Documentation
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{% block title %}rustango operator console{% endblock %}</title>
  <style>
    :root {
      --bg: #fdfdfd;
      --fg: #222;
      --muted: #666;
      --border: #d0d0d0;
      --accent: #b04a2c;     /* warm rust */
      --accent-bg: #f7e9e1;
      --sidebar-bg: #f5f0eb;
    }
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font: 14px/1.45 -apple-system, "Segoe UI", Roboto, sans-serif;
      color: var(--fg);
      background: var(--bg);
    }
    .shell { display: flex; min-height: 100vh; }
    aside.sidebar {
      width: 220px;
      background: var(--sidebar-bg);
      border-right: 1px solid var(--border);
      padding: 1rem 0;
      display: flex;
      flex-direction: column;
    }
    aside .brand {
      font-weight: 700;
      padding: 0 1rem 1rem 1rem;
      border-bottom: 1px solid var(--border);
      margin-bottom: 0.75rem;
      color: var(--accent);
    }
    aside nav { flex: 1; }
    aside nav a {
      display: block;
      padding: 0.55rem 1rem;
      color: var(--fg);
      text-decoration: none;
      border-left: 3px solid transparent;
    }
    aside nav a:hover { background: rgba(176, 74, 44, 0.05); }
    aside nav a.active {
      background: var(--accent-bg);
      border-left-color: var(--accent);
      font-weight: 600;
    }
    aside .who {
      padding: 0.5rem 1rem;
      font-size: 12px;
      color: var(--muted);
      border-top: 1px solid var(--border);
    }
    aside form.logout button {
      width: calc(100% - 2rem);
      margin: 0.5rem 1rem;
      padding: 0.4rem 0.6rem;
      background: white;
      border: 1px solid var(--border);
      border-radius: 4px;
      font: inherit;
      cursor: pointer;
      color: var(--fg);
    }
    aside form.logout button:hover { background: var(--accent-bg); border-color: var(--accent); }
    main {
      flex: 1;
      padding: 1.5rem 2rem;
      overflow-x: auto;
    }
    h1 { margin-top: 0; color: var(--accent); }
    table { border-collapse: collapse; width: 100%; margin-top: 1rem; }
    th, td {
      text-align: left;
      padding: 0.5rem 0.75rem;
      border-bottom: 1px solid var(--border);
    }
    th {
      background: var(--sidebar-bg);
      font-weight: 600;
      color: var(--muted);
      font-size: 12px;
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }
    tr:hover td { background: rgba(176, 74, 44, 0.03); }
    .empty {
      color: var(--muted);
      font-style: italic;
      padding: 1rem 0;
    }
    code {
      background: var(--sidebar-bg);
      padding: 0.1rem 0.35rem;
      border-radius: 3px;
      font-size: 0.9em;
    }
  </style>
</head>
<body>
  <div class="shell">
    <aside class="sidebar">
      <div class="brand">rustango</div>
      <nav>
        <a href="/" class="{% if section == 'home' %}active{% endif %}">Home</a>
        <a href="/operators" class="{% if section == 'operators' %}active{% endif %}">Operators</a>
        <a href="/orgs" class="{% if section == 'orgs' %}active{% endif %}">Organizations</a>
      </nav>
      <div class="who">signed in as <strong>{{ operator_username }}</strong></div>
      <form class="logout" method="post" action="/logout">
        <button type="submit">Sign out</button>
      </form>
    </aside>
    <main>
      {% block content %}{% endblock %}
    </main>
  </div>
</body>
</html>