Functional Requirements Specification Functional Requirements Specification (FRS): 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. System Overview System Name: Bilko — Balkan Accounting SaaS System Purpose: Bilko is a cloud-based accounting platform for Balkan SMBs that handles e-invoicing (Serbian SEF), expense tracking, double-entry bookkeeping, bank reconciliation, VAT/PDV management, and financial reporting. It provides a simple, compliant, affordable alternative to legacy ERP systems, accessible from any browser. System Context Diagram: graph TB subgraph "Bilko Platform" UI[Web App\nNext.js 15 + React 19] API[Backend API\nExpress + TypeScript] DB[(PostgreSQL\nPrisma ORM)] end U1[SMB Owner] -->|Uses| UI U2[Accountant] -->|Uses| UI U3[Viewer / Employee] -->|Read-only| UI API -->|Reads/Writes| DB API -->|Submits e-invoices| SEF[SEF Platform\nefaktura.gov.rs] API -->|Sends invoice PDFs| EMAIL[Email Provider\nTransactional] API -->|Fetches rates| FX[Exchange Rate API\nECB / fixer.io] ADM[Admin\nOrg Owner] -->|Manages org + users| UI 2. Actors & Personas Actor ID Actor Name Type Description Access Level ACT-01 Organization Owner Human Business owner who created the Bilko account; full control Owner role — all permissions ACT-02 Admin Human Designated admin (accountant or office manager) Admin role — all except billing ACT-03 Accountant Human External bookkeeper managing the organization's books Accountant role — financial data, reports; cannot delete ACT-04 Viewer Human Employee or partner with read-only access Viewer role — read only ACT-05 SEF Platform System Serbian government e-invoice platform External API ACT-06 Email Provider System Transactional email for invoice delivery External API ACT-07 Exchange Rate API System Currency rate provider (ECB / fixer.io) External API Persona Detail Persona: Marko Petrović — SMB Owner Role: Owner of a 8-person IT consulting firm in Belgrade Goal: Create and submit SEF invoices fast; see real-time P&L; file PDV without an accountant Pain Points: SEF portal is slow; Pantheon is complex; doesn't understand bookkeeping jargon Tech Savviness: Medium — uses Google Suite, smartphones, but not accounting software Frequency of Use: Daily (invoices) + monthly (PDV report) Persona: Ana Nikolić — Accountant Role: Independent bookkeeper managing 12 SMB clients Goal: Access all client organizations from one login; export VAT reports in required formats Pain Points: Each client uses different software; reconciliation takes too long each month Tech Savviness: High — experienced with accounting software, Excel, CSV workflows Frequency of Use: Daily across multiple client orgs 3. Functional Requirements 3.1 Module: Authentication & User Management Module Overview Handles user registration, login, session management, organization creation, and role-based access control (RBAC). Multi-tenant: one user can belong to multiple organizations. FR-001: User Registration ⚠️ SUPERSEDED (2026-06-25). Email/password registration is RETIRED. Auth is Microsoft Entra External ID (CIAM) SSO only — the email/password endpoints return HTTP 410 ( AuthRoutes.kt ~242/254). New users are provisioned via Entra JIT on first SSO login, or via the FR-003 tokenized invite flow ( /accept-invite → Entra SSO). The criteria below (password complexity, verification email) DO NOT apply. Retained for historical trace only. Attribute Value Module Authentication Priority Must Have Trace BR-014 UI Reference /auth/register page Description: A new user registers with email and password. On successful registration, a verification email is sent and a default organization is created for the user with Owner role. Acceptance Criteria: Given a valid, unregistered email and strong password (≥8 chars, 1 uppercase, 1 number), when user submits registration form, then account is created, verification email sent, user redirected to email verification page Given an already-registered email, when user submits, then error "An account with this email already exists" shown; no account created Given password does not meet complexity rules, when user submits, then inline validation error shown before submission Data Requirements: Input: email (unique), password, full name, organization name Output: user record, organization record, Owner role assignment, verification token Validation: email format, password complexity, uniqueness check Business Rules: RUL-08 (org scoping from first login) FR-002: User Login ⚠️ SUPERSEDED (2026-06-25). Email/password login is RETIRED (HTTP 410). Login is Microsoft Entra External ID (CIAM) SSO only — /login triggers signInWithMicrosoft() → *.ciamlogin.com ; backend issues the session from the Entra id_token ( AuthService.createSessionFromEntraIdToken ). The email/password criteria below DO NOT apply. Retained for historical trace only. Attribute Value Module Authentication Priority Must Have Trace BR-014 UI Reference /auth/login page Description: Authenticated users log in with email and password. Returns JWT access token (15-min TTL) + refresh token (30-day TTL). Acceptance Criteria: Given valid credentials, when user submits login, then JWT issued, user redirected to dashboard Given invalid credentials, when user submits, then generic error "Invalid email or password" (no user enumeration) Given 5 consecutive failed attempts, when user tries again, then account locked for 15 minutes Given idle session > 30 minutes, when user attempts action, then redirected to login FR-003: Invite User to Organization Attribute Value Module Authentication Priority Must Have Trace BR-007 UI Reference /settings/team page Description: Organization Owner or Admin can invite users by email with a specific role (Admin, Accountant, Viewer). Invited user receives email with accept link; on acceptance, they are added to the organization with the assigned role. Acceptance Criteria: Given an Owner invites user@email.com as Accountant, when invite is sent, then invitation email received within 2 minutes with unique accept link Given invited user accepts link within 48 hours, when they register or log in, then added to organization with Accountant role Given invite link expires (48h), when user clicks link, then error shown with option to request new invite 3.2 Module: Invoicing Module Overview Core invoicing functionality. Create, edit, preview, send, and track invoices. For Serbia: automatic SEF submission on send. Multi-currency. PDF generation with client/Bilko branding. FR-010: Create Invoice Attribute Value Module Invoicing Priority Must Have Trace BR-001, BR-002, BR-004, BR-008 UI Reference /invoices/create — 6-step wizard Description: User creates a new invoice by selecting a client (Contact), adding line items with quantities and unit prices, selecting currency and PDV rate. System auto-calculates PDV and totals. Preview shows PDF representation before sending. Acceptance Criteria: Given an authenticated user, when they complete the 6-step invoice wizard with valid data, then invoice is created in Draft status with correct PDV calculation Given Serbian PDV rate of 20%, when line item total is 1000 RSD, then PDV = 200 RSD, total = 1200 RSD Given multi-currency invoice in EUR, when created, then exchange rate at transaction date is locked and stored Given invoice is in Draft, when user sends it, then status changes to Sent, PDF emailed to client, SEF submission initiated (Serbia) Data Requirements: Input: client (Contact), invoice_date, due_date, currency, line_items (description, qty, unit_price, vat_rate), notes Output: Invoice record with auto-generated invoice_number, PDV amounts, total_amount in NUMERIC(19,4) Validation: due_date > invoice_date; at least one line item; contact required Business Rules: RUL-01 (NUMERIC), RUL-02 (double-entry on payment), RUL-05 (sequential numbering), RUL-06 (PDV rate selection) FR-011: SEF E-Invoice Submission (Serbia) Attribute Value Module Invoicing Priority Must Have Trace BR-001 UI Reference Automatic on invoice send; status shown in invoice detail Description: When a user sends an invoice for a Serbian B2B transaction, Bilko automatically submits the invoice to SEF (efaktura.gov.rs) in UBL 2.1 XML format. SEF status (sent, accepted, rejected) is tracked and displayed. Acceptance Criteria: Given a Serbian B2B invoice is sent, when the send action is triggered, then UBL 2.1 XML is generated and submitted to SEF API within 30 seconds Given SEF accepts the invoice, when success response received, then invoice SEF status updated to "Accepted" and SEF invoice ID stored Given SEF rejects the invoice, when rejection response received, then user is notified with the rejection reason from SEF; invoice stays in Sent status pending correction Given SEF API is unavailable, when submission attempted, then invoice queued for retry; user notified; max 3 retries with exponential backoff Data Requirements: Input: Invoice record + organization SEF credentials Output: SEF invoice ID, submission timestamp, SEF status Validation: Required SEF fields present (buyer tax ID, invoice type, issue date) FR-012: Track Invoice Status Attribute Value Module Invoicing Priority Must Have Trace BR-001, BR-008 Description: Invoices progress through status states: Draft → Sent → SEF Accepted → Paid / Overdue. Users can mark invoices as paid, add payment date and amount. Acceptance Criteria: Given invoice is Sent, when user marks as paid with payment date and amount, then status changes to Paid and payment transaction auto-created Given invoice is Sent and due_date has passed, when system checks daily, then status automatically changes to Overdue Given a list of invoices, when user filters by status, then only matching invoices shown 3.3 Module: Expense Tracking Module Overview Record business expenses with categorization, multi-currency support, and receipt attachment. Feeds double-entry bookkeeping automatically. FR-020: Create Expense Attribute Value Module Expenses Priority Must Have Trace BR-009 UI Reference /expenses/create Description: User records a business expense with vendor, amount, currency, category, payment method, and optional receipt photo. System auto-creates the double-entry transaction. Acceptance Criteria: Given valid expense data, when user submits, then expense saved with debit to expense account + credit to payment account Given a foreign currency expense, when created, then exchange rate at expense date locked and stored; amount also shown in base currency Given receipt image uploaded (JPG/PNG/PDF, max 10MB), when expense saved, then receipt stored and accessible from expense record 3.4 Module: Double-Entry Bookkeeping Module Overview The accounting engine. Every financial event generates balanced debit + credit Transaction entries. Supports Chart of Accounts per Balkan GAAP (Serbian Kontni Okvir 2021). FR-030: Chart of Accounts Attribute Value Module Bookkeeping Priority Must Have Trace BR-003, BR-010 UI Reference /settings/accounts Description: Every organization is seeded with the Serbian Kontni Okvir (Chart of Accounts) per Pravilnik 2021 on creation. Accountants can add custom sub-accounts. Pre-populated accounts cover all 10 account classes (0-9). Acceptance Criteria: Given a new Serbian organization is created, when setup completes, then all standard Kontni Okvir accounts are pre-populated (Classes 0-9) Given an accountant adds a custom sub-account under 411, when saved, then account 411xxx appears in Chart of Accounts and is available in transaction entry Given an account has transactions, when user attempts to delete it, then deletion blocked with explanation FR-031: Double-Entry Transaction Recording Attribute Value Module Bookkeeping Priority Must Have Trace BR-003 UI Reference Auto-generated; viewable in /bookkeeping/journal Description: Every financial event (invoice paid, expense recorded, bank reconciliation) automatically generates a balanced Transaction record with debitAccountId, creditAccountId, and amount in NUMERIC(19,4). Acceptance Criteria: Given an invoice of 1200 RSD (1000 + 200 PDV) is marked paid, when payment recorded, then Transaction created: Debit 1200 (bank account), Credit 1000 (revenue), Credit 200 (PDV payable) Given any transaction is created, when saved, then sum of all debits = sum of all credits (ACID enforcement) Given a transaction is created, when user attempts to delete it, then soft-delete only — LoggedAction records the deletion; original data preserved Business Rules: RUL-01, RUL-02, RUL-03, RUL-04 3.5 Module: Bank Reconciliation Module Overview Import bank statements via CSV upload. Auto-match transactions. Manual reconciliation for unmatched items. FR-040: Bank Statement CSV Import Attribute Value Module Banking Priority Must Have Trace BR-005 UI Reference /banking page Description: Users upload bank statement CSV files (Serbian bank format). System parses transactions and attempts to auto-match with existing invoices/expenses by amount and date proximity. Acceptance Criteria: Given a valid CSV in supported Serbian bank format, when uploaded, then all transactions parsed and displayed for review Given parsed transaction matches an open invoice by amount ± 5%, when suggested, then match highlighted for user confirmation Given unmatched transaction, when user manually matches or categorizes, then Transaction and double-entry entry created 3.6 Module: VAT / PDV Management Module Overview Auto-calculate, track, and generate PDV reports for monthly filing with Poreska Uprava (Serbia). FR-050: PDV Report Generation Attribute Value Module VAT/PDV Priority Must Have Trace BR-002, BR-006 UI Reference /reports/vat Description: System aggregates all VAT-applicable transactions for a period and generates the PDV report in the format required by Poreska Uprava. Export in PDF and XML/JSON formats. Acceptance Criteria: Given a reporting period (month), when user generates PDV report, then all sales PDV and input PDV correctly summed; net PDV payable/refundable calculated Given PDV report generated, when user exports, then PDF and XML export available; XML format compatible with ePorezi portal Given zero PDV period, when report generated, then zero report generated correctly (still required by law) 3.7 Module: Financial Reports Module Overview P&L Statement, Balance Sheet, Cash Flow Statement — generated from double-entry transaction data. PDF and Excel export. FR-060: Profit & Loss Statement Attribute Value Module Reports Priority Must Have Trace BR-006 UI Reference /reports hub Acceptance Criteria: Given a date range, when P&L generated, then all revenue and expense accounts summarized; net profit/loss calculated and matches double-entry totals Given multi-currency org, when P&L generated, then all amounts shown in base currency using locked exchange rates FR-061: Balance Sheet Attribute Value Module Reports Priority Must Have Trace BR-006 Acceptance Criteria: Given any date, when Balance Sheet generated, then Assets = Liabilities + Equity (double-entry balance enforced) Given Balance Sheet is unbalanced (should be impossible), when detected, then alert raised immediately for investigation 3.8 Module: Multi-Currency Module Overview Support BAM, RSD, EUR, USD. Exchange rates fetched daily from ECB / fixer.io. Rates locked at transaction date per IFRS requirements. FR-070: Exchange Rate Management Attribute Value Module Multi-Currency Priority Must Have Trace BR-004 Acceptance Criteria: Given a transaction in non-base currency, when created, then exchange rate at transaction date is fetched, stored, and locked — cannot be edited later Given ECB rate API unavailable, when transaction attempted, then system uses cached rate (max 24h old) or prompts user for manual entry Given organization base currency is RSD, when EUR invoice created, then both EUR amount and RSD equivalent stored; reports show RSD 4. Use Case Diagrams 4.1 Core Workflows graph LR Owner((Owner)) --> UC1[FR-001: Register] Owner --> UC2[FR-010: Create Invoice] Owner --> UC3[FR-011: Submit to SEF] Owner --> UC4[FR-050: Generate PDV Report] Owner --> UC5[FR-060: View P&L] Accountant((Accountant)) --> UC2 Accountant --> UC6[FR-030: Manage Chart of Accounts] Accountant --> UC7[FR-031: Record Manual Transaction] Accountant --> UC4 Accountant --> UC8[FR-040: Import Bank CSV] Viewer((Viewer)) --> UC9[View Reports — Read Only] SEF((SEF API)) --> UC3 5. System Behavior Specifications 5.1 Error Handling All user-facing errors display human-readable Serbian/English message (no stack traces) All errors logged with correlation ID, timestamp, user ID (if authenticated), and action Validation errors shown inline, adjacent to the invalid field SEF API errors: show SEF's rejection reason in user-readable format + link to fix 5.2 Data Persistence All financial data persisted within 500ms of user action Optimistic UI updates rolled back if server confirmation fails All mutations (create/update/delete) audited in LoggedAction with user ID and timestamp 5.3 Session & State Session timeout: 30 minutes of inactivity (JWT expiry) Refresh token: 30-day rolling TTL Concurrent sessions: allowed (mobile + desktop) Browser refresh: state restored from server (no stale data) 5.4 Notifications Email notifications: invoice sent, invoice paid, SEF acceptance/rejection, account invitation In-app notifications: overdue invoices, PDV filing reminder (14th of month), bank import complete All marketing emails include unsubscribe link (GDPR) 5.5 Accessibility WCAG 2.1 Level AA compliance Keyboard navigation for all interactive elements Screen reader compatibility (Radix UI / shadcn ARIA labels) Color contrast ratio ≥ 4.5:1 (Bilko mint green #00E5A0 on dark backgrounds verified) 6. Requirements Summary Table ID Feature Name Module Priority Status Trace FR-001 User Registration Authentication Must Have SUPERSEDED — Entra SSO/JIT + FR-003 invite (email/pw retired, 410) BR-014 FR-002 User Login Authentication Must Have SUPERSEDED — Entra CIAM SSO only (email/pw retired, 410) BR-014 FR-003 Invite User to Organization Authentication Must Have Not Started BR-007 FR-010 Create Invoice Invoicing Must Have Not Started BR-001, BR-002, BR-004, BR-008 FR-011 SEF E-Invoice Submission Invoicing Must Have Not Started BR-001 FR-012 Track Invoice Status Invoicing Must Have Not Started BR-001, BR-008 FR-020 Create Expense Expenses Must Have Not Started BR-009 FR-030 Chart of Accounts Bookkeeping Must Have Not Started BR-003, BR-010 FR-031 Double-Entry Transaction Recording Bookkeeping Must Have Not Started BR-003 FR-040 Bank Statement CSV Import Banking Must Have Not Started BR-005 FR-050 PDV Report Generation VAT/PDV Must Have Not Started BR-002, BR-006 FR-060 P&L Statement Reports Must Have Not Started BR-006 FR-061 Balance Sheet Reports Must Have Not Started BR-006 FR-070 Exchange Rate Management Multi-Currency Must Have Not Started BR-004 Requirements Count: Must Have: 14 Should Have: 0 in this document (Croatian eRačun in Phase 2 FRS) Could Have: 0 Won't Have (Phase 1): Payroll, AI bookkeeping, live bank feeds 7. Traceability to Business Requirements FR ID Feature Name Business Requirement (BR ID) Business Objective (BO ID) FR-001 User Registration BR-014 BO-01 FR-002 User Login BR-014 BO-01 FR-003 Invite User BR-007 BO-02 FR-010 Create Invoice BR-001, BR-002, BR-004, BR-008 BO-01, BO-02 FR-011 SEF Submission BR-001 BO-01 FR-012 Invoice Status Tracking BR-001, BR-008 BO-02 FR-020 Create Expense BR-009 BO-02 FR-030 Chart of Accounts BR-003, BR-010 BO-01 FR-031 Double-Entry Recording BR-003 BO-01 FR-040 Bank CSV Import BR-005 BO-02 FR-050 PDV Report BR-002, BR-006 BO-01, BO-03 FR-060 P&L Statement BR-006 BO-03 FR-061 Balance Sheet BR-006 BO-01, BO-03 FR-070 Exchange Rates BR-004 BO-01 Full traceability matrix: RTM.md Approval Role Name Date Signature Author John (AI Director) 2026-02-23 Reviewer Business Analyst John 2026-02-23 Tech Lead John 2026-02-23 Product Owner John 2026-02-23 AI Director (John) John 2026-02-23 CEO (Alem) Alem Bašić