Warning

Generally when writing any document, consider the flow of information. By reading down you shouldn’t need to jump to a section further down to understand what is expected. It is ok not to go into much details.

Principles

Why Is This Needed?

  • Understanding the problem
    • Writing a good solution design document, forces you to thoroughly analyse the problem.
      • Requirements
      • Constraints
      • User needs
  • Architecture Planning
  • Risk Planning
    • Understand potential risks and challenges early on, so we can address them during the development process by developing mitigation strategies and contingency plans
  • Communication and Collaboration
    • The document serves as a communication tool for all stakeholders.
      • Developers, project managers, clients, qa and the dev team.
    • This will ensure that everyone understand the proposed solution and will give everyone the opportunity to provide feedback.
  • Resource Allocation
  • Scalability and Maintainability

Introduction

  • Briefly describe the focus and scope of the document
  • Clearly define what problem that the solution design aims to solve
  • Outline goals and objectives
  • Describe who the document is aimed for

Background

  • The document needs to provide a full picture of what needs to be done. This includes adding context and any other relevant background information
  • Explain the current state of affairs.
    • Explain which systems the current solution will interact with if any
    • Explain which systems will be replaced if there are any
    • What is currently in place?

Scope

  • Provide a clear scope of what needs to be done as part of the solution.
  • Clearly define boundaries of the solution.
  • List features that will be part of this solution.
  • Define what will not be done as part of this solution.
    • It’s a good idea here to outline what is expected the state of those parts to be.
      • Example if we depend on Service Now , what is expected SNOW to provide and ideally who is responsible for it.

Architecture Overview

  • Describe the high-level architecture of the software solution.
    • Make sure to create a Glossary of Names if needed
      • Usually added somewhere to the top of the document to be used for the entire scope of the document
    • Provide current versions that will be a target of the solution
    • Identify the major components/modules of the system and their interactions.
  • Use diagrams (e.g., UML diagrams, architectural diagrams) to illustrate the architecture.
    • Write a sequence diagram of how the different systems interact with each other.

Design Considerations

  • Discuss the key design decisions that have been made.
    • Don’t go into too much detail for things that will be covered later on, you can link them however.
  • Justify these decisions based on factors such as Performance, Scalability, Maintainability, Security
  • Address any trade-offs that were considered during the design process.
    • It’s good to outline these, so later on that can be used as reference.
      • For example lets say you looked into a potential alternative to something and decided that it is not applicable, then during development if a developer stumbles on the same questions, they can verify it against what was documented

Technologies Used

  • List the technologies, frameworks, and tools that will be used to implement the solution.
    • Versions are a must
  • Provide rationale for the selection of each technology.
  • Include any dependencies or external APIs that the solution will rely on.

Security

  • Outline risks and potential security vulnerabilities
    • Outline how these risks and vulnerabilities will be addressed.
  • Authentication/Authorization/etc should be defined in this section as a general overview
    • In-depth details for use cases should be added with the respective use case.
  • Other security features in place can be documented here too

Non Functional Requirements

  • Non-Functional Requirements

    • Not related to the system functionality, rather define how the system should perform.
    • Non Functional requirements define the quality attributes or characteristics that a software solution should have rather than specific use cases/behaviours or functionalities.
    • Describe how the system should behave, not what it should do.

    Example:

    • The system should handle 10 million concurrent users.
    • The website should load in less than 1 second.

    Example of Non-Functional Requirements

    1. Performance:
      • Response time: The system must respond to user actions within 2 seconds.
      • Throughput: The system should support 1000 concurrent users.
      • Scalability: The system should scale to accommodate a 50% increase in user load.
    2. Reliability:
      • Availability: The system should be available 99.9% of the time.
      • Fault tolerance: The system should continue to operate in the event of hardware or software failures.
      • Disaster recovery: The system should have a backup and recovery plan in case of catastrophic failures.
    3. Security:
      • Authentication: Users must authenticate using a username and password.
      • Authorization: Access to sensitive data should be restricted based on user roles and permissions.
      • Data encryption: All sensitive data must be encrypted both in transit and at rest.
    4. Usability:
      • User interface consistency: The user interface should have a consistent look and feel across all modules.
      • Accessibility: The system should be accessible to users with disabilities.
      • Learnability: The system should be easy for new users to learn and use.
    5. Scalability:
      • Horizontal scalability: The system should be able to scale out by adding more instances to handle increased load.
      • Vertical scalability: The system should be able to scale up by upgrading hardware to handle increased load.
    6. Maintainability:
      • Code maintainability: The codebase should be well-organized and documented to facilitate maintenance and future enhancements.
      • Modifiability: The system architecture should allow for easy modifications without impacting other components.
      • Testability: The system should be designed to facilitate automated testing.
    7. Compatibility:
      • Cross-browser compatibility: The system should work correctly on popular web browsers such as Chrome, Firefox, and Safari.
      • Platform compatibility: The system should run on different operating systems such as Windows, Linux, and macOS.
      • Integration compatibility: The system should be able to integrate with other systems and third-party services.
    8. Regulatory:
      • Compliance: The system must comply with relevant regulations and industry standards such as GDPR, HIPAA, or PCI DSS.
      • Data retention: The system should adhere to data retention policies and guidelines.
    9. Robustness:
      • Error handling: The system should gracefully handle unexpected errors and failures without crashing or losing data integrity.
      • Recovery: The system should be able to recover from failures automatically or with minimal manual intervention.
      • Graceful Degradation: In case of high load or failure, the system should degrade functionality gracefully to ensure essential services remain available.
    10. Load:
      • Load balancing: The system should distribute incoming requests evenly across multiple servers to ensure optimal performance and resource utilization.
      • Stress testing: The system should be tested under heavy loads to determine its performance and scalability limits.
      • Capacity planning: The system should have sufficient capacity to handle expected peak loads without degradation of performance.
    11. Configurability:
      • Parameterization: The system should allow key parameters and settings to be easily configured without requiring code changes.
      • Dynamic configuration: Configuration changes should take effect immediately without requiring a system restart.
      • Versioning: Configuration changes should be versioned and auditable to track changes and roll back if necessary.
    12. Testability:
      • Automation: The system should be designed for automated testing, with well-defined interfaces and testable components.
      • Mocking: The system should support mocking of external dependencies to facilitate isolated unit testing.
      • Test coverage: The system should have comprehensive test coverage to ensure all critical functionality is tested thoroughly.
    13. Operability:
      • Logging: The system should generate detailed logs for monitoring, troubleshooting, and auditing purposes.
      • Health checks: The system should expose endpoints or interfaces for monitoring its health and status.
      • Failure Recovery: The system should have mechanisms in place to detect and recover from common failures automatically.
    14. Monitorability:
      • Metrics: The system should expose key performance metrics and telemetry data for monitoring and analysis.
      • Alerting: The system should generate alerts based on predefined thresholds or anomalies to notify administrators of potential issues.
      • Visualization: The system should provide dashboards or visualizations to help administrators monitor system health and performance in real-time.
    Link to original

Functional Requirements/Use Cases

  • Identify the primary actors (users or systems) interacting with the software solution.
  • Document detailed use case scenarios that describe how these actors interact with the system to achieve specific goals or tasks.
  • Use a structured format for each use case,
    • Title
    • Brief description
    • Acceptance Criteria(s)
    • Preconditions
    • Main flow of events
    • Alternate flows
    • Postconditions
  • Provide clear and concise descriptions of each step in the use case flow
    • Outline which tasks should be performed by which user
  • Use diagrams such as UML use case diagrams to visualize the relationships between actors and use cases.

Assumptions And Dependencies

  • Document any external dependencies or assumptions that the software solution relies on.
  • Clearly state any assumptions that have been made during the design process.