Engineering Specifications

Software Requirements Specification (SRS)

A Software Requirements Specification (SRS) is the definitive technical contract describing the software system's behaviors, API schemas, database state machines, and quantitative performance budgets (P99 latency, security protocols, SLAs).

PRD vs. SRS: Side-by-Side Architectural Breakdown

Understanding the distinct boundary between a Product Requirements Document (PRD) and a Software Requirements Specification (SRS) prevents endless back-and-forth debates between Product and Engineering:

PRD (Product Focus)"What & Why"

User Experience & Problem Space

  • Target Audience: Cross-functional squad (Designers, Devs, QA, Marketing).
  • Example Requirement: "Users must be able to log in securely with their Google Workspace account and automatically sync profile avatars."
  • Artifacts: Figma wireframes, user journeys, INVEST User Stories, success KPIs.
SRS (Engineering Focus)"How Technically"

System Contracts & Execution Space

  • Target Audience: Software Engineers, QA Automation, DevOps, InfoSec.
  • Example Requirement: "Auth service shall exchange Google OAuth authorization codes via RFC 7636 PKCE, issuing RS256 signed JWTs with 900s TTL and \`roles\` claim array."
  • Artifacts: JSON Schemas, ERD relational constraints, state machines, P99 latency budgets.

Non-Functional Requirements (NFR) Masterclass (ISO 25010)

Quantitative Quality Model

Non-Functional Requirements define how well the system behaves under pressure. Vague phrases like "the system must be fast" fail engineering reviews. Use quantitative, measurable metrics:

Performance & Latency (P95 / P99)

Speed & Throughput
P99 Ingestion Latency
< 150ms

Maximum response time for 99% of all incoming API calls under peak load.

Peak Throughput
5,000 RPS

Sustained requests-per-second without CPU throttling or queue backup.

DB Query Execution
< 20ms

Maximum latency budget for indexed database reads.

🔬 Verification / Testing Method: Load testing via k6 or Locust simulating 10,000 virtual users.
01

Regulated & Safety-Critical

FinTech payment processors, medical devices (FDA / ISO 13485), and government defense contracts requiring strict requirements traceability matrices (RTM).

02

Outsourced & Vendor Contracts

Offshore engineering teams or software agencies where contractual acceptance requires deterministic, mathematically verifiable criteria.

03

Complex Distributed Microservices

Multi-squad distributed architectures where async message protocols (Kafka / gRPC / Protobuf) and database transaction locks must be documented.

Real-World Technical SRS Example

This production-grade specification models a high-throughput webhook dispatcher with cryptographic signature validation and idempotency caching:

# Software Requirements Specification (SRS)
## System Module: Payment Gateway Webhook Dispatcher & Idempotent Event Processor
- **Document Version:** 2.1.0
- **Technical Author:** Lead Systems Architect / Tech Lead
- **Related PRD:** [PRD-PAY-2026-03](https://learnprd.vercel.app/core-components)
- **Target Release:** Sprint 42 (v2.4.0)
- **Status:** Approved for Sprint Backlog

---

### 1. System Architecture & Context
The Payment Webhook Dispatcher is an asynchronous ingestion microservice responsible for receiving raw HTTP webhooks from external Payment Service Providers (Stripe, Adyen, PromptPay), verifying cryptographic authenticity, deduplicating payloads via distributed caching, and publishing canonical domain events to Apache Kafka.

---

### 2. Functional Requirements (FR)
| Requirement ID | System Feature | Input / Trigger | Processing Logic & Constraints | Expected Output / State Change |
| :--- | :--- | :--- | :--- | :--- |
| **`FR-WH-01`** | Webhook Ingestion | `POST /v1/webhooks/{provider}` | Ingest raw JSON payload (max body size: 1MB). | Return `HTTP 202 Accepted` within 120ms. |
| **`FR-WH-02`** | Signature Verification | HTTP Header `Stripe-Signature` | Compute HMAC-SHA256 hash using provider secret key in HashiCorp Vault. | If hash mismatch, reject with `HTTP 401 Unauthorized`. |
| **`FR-WH-03`** | Idempotency Check | Extracted `event_id` | Query Redis cluster key `idemp:{provider}:{event_id}` (TTL = 48h). | If key exists, log duplicate and return `HTTP 200 OK` without dispatch. |
| **`FR-WH-04`** | Event Publishing | Validated Webhook Event | Transform to Protobuf schema `PaymentSucceededEvent` and publish to Kafka topic `payments.incoming.v1`. | Kafka message partition key = `customer_uuid`. |

---

### 3. Non-Functional Requirements (NFR) — ISO 25010 Quality Model
#### 3.1 Performance & Latency (P99)
- **`NFR-PERF-01` Ingestion Latency:** The webhook listener endpoint must respond with `HTTP 202` in $le$ 150ms at P99 under 3,500 requests/second load.
- **`NFR-PERF-02` Database Query Budget:** PostgreSQL index lookup for order reconciliation must execute in $le$ 15ms.

#### 3.2 Security & Data Protection
- **`NFR-SEC-01` Transport Security:** All inbound HTTP traffic must enforce TLS 1.3 with HSTS enabled.
- **`NFR-SEC-02` Encryption at Rest:** Webhook raw payloads stored in cold storage (AWS S3) must use AES-256-GCM server-side encryption.
- **`NFR-SEC-03` Zero PII Logging:** Credit card tokens and account holder names must be stripped before emitting to Datadog log sinks.

#### 3.3 Reliability, Availability & Fault-Tolerance
- **`NFR-REL-01` Availability SLA:** Ingestion microservice must achieve 99.99% monthly uptime (~4.38 minutes allowed downtime/month).
- **`NFR-REL-02` Dead Letter Queue (DLQ):** Messages failing Kafka publishing after 3 exponential backoff retries (100ms, 400ms, 1600ms) must be routed to `payments.dlq` with error metadata.

---

### 4. Interface & Schema Contract
```json
// Schema Definition: POST /v1/webhooks/stripe Response
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "status": { "type": "string", "enum": ["accepted", "duplicate"] },
    "event_id": { "type": "string", "pattern": "^evt_[a-zA-Z0-9]+$" },
    "ingested_at": { "type": "string", "format": "date-time" }
  },
  "required": ["status", "event_id", "ingested_at"]
}
```