You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ai_synth/docs/superpowers/specs/2026-03-26-polish-optimizat...

4.2 KiB

Design: Polish & Optimization Items (Audit Medium Priority)

Date: 2026-03-26 Scope: 8 polish/optimization items from the code audit Source: docs/audit/00-consolidated-summary.md — Medium Priority section


1. Batch article history INSERTs

Problem: Each trace_article call does an individual INSERT. 20+ sequential DB round-trips per generation.

Fix: Add batch_insert_entries(pool, entries: &[ArticleHistoryEntry]) in db/article_history.rs using unnest() arrays for bulk INSERT. In synthesis.rs, collect traces into a Vec and flush in a single batch call at the end of each processing phase.

Files: backend/src/db/article_history.rs, backend/src/services/synthesis.rs


2. Reduce .clone() in pipeline with Arc

Problem: model_research, classification_categories, classify_schema, and other immutable values are cloned into every spawned task (59 clones identified).

Fix: Wrap these values in Arc<str> or Arc<Value> at the start of run_generation_inner. Spawned tasks clone the Arc (cheap pointer copy) instead of the full string/JSON value. Target the heaviest clones inside the batch loops.

Files: backend/src/services/synthesis.rs


3. Cache CSS selectors with LazyLock

Problem: Selector::parse("a[href]") is called on every invocation of link extraction functions, re-parsing the same static selector.

Fix: Use std::sync::LazyLock<Selector> for static selectors in source_scraper.rs and scraper.rs.

Files: backend/src/services/source_scraper.rs, backend/src/services/scraper.rs


4. Standardize frontend data fetching on createResource

Problem: Some pages use createResource, others use onMount + manual signals for data loading. Inconsistent patterns.

Fix: Convert pages that use onMount + createSignal for data loading to use createResource. Only change pages where the pattern is clearly onMount → fetch → setSignal and createResource is a direct fit. Don't force conversions where the pattern is more complex (e.g. SSE, conditional fetching).

Files: Frontend pages using the onMount + signal pattern (identify by reading each page)


5. Use existing Button component

Problem: A reusable Button component exists but inline Tailwind button classes are duplicated across pages.

Fix: Replace obvious inline button markup with the existing Button component. Only do clear-cut cases where the button matches the component's API — don't force every button into it.

Files: Frontend pages with inline button markup


6. Align default settings between frontend and backend

Problem: DEFAULT_SETTINGS in frontend and Default for UserSettings in backend have different category lists and potentially other divergent values.

Fix: The backend is authoritative. Update DEFAULT_SETTINGS in frontend/src/types.ts to match Default for UserSettings in backend/src/models/settings.rs. The frontend defaults are only used as initial form state before the API response arrives, so they should match what the backend would return for a new user.

Files: frontend/src/types.ts


7. Remove unused SESSION_SECRET

Problem: session_secret is loaded from env, validated (min 64 chars), stored in AppConfig, but never referenced anywhere in the codebase. The app uses DB-backed session tokens, not signed cookies.

Fix:

  • Remove session_secret field from AppConfig struct
  • Remove required_var("SESSION_SECRET") from config loading
  • Remove the session_secret length validation
  • Remove from .env.example
  • Update related tests

Files: backend/src/config.rs, .env.example


8. Wrap AppConfig master key in Arc

Problem: master_encryption_key is a cloneable String in AppConfig. Since AppConfig is cloned into AppState, the secret exists in multiple memory locations.

Fix: Change master_encryption_key: String to master_encryption_key: Arc<String> in AppConfig. Update all call sites that reference state.config.master_encryption_key — they already call MasterKey::from_hex(&...) which takes &str, so Arc<String> derefs transparently.

Files: backend/src/config.rs, and any files that access config.master_encryption_key