Skip to content

feat: update extraction engine logic and web UI workflow - #6

Merged
SwastikKaushal1 merged 1 commit into
mainfrom
swastik
Sep 14, 2026
Merged

SwastikKaushal1 merged 1 commit into
mainfrom
swastik

Conversation

@SwastikKaushal1

Copy link
Copy Markdown
Member

Summary

This PR introduces a full-stack update that enhances the LLM extraction logic and rules engine in the backend, while delivering a comprehensive UI revamp for the web frontend. It includes core layout updates, newly added branding assets (logos and app icons), and the addition of the ClaimClear Audit Report.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Changes

Backend (Extraction Service):

  • Updated apps/extraction-service/llm_extract.py to refine the LLM extraction logic.
  • Updated apps/extraction-service/rules_engine.py to adjust processing rules.

Frontend (Web UI):

  • Revamped global styling and core layout in globals.css and layout.tsx.
  • Updated core page flows across page.tsx, upload/page.tsx, processing/page.tsx, and results/page.tsx.
  • Added new logo component (logo.tsx) and visual assets (logo.png, icon.png).
  • Added ClaimClear_Audit_Report.pdf to the public directory.

Cleanup:

  • Removed unused msg.txt from the root directory.

Testing

  • Verify the backend extraction pipeline successfully processes standard inputs using the updated llm_extract.py and rules_engine.py.
  • Navigate through the web app (Home -> Upload -> Processing -> Results) to ensure the new UI layout and styles render correctly without breaking the user flow.
  • Confirm that the new logo and app icons render properly across different screen sizes.
  • Verify that ClaimClear_Audit_Report.pdf is successfully accessible via its public route.

- Update LLM extraction and rules engine in the extraction service
- Revamp web UI styling, layout, and core page flows (upload, processing, results)
- Add new logo components, app icons, and ClaimClear Audit Report PDF
- Clean up unused msg.txt
@SwastikKaushal1 SwastikKaushal1 self-assigned this Sep 14, 2026
@SwastikKaushal1
SwastikKaushal1 requested a lite review from Copilot and removed request for RawaldinhoJr September 14, 2026 22:50
@SwastikKaushal1
SwastikKaushal1 merged commit ae2e775 into main Sep 14, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical extraction and bank-detail rule issues, retry behavior problems, and responsive UI defects remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR updates backend extraction and audit rules while revamping the web UI, branding, and workflow presentation.

Changes:

  • Adds LLM provider fallback and extraction validation.
  • Updates chronology and bank-detail audit rules.
  • Refreshes layouts, styling, branding, and workflow pages.
File summaries
File Summary
msg.txt Removes stale repository file.
apps/web/components/logo.tsx Adds shared logo component.
apps/web/app/upload/page.tsx Updates branded upload flow.
apps/web/app/results/page.tsx Updates branded results flow.
apps/web/app/processing/page.tsx Updates branded processing flow.
apps/web/app/page.tsx Revamps landing page.
apps/web/app/layout.tsx Updates fonts and metadata.
apps/web/app/globals.css Updates theme, layout, and responsive styles.
apps/extraction-service/rules_engine.py Updates chronology and bank-detail rules.
apps/extraction-service/llm_extract.py Adds provider retries, fallback, and output validation.
Review details

Suppressed comments (5)

apps/extraction-service/llm_extract.py:17

  • The new fallback key is not part of apps/extraction-service/.env.example, even though setup copies that file and the README lists both provider keys. A standard setup therefore leaves GROQ_API_KEY unset and makes this fallback unavailable; document the variable in the example/configuration instructions.
GROQ_API_KEY = os.getenv("GROQ_API_KEY")  # get a free key at https://console.groq.com/keys

apps/extraction-service/rules_engine.py:130

  • RULE_02_DATE_CHRONOLOGY treats equal admission and discharge timestamps as invalid (claim_dis <= claim_adm), but this guard only filters negative durations. Equal timestamps therefore produce both the chronology finding and a second 0.0 hours sub-24-hour finding. Use <= 0 here to avoid reporting the same root cause twice.
        if duration_hours < 0:

apps/extraction-service/rules_engine.py:183

  • The configured RULE_18 description also requires bank branch details, but this implementation only reads account_number and ifsc_code. Once Section F is supplied, a claim containing those two fields but no branch details will incorrectly pass the rule; either extract/check the branch field or align the rule metadata with the actual requirement.
    bank_details = claim.get("section_f_bank_details", {}) or {}
    account_no = bank_details.get("account_number")
    ifsc_code = bank_details.get("ifsc_code")

    missing = []
    if not account_no or not str(account_no).strip():
        missing.append("account number")
    if not ifsc_code or not str(ifsc_code).strip():
        missing.append("IFSC code")

apps/web/app/globals.css:57

  • At mobile widths, the 320×92 asset is rendered at 68px high (about 236px wide), while the header remains a non-wrapping flex row. The 343px content area at a 375px viewport cannot fit the logo plus the upload/results header actions, so these pages overflow horizontally. Add a responsive wrap or size/reduction rule for the header and actions.
.site-header { display: flex; align-items: center; justify-content: space-between; padding: 22px 0; }

apps/web/app/globals.css:209

  • The responsive filename constraints removed from the end of the stylesheet are still needed: the new .file-name { display: inline-flex; } rule leaves the flex item at its automatic min-content width, so a long uploaded filename can push .file-row and the dropzone beyond the viewport instead of shrinking/ellipsizing. Restore min-width: 0/flex: 1 1 auto on .file-name (and keep the size/remove controls non-shrinking).
.flow-steps { display: flex; align-items: center; gap: 14px; margin-top: 52px; } .dropzone { min-height: 270px; border: 1px solid var(--line); border-radius: 18px; padding: 28px; cursor: pointer; transition: border-color 160ms ease, background 160ms ease, transform 160ms ease; } .dropzone:hover, .dropzone.is-dragging { border-color: var(--teal); background: color-mix(in srgb, var(--teal) 7%, var(--paper)); transform: translateY(-2px); } .upload-icon { display: grid; place-items: center; width: 48px; height: 48px; border: 1px solid var(--line); border-radius: 12px; color: var(--teal); } .dropzone-top { align-items: flex-start; } .dropzone h2 { margin-top: 28px; } .dropzone p { line-height: 1.7; } .dropzone p small { font-size: 12px; color: var(--muted); } .browse { color: var(--ink); font-weight: 600; } .file-name { display: inline-flex; align-items: center; gap: 7px; } .upload-note { display: flex; align-items: center; gap: 8px; color: var(--muted); font: 12px var(--font-plex-mono), monospace; margin-bottom: 24px; } .page-main:has(.results-head) { display: grid; grid-template-columns: minmax(280px, .7fr) minmax(0, 1.3fr); gap: 64px; align-items: start; } .results-head { display: block; align-items: center; padding-bottom: 0; border-bottom: 0; position: sticky; top: 24px; } .score-panel { min-width: 330px; } .score-circle { display: flex; align-items: baseline; justify-content: center; width: 190px; height: 190px; border: 10px solid var(--amber); border-radius: 50%; padding-top: 4px; } .score-circle strong { font-size: 68px; line-height: 1; letter-spacing: -.08em; } .score-circle span { color: var(--muted); font: 13px var(--font-plex-mono), monospace; margin-left: 3px; } .score-status { margin: 18px 0 20px; } .score-warning { display: flex; align-items: flex-start; gap: 9px; max-width: 320px; color: var(--muted); font-size: 13px; line-height: 1.45; } .score-warning svg { flex: 0 0 auto; color: var(--rust); margin-top: 2px; } .score-warning strong { color: var(--rust); } .report-meta { align-self: flex-end; text-align: right; color: var(--muted); font-size: 13px; } .report-meta p { margin: 0 0 8px; } .findings { min-width: 0; } .findings-heading { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 30px; } .findings h2 { margin: 0; } .findings h2 span { color: var(--muted); font-weight: 400; } .findings-note { margin: 0; color: var(--muted); font-size: 13px; } .finding { display: grid; grid-template-columns: 28px 1fr; gap: 14px; padding-left: 16px; } .finding-icon { color: var(--amber); padding-top: 2px; } .finding-critical .finding-icon { color: var(--rust); } .finding-minor .finding-icon { color: var(--teal); } .finding h3 { margin-bottom: 7px; } .center-page { min-height: auto; padding: 84px 24px 100px; } .processing { width: min(100%, 560px); } .processing h1 { margin-bottom: 38px; } .site-footer { margin-top: auto; }
  • Files reviewed: 10/14 changed files
  • Comments generated: 7
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 243 to +247
client = genai.Client(api_key=GEMINI_API_KEY)


def _call_gemini(prompt: str) -> dict:
response = client.models.generate_content(
raise RuntimeError("GROQ_API_KEY not set in .env")

response = groq_client.chat.completions.create(
model="llama-3.3-70b-versatileL",
Comment on lines +175 to +177
bank_details = claim.get("section_f_bank_details", {}) or {}
account_no = bank_details.get("account_number")
ifsc_code = bank_details.get("ifsc_code")
gemini_error = e
print(f"[Gemini] attempt {attempt}/{GEMINI_MAX_RETRIES} failed: {e}")
if attempt < GEMINI_MAX_RETRIES:
time.sleep(GEMINI_RETRY_DELAY_SECONDS * attempt)
Comment on lines +316 to +320
if result is None:
raise RuntimeError(
f"All providers failed.\n"
f"Gemini error: {gemini_error}\n"
f"Groq error: {groq_error}"
export function Logo() {
return (
<Link className="wordmark" href="/" style={{ display: 'inline-flex', alignItems: 'center' }}>
<Image src="/logo.png" alt="ClaimClear" width={320} height={92} priority style={{ height: 68, width: 'auto' }} /> </Link>
Comment thread apps/web/app/page.tsx
<div className="hero-content">
<p className="mono-label">CLAIMS, MADE CLEAR</p>
<h1>Know what to fix before you <span className="accent-italic">submit</span>.</h1>
<p className="hero-copy">ClaimClear reviews your clinical record and draft claim in one calm, guided pass-so avoidable errors do not become delays.</p>
@SwastikKaushal1
SwastikKaushal1 deleted the swastik branch September 27, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants