Repository navigation
Conversation
Introduce a single source of truth for hiding non-MVP areas: a `features` map in both environment files (all off), typed by the `FeatureKey` union and checked with `satisfies FeatureFlagMap`, read through the `FeatureFlags.isEnabled()` service. Tests override flags with `provideFeatureFlags()`. `featureGuard(key, next?)` is a functional canMatch guard: while the flag is off the route does not match, so the URL falls through to the wildcard fallback like an unknown path (no blank page, no lazy chunk). An existing canMatch guard is chained through `next` because Angular runs every guard of a canMatch array eagerly.
Gate every non-MVP route with featureGuard so a disabled feature's URLs fall through to the `**` -> /projects fallback like unknown paths: billing (settings page + checkout success/cancel), usage, integrations (org + project pages and the Jira OAuth callback), members (org + project pages and the invitation landing), customRoles (roles list/new/edit) and the notifications/tokens account placeholders. Routes that already had a permission canMatch chain it through featureGuard so a hidden page never fetches permissions or toasts a denial. The invitation landing follows `members`: with it off nobody can invite from the UI and an owner has no screen to see or remove whoever joins, so a stale link must not add people to an org. The project settings landing skips members/roles while their feature is off. A spec drives the real route table to pin both directions.
Move the nav segment lists and their visibility rule into shell-nav.ts so they can be unit-tested, and add an optional `feature` to NavSeg that visibleNavSegs checks alongside role/permission. Flagged entries: org members/billing/integrations/usage, project roles/members/integrations and the account notifications/tokens placeholders. A "Settings" root entry with no reachable sub-page is now dropped, and the org one opens the first reachable sub-page instead of the owner-only General, so an admin never lands on a "no access" toast. The Jira job banner only mounts while integrations are on.
…menu The palette's "Members" quick action and backend MEMBER hits (both open /settings/members) only appear while `members` is on; the user menu's "Upgrade" CTA only while `billing` is on.
Wrap the backlog's Import from Jira / Push all / Push selected buttons and the story detail's Push to Jira in the `integrations` flag, skip the backlog's Jira-target lookup, and only let INTEGRATION_SYNC reveal the row-selection column while bulk push exists (bulk delete still needs STORY_DELETE).
The project overview drops its Members card (and no longer counts members/roles toward the Settings card) while `members` / `customRoles` are off. Org General hides the Transfer ownership card, and skips the member fetch that only feeds it, while `members` is off: without members there is nobody to pick and its empty state asks to invite someone.
Usage and billing are separate flags; keep the usage page free of a dead link to /settings/billing when only `usage` is turned on.
Add docs/FEATURE-FLAGS.md (each flag, what it hides, how to turn it on or add one, the invitation/ownership decisions and the backend FREE-plan limits) and link it from the README environments section.
Adds a `meeting` audio source for virtual calls (Zoom / Meet / Teams): the recorder opens the screen-share picker first (it needs the click's transient activation), keeps the shared surface's audio with voice processing off, stops the unused video track and then takes the mic. Both sources feed one mono GainNode mixer (explicit 1 channel, speakers down-mix) that drives the level meter and the PCM worklet, so `/ws/stt` still gets 16 kHz Int16 mono. - Sharing without "Share tab audio" stops the tracks and sets a notice; a dismissed picker stays idle without messages. - "Stop sharing" (audio track `ended`) disconnects the meeting audio and keeps streaming the mic with a notice; `shareMeetingAudio()` re-shares. - `pauseStreaming()` keeps the shared surface so a resume never re-opens the picker; `stopStreaming()` releases everything. - Socket handlers are detached before closing so a late close event can't tear down the next socket, and a session that fails to start releases the capture.
…ecorder Mocks navigator.mediaDevices to cover the picker-before-mic ordering (no await before getDisplayMedia), the display constraints, the dropped video track, the no-audio-track warning, silent picker dismissal, real capture failures, a missing getDisplayMedia, mic denial releasing the shared tab, the "Stop sharing" mic-only fallback and re-share, and pause vs. stop release. A real Web Audio graph with a fake socket checks that both sources feed the mono mixer, which drives the meter and the worklet. Also covers the desktop-Chromium support check and dismissal detection.
A compact segmented control next to the record button picks where the next recording takes its audio from: "In person (microphone)" or "Virtual meeting (microphone + meeting audio)". The choice is remembered per user in localStorage (try/catch) and locked while starting or once a session is live; the record click passes it to the recorder before any await so the screen-share picker keeps the click's activation, and a second click can't stack another picker. The virtual option stays visible but inert outside desktop Chromium, with the reason as tooltip and, on tap, as the composer hint. With the virtual source selected the hint explains to tick "Share tab audio" and to wear headphones; recorder notices (amber) render in the same line.
Covers the pressed state, switching to the virtual source, the inert virtual option (tooltip + unavailable event) where meeting audio is unsupported, the lock during a live session, the per-user storage key and the fallback to the microphone when a stored virtual choice can't be honoured.
…e session bar Virtual-meeting recordings show a meeting-audio badge next to the timer while the shared audio is mixed in. Once the user clicks "Stop sharing" (the recording carries on with the mic), the bar shows an amber "Share again" action that re-opens the picker straight from the click and mixes the new surface into the live (or paused) recording.
…hare Covers that in-person recordings show no meeting controls, that the badge shows while the meeting audio is captured, and that after "Stop sharing" the bar offers an accessible "Share again" button that calls the recorder.
# Conflicts: # CHANGELOG.md
Adds ai / verified / pending and priority tokens (light + dark) so AI-originated, human-validated and awaiting-review content stop sharing the brand red. The red fill moves to #dc2626 so white button labels pass AA (4.83:1); in dark, red used as text takes a lighter step. Muted text, the default focus outline and the active sidebar item now meet AA, and the nav indicator animates with transform.
hlmInput gave textareas the inputs' fixed h-10, so rows were ignored and story statements and Gherkin steps were clipped. Textareas now size to their content (field-sizing) from a two-line minimum. hlmLabel also styles span and legend labels, which rendered unstyled at 16px next to 14px labels.
AI status lines, review-tray and provenance labels, Gherkin hints, story status explanations, the labelled audio-source picker and its two-step virtual-meeting guidance, and the optional/required markers for the project forms. Speakers read "Participante n" in Spanish so they no longer collide with the story role.
…dges Shared presentational pieces: Given/When/Then steps behind a keyword gutter, a priority chip with a direction glyph (critical red, high orange, medium and low neutral), a review-status chip (draft = amber dashed, approved = emerald check) and an origin chip (AI from a session vs manual). Backlog stories in the chat store now keep their review status for the side panel.
…ions as AI The decision queue no longer floats over the viewport: it docks to the feed column, so the session bar (pause/stop), the header actions and the side panel stay reachable. A tray header names it, carries the counter with prev/next and minimize, and announces changes. Suggestion cards carry violet AI provenance, read the story as its sentence and criteria as Gherkin steps, highlight every field an update changes, edit in labelled auto-growing fields, and keep Discard apart from Edit/Cancel.
…reams
A status line at the live edge of each session says whether the AI is listening
(with the last suggestion's age), paused, generating the final stories after
Stop, or failed (with the backend reason). The transcript recedes into neutral
bubbles with always-visible speaker and time; human decisions become compact
rows ("accepted/resolved by the analyst"); AI-generated stories carry violet
provenance plus "awaiting review". Accepting confirms where the content went,
the load error offers a retry, and screen readers hear the review count. The
side panel gains tab semantics, labelled filters, Gherkin steps and status chips.
…te announced The picker becomes a labelled segmented control (In person / Virtual meeting) so it is never confused with the record button, which now shows a record dot and a "Record" label. The virtual-meeting guidance is a calm two-step note (share the meeting tab with its audio; wear headphones), and the missing-audio notice offers "Share again" in place. The session bar keeps its status label for screen readers on mobile and shows the meeting-audio badge on every width.
Sortable column headers with a direction arrow and aria-sort, plus a visible "sorted by" caption. Priority sorting is re-ordered by meaning on the page, since the API sorts the enum alphabetically. Rows show priority, review status and origin (AI from a session vs manual) chips, link their title for keyboard users, collapse into a chip row below sm, and use unambiguous dates. The empty state offers next steps and load errors offer a retry.
…d state The detail page leads with the story's title, review status (with what it means) and origin, linking an AI story back to its capture session. Role, action and benefit read top-down as the story sentence in full-width, auto-growing fields; Save enables only once something changed. Criteria use a Gherkin keyword gutter with labelled fields, flag new or edited rows as unsaved and only enable their own Save then. The create page shares the layout.
…tings Only the name is required, and both forms now say so. The technical profile is one clearly optional section grouped into business context (domain, architecture) and tech stack (chip lists, with an Enter-to-add hint), with placeholders that read as examples. Settings drop from eight one-field cards to General and Technical profile, each with its own Save, and the logo card is titled for the project. Chip inputs accept an id for their label, describe their hint and name each remove button.
The projects page was the only module without a visible heading; it now opens with its title and subtitle like the others, and the search field shows focus.
Light theme, 1440x900, Spanish demo data: projects list, new project and project settings, the live session (review tray, suggestion editing, an update diff, an AI question, processing after Stop), both audio sources, the backlog (default and by priority) and the story detail with its Gherkin criteria.
Tailwind's utilities are imported unlayered, so the layered override lost to .text-primary and red links stayed at 3.3:1 on navy. The override is now unlayered and wins by specificity (4.5:1 or better).
Also rewords the draft status hint so it no longer contradicts "accepted by the analyst": a draft is simply not approved yet.
…edge visible Arrow keys browse the tray and Escape minimizes it (ignored while typing); after a decision focus returns to the tray instead of the page body; focusing a feed control the tray covers minimizes it (WCAG 2.4.11). From sm the tray stops short of the feed bottom so the latest lines and the AI status stay in view; on phones its title is shortened. The audio picker no longer truncates its labels on desktop.
… fields Below sm the backlog page scrolls instead of a nested box that showed about one row. Draft status becomes an amber dashed outline so it is not mistaken for the filled orange High priority beside it. Story create/edit fields now say inline when a required field is left empty (aria-invalid + described message).
Both options split the picker evenly, which truncated "Reunión virtual". From sm each option takes its own width; on phones they still share the full row.
feat(discovery): capture virtual-meeting audio alongside the mic
feat(core): MVP feature flags that hide non-MVP areas
# Conflicts: # CHANGELOG.md
feat(ui): MVP UX polish from the heuristic evaluation
…nd CloudFront The S3 bucket and CloudFront distribution the old workflow targeted no longer exist. A push to main now dispatches deploy-mvp.yml in Kntro-Soft/reqsai-infra with web_ref set to the pushed commit, using the INFRA_DEPLOY_TOKEN secret; without the secret the job only logs a notice.
ci: deploy main through the reqsai-infra MVP pipeline
fix(ci): keep the running API image when the web triggers a deploy
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.
Description
Release of the MVP to
main:reqsai-infra(ci: deploy main through the reqsai-infra MVP pipeline #46, fix(ci): keep the running API image when the web triggers a deploy #47): a push tomaintriggers the "Deploy MVP" workflow withweb_ref=<sha>andapi_ref=keep, so only the web is rebuilt.Feature module / area: discovery / core / layout / shared / workspace / ci
How to Test
After merging, the "Deploy" workflow on
maintriggers "Deploy MVP" inKntro-Soft/reqsai-infra. Check https://reqsai.tech: the audio source picker, the MVP-only navigation and the polished session and stories pages.