From Analysis to System Design

Project: A Design Specification

18 min Lesson 10 of 10

Project: A Design Specification

Every concept introduced across this tutorial — the analysis-to-design transition, architectural layers, module decomposition, interface contracts, data-layer design, input/output design, and the written specification document — converges in one final deliverable: the Design Specification. In this lesson you will build a compact but complete design spec for a realistic system, working through each section step by step. The process is repeatable: once you have done it once you can apply it to any project of any scale.

The case study is a small-business logistics platform called SwiftRoute. A regional courier company uses it to manage customer shipments, assign drivers, and track deliveries in real time. The requirements analysis and ERD were completed in earlier phases; here the analyst team transitions that analysis into a coherent design.

Section 1: System Overview and Scope

The first section of any design spec orients the reader. It states what the system does, which version this document covers, and which stakeholders approved it.

SwiftRoute Logistics Platform — Design Specification v1.0 System: Shipment management, driver dispatch, and real-time delivery tracking Scope: Customer-facing web portal + internal dispatch console + driver mobile app In scope: Shipment lifecycle (create → assign → in-transit → delivered/failed) Out of scope: Billing/invoicing (Phase 2), fleet maintenance module (Phase 3) Prepared by: Systems Analysis Team Approved by: Head of Operations, CTO Date: 2024-09-01

The scope boundary is critical: it prevents scope creep from re-entering during design and keeps the specification reviewable within a reasonable time box.

Section 2: Architectural Design

A brief architectural narrative explains why the chosen structure was selected over alternatives. For SwiftRoute the team chose a three-tier web architecture with a separate mobile-API layer for the driver app. The justification: the operations team runs the dispatch console on desktop browsers, but the 40 active drivers use Android phones on cellular networks — different latency and bandwidth profiles demand a dedicated lightweight API.

SwiftRoute — Three-Tier + Mobile API Architecture SwiftRoute — Architectural Layers Tier 1 — Presentation Customer Web Portal Dispatch Console Driver Mobile App Tier 2 — Application (Business Logic) Shipment Service Dispatch Service Driver API (lightweight REST) Notification Service Tier 3 — Data SwiftRoute DB (MySQL) Redis (Session/Cache) Object Storage (Files) Standard call (HTTP/SQL) Mobile Driver API (lightweight REST)
SwiftRoute three-tier architecture: presentation clients, application services (including a dedicated Driver API), and data stores.

Section 3: Module Decomposition

The architecture names the layers; the module decomposition names what lives inside each layer and what each module is responsible for. In the spec this appears as a table or structured list — not a vague description, but a precise responsibility assignment:

MODULE REGISTER — Application Tier (Tier 2) ┌──────────────────────┬───────────────────────────────────────────────────────┐ │ Module │ Responsibilities │ ├──────────────────────┼───────────────────────────────────────────────────────┤ │ Shipment Service │ Create, update, cancel shipments; validate addresses; │ │ │ calculate ETAs; expose REST endpoints for portal. │ ├──────────────────────┼───────────────────────────────────────────────────────┤ │ Dispatch Service │ Assign drivers to shipments; enforce zone rules; │ │ │ requeue failed assignments; expose console endpoints. │ ├──────────────────────┼───────────────────────────────────────────────────────┤ │ Driver API │ Accept driver location pings; accept status updates │ │ │ (picked-up, delivered, failed); optimised for mobile. │ ├──────────────────────┼───────────────────────────────────────────────────────┤ │ Notification Service │ Send email/SMS on shipment events; queue-based; │ │ │ retryable; no direct DB writes. │ └──────────────────────┴───────────────────────────────────────────────────────┘

Section 4: Key Interface Specifications

A full spec documents every interface; in this compact project spec we cover the two most critical ones — the customer shipment creation endpoint and the driver status-update endpoint — since they carry the highest integration risk.

IF-1: POST /api/v1/shipments (Customer Portal → Shipment Service) Input: { sender_id, recipient_name, recipient_address, weight_kg, service_level } Success: 201 { shipment_id, tracking_code, estimated_delivery } Errors: 400 INVALID_ADDRESS | 422 WEIGHT_EXCEEDED | 401 UNAUTHORIZED IF-2: PATCH /driver/v1/shipments/{id}/status (Driver App → Driver API) Input: { status: enum(picked_up|in_transit|delivered|failed), location_lat, location_lng, note? } Success: 200 { shipment_id, new_status, updated_at } Errors: 404 SHIPMENT_NOT_FOUND | 409 INVALID_STATUS_TRANSITION | 401 UNAUTHORIZED
Status transition rules belong in the spec. The INVALID_STATUS_TRANSITION error means the system enforces that a driver cannot mark a shipment as delivered without it first being picked_up. Capture these state-machine rules in the spec — not as an afterthought in code comments.

Section 5: Data Layer Design

The data layer section maps the ERD entities to concrete tables, notes primary and foreign keys, and calls out any performance decisions (indexes, partitioning, read replicas). For SwiftRoute:

TABLE: shipments shipment_id BIGINT PK AUTO_INCREMENT sender_id INT FK → customers(customer_id) recipient_name VARCHAR(120) NOT NULL recipient_addr TEXT NOT NULL weight_kg DECIMAL(6,2) NOT NULL service_level ENUM('standard','express','same-day') NOT NULL status ENUM('created','assigned','picked_up','in_transit','delivered','failed') tracking_code VARCHAR(20) UNIQUE NOT NULL created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX: (sender_id), (status), (tracking_code) TABLE: driver_locations location_id BIGINT PK driver_id INT FK → drivers(driver_id) shipment_id BIGINT FK → shipments(shipment_id) lat DECIMAL(9,6), lng DECIMAL(9,6) recorded_at TIMESTAMP NOTE: High-frequency insert table — partitioned by MONTH(recorded_at). Only last 30 days retained in primary partition; older rows archived.

Section 6: Input and Output Design

The spec includes wireframe-level descriptions of the key user interfaces. Full pixel-perfect designs belong in the UI prototype, but the spec must document field names, validation rules, and output formats so that any developer — or a reviewer checking traceability — can verify alignment with requirements.

SwiftRoute — Create Shipment form wireframe and tracking output Input Design (Create Shipment) and Output Design (Tracking View) CREATE SHIPMENT Recipient Name * Delivery Address * Weight (kg) * [max 50 kg] Service Level * ▾ Standard ✖ Address must include city and postcode Book Shipment * Required. Weight validated against service-level limits before submit. TRACKING VIEW SWF-20240901-00421 Created — 2024-09-01 09:14 Assigned — Driver: M. Al-Rashid Picked Up — 2024-09-01 11:02 In Transit (pending) Delivered (pending) ETA: 2024-09-01 by 17:00
Wireframe: Create Shipment form (left) with validation callouts, and Tracking View output (right) with live status timeline.

Section 7: Traceability Summary

The final section of a compact design spec is a traceability snapshot: a table that links every functional requirement to the design element that satisfies it. Even a short table proves that nothing has been forgotten and gives reviewers a place to challenge gaps.

TRACEABILITY SNAPSHOT (selected rows) ┌────────┬─────────────────────────────────────┬────────────────────────┬──────────────┐ │ Req ID │ Requirement │ Design Element │ Status │ ├────────┼─────────────────────────────────────┼────────────────────────┼──────────────┤ │ FR-01 │ Customer books a shipment online │ IF-1, Shipment Service │ Designed │ │ FR-02 │ Dispatcher assigns driver to order │ Dispatch Service UI │ Designed │ │ FR-03 │ Driver updates status from mobile │ IF-2, Driver API │ Designed │ │ FR-04 │ Customer tracks shipment in real- │ Tracking View, Redis │ Designed │ │ │ time via tracking code │ cache layer │ │ │ FR-05 │ System sends SMS on delivery │ Notification Service │ Designed │ │ NFR-01 │ Tracking page loads in < 1 second │ Redis cache + CDN │ Designed │ │ NFR-02 │ Driver API available on 2G/3G │ Lightweight REST API │ Designed │ └────────┴─────────────────────────────────────┴────────────────────────┴──────────────┘
Keep the spec alive, not archived. After the design review, update the traceability table as each design element is implemented and tested. A spec that reflects the built system is a priceless maintenance asset; a spec that diverges from the code is a liability. Assign an owner and a review cadence before the project moves into development.

What Makes a Good Design Spec

Looking back at SwiftRoute, the characteristics that make this spec effective are: it is scoped (out-of-scope items are listed explicitly), structured (each section has a defined purpose), traceable (every requirement maps to a design element), and reviewable (diagrams and tables allow a reviewer to spot missing pieces in minutes rather than hours). A design spec does not need to be long — it needs to be complete within its scope.

The most common failure mode is a spec that is strong on architecture diagrams but silent on interface error cases and data validation rules. Developers then make independent assumptions about those gaps, and the integration fails. Always give every interface a named error catalogue, and every input field a stated validation rule — even if it is just "max 255 characters."

Tutorial Complete!

Congratulations! You have completed all lessons in this tutorial.