refactor: update AsyncQueueManager to use a single RabbitMQ priority queue and enhance connection handling; add default queue name and priority mapping#256
Conversation
…nce Tailwind CSS configuration for improved styling
…ist sections with improved styling and functionality
…onents with QuickLink for improved hash navigation, and update Waitlist component for type safety
…default behavior in handleSmoothScroll function in Navbar
…queue and enhance connection handling; add default queue name and priority mapping
📝 WalkthroughWalkthroughThis PR introduces a major backend queue architecture refactoring and comprehensive landing page redesign. The backend replaces inefficient polling-based multi-queue system with a single RabbitMQ priority queue using push-based consumption. The landing pages are redesigned with Material-UI components, new CSS design tokens, and animated interactive elements including updated navigation, footer, hero section, and waitlist form, alongside new dependencies and a custom Button component. Changes
Sequence DiagramsequenceDiagram
actor Client
participant Manager as AsyncQueueManager
participant RabbitMQ as RabbitMQ<br/>(Single Priority Queue)
participant Worker1 as Worker 1
participant Handler as Message Handler
Note over Client,Handler: Old Flow (Polling-Based)
Client->>Manager: enqueue(msg, priority=HIGH)
Manager->>RabbitMQ: publish to HIGH_QUEUE
Worker1->>Worker1: sleep(0.1)
Worker1->>RabbitMQ: poll HIGH_QUEUE
Worker1->>RabbitMQ: poll MEDIUM_QUEUE
Worker1->>RabbitMQ: poll LOW_QUEUE
RabbitMQ-->>Worker1: message (if available)
Note over Client,Handler: New Flow (Push-Based)
Client->>Manager: enqueue(msg, priority=HIGH)
Manager->>RabbitMQ: publish to queue<br/>with priority=10
Worker1->>RabbitMQ: await queue.iterator()
RabbitMQ-->>Worker1: push message immediately
Worker1->>Manager: _process_item(msg)
Manager->>Handler: call async/sync handler
Handler-->>Manager: result
Manager->>RabbitMQ: ack message
RabbitMQ-->>Worker1: ready for next message
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
landing/src/components/sections/Waitlist.tsx (1)
55-104: Trim values before submission to avoid trailing-space data.You validate with
trim()but still submit raw values. This can store whitespace in Google Forms entries.✅ Suggested fix
- if (!name.trim() || !email.trim() || !organization.trim() || !role) { + const trimmedName = name.trim(); + const trimmedEmail = email.trim(); + const trimmedOrganization = organization.trim(); + const trimmedSuggestions = suggestions.trim(); + + if (!trimmedName || !trimmedEmail || !trimmedOrganization || !role) { throw new Error('All fields are required except suggestions'); } const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - if (!emailRegex.test(email)) { + if (!emailRegex.test(trimmedEmail)) { throw new Error('Please enter a valid email address'); } const formData = new URLSearchParams(); - formData.append(FIELD_MAPPINGS.name, name); - formData.append(FIELD_MAPPINGS.email, email); - formData.append(FIELD_MAPPINGS.organization, organization); + formData.append(FIELD_MAPPINGS.name, trimmedName); + formData.append(FIELD_MAPPINGS.email, trimmedEmail); + formData.append(FIELD_MAPPINGS.organization, trimmedOrganization); formData.append(FIELD_MAPPINGS.role, role); - if (suggestions) { - formData.append(FIELD_MAPPINGS.suggestions, suggestions); + if (trimmedSuggestions) { + formData.append(FIELD_MAPPINGS.suggestions, trimmedSuggestions); }backend/app/core/orchestration/queue_manager.py (1)
145-165: Propagate handler failures so messages aren’t silently acked.
Exceptions are caught and swallowed, so_workerstill acks messages even when processing fails. Re-raise after logging (or return a success flag) so the worker can nack and avoid silent loss.🐛 Suggested fix
except Exception as e: logger.error(f"Error processing item {item.get('id', 'unknown')}: {str(e)}") + raise
🤖 Fix all issues with AI agents
In `@backend/app/core/orchestration/queue_manager.py`:
- Around line 87-109: Guard the enqueue method against an uninitialized or
closed channel by checking self.channel exists and is open before publishing (in
the enqueue function) and raise or log a clear error if not ready; update stop()
to explicitly set self.channel = None (and any related connection state) so
post-shutdown calls hit the guard; reference the enqueue method's use of
self.channel.default_exchange.publish and the stop/connect/start lifecycle
methods to implement these checks and state resets.
In `@landing/package.json`:
- Around line 15-16: Update package.json to pin the react-is package to the
React 18-compatible release so MUI v7 doesn't pull react-is@19; add or update
the dependency resolution settings (use "resolutions" for yarn or "overrides"
for npm >=8.13+) to force "react-is": "18.3.1" alongside your existing
dependencies ("@mui/material" and "@mui/icons-material") and run install to lock
the transitive version.
In `@landing/src/components/layout/Footer.tsx`:
- Around line 28-74: QuickLink is declared inside Footer causing re-creation on
each render; move the QuickLink component definition out of Footer (make it a
top-level component) and update its signature to accept props for navigate and
isHomePage (or obtain navigate via context) so Footer passes navigate and
isHomePage into QuickLink; ensure the prop type remains React.FC<{ link: {
label: string; href: string }; isHomePage: boolean; navigate: (to: string) =>
void }> (or adjust if using context) and update Footer usage to pass the values
accordingly.
In `@landing/src/components/layout/Navbar.tsx`:
- Around line 53-60: Update the misleading comment inside handleSmoothScroll to
match the actual behavior: since e.preventDefault() is called, remove or
rephrase the line that says "Do not prevent default navigation" so it accurately
states that default navigation is prevented, the mobile menu is closed via
setIsOpen(false), and navigation is performed programmatically with
navigate(href) (the scrolling is handled elsewhere by the useEffect). Ensure the
comment references handleSmoothScroll, e.preventDefault(), setIsOpen, and
navigate for clarity.
In `@landing/src/index.css`:
- Around line 142-153: The pseudo-element stacking for buttons is wrong: update
.btn-primary::before and .btn-secondary::before to use z-index: 1 (instead of
-1), ensure any corresponding ::after pseudo-element keeps z-index: 0, and
ensure the button inner content (e.g., the element targeted by .btn-primary
.content or the main button selector) has z-index: 10 so the gradient sits
behind content but above the button background; alternatively, if the Hero
component intentionally uses inline sx overrides for backgroundPosition and you
want to remove the unused animation, delete the ::before/::after
animation/transition rules for .btn-primary/.btn-secondary and rely on the
inline styles used in the Hero component.
🧹 Nitpick comments (5)
landing/src/components/layout/Navbar.tsx (1)
81-91: Consider extracting the brand gradient to a reusable style.The gradient style for "Devr.AI" is defined inline here and duplicated in
Footer.tsx. Consider extracting it to a CSS class inindex.cssor a shared constant to maintain consistency and reduce duplication.landing/src/components/layout/Footer.tsx (1)
138-199: Redundant styling:classNameduplicatessxprop.Multiple elements define the same styles in both Tailwind
classNameand MUIsxprop (e.g., lines 139-144). Choose one styling approach for consistency and reduced maintenance burden.Example of redundancy at lines 139-144
// Current: both className and sx define the same styles <Box className="absolute inset-0 pointer-events-none" sx={{ position: 'absolute', inset: 0, pointerEvents: 'none', }} >Pick either Tailwind classes or MUI
sxprop, not both.landing/src/components/sections/Hero.tsx (2)
32-45: Avoid duplicate layout sources (className + sx).Both
classNameandsxdefine the same layout (minHeight, flex, alignment, padding). Picking one source prevents future drift and style conflicts.♻️ Suggested cleanup
- <Box - component="section" - className="relative min-h-screen flex items-center justify-center pt-32 pb-20 overflow-hidden" + <Box + component="section" sx={{ position: 'relative', minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', paddingTop: { xs: 8, md: 16 }, paddingBottom: { xs: 5, md: 10 }, overflow: 'hidden', }} >
190-218: Considerdisplay: inline-blockfor gradient span.Some browsers handle background-clip on inline text more reliably with
inline-block.🎨 Optional tweak
<Box component="span" className="gradient-text" sx={{ + display: 'inline-block', background: 'linear-gradient(to right, `#4ade80`, `#3b82f6`, `#22d3ee`, `#2563eb`, `#10b981`)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', }} >landing/src/components/sections/Waitlist.tsx (1)
322-417: Consider extracting shared TextField styles.The same
sxpattern repeats across multiple fields; a shared base style would reduce duplication and ease maintenance.♻️ Example extraction
+ const baseTextFieldSx = { + '& .MuiOutlinedInput-root': { + backgroundColor: 'rgba(39, 39, 42, 0.8)', + backdropFilter: 'blur(8px)', + color: 'white', + borderRadius: '12px', + border: '1px solid rgba(63, 63, 70, 1)', + transition: 'all 0.3s ease', + '&:hover': { borderColor: 'rgba(82, 82, 91, 1)' }, + '& fieldset': { border: 'none' }, + }, + '& .MuiInputLabel-root': { + color: 'rgba(209, 213, 219, 1)', + fontWeight: 600, + fontSize: '0.875rem', + }, + '& .MuiInputBase-input': { + color: 'white', + '&::placeholder': { color: 'rgba(113, 113, 122, 1)', opacity: 1 }, + }, + };Then apply in fields:
- <TextField + <TextField id="name" ... - sx={{ - '& .MuiOutlinedInput-root': { ... }, - '& .MuiInputLabel-root': { ... }, - '& .MuiInputBase-input': { ... }, - }} + sx={{ + ...baseTextFieldSx, + '& .MuiOutlinedInput-root': { + ...baseTextFieldSx['& .MuiOutlinedInput-root'], + '&.Mui-focused': { + borderColor: 'rgba(34, 197, 94, 0.5)', + boxShadow: '0 0 0 2px rgba(34, 197, 94, 0.1)', + }, + }, + '& .MuiInputLabel-root': { + ...baseTextFieldSx['& .MuiInputLabel-root'], + '&.Mui-focused': { color: 'rgba(34, 197, 94, 1)' }, + }, + }} />
| async def enqueue( | ||
| self, | ||
| message: Dict[str, Any], | ||
| priority: QueuePriority = QueuePriority.MEDIUM, | ||
| delay: float = 0, | ||
| ) -> None: | ||
| """Add a message to the single priority queue.""" | ||
| if delay > 0: | ||
| await asyncio.sleep(delay) | ||
|
|
||
| queue_item = { | ||
| "id": message.get("id", f"msg_{datetime.now().timestamp()}"), | ||
| "priority": priority, | ||
| "data": message | ||
| "priority": priority.value, | ||
| "data": message, | ||
| } | ||
| json_message = json.dumps(queue_item).encode() | ||
| json_body = json.dumps(queue_item).encode() | ||
| numeric_priority = PRIORITY_MAP[priority] | ||
|
|
||
| await self.channel.default_exchange.publish( | ||
| aio_pika.Message(body=json_message), | ||
| routing_key=self.queues[priority] | ||
| aio_pika.Message(body=json_body, priority=numeric_priority), | ||
| routing_key=self.queue_name, | ||
| ) | ||
| logger.info(f"Enqueued message {queue_item['id']} with priority {priority}") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's find the queue_manager.py file and check its full implementation
find . -name "queue_manager.py" -type fRepository: AOSSIE-Org/Devr.AI
Length of output: 111
🏁 Script executed:
# Read the queue_manager.py file to understand the full context
cat -n backend/app/core/orchestration/queue_manager.pyRepository: AOSSIE-Org/Devr.AI
Length of output: 7410
🏁 Script executed:
# Search for all calls to enqueue() to see how it's being used
rg -n "enqueue\s*\(" -C3Repository: AOSSIE-Org/Devr.AI
Length of output: 2515
🏁 Script executed:
# Check the discord bot initialization to see how queue_manager is set up
grep -n "queue_manager\|AsyncQueueManager" backend/integrations/discord/bot.py -C5Repository: AOSSIE-Org/Devr.AI
Length of output: 2013
🏁 Script executed:
# Check the agent_coordinator to see how queue_manager is initialized there
grep -n "queue_manager\|AsyncQueueManager" backend/app/core/orchestration/agent_coordinator.py -C5Repository: AOSSIE-Org/Devr.AI
Length of output: 1806
🏁 Script executed:
# Check the cogs.py to understand the queue initialization
grep -n "queue\|AsyncQueueManager" backend/integrations/discord/cogs.py -C5Repository: AOSSIE-Org/Devr.AI
Length of output: 2138
🏁 Script executed:
# Find the main entry point and bot startup logic
find . -name "main.py" -o -name "run.py" -o -name "app.py" | head -5Repository: AOSSIE-Org/Devr.AI
Length of output: 79
🏁 Script executed:
# Search for where the bot and queue_manager are initialized
rg -n "AsyncQueueManager\(\|DiscordBot\(" -C5 | head -60Repository: AOSSIE-Org/Devr.AI
Length of output: 44
🏁 Script executed:
# Check if there's a startup sequence or main module
find . -name "*.py" -path "*/backend/*" -type f | grep -E "(main|run|startup|__main__|server)" | head -10Repository: AOSSIE-Org/Devr.AI
Length of output: 181
🏁 Script executed:
# Check the main.py to see the startup sequence
cat -n ./backend/main.pyRepository: AOSSIE-Org/Devr.AI
Length of output: 6106
Guard enqueue() against disconnected/uninitialized queue manager.
If enqueue() is called before connect()/start() completes or after stop() is invoked, self.channel is either None or closed, causing runtime failures. Add a defensive guard:
async def enqueue(
self,
message: Dict[str, Any],
priority: QueuePriority = QueuePriority.MEDIUM,
delay: float = 0,
) -> None:
"""Add a message to the single priority queue."""
+ if not self.channel:
+ raise RuntimeError("Queue manager not connected. Call start() before enqueue().")
if delay > 0:
await asyncio.sleep(delay)Note: The stop() method should also reset self.channel = None to ensure the guard catches post-shutdown attempts.
🤖 Prompt for AI Agents
In `@backend/app/core/orchestration/queue_manager.py` around lines 87 - 109, Guard
the enqueue method against an uninitialized or closed channel by checking
self.channel exists and is open before publishing (in the enqueue function) and
raise or log a clear error if not ready; update stop() to explicitly set
self.channel = None (and any related connection state) so post-shutdown calls
hit the guard; reference the enqueue method's use of
self.channel.default_exchange.publish and the stop/connect/start lifecycle
methods to implement these checks and state resets.
| "@mui/icons-material": "^7.3.7", | ||
| "@mui/material": "^7.3.7", |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
MUI Material @mui/material v7.3.7 React 18 compatibility peer dependencies
💡 Result:
For MUI Material @mui/material@7.3.7, the React 18-compatible peer dependency ranges are:
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
}[1]
Important for React 18 (and below): MUI v7 uses react-is@19, so if you’re on React 18 you should pin/override react-is to the same version as your react (e.g., react-is@18.3.1) to avoid runtime issues. [1][2]
Sources: [1] MUI v7.3.7 Installation docs, [2] MUI “Upgrade to v7” migration docs.
Pin react-is to match React version to avoid runtime issues with MUI v7.
MUI v7.3.7 is compatible with React 18.2.0, but v7 uses react-is@19. Add or update resolutions (yarn) or overrides (npm 8.13+) to pin react-is@18.3.1 to match your React version and prevent runtime issues.
🤖 Prompt for AI Agents
In `@landing/package.json` around lines 15 - 16, Update package.json to pin the
react-is package to the React 18-compatible release so MUI v7 doesn't pull
react-is@19; add or update the dependency resolution settings (use "resolutions"
for yarn or "overrides" for npm >=8.13+) to force "react-is": "18.3.1" alongside
your existing dependencies ("@mui/material" and "@mui/icons-material") and run
install to lock the transitive version.
| const QuickLink: React.FC<{ link: { label: string; href: string }; isHomePage: boolean }> = ({ link, isHomePage }) => { | ||
| const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => { | ||
| e.preventDefault(); | ||
|
|
||
| // Construct target href (preserve hash). On non-home pages we prefix with '/' | ||
| const target = isHomePage ? link.href : `/${link.href}`; | ||
|
|
||
| // Navigate so location.hash updates; scrolling is handled by Navbar's useEffect | ||
| navigate(target); | ||
| }; | ||
|
|
||
| return ( | ||
| <MuiLink | ||
| href={link.href} | ||
| onClick={(e) => handleClick(e)} | ||
| className="text-gray-400 hover:text-green-400 text-sm transition-colors duration-300 inline-flex items-center gap-2 group" | ||
| sx={{ | ||
| color: 'rgba(161, 161, 170, 1)', | ||
| fontSize: '0.875rem', | ||
| textDecoration: 'none', | ||
| display: 'inline-flex', | ||
| alignItems: 'center', | ||
| gap: '8px', | ||
| position: 'relative', | ||
| transition: 'color 0.3s ease', | ||
| '&:hover': { | ||
| color: 'rgba(34, 197, 94, 1)', | ||
| }, | ||
| '&::before': { | ||
| content: '""', | ||
| width: 0, | ||
| height: '2px', | ||
| background: 'linear-gradient(to right, #4ade80, #22d3ee)', | ||
| transition: 'width 0.3s ease', | ||
| position: 'absolute', | ||
| left: 0, | ||
| bottom: '-2px', | ||
| }, | ||
| '&:hover::before': { | ||
| width: '16px', | ||
| }, | ||
| }} | ||
| > | ||
| {link.label} | ||
| </MuiLink> | ||
| ); | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Move QuickLink outside the Footer component to prevent unnecessary re-renders.
QuickLink is defined inside Footer, causing it to be recreated on every render. This breaks React's reconciliation and can cause performance issues. Move it outside the component, passing navigate and isHomePage as props or via context.
♻️ Suggested refactor
+interface QuickLinkProps {
+ link: { label: string; href: string };
+ isHomePage: boolean;
+ navigate: ReturnType<typeof useNavigate>;
+}
+
+const QuickLink: React.FC<QuickLinkProps> = ({ link, isHomePage, navigate }) => {
+ const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
+ e.preventDefault();
+ const target = isHomePage ? link.href : `/${link.href}`;
+ navigate(target);
+ };
+
+ return (
+ <MuiLink
+ href={link.href}
+ onClick={handleClick}
+ // ... rest of the component
+ >
+ {link.label}
+ </MuiLink>
+ );
+};
const Footer: React.FC = () => {
const currentYear = new Date().getFullYear();
const location = useLocation();
const isHomePage = location.pathname === '/';
const navigate = useNavigate();
-
- // QuickLink component to handle hash navigation/smooth scroll via router
- const QuickLink: React.FC<{ link: { label: string; href: string }; isHomePage: boolean }> = ({ link, isHomePage }) => {
- // ... component definition
- };🤖 Prompt for AI Agents
In `@landing/src/components/layout/Footer.tsx` around lines 28 - 74, QuickLink is
declared inside Footer causing re-creation on each render; move the QuickLink
component definition out of Footer (make it a top-level component) and update
its signature to accept props for navigate and isHomePage (or obtain navigate
via context) so Footer passes navigate and isHomePage into QuickLink; ensure the
prop type remains React.FC<{ link: { label: string; href: string }; isHomePage:
boolean; navigate: (to: string) => void }> (or adjust if using context) and
update Footer usage to pass the values accordingly.
| const handleSmoothScroll = (e:React.MouseEvent<HTMLAnchorElement>, href: string) => { | ||
| e.preventDefault(); | ||
| // Do not prevent default navigation; close mobile menu then navigate so location.hash updates | ||
| setIsOpen(false); | ||
|
|
||
| // Navigate to the link (includes hash when present). The useEffect above will handle scrolling. | ||
| navigate(href); | ||
| }; |
There was a problem hiding this comment.
Misleading comment contradicts the code.
Line 55's comment says "Do not prevent default navigation" but e.preventDefault() is called on line 54. The comment should be updated or removed to accurately reflect the behavior.
📝 Suggested fix
const handleSmoothScroll = (e:React.MouseEvent<HTMLAnchorElement>, href: string) => {
e.preventDefault();
- // Do not prevent default navigation; close mobile menu then navigate so location.hash updates
+ // Close mobile menu then navigate so location.hash updates; scrolling handled by useEffect
setIsOpen(false);
- // Navigate to the link (includes hash when present). The useEffect above will handle scrolling.
navigate(href);
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleSmoothScroll = (e:React.MouseEvent<HTMLAnchorElement>, href: string) => { | |
| e.preventDefault(); | |
| // Do not prevent default navigation; close mobile menu then navigate so location.hash updates | |
| setIsOpen(false); | |
| // Navigate to the link (includes hash when present). The useEffect above will handle scrolling. | |
| navigate(href); | |
| }; | |
| const handleSmoothScroll = (e:React.MouseEvent<HTMLAnchorElement>, href: string) => { | |
| e.preventDefault(); | |
| // Close mobile menu then navigate so location.hash updates; scrolling handled by useEffect | |
| setIsOpen(false); | |
| navigate(href); | |
| }; |
🤖 Prompt for AI Agents
In `@landing/src/components/layout/Navbar.tsx` around lines 53 - 60, Update the
misleading comment inside handleSmoothScroll to match the actual behavior: since
e.preventDefault() is called, remove or rephrase the line that says "Do not
prevent default navigation" so it accurately states that default navigation is
prevented, the mobile menu is closed via setIsOpen(false), and navigation is
performed programmatically with navigate(href) (the scrolling is handled
elsewhere by the useEffect). Ensure the comment references handleSmoothScroll,
e.preventDefault(), setIsOpen, and navigate for clarity.
| .btn-primary::before { | ||
| content: ''; | ||
| position: absolute; | ||
| top: 0; | ||
| left: 0; | ||
| right: 0; | ||
| bottom: 0; | ||
| background: linear-gradient(135deg, var(--color-primary-400) 0%, var(--color-primary-500) 100%); | ||
| opacity: 0; | ||
| transition: opacity 0.4s ease; | ||
| z-index: -1; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's see the full button styling context around lines 130-160
sed -n '130,165p' landing/src/index.cssRepository: AOSSIE-Org/Devr.AI
Length of output: 1064
🏁 Script executed:
# Check if there's a Button.tsx component
find landing -name "Button.tsx" -o -name "Button.ts" -o -name "Button.jsx" -o -name "Button.js" | head -20Repository: AOSSIE-Org/Devr.AI
Length of output: 98
🏁 Script executed:
# Search for z-index usage in the CSS file to understand the full layering strategy
rg -n "z-index" landing/src/index.css | head -20Repository: AOSSIE-Org/Devr.AI
Length of output: 173
🏁 Script executed:
# Check for button-related classes and their styling
rg -n "\.btn-" landing/src/index.css | head -30Repository: AOSSIE-Org/Devr.AI
Length of output: 593
🏁 Script executed:
# Let's see the hover states to understand the intended animation behavior
sed -n '169,195p' landing/src/index.cssRepository: AOSSIE-Org/Devr.AI
Length of output: 602
🏁 Script executed:
# Also check the full context of btn-secondary to see if same pattern is used
sed -n '196,260p' landing/src/index.cssRepository: AOSSIE-Org/Devr.AI
Length of output: 1612
🏁 Script executed:
# Check if Button.tsx uses inline styles that might override or complement these styles
cat -n landing/src/components/ui/Button.tsx | head -80Repository: AOSSIE-Org/Devr.AI
Length of output: 3100
🏁 Script executed:
# Check if the landing page uses the btn-primary class from index.css or relies on Button.tsx
rg -n "btn-primary\|btn-secondary" landing/src --include="*.html" --include="*.tsx" --include="*.jsx" | head -20Repository: AOSSIE-Org/Devr.AI
Length of output: 503
🏁 Script executed:
# Verify if there are any visual effects or animations that might work around this z-index issue
sed -n '140,260p' landing/src/index.css | grep -A 2 -B 2 "opacity:"Repository: AOSSIE-Org/Devr.AI
Length of output: 508
🏁 Script executed:
# Check where btn-primary/btn-secondary classes are actually used
rg "btn-primary|btn-secondary" landing/src -t css -t html -t tsx -t jsx 2>/dev/null | head -30Repository: AOSSIE-Org/Devr.AI
Length of output: 44
🏁 Script executed:
# Simpler search - just look for button usage patterns in landing pages
fd "\.tsx$|\.jsx$|\.html$" landing/src | xargs grep -l "btn-primary\|btn-secondary" 2>/dev/null | head -10Repository: AOSSIE-Org/Devr.AI
Length of output: 102
🏁 Script executed:
# Check Hero.tsx to see how btn-primary and btn-secondary are used
cat -n landing/src/components/sections/Hero.tsxRepository: AOSSIE-Org/Devr.AI
Length of output: 20022
🏁 Script executed:
# Also check if there are any developer notes or comments about the z-index layering
rg -n "z-index|layering|stacking" landing/src/index.css -B 2 -A 2Repository: AOSSIE-Org/Devr.AI
Length of output: 590
z-index: -1 on ::before creates a stacking bug, but inline styles currently bypass it.
The .btn-primary::before and .btn-secondary::before pseudo-elements with z-index: -1 are placed behind the parent button's background gradient, making the opacity transition ineffective. However, the Hero component uses inline sx overrides that replace the CSS hover animation with backgroundPosition changes, so the bug doesn't manifest in practice. This should still be fixed for consistency: change z-index: -1 to z-index: 1 for ::before, keep z-index: 0 for ::after, and z-index: 10 for content—or remove the unused CSS animation rules if inline styles are the intended approach.
🤖 Prompt for AI Agents
In `@landing/src/index.css` around lines 142 - 153, The pseudo-element stacking
for buttons is wrong: update .btn-primary::before and .btn-secondary::before to
use z-index: 1 (instead of -1), ensure any corresponding ::after pseudo-element
keeps z-index: 0, and ensure the button inner content (e.g., the element
targeted by .btn-primary .content or the main button selector) has z-index: 10
so the gradient sits behind content but above the button background;
alternatively, if the Hero component intentionally uses inline sx overrides for
backgroundPosition and you want to remove the unused animation, delete the
::before/::after animation/transition rules for .btn-primary/.btn-secondary and
rely on the inline styles used in the Hero component.
Pull Request
Closes #251
📝 Description
Refactors
AsyncQueueManagerto fix inefficient queue polling and make it production-ready. Replaces three separate queues (high_task_queue,medium_task_queue,low_task_queue) with a single RabbitMQ priority queue and push-based consumption. Workers no longer poll withqueue.get()and a fixed sleep; priority is enforced by the broker viax-max-priorityand per-messagepriority, and workers usequeue.iterator()so the broker pushes messages instead of the app polling.🔧 Changes Made
task_queue) declared withx-max-priority: 10. All messages go to this queue with a numeric priority (HIGH=10, MEDIUM=5, LOW=1).queue.get(). Each worker usesasync with queue.iterator(): async for message in queue_iterso the broker pushes messages; no polling orasyncio.sleep(0.1).channel.set_qos(prefetch_count=1)so the broker doesn’t over-deliver; each consumer has at most one unacked message.enqueue()publishes to the single queue withaio_pika.Message(..., priority=numeric_priority)and the samerouting_key. Public API unchanged:enqueue(message, priority=QueuePriority.MEDIUM, delay=0).stop()clearsworker_tasksaftergatherand closes channel/connection. Workers break out of the iterator when cancelled or whenself.runningis False.📷 Screenshots or Visual Changes (if applicable)
N/A
🤝 Collaboration
✅ Checklist
N/A
Summary by CodeRabbit
Release Notes
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.