Add admin-togglable feature flags, gate AI monster generator - #360
Open
HarmlessHarm wants to merge 9 commits into
Open
Add admin-togglable feature flags, gate AI monster generator#360HarmlessHarm wants to merge 9 commits into
HarmlessHarm wants to merge 9 commits into
Conversation
Adds a small, code-defined feature flag registry backed by Firebase, an admin page to toggle flags, and a Vuex module that fetches current values once per app load (client boot / each SSR render) — no live push to open tabs, no redeploy required for a toggle to take effect. Wires up the first flag, monster_generator, in two places: hides the "Generate from description" entry point in the New Monster dialog when disabled, and rejects POST /ai/generate-monster server-side so the kill switch is authoritative even if a request bypasses the UI. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
q-list wasn't passed the dark prop, so q-item-label text (the flag id caption) rendered with light-theme coloring on the dark background. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
- EditNpc.vue: hide the "OR" divider along with the "Generate from description" button so it doesn't dangle when the flag is off. - Npcs.vue: the NPC list page has its own "Generate" toolbar button and overflow-menu item that also open the AI generator; gate both. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
ImportContent/index.vue has its own "Generate" button opening GenerateMonster.vue, separate from the NPC list and New Monster dialog. Verified via grep that all GenerateMonster.vue usages (3 total) are now gated by the monster_generator flag. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
All 27 tasks confirmed complete. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
src-ssr/*.js is not run through Babel (see the warning comment in src-ssr/index.js), and this project's webpack 4 parser doesn't understand the ES2020 optional-chaining/nullish-coalescing syntax used in isFlagEnabled's fallback lookup. Dev mode (npm run ssr) didn't catch this since it takes a different, more lenient path; the production build (npx quasar build -m ssr, used by the Dockerfile) failed to parse it. Replaced with a plain flagDefault() helper using only pre-ES2020 syntax. Verified with a full `npx quasar build -m ssr` run. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
src/utils/featureFlags.js) backed by Firebase (feature_flags/<flag_id>), with a Vuex module (src/store/modules/featureFlags.js) that fetches current values once per app load — client boot and every SSR render, not live-reactive to already-open tabs, and no redeploy required for a toggle to take effect./admin/feature-flags(src/views/Admin/FeatureFlags.vue) listing every registered flag with a toggle, gated the same way as the rest of/admin.monster_generator(default: enabled), wired up in two places:EditNpc.vue) when disabled.POST /ai/generate-monsterinsrc-ssr/api/index.jsnow rejects with a 403 when disabled, before any credit lookup or call to the external generator API.feature_flags(admin-only write, public read) have been added, matching the existingpromotionsrule.openspec/changes/feature-flags-admin/Test plan
npm run lintpassesnpm run ssr— client and server compile cleanly;/returns 200;/admin/feature-flags302-redirects when not signed in as admin/admin/feature-flagslistsmonster_generatortoggled on by defaultmonster_generatoroff, reload the New Monster dialog inEditNpc.vue, confirm "Generate from description" is gonePOST /ai/generate-monsterdirectly with a valid token and confirm it's rejected without spending credits or calling the external APIfeature_flags/monster_generatornode entirely and confirm the feature behaves as enabled (registry default)🤖 Generated with Claude Code
https://claude.ai/code/session_017AuRuGWkBbBzeKpqtrq9qR