Move feature flags and faucet config into /api/config#52
Conversation
📝 WalkthroughWalkthroughThis PR adds chain feature flags and faucet configuration to the /api/config payload, moves DA-tracking out of /status, wires new faucet fields through server AppState and runtime, and updates frontend types, normalization, context, hooks, and pages to consume the new Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Frontend
participant Server
participant AppState
Client->>Frontend: open app / Faucet page
Frontend->>Server: GET /api/config
Server->>AppState: read branding + features + faucet fields
AppState-->>Server: return config state
Server-->>Frontend: 200 JSON (branding + features + faucet)
Frontend->>Frontend: normalizeBrandingConfig(...)
Frontend->>BrandingContext: set branding (features, faucet, loaded)
Frontend->>FaucetHook: useFaucetInfo(faucet.enabled)
Note right of Frontend: Components render based on faucet.enabled and fetched info
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/api/config.ts`:
- Around line 20-25: getConfig() currently returns the raw /config response
typed as BrandingConfig but does no runtime validation; update getConfig to
normalize and validate the returned object so required fields are always
present: call client.get("/config"), verify that features exists and is an
object (fallback to a default ChainFeatures object) and that faucet exists and
matches FaucetConfig shape (fallback to { enabled: false, ...defaultProps }),
then return a fully populated BrandingConfig; reference the getConfig function
and the BrandingConfig/ChainFeatures/FaucetConfig types and ensure consumers
like Layout.tsx and FaucetPage.tsx can safely access faucet.enabled without
runtime errors.
In `@frontend/src/hooks/useFaucetInfo.ts`:
- Around line 37-53: The async handler in useFaucetInfo can let a response from
an earlier request overwrite state after enabled flips false; add a
request-version guard: create a mutable request counter/ref (e.g., requestIdRef)
that you increment when a new fetch starts in the function that calls
getFaucetInfo and capture the current id in the try block, then before calling
setFaucetInfo, setNotFound, setError, or setLoading check that the captured id
=== requestIdRef.current and skip state updates if it differs (also ensure the
guard handles the background flag similarly). Update functions referenced in the
diff (getFaucetInfo call and the setFaucetInfo / setNotFound / setError /
setLoading calls) to respect this request-id check so late in-flight responses
are ignored.
In `@frontend/src/pages/FaucetPage.tsx`:
- Around line 33-36: The NotFoundPage is rendering prematurely because
brandingDefaults initializes faucet.enabled=false; update the render logic to
wait for branding to finish loading from useBranding before treating notFound as
a 404: use the branding "loaded" (or similarly named) flag returned by
useBranding and gate the notFound/404 branch with it (i.e. only show
NotFoundPage when loaded && notFound). Apply the same change to the other
NotFound branch referenced (the block around the later faucet rendering at lines
~98-104) so both places check the branding loaded flag in addition to notFound.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6ad890fa-6085-4d8d-b6b8-7dcb0637aa82
📒 Files selected for processing (18)
backend/crates/atlas-server/src/api/handlers/config.rsbackend/crates/atlas-server/src/api/handlers/faucet.rsbackend/crates/atlas-server/src/api/handlers/health.rsbackend/crates/atlas-server/src/api/handlers/metrics.rsbackend/crates/atlas-server/src/api/handlers/status.rsbackend/crates/atlas-server/src/api/mod.rsbackend/crates/atlas-server/src/main.rsbackend/crates/atlas-server/tests/integration/common.rsfrontend/src/api/config.tsfrontend/src/api/status.tsfrontend/src/components/Layout.tsxfrontend/src/context/FaucetInfoContext.tsxfrontend/src/context/branding-context.tsfrontend/src/context/branding.tsfrontend/src/hooks/useFaucetInfo.tsfrontend/src/hooks/useFeatures.tsfrontend/src/pages/FaucetPage.tsxfrontend/src/types/index.ts
💤 Files with no reviewable changes (1)
- frontend/src/context/FaucetInfoContext.tsx
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
frontend/src/api/config.ts (1)
58-61: Normalize the optional branding strings too.This function now hardens
featuresandfaucet, but...configstill passeslogo_url*and color fields through unchanged. Since this normalizer now sits on both the/configand cached-config path, it would be safer to whitelist the existing optional string fields here as well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/api/config.ts` around lines 58 - 61, The returned config still spreads unvalidated branding fields; extend the normalizer to whitelist and sanitize optional branding strings (e.g. logo_url, logo_url_dark, favicon_url, and any theme/accent color fields) instead of passing them via ...config. Add a small helper (or reuse existing normalizers) and invoke it alongside normalizeFeatures and normalizeFaucet (e.g. normalizeBranding(config)) to coerce non-string values to null/empty-string and strip unexpected keys so only the allowed branding string/color fields are returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/api/config.ts`:
- Around line 49-50: The current check uses typeof faucet.cooldown_minutes ===
"number" which allows NaN, Infinity, negatives and fractions; change the
validation for cooldown_minutes in frontend/src/api/config.ts to only accept
finite, non-negative integers by replacing that predicate with a stricter one
such as Number.isFinite(faucet.cooldown_minutes) && faucet.cooldown_minutes >= 0
&& Number.isInteger(faucet.cooldown_minutes), and ensure the normalized object
includes cooldown_minutes only when that condition passes (refer to the existing
faucet.cooldown_minutes usage in the normalizer).
In `@frontend/src/hooks/useFaucetInfo.ts`:
- Around line 41-45: The background refresh success path in useFaucetInfo
(inside the try where getFaucetInfo() returns and you call setFaucetInfo(info))
must also clear any previously latched failure flags so the UI unblocks; after
verifying requestVersion === requestVersionRef.current and calling
setFaucetInfo(info), reset the error and notFound flags (e.g. call the relevant
setters such as setError(null/undefined) and setNotFound(false) or whatever
state setters you have for those flags) so a successful background refetch
clears earlier failures.
---
Nitpick comments:
In `@frontend/src/api/config.ts`:
- Around line 58-61: The returned config still spreads unvalidated branding
fields; extend the normalizer to whitelist and sanitize optional branding
strings (e.g. logo_url, logo_url_dark, favicon_url, and any theme/accent color
fields) instead of passing them via ...config. Add a small helper (or reuse
existing normalizers) and invoke it alongside normalizeFeatures and
normalizeFaucet (e.g. normalizeBranding(config)) to coerce non-string values to
null/empty-string and strip unexpected keys so only the allowed branding
string/color fields are returned.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 89c93471-201b-4c39-8bd8-e50562c376b7
📒 Files selected for processing (4)
frontend/src/api/config.tsfrontend/src/context/BrandingContext.tsxfrontend/src/hooks/useFaucetInfo.tsfrontend/src/pages/FaucetPage.tsx
✅ Files skipped from review due to trivial changes (1)
- frontend/src/context/BrandingContext.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/pages/FaucetPage.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/api/config.ts (1)
24-25: Avoid returning shared default object instances.Line 29 and Line 40 return module-level default objects by reference. Returning fresh objects avoids accidental cross-call mutation if any consumer mutates the normalized result.
♻️ Suggested hardening
-const defaultFeatures: ChainFeatures = { da_tracking: false }; -const defaultFaucet: FaucetConfig = { enabled: false }; +const makeDefaultFeatures = (): ChainFeatures => ({ da_tracking: false }); +const makeDefaultFaucet = (): FaucetConfig => ({ enabled: false }); function normalizeFeatures(value: unknown): ChainFeatures { if (!value || typeof value !== "object") { - return defaultFeatures; + return makeDefaultFeatures(); } @@ function normalizeFaucet(value: unknown): FaucetConfig { if (!value || typeof value !== "object") { - return defaultFaucet; + return makeDefaultFaucet(); }Also applies to: 29-30, 39-41
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/api/config.ts` around lines 24 - 25, defaultFeatures and defaultFaucet are module-level objects returned by reference; change the code to return fresh objects instead of the shared instances to prevent accidental cross-call mutation—either replace the constants with factory functions (e.g., getDefaultFeatures(), getDefaultFaucet()) that create and return new objects, or always return shallow copies (e.g., {...defaultFeatures}, {...defaultFaucet}) where the normalized result is produced (refer to the constants defaultFeatures and defaultFaucet to locate the code paths that currently return them).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@frontend/src/api/config.ts`:
- Around line 24-25: defaultFeatures and defaultFaucet are module-level objects
returned by reference; change the code to return fresh objects instead of the
shared instances to prevent accidental cross-call mutation—either replace the
constants with factory functions (e.g., getDefaultFeatures(),
getDefaultFaucet()) that create and return new objects, or always return shallow
copies (e.g., {...defaultFeatures}, {...defaultFaucet}) where the normalized
result is produced (refer to the constants defaultFeatures and defaultFaucet to
locate the code paths that currently return them).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 06d85049-39f2-45ed-aa33-9f03d790813f
📒 Files selected for processing (2)
frontend/src/api/config.tsfrontend/src/hooks/useFaucetInfo.ts
✅ Files skipped from review due to trivial changes (1)
- frontend/src/hooks/useFaucetInfo.ts
Summary
/api/config, and keep/api/heightlimited to height data/api/faucet/infofrom the global layoutValidation
cargo test -p atlas-serverbunx tsc --noEmitSummary by CodeRabbit
New Features
Refactor
Style