Template
Sweepwell
A data-retention settings page for an AI agent and workflow platform. Admins see where stored data lives, set how long runs are kept, and can purge inputs past the retention horizon immediately, with guard rails that protect active and pinned data.
Agent platform data-retention settings with purge controls · App screen: settings · Small tools and apps · full-stack app (auth + DB)
A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.
Start from this screenRead the build prompt
Typefaces
The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.
- InterHeadings: Inter 600, 18px section title; 24px storage figure (600)
- InterBody: Inter 400 16px explanations at 1.5; 14px labels (600); 13px helpers
Patterns
- three-level layout: app sidebar, settings sub-nav in tinted panel, content
- storage summary figure ("5.2 KB across 2 objects")
- area table with size and object count
- danger-bordered "Enforce now" card
- segmented controls for scope choices
- number inputs with trailing unit labels and helper counts
- disabled destructive button showing live count
- breadcrumb header with org switcher
States it is designed for
- Nothing to purge (disabled button + explanatory line)
- Items to purge with counts
- Purge in progress (progress bar, cancel)
- Purge completed (summary toast + audit link)
- Purge partially failed (retry failed batches)
- Invalid numbers (min 1 day, max 3650) inline errors
- Non-admin read-only
- Storage scan loading / failed
Who it is for
- Platform admins and security leads
- ML ops engineers managing storage
- Compliance officers enforcing retention policies
Layout
- App sidebar (~125-240px): logo; Trigger, Runs, Reviews, Monitoring; AGENT (Agents, Shared resources); WORKFLOW (Workflows, Templates); DEVELOPER (Webhooks, API keys, Connect); Settings (active, dark pill); Documentation; theme switcher
- Header: org switcher breadcrumb / Settings
- Settings sub-nav (grey rounded panel): Organization, Members, Model, Usage, Email servers, Data retention (active white pill), Billing, Monitoring
- Content: H2 + explanation; storage summary + Refresh; area table; Enforce now card (red border) with segmented controls, three number fields with units and helpers, Save policy, status line, danger button
- Mobile: sub-nav becomes a select; number fields stack
Palette
serious, precise, transparent, safe. Destructive power presented with visible guard rails.
- content background
#ffffff - sub-nav panel, segmented track
#f7f7f7 - primary text
#1a1a1a - explanations, helpers
#6b6b6b - active app nav pill
#1c1c1c - text on active pill
#ffffff - purge button fill
#b33a3a - danger card border
#d98080 - number input outline
#8a8a8a - logo and success mark
#1f9d55
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.40:1 | 4.5:1 |
| Aa | muted helper | 5.33:1 | 4.5:1 |
| Aa | sub-nav text on panel | 4.97:1 | 4.5:1 |
| Aa | active nav label | 17.04:1 | 4.5:1 |
| Aa | danger button label | 5.86:1 | 4.5:1 |
| input border | 3.45:1 | 3:1 | |
| focus ring | 17.04:1 | 3:1 | |
| brand mark | 3.49:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent
- destructive *
Type scale
- Display
- Inter 600, 18px section title; 24px storage figure (600)
- Body
- Inter 400 16px explanations at 1.5; 14px labels (600); 13px helpers
Similar to the observed grotesk. Paths like "agents/" in JetBrains Mono 13px. Nav group labels 12px uppercase with 0.08em tracking.
Spacing and imagery
Medium density: 4px base; content max 520-720px; card padding 16px; 16px between field groups; radius 10px cards and sub-nav panel, 8px segmented items and inputs; no shadows.
None. Outline icons in nav; a small database icon in sub-nav items.
Components
- App sidebar with group labels and active dark pill
- Breadcrumb with org switcher
- Settings sub-nav
- Storage summary with Refresh
- Area table
- Danger card
- Segmented control (What to delete; Which runs)
- Number input with unit suffix and helper count
- Save policy button
- Purge button with live count
- Typed confirmation dialog
Interactions
- Changing any control recalculates "N with inputs past this horizon" helpers (debounced 300ms)
- Purge disabled when count is 0; label shows count "Purge inputs of both (12)…"
- Purge opens a dialog requiring the org name to be typed; progress then streams per batch
- Save policy persists for scheduled enforcement; unsaved changes show a dot on the button
- Refresh re-scans storage with spinner
Data
RetentionPolicy{org_id, delete_scope (inputs|full_runs), run_kinds (eval|other|both), eval_days, other_days, max_per_pass, updated_by, updated_at}StorageArea{org_id, name, path, bytes, objects}Run{id, org_id, kind (eval|manual|api|email|scheduled), status (active|terminal), pinned bool, created_at, inputs_path}PurgeJob{id, org_id, requested_by, status (queued|running|done|failed), deleted_count, started_at}AuditEvent{id, org_id, actor_id, action, details jsonb, at}
Guardrails
Experience
- Explain exactly what is never deleted (active, pinned, dataset content) above the controls
- Show the live count of affected items before any destructive action
- Separate "Save policy" (scheduled) from "Purge now" (immediate)
- Process oldest first and cap per pass; say so in helper text
- Always link to the audit log after a purge
Accessibility
- Segmented controls are radio groups with a legend
- Number inputs have labels, unit text via aria-describedby, and inline errors
- Danger card border is supplemented by a heading and icon, not colour only
- Confirmation dialog focuses the text field and names the consequence
- Live count changes announced politely
Security
- Purge runs server-side as a queued job with the caller's admin role verified
- Typed confirmation + recent re-authentication for destructive actions
- Every policy change and purge written to an append-only audit log
- RLS: only org admins update retention policies; members read-only
- Rate-limit purge requests (one running job per org)
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack entries) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs. ### SaaS screen baseline - Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs. - Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible. - Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy. - Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke. - Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal
Build **Sweepwell**, the Data retention page in an AI agent platform's settings. Admins see how much is stored and where, set retention horizons for evaluation runs and other runs, save that as a scheduled policy, and can purge eligible run inputs right away. Active runs, pinned runs and dataset content are never deleted.
### Stack
React + TypeScript + Vite, Tailwind CSS, shadcn/ui (ToggleGroup, Input, Dialog, Table, Progress, Toast) on Radix, lucide-react, TanStack Query, react-hook-form + zod. Supabase for auth, policies and runs; an Edge Function performs purges in batches and writes audit events.
### Pages & layout
1. **App sidebar**: logo; Trigger, Runs, Reviews, Monitoring; AGENT: Agents, Shared resources; WORKFLOW: Workflows, Templates; DEVELOPER: Webhooks, API keys, Connect; Settings (active dark pill); Documentation; a light/dark/system switch.
2. **Header**: org switcher ("Fernhill Labs") / Settings.
3. **Settings sub-nav** (grey rounded panel): Organization, Members, Model, Usage, Email servers, Data retention (active white pill), Billing, Monitoring.
4. **Content**: title and a two-line explanation; "5.2 KB across 2 objects" with Refresh; an area table (Area with mono path and description, Size, Objects).
5. **Enforce now card** (red-tinted border): "What to delete" segmented (Input files only / Full runs); "Which runs" segmented (Eval / Other / Both); three number inputs with units and helpers (Eval runs older than 30 days, Other runs older than 90 days, Max per pass 500 runs); Save policy; status line ("No runs past the horizon, nothing to purge"); danger button "Purge inputs of both (0)…".
6. Mobile: the sub-nav becomes a Select; fields stack.
### Design system
- Colors: `--bg: #ffffff` (content background), `--canvas: #f7f7f7` (sub-nav panel, segmented track), `--fg: #1a1a1a` (primary text), `--muted: #6b6b6b` (explanations, helpers), `--nav-active: #1c1c1c` (active app nav pill), `--on-dark: #ffffff` (text on active pill), `--danger: #b33a3a` (purge button fill), `--danger-border: #d98080` (danger card border), `--input-border: #8a8a8a` (number input outline), `--brand: #1f9d55` (logo and success mark).
- Fonts: Inter (similar to the observed grotesk): section title 18px/600, storage figure 24px/600, body 16px/1.5, labels 14px/600, helpers 13px; JetBrains Mono 13px for paths; nav group labels 12px uppercase with 0.08em tracking.
- Spacing: 4px base; card padding 16px; 16px field-group gap; content max 720px.
- Radius: 10px cards and panels; 8px inputs and segments.
- Shadows: none.
- Motion: 150ms segment slide; progress bar during purge.
### Components & interactions
AppSidebar, Breadcrumb, SettingsSubNav, StorageSummary (Refresh with spinner), AreaTable, DangerCard, SegmentedRadio, NumberWithUnit (min 1, max 3650, inline errors), EligibleCountHelper (recomputed 300ms after changes; announced politely), SavePolicyButton (unsaved dot), PurgeButton (disabled at 0; shows count), ConfirmPurgeDialog (type the org name; shows what will and won't be deleted), PurgeProgress (per batch, cancel), Toast with audit link.
### Data & state
Tables: `retention_policies(org_id, delete_scope, run_kinds, eval_days, other_days, max_per_pass, updated_by, updated_at)`, `storage_areas(org_id, name, path, bytes, objects)`, `runs(id, org_id, kind, status, pinned, created_at, inputs_path)`, `purge_jobs(id, org_id, requested_by, status, deleted_count)`, `audit_events(id, org_id, actor_id, action, details, at)`. RPC `count_purge_candidates(policy)` returns counts. Mock two areas and 40 runs. Handle states: nothing to purge, items to purge, in progress, completed, partial failure, invalid numbers, read-only, scan failed.
### Accessibility
Segmented controls are radio groups with legends. Inputs have labels and describe their units and helpers. The danger card has a heading and warning icon besides its border. The dialog names the consequence and focuses the field. Count changes announce politely. Focus ring: 2px near-black with offset.
Verified contrast: body text: #1a1a1a on #ffffff = 17.40:1; muted helper: #6b6b6b on #ffffff = 5.33:1; sub-nav text on panel: #6b6b6b on #f7f7f7 = 4.97:1; active nav label: #ffffff on #1c1c1c = 17.04:1; danger button label: #ffffff on #b33a3a = 5.86:1; input border: #8a8a8a on #ffffff = 3.45:1; focus ring: #1c1c1c on #ffffff = 17.04:1; brand mark: #1f9d55 on #ffffff = 3.49:1.
### Security
Purges run only in the Edge Function after verifying the admin role and a recent re-authentication. Candidates exclude active, pinned and dataset-linked runs in SQL, not in the UI. Only one job per org runs at a time. Every policy save and purge writes an append-only audit row. RLS: admins update policies; members read.
### Performance & SEO
Purge in batches up to max-per-pass, oldest first, streaming progress. Cache the storage scan for 5 minutes. The app is noindex.
### Guardrails
- Invented org and agent names.
- Never enable purge without a visible count and a typed confirmation.
- Acceptance criteria: (1) counts update as controls change; (2) protected runs are never deleted; (3) policy save and purge are separate; (4) the audit log records both; (5) all states render; (6) keyboard and screen-reader checks pass.