Skip to content

๐Ÿ” API Reference & RBAC Architecture

This document provides the canonical API contracts, Role-Based Access Control (RBAC) hierarchy, authentication lifecycle, and idempotency guarantees implemented in apps/api[cite: 3, 5, 7].


๐Ÿ‘‘ Role-Based Access Control (RBAC) Hierarchy

The platform defines a strict 4-tier hierarchical authorization model[cite: 3, 6]:

Role Target Identity Scope & Authority
ROOT_ADMIN[cite: 3, 6] Founder / Lead Architect (mert@duespay.local)[cite: 3] Unrestricted root platform access[cite: 3, 7]. Can provision system administrators, manage the global chart of accounts (Revenue 600), and oversee cross-tenant PayTR reconciliation[cite: 3]. Bypasses route guards[cite: 7].
SUPER_ADMIN[cite: 3, 6] Engineering & Operations Team[cite: 3] Operational management across all complexes[cite: 3]. Oversees DLQ queues, vector telemetry, and audit logs[cite: 3]. Cannot modify ROOT_ADMIN credentials[cite: 3].
COMPLEX_ADMIN[cite: 3, 6] Complex / Site Manager[cite: 3] Scoped strictly to assigned complex_id[cite: 3]. Manages units, tariffs, monthly assessments, recurring expenses, and complex announcements[cite: 3, 5, 6].
RESIDENT[cite: 3, 6] Apartment Tenant / Property Owner[cite: 3] Scoped to assigned unit_id and complex_id[cite: 3, 6]. Views unpaid dues, executes gateway payments, downloads 5-year digital receipts, and reads announcements[cite: 3].

๐Ÿ”‘ Authentication & Session Model

JWT Token Specifications

  • Signature Algorithm: HMAC-SHA256 (HS256)[cite: 5].
  • Session TTL: 24 hours standard; 7 days (168 hours) when remember_me = true[cite: 5].
  • Token Claims Payload: json { "sub": "e0000000-0000-0000-0000-000000000003", "email": "mert@example.com", "role": "RESIDENT", "complex_id": "a1b2c3d4-0000-0000-0000-000000000001", "unit_id": "b1b2c3d4-0000-0000-0000-000000000002", "iss": "dues-pay-engine-auth", "iat": 1786981111, "exp": 1787067511 }[cite: 3, 5]

Authorization Header Format

Protected endpoints require standard Bearer token transmission[cite: 3, 7]: http Authorization: Bearer <JWT_TOKEN>[cite: 3, 7]


๐Ÿ›ก๏ธ Idempotency & Reuse-Intent Standard

To prevent duplicate charges from network retries or multiple button clicks, the engine enforces a 15-minute pending session window[cite: 4]:

  1. Client Generation: The frontend generates a unique Idempotency-Key (UUIDv4) upon the first payment click[cite: 4].
  2. Reuse Window: If an active session with status CREATED exists for the given assessment_id within the last 15 minutes, the API returns the existing merchant_oid and payment token rather than creating a duplicate database record[cite: 4].
  3. Database Guard: The merchant_oid and idempotency_key columns maintain strict unique constraints on the payment_intents table[cite: 3, 4].

๐Ÿ“ก API Endpoint Reference

1. Authentication & Session

Authenticate User

http POST /api/v1/auth/login Content-Type: application/json[cite: 3, 5] * Access Level: Public[cite: 3, 5] * Request Body: json { "email": "yonetim@flora.example.com", "password": "manager123", "remember_me": true }[cite: 5] * Response (200 OK): json { "access_token": "eyJhbGciOiJIUzI1...", "expires_at": "2026-09-07T18:38:31Z", "user": { "id": "e0000000-0000-0000-0000-000000000002", "email": "yonetim@flora.example.com", "full_name": "Ahmet Yonetici", "role": "COMPLEX_ADMIN", "complex_id": "a1b2c3d4-0000-0000-0000-000000000001", "unit_id": null } }[cite: 3, 5, 6]


2. Resident Portal Endpoints

Get Announcements

http GET /api/v1/portal/announcements Authorization: Bearer <TOKEN>[cite: 3] * Allowed Roles: RESIDENT, COMPLEX_ADMIN, ROOT_ADMIN[cite: 3, 7] * Behavior: Returns announcements scoped to the user's complex_id, sorted with pinned notices first[cite: 3].

Get Outstanding Dues Summary

http GET /api/v1/portal/dues/summary Authorization: Bearer <TOKEN>[cite: 3] * Allowed Roles: RESIDENT, ROOT_ADMIN[cite: 3, 7] * Response (200 OK): json { "total_outstanding": "1500.00", "unpaid_count": 1, "assessments": [ { "id": "c1b2c3d4-0000-0000-0000-000000000003", "unit_id": "b1b2c3d4-0000-0000-0000-000000000002", "period": "2026-08", "base_amount": "1500.00", "status": "UNPAID", "due_date": "2026-08-31" } ] }[cite: 3]

Get 5-Year Payment & Document History

http GET /api/v1/portal/dues/history Authorization: Bearer <TOKEN>[cite: 3] * Allowed Roles: RESIDENT, ROOT_ADMIN[cite: 3, 7] * Behavior: Returns settled payments from the last 5 years along with download URLs for generated PDF receipts and UBL-TR invoices[cite: 3].


3. Manager & Complex Operations

List Complex Units & Balances

http GET /api/v1/manager/units Authorization: Bearer <TOKEN>[cite: 3] * Allowed Roles: COMPLEX_ADMIN, SUPER_ADMIN, ROOT_ADMIN[cite: 3, 7] * Query Parameters: complex_id (optional for COMPLEX_ADMIN, inferred from JWT)[cite: 5, 7].

Update Resident Contact Assignment (Tenant Transfer)

http PATCH /api/v1/manager/units/{unit_id} Authorization: Bearer <TOKEN> Content-Type: application/json[cite: 3] * Allowed Roles: COMPLEX_ADMIN, ROOT_ADMIN[cite: 3, 7] * Request Body: json { "resident_name": "AyลŸe Yeni Kiracฤฑ", "resident_phone": "+905557778899", "resident_email": "ayse@example.com" }[cite: 3] * Behavior: Replaces tenant details while preserving unit billing history and outstanding ledger balance[cite: 3].

Publish Complex Announcement

http POST /api/v1/manager/announcements Authorization: Bearer <TOKEN> Content-Type: application/json[cite: 3] * Allowed Roles: COMPLEX_ADMIN, ROOT_ADMIN[cite: 3, 7] * Request Body: json { "title": "2026 Yฤฑlฤฑ OlaฤŸan Genel Kurul Kararlarฤฑ", "content": "AฤŸustos ayฤฑ genel kurulunda alฤฑnan kararlar gereฤŸi aidatlar 1.500 TL olarak belirlenmiลŸtir.", "type": "DECISION", "is_pinned": true }[cite: 3]


4. Webhooks & Gateways

PayTR Settlement Notification Callback

http POST /api/v1/webhooks/paytr Content-Type: application/x-www-form-urlencoded[cite: 3] * Access Level: Gateway IP Whitelist / Public HMAC-SHA256 verification[cite: 3]. * Idempotency Rule: If the associated merchant_oid is already marked SETTLED, the endpoint skips double ledger booking and responds with OK immediately[cite: 3, 4]. * Response: OK (raw text string)[cite: 3, 4].