Skip to main content

Acceptance Criteria

Acceptance Criteria: Bilko

Project: Bilko — Balkan Accounting SaaS Version: 1.0 Date: 2026-02-25 Author: John (AI Director) Status: Final Reviewers: Alem Bašić (CEO)

Document History

Version Date Author Changes
0.1 2026-02-23 John (AI Director) Initial draft — Phase 1 Serbia MVP
1.0 2026-02-25 John (AI Director) Finalized for v1.0 release

1. Purpose & Methodology

1.1 What Are Acceptance Criteria?

Acceptance criteria are the conditions that the Bilko system must satisfy to be accepted as working correctly. They answer: "How will we know when this feature is done?"

For financial software, acceptance criteria are especially critical because errors have direct legal and financial consequences for users (SEF fines, incorrect PDV filings, balance sheet errors).

Good acceptance criteria are:

  • Testable — Can be verified with a specific test procedure
  • Clear — Unambiguous; no room for interpretation
  • Complete — Cover happy path, error paths, and edge cases
  • Financially accurate — For accounting features: verified against Balkan GAAP and tax law

1.2 Format: Given / When / Then (Gherkin-Style)

Given [an initial context / precondition that is true]
When  [an action or event occurs]
Then  [the expected outcome is observed]
And   [additional expected outcomes, chained]

1.3 Categories of Acceptance Criteria

Category Description Example
Positive (Happy Path) System works as expected with valid inputs Invoice submitted to SEF successfully
Negative (Sad Path) System handles invalid inputs gracefully SEF rejects invoice — error shown
Edge Case Boundary conditions Zero-PDV invoice; zero-balance period
Integration System works with external services SEF API, exchange rate API
Financial Accuracy Calculations correct per tax law PDV = base × 0.20 exact to 4 decimal places
Non-Functional Performance, accessibility, security Invoice creation < 5s end-to-end

2. Feature Acceptance Criteria


Module: Authentication & User Management


Feature: User Registration (FR-001)

Feature Description: New users register with email/password and automatically get an organization with Serbian Chart of Accounts. Business Requirement: BR-014 Linked User Stories: US-001

Positive Scenarios:

# Scenario Given When Then
AC-001 Successful registration A new user with valid email "[email protected]" and strong password User submits form with org name "Firma d.o.o." Account created; org created with Kontni Okvir pre-populated; verification email sent within 2 minutes
AC-002 Email verification Account just created User clicks verification link (valid within 48h) Email confirmed; user redirected to organization dashboard
AC-003 Chart of Accounts pre-populated New organization created User opens /settings/accounts All 10 account classes (0-9) visible with standard Serbian accounts

Negative Scenarios:

# Scenario Given When Then
AC-004 Duplicate email Account already exists for [email protected] User submits registration with same email Error "Nalog sa ovim emailom već postoji"; no account created
AC-005 Weak password User is on registration form User submits password "abc123" (no uppercase/special) Inline error shown before form submission; form not submitted
AC-006 Invalid email format User is on registration form User submits "notanemail" as email Inline validation error shown

Edge Cases:

# Scenario Given When Then
AC-007 Verification link expiry Verification link generated 49+ hours ago User clicks expired link Error "Link je istekao"; option to resend verification shown
AC-008 Double registration attempt User submits form twice rapidly Two identical POST requests within 1 second Only one account created; second returns appropriate error

Non-Functional Acceptance Criteria:

# Category Criterion
AC-009 Performance Registration + org creation + CoA seeding completes in < 3 seconds
AC-010 Security Password stored as bcrypt hash (cost 12+); never in plaintext logs

Feature: User Login (FR-002)

Feature Description: Authenticated users log in with email and password. Business Requirement: BR-014 Linked User Stories: US-002

Positive Scenarios:

# Scenario Given When Then
AC-020 Successful login Verified user with valid credentials User submits login form Authenticated; access token (15min) + refresh token (30d) set; redirected to dashboard
AC-021 Silent token refresh User's access token expired; refresh token valid User makes API call New access token issued silently; user not logged out; original request succeeds

Negative Scenarios:

# Scenario Given When Then
AC-022 Wrong password Registered user exists User submits wrong password Generic error "Pogrešan email ili lozinka" (no user enumeration)
AC-023 Non-existent email No account for this email User submits login Same generic error "Pogrešan email ili lozinka"
AC-024 Account locked 5 failed attempts within 15 minutes 6th attempt Error "Nalog zaključan. Pokušajte za 15 minuta."
AC-025 Unverified account Account created but email not verified User attempts login Error "Molimo vas potvrdite email adresu" with option to resend

Edge Cases:

# Scenario Given When Then
AC-026 Session expiry User idle for 30+ minutes; access token expired; refresh token also expired User attempts action Redirected to login; message "Vaša sesija je istekla"

Module: Invoicing


Feature: Create Invoice with PDV (FR-010)

Feature Description: Create invoices with auto-PDV calculation. Financial accuracy is critical — NUMERIC(19,4) precision required. Business Requirement: BR-001, BR-002 Linked User Stories: US-010

Positive Scenarios:

# Scenario Given When Then
AC-030 Invoice with 20% PDV Line item: 1000.0000 RSD base, 20% PDV rate Invoice created and viewed PDV amount = 200.0000 RSD; total = 1200.0000 RSD exactly (NUMERIC precision)
AC-031 Invoice with 10% PDV Line item: 500.0000 RSD base, 10% PDV rate Invoice created PDV = 50.0000 RSD; total = 550.0000 RSD
AC-032 Multi-line invoice with mixed PDV rates 3 line items: 1000 @ 20%, 500 @ 10%, 200 @ 0% Invoice created PDV breakdown shown per rate; total PDV = 250.0000 RSD; grand total = 1950.0000 RSD
AC-033 Invoice saved as Draft All required fields filled User clicks "Save Draft" Invoice in Draft status; not submitted to SEF; can be edited
AC-034 Invoice number sequential Previous invoice number: INV-2026-001 New invoice created Invoice number: INV-2026-002 (no gaps)

Negative Scenarios:

# Scenario Given When Then
AC-035 Missing required field Invoice wizard open User tries to advance without selecting client Inline error "Odaberite klijenta"; cannot advance to next step
AC-036 Zero-amount invoice User enters 0 for all line item prices User tries to save Validation error "Iznos fakture mora biti veći od 0"
AC-037 Due date before invoice date Invoice date: 2026-03-01, due date: 2026-02-28 User saves invoice Validation error "Rok plaćanja mora biti nakon datuma fakture"

Edge Cases:

# Scenario Given When Then
AC-038 PDV rounding edge case Line item: 333.3333 RSD, 20% PDV Invoice calculated PDV = 66.6667 RSD (ROUND to 4 decimal places, not truncate); total = 400.0000 RSD
AC-039 PDV-exempt invoice (0%) Business in PDV exemption regime Invoice created with 0% PDV PDV amount = 0.0000; total = base amount; PDV field shows "PDV 0%" with exemption reason

Financial Accuracy Criteria:

# Category Criterion
AC-040 NUMERIC precision All PDV and total amounts stored as NUMERIC(19,4) — verified in DB; no floating point
AC-041 PDV law compliance PDV calculation matches Zakon o PDV Art. 17 — base × rate formula verified for 20 test cases

Feature: SEF E-Invoice Submission (FR-011)

Feature Description: Automatic submission of Serbian B2B invoices to efaktura.gov.rs. Business Requirement: BR-001 Linked User Stories: US-011

Positive Scenarios:

# Scenario Given When Then
AC-050 Successful SEF submission Serbian B2B invoice, organization has SEF credentials User clicks "Pošalji fakturu" UBL 2.1 XML generated and submitted to SEF within 10 seconds; SEF status = "Prihvaćeno"; SEF invoice ID stored
AC-051 SEF status visible Invoice submitted to SEF User views invoice detail SEF status shown: "Prihvaćeno" + SEF invoice ID

Negative Scenarios:

# Scenario Given When Then
AC-052 SEF rejects — missing buyer PIB Invoice created without buyer's PIB (tax ID) Submission attempted SEF rejection error shown in Serbian: reason from SEF response; invoice status = "SEF Odbijeno"; user can edit and resubmit
AC-053 SEF API unavailable (503) SEF platform returns 503 Submission attempted Invoice queued for retry; user notified "Faktura je u redu čekanja za SEF. Prosleđivanje za max 30 minuta."; max 3 retries

Edge Cases:

# Scenario Given When Then
AC-054 Duplicate SEF submission attempt Invoice already submitted and Accepted User somehow triggers send again System detects SEF invoice ID exists; blocks resubmission; shows "Faktura je već prosleđena SEF-u"
AC-055 B2C invoice (no SEF required) Invoice for individual (no PIB) User sends PDF emailed; SEF submission skipped; no SEF status shown

Feature: Invoice Payment Tracking (FR-012)

Linked User Stories: US-012

Positive Scenarios:

# Scenario Given When Then
AC-060 Mark invoice paid Invoice status = Sent User marks as paid with date 2026-03-15 and amount 1200 RSD Status = Paid; double-entry: Debit 1200 (110 — tekući račun), Credit 1200 (200 — potraživanja); payment date recorded
AC-061 Overdue detection Invoice due 2026-03-14; today is 2026-03-15; status = Sent System daily check runs Status automatically changes to Overdue; in-app notification sent

Negative Scenarios:

# Scenario Given When Then
AC-062 Mark paid with wrong amount Invoice total = 1200 RSD User marks paid with amount 1000 RSD Warning: "Plaćeni iznos (1.000 RSD) je manji od iznosa fakture (1.200 RSD). Potvrdi parcijalno plaćanje."

Module: Expense Tracking


Feature: Create Expense (FR-020)

Feature Description: Record business expenses with double-entry auto-creation. Business Requirement: BR-009 Linked User Stories: US-020

Positive Scenarios:

# Scenario Given When Then
AC-070 Record expense with double-entry Expense: 5000 RSD, category "Kirija" (account 480), paid from tekući račun (110) User submits expense Expense saved; Transaction: Debit 5000 (480 — Expenses), Credit 5000 (110 — Bank); LoggedAction entry created
AC-071 Receipt attachment Expense saved User attaches JPEG receipt (3MB) Receipt stored; accessible from expense record; thumbnail shown

Negative Scenarios:

# Scenario Given When Then
AC-072 Receipt too large User attaches 15MB PDF Upload attempted Error "Dokument ne može biti veći od 10MB"
AC-073 Future date expense User enters expense date 2027-01-01 Form submitted Warning "Datum troška je u budućnosti. Potvrdi unos." — requires explicit confirmation

Module: VAT/PDV Management


Feature: PDV Report Generation (FR-050)

Feature Description: Monthly PDV report aggregating all sales and purchase PDV. Critical for legal compliance. Business Requirement: BR-002, BR-006 Linked User Stories: US-050

Positive Scenarios:

# Scenario Given When Then
AC-080 January PDV report January 2026: 3 invoices (PDV 600+400+200=1200 RSD), 2 expenses (input PDV 240+120=360 RSD) User generates January PDV report Output PDV = 1200 RSD; Input PDV = 360 RSD; Net PDV payable = 840 RSD
AC-081 PDV report PDF export PDV report generated User clicks "Exportuj PDF" PDF with header "PDV Prijava — Januar 2026", org name, PIB, all amounts per official format
AC-082 Zero PDV period December: no PDV transactions User generates December PDV report Zero-value report generated with all fields = 0; exportable (still legally required)

Financial Accuracy Criteria:

# Category Criterion
AC-083 PDV accuracy PDV report totals verified against sum of all invoice/expense PDV fields in DB — must match to 4 decimal places
AC-084 PDV law compliance Output PDV = sum of all 20% standard + sum of all 10% reduced PDV from outgoing invoices per Zakon o PDV

3. Integration Scenarios

# Integration Scenario Expected Behavior Test Environment
INT-001 SEF API (efaktura.gov.rs) Valid invoice submission SEF returns invoice ID + "Accepted" status within 30s SEF sandbox
INT-002 SEF API Invalid invoice (missing buyer PIB) SEF returns rejection with specific reason code SEF sandbox
INT-003 SEF API SEF unavailable (503) Bilko queues submission; retries 3× with exponential backoff; user notified Mocked 503
INT-004 Email provider Invoice PDF delivery Recipient receives PDF invoice within 2 minutes of send Mailtrap / staging
INT-005 Exchange rate API (ECB) EUR/RSD rate fetch Rate fetched and cached; used for multi-currency invoice ECB test endpoint
INT-006 Exchange rate API API unavailable Cached rate (< 24h) used; if no cache, user prompted for manual entry Mocked timeout
INT-007 SEF API SEF credentials invalid Error shown to user: "SEF akreditivi su nevalidni. Proveri podešavanja." SEF sandbox

4. Non-Functional Acceptance Criteria

4.1 Performance

# Criterion Target Test Method
NF-AC-001 Dashboard initial load < 3 seconds (4G) Lighthouse on staging
NF-AC-002 Dashboard subsequent navigation < 1 second Lighthouse warm cache
NF-AC-003 Invoice creation (full wizard + API save) < 5 seconds end-to-end Manual timing + k6
NF-AC-004 SEF submission (Bilko to SEF confirmation) < 30 seconds E2E test in SEF sandbox
NF-AC-005 PDV report generation (1 year of data) < 5 seconds Load test with synthetic data

4.2 Accessibility

# Criterion Target Test Method
NF-AC-010 No critical accessibility violations 0 critical violations axe-core on all pages
NF-AC-011 Invoice wizard keyboard navigation Complete wizard without mouse Manual keyboard test
NF-AC-012 Color contrast ≥ 4.5:1 (normal text), ≥ 3:1 (large text) Contrast checker — Bilko #00E5A0 on dark verified

4.3 Security

# Criterion Target Test Method
NF-AC-020 Organization data isolation User from Org A cannot access Org B data API test: send request with Org A token for Org B resource — must return 403
NF-AC-021 No financial data in client-side logs No amounts, invoices, or PII in browser console Manual browser DevTools review
NF-AC-022 Input injection prevention No SQL/XSS injection vulnerabilities OWASP ZAP + Snyk SAST
NF-AC-023 SEF credentials encrypted SEF API keys not stored in plaintext in DB DB inspection + code review

4.4 Financial Accuracy

# Criterion Target Test Method
NF-AC-030 Debit = Credit invariant Sum of all debits = sum of all credits across ALL transactions Automated DB check in CI: SELECT SUM(debit_amount) - SUM(credit_amount) FROM transactions must = 0
NF-AC-031 NUMERIC precision Zero floating point errors in PDV and totals 1000 PDV calculations with known expected values; compare to NUMERIC result
NF-AC-032 Exchange rate immutability Changing today's rate does not affect historical transactions Create transaction, change rate, verify transaction amount unchanged

5. UAT Scenario Mapping

AC ID AC Description UAT Scenario ID UAT Tester Status
AC-001 Successful registration UAT-001 Beta SMB owner Not Started
AC-030 Invoice PDV 20% calculation UAT-010 Beta accountant Not Started
AC-050 SEF submission success UAT-020 Beta SMB owner Not Started
AC-080 PDV report generation UAT-030 Beta accountant Not Started
NF-AC-030 Debit = Credit invariant UAT-ACC-001 Beta accountant Not Started
NF-AC-001 Dashboard load < 3s UAT-P01 Any beta user Not Started

6. Traceability to Requirements

AC ID Acceptance Criterion FR Reference BR Reference US Reference
AC-001 Successful registration FR-001 BR-014 US-001
AC-020 Successful login FR-002 BR-014 US-002
AC-030 Invoice PDV 20% FR-010 BR-002 US-010
AC-050 SEF submission success FR-011 BR-001 US-011
AC-060 Mark invoice paid FR-012 BR-001 US-012
AC-070 Record expense FR-020 BR-009 US-020
AC-080 PDV report January FR-050 BR-002, BR-006 US-050

Full traceability: RTM.md


Approval

Role Name Date Signature
Author John (AI Director) 2026-02-23
Reviewer
Business Analyst John 2026-02-23
Product Owner John 2026-02-23
QA Engineer validator agent
AI Director (John) John 2026-02-23
CEO (Alem) Alem Bašić