MrInvincible96 commited on
Commit
607dadc
·
verified ·
1 Parent(s): 3a2ca61

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +177 -46
app.py CHANGED
@@ -2,12 +2,79 @@ import re
2
  import gradio as gr
3
 
4
 
5
- def clean_lines(notes):
6
- raw_lines = notes.splitlines()
7
- lines = [line.strip(" -•\t") for line in raw_lines if line.strip()]
8
- if not lines:
9
- lines = [part.strip() for part in re.split(r"[.;]\s*", notes) if part.strip()]
10
- return lines
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
 
13
  def guess_title(notes):
@@ -262,15 +329,16 @@ def format_brd(notes):
262
  risks = build_risks(notes)
263
  metrics = build_success_metrics(notes)
264
 
265
- business_problem = "Stakeholder notes indicate that the current process is slow, inconsistent, or causing user friction. A clearer and more structured solution is needed to improve efficiency and business outcomes."
266
-
267
  brd = f"""# Business Requirements Document
268
 
269
  ## Project Title
270
  {title}
271
 
 
 
 
272
  ## Business Problem
273
- {business_problem}
274
 
275
  ## Objectives
276
  """ + "\n".join([f"- {item}" for item in objectives]) + """
@@ -304,20 +372,44 @@ def format_stories(notes):
304
  sections.append(
305
  f"""
306
  ## User Story {index}
307
- As a {story['role']},
308
- I want to {story['goal']},
309
  So that {story['benefit']}.
310
 
311
  ### Acceptance Criteria
312
- Given {story['given']}
313
- When {story['when']}
314
- Then {story['then']}
315
  """.strip()
316
  )
317
 
318
  return "\n\n".join(sections)
319
 
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  def generate_documents(notes):
322
  notes = notes.strip()
323
 
@@ -327,41 +419,80 @@ def generate_documents(notes):
327
 
328
  brd = format_brd(notes)
329
  stories = format_stories(notes)
330
-
331
- before_after = f"""# Before vs After
332
-
333
- ## Before: Raw Stakeholder Notes
334
- {notes}
335
-
336
- ## After: What The Agent Produced
337
- - Structured BRD
338
- - BDD-style user stories
339
- - Cleaner business-ready documentation
340
- """
341
 
342
  return brd, stories, before_after
343
 
344
 
345
- demo = gr.Interface(
346
- fn=generate_documents,
347
- inputs=gr.Textbox(
348
- lines=12,
349
- label="Paste Raw Stakeholder Notes",
350
- placeholder="Example: Customers are leaving carts before payment. They want UPI, cards, wallets, guest checkout, and a mobile-friendly checkout experience."
351
- ),
352
- outputs=[
353
- gr.Markdown(label="Generated BRD"),
354
- gr.Markdown(label="Generated BDD User Stories"),
355
- gr.Markdown(label="Before vs After Summary")
356
- ],
357
- title="Agentic BA | Free BRD and User Story Generator",
358
- description="Paste messy stakeholder notes and generate a structured BRD, BDD-style user stories, and a clear before-vs-after portfolio demo. This version is fully free and runs without paid APIs.",
359
- examples=[
360
- ["Customers are abandoning carts before payment. They want easier checkout, UPI, cards, wallets, mobile-friendly pages, guest checkout, and fewer support issues."],
361
- ["Hospital reception staff say patient registration is slow. They want OTP verification, fewer manual steps, tablet support, and a simple dashboard for receptionists."],
362
- ["Users find login confusing. Stakeholders want optional sign-in where possible, a simpler user flow, faster completion, and fewer helpdesk calls."]
363
- ],
364
- flagging_mode="never"
365
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
  demo.launch()
 
2
  import gradio as gr
3
 
4
 
5
+ CUSTOM_CSS = """
6
+ body {
7
+ background: linear-gradient(135deg, #f7f4ea 0%, #eef7f2 100%);
8
+ }
9
+
10
+ .gradio-container {
11
+ max-width: 1200px !important;
12
+ font-family: Georgia, "Times New Roman", serif;
13
+ }
14
+
15
+ .hero {
16
+ padding: 22px 24px;
17
+ border-radius: 20px;
18
+ background: linear-gradient(135deg, #133b2c 0%, #245c46 100%);
19
+ color: white;
20
+ box-shadow: 0 12px 30px rgba(19, 59, 44, 0.18);
21
+ margin-bottom: 12px;
22
+ }
23
+
24
+ .hero h1 {
25
+ margin: 0 0 10px 0;
26
+ font-size: 2.2rem;
27
+ }
28
+
29
+ .hero p {
30
+ margin: 0;
31
+ font-size: 1.02rem;
32
+ line-height: 1.6;
33
+ color: #edf7f1;
34
+ }
35
+
36
+ .badges {
37
+ display: flex;
38
+ gap: 10px;
39
+ flex-wrap: wrap;
40
+ margin-top: 14px;
41
+ }
42
+
43
+ .badge {
44
+ background: rgba(255, 255, 255, 0.14);
45
+ padding: 7px 12px;
46
+ border-radius: 999px;
47
+ font-size: 0.92rem;
48
+ border: 1px solid rgba(255, 255, 255, 0.2);
49
+ }
50
+
51
+ .section-card {
52
+ background: white;
53
+ border: 1px solid #e6e1d6;
54
+ border-radius: 18px;
55
+ padding: 18px;
56
+ box-shadow: 0 10px 24px rgba(60, 50, 30, 0.07);
57
+ }
58
+
59
+ .label-note {
60
+ color: #4e5d55;
61
+ font-size: 0.95rem;
62
+ line-height: 1.5;
63
+ }
64
+
65
+ .footer-note {
66
+ padding: 12px 16px;
67
+ border-radius: 14px;
68
+ background: #f3f8f5;
69
+ border: 1px solid #d7e6dd;
70
+ color: #264635;
71
+ font-size: 0.94rem;
72
+ }
73
+
74
+ textarea {
75
+ font-size: 0.98rem !important;
76
+ }
77
+ """
78
 
79
 
80
  def guess_title(notes):
 
329
  risks = build_risks(notes)
330
  metrics = build_success_metrics(notes)
331
 
 
 
332
  brd = f"""# Business Requirements Document
333
 
334
  ## Project Title
335
  {title}
336
 
337
+ ## Executive Summary
338
+ This document translates unstructured stakeholder notes into a cleaner, review-ready business requirements format. It is designed to help Business Analysts move faster from conversation capture to formal documentation.
339
+
340
  ## Business Problem
341
+ Stakeholder feedback suggests that the current process contains friction, inconsistency, or avoidable manual effort. A more structured solution is needed to improve user outcomes and business performance.
342
 
343
  ## Objectives
344
  """ + "\n".join([f"- {item}" for item in objectives]) + """
 
372
  sections.append(
373
  f"""
374
  ## User Story {index}
375
+ As a {story['role']},
376
+ I want to {story['goal']},
377
  So that {story['benefit']}.
378
 
379
  ### Acceptance Criteria
380
+ - Given {story['given']}
381
+ - When {story['when']}
382
+ - Then {story['then']}
383
  """.strip()
384
  )
385
 
386
  return "\n\n".join(sections)
387
 
388
 
389
+ def format_before_after(notes):
390
+ cleaned = notes.strip()
391
+ bullet_lines = [line.strip(" -•\t") for line in cleaned.splitlines() if line.strip()]
392
+ if not bullet_lines:
393
+ bullet_lines = [part.strip() for part in re.split(r"[.;]\s*", cleaned) if part.strip()]
394
+
395
+ before = "\n".join([f"- {line}" for line in bullet_lines[:8]])
396
+
397
+ return f"""# Before vs After
398
+
399
+ ## Before: Raw Stakeholder Notes
400
+ {before}
401
+
402
+ ## After: Business-Ready Output
403
+ - Raw notes were grouped into a formal BRD structure
404
+ - Requirements were separated into functional and non-functional areas
405
+ - User needs were rewritten as BDD-style stories
406
+ - The output is now easier to review, share, and present
407
+
408
+ ## Portfolio Value
409
+ This demonstrates BA lifecycle thinking, requirement structuring, and workflow automation in a recruiter-friendly format.
410
+ """
411
+
412
+
413
  def generate_documents(notes):
414
  notes = notes.strip()
415
 
 
419
 
420
  brd = format_brd(notes)
421
  stories = format_stories(notes)
422
+ before_after = format_before_after(notes)
 
 
 
 
 
 
 
 
 
 
423
 
424
  return brd, stories, before_after
425
 
426
 
427
+ with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Soft()) as demo:
428
+ gr.HTML("""
429
+ <div class="hero">
430
+ <h1>Agentic BA</h1>
431
+ <p>
432
+ Turn messy stakeholder notes into a structured Business Requirements Document,
433
+ polished BDD-style user stories, and a strong before-vs-after portfolio demo.
434
+ </p>
435
+ <div class="badges">
436
+ <div class="badge">100% Free</div>
437
+ <div class="badge">Recruiter-Friendly</div>
438
+ <div class="badge">Portfolio Ready</div>
439
+ <div class="badge">No Paid APIs</div>
440
+ </div>
441
+ </div>
442
+ """)
443
+
444
+ with gr.Row():
445
+ with gr.Column(scale=5):
446
+ with gr.Group(elem_classes=["section-card"]):
447
+ gr.Markdown("## Input")
448
+ gr.Markdown(
449
+ "<div class='label-note'>Paste rough interview notes, stakeholder comments, or unstructured business observations below.</div>"
450
+ )
451
+ notes_input = gr.Textbox(
452
+ lines=14,
453
+ label="Raw Stakeholder Notes",
454
+ placeholder="Example: Customers are abandoning carts before payment. They want UPI, cards, wallets, guest checkout, mobile-friendly checkout, and fewer support issues."
455
+ )
456
+
457
+ with gr.Row():
458
+ generate_btn = gr.Button("Generate Documents", variant="primary")
459
+ clear_btn = gr.Button("Clear", variant="secondary")
460
+
461
+ gr.Examples(
462
+ examples=[
463
+ ["Customers are abandoning carts before payment. They want easier checkout, UPI, cards, wallets, mobile-friendly pages, guest checkout, and fewer support issues."],
464
+ ["Hospital reception staff say patient registration is slow. They want OTP verification, fewer manual steps, tablet support, and a simple dashboard for receptionists."],
465
+ ["Users find login confusing. Stakeholders want optional sign-in where possible, a simpler user flow, faster completion, and fewer helpdesk calls."]
466
+ ],
467
+ inputs=notes_input,
468
+ label="Try a sample"
469
+ )
470
+
471
+ with gr.Column(scale=7):
472
+ with gr.Group(elem_classes=["section-card"]):
473
+ gr.Markdown("## Output")
474
+ with gr.Tabs():
475
+ with gr.Tab("BRD"):
476
+ brd_output = gr.Markdown()
477
+ with gr.Tab("BDD Stories"):
478
+ stories_output = gr.Markdown()
479
+ with gr.Tab("Before vs After"):
480
+ before_after_output = gr.Markdown()
481
+
482
+ gr.Markdown(
483
+ "<div class='footer-note'><strong>Portfolio note:</strong> This demo showcases structured BA workflow automation in a fully free public app. It is ideal for LinkedIn, resumes, and recruiter sharing.</div>"
484
+ )
485
+
486
+ generate_btn.click(
487
+ fn=generate_documents,
488
+ inputs=notes_input,
489
+ outputs=[brd_output, stories_output, before_after_output]
490
+ )
491
+
492
+ clear_btn.click(
493
+ fn=lambda: ("", "", "", ""),
494
+ inputs=[],
495
+ outputs=[notes_input, brd_output, stories_output, before_after_output]
496
+ )
497
 
498
  demo.launch()