Skip to main content

General Engineering Guidelines

Introduction

These guidelines define how engineers at Sadeem Informatique design systems, write software, collaborate, and operate. They ensure consistency, scalability, maintainability, security, and long-term reliability. These principles apply to all engineers, all repositories, and all environments.

Living document

These guidelines will evolve. If you spot gaps or better practices, propose an update so the whole organization benefits.

1. Engineering Mindset

Engineers are responsible for delivering reliable systems, not just code.

Expectations:

  • Think in terms of systems, not files
  • Consider long-term maintainability
  • Understand business impact of technical decisions
  • Take ownership of outcomes, not just tasks

Engineering decisions balance:

  • Simplicity
  • Reliability
  • Performance
  • Scalability
  • Cost

2. Simplicity First

We prioritize simple, understandable solutions.

Engineers must:

  • Prefer straightforward implementations
  • Avoid unnecessary abstraction or complexity
  • Avoid premature optimization
  • Build for current requirements, not hypothetical future needs

Rule: If a solution is hard to explain, it is too complex.

Keep it explainable

If you can’t explain the approach clearly in a few sentences, simplify it before you ship it.

3. Consistency Across the Organization

Consistency improves:

  • Onboarding speed
  • Collaboration
  • Debugging
  • Code reuse
  • System reliability

Engineers must follow:

  • Established architectural patterns
  • Project structure conventions
  • Naming standards
  • Deployment workflows
  • Tooling decisions
Propose improvements

Propose better patterns and tooling via PRs and team discussion—don’t silently diverge from standards.

4. Respect Frameworks, Platforms, and Architecture

Frameworks exist to enforce proven patterns.

Engineers must:

  • Follow framework architecture and lifecycle
  • Use built-in mechanisms before custom solutions
  • Respect separation of concerns and layering
  • Follow recommended project structure

Principle: Extend frameworks thoughtfully — do not fight them.

5. Ownership and Responsibility

Every system must have clear ownership.

Teams and engineers are responsible for:

  • Services they build
  • Production behavior
  • Monitoring and alerts
  • Operational stability

Rule: If you deploy it, you own it — including incidents, reliability improvements, and technical debt reduction.

6. Documentation as a Deliverable

Features are incomplete without documentation.

Each service must include:

  • Setup instructions
  • Configuration details
  • API usage documentation
  • Architecture notes when relevant

Goal: New engineers can run, understand, and contribute to the system from documentation alone.

Write docs while building

If it’s hard to document, it’s usually a sign the workflow or API needs simplifying.

7. Security is Everyone’s Responsibility

Engineers must:

  • Validate all external inputs
  • Protect sensitive data
  • Avoid leaking internal details in errors
  • Apply least-privilege access
  • Never store secrets in code

Principle: Security failures are system failures.

Non-negotiable

Never commit secrets (keys, tokens, passwords) to the repository. Use environment variables or a secure vault.

8. Testing and Reliability Culture

Engineers are expected to verify software works, not assume it does.

  • Unit tests for business logic
  • Integration tests for boundaries
  • End-to-end tests for critical flows
  • Regression tests for fixed bugs

Principle: Testing improves confidence, speed, and system stability.

Tests are design feedback

If a component is difficult to test, it may have too many responsibilities or unclear boundaries.

9. Collaboration and Communication

Strong engineering teams communicate clearly.

Engineers must:

  • Make work visible via tickets
  • Explain why, not just what
  • Open focused, reviewable pull requests
  • Share knowledge openly
  • Ask for help early

Goal: Optimize team productivity, not individual heroics.

PR quality bar

Prefer small PRs with clear scope and context. Make reviews easy to perform and easy to trust.

10. Continuous Improvement

Engineering practices are living processes.

Engineers are expected to:

  • Refactor when necessary
  • Propose better tools and workflows
  • Automate repetitive tasks
  • Share lessons from failures

Principle: Mistakes are acceptable; ignoring them is not.

11. Continuous Learning and Technical Awareness

Engineers must stay current in their areas of specialization:

  • Framework and language updates (e.g., Flutter, TypeScript, Laravel)
  • Security advisories and performance improvements
  • Industry trends (AI, new architectures, coding tools)
  • Emerging patterns and best practices

Goal: Avoid outdated patterns and maintain competitive engineering practices.

12. Awareness of Emerging Technologies and AI-Assisted Development

Engineers are encouraged to:

  • Learn about AI coding assistants and development automation tools
  • Evaluate new productivity-enhancing technologies
  • Explore modern paradigms like AI-supported testing, documentation, and architecture

Principle: AI is a productivity multiplier, not a replacement for engineering judgment.

13. Responsible Use of AI

Engineers remain in control of architecture and design; AI may assist but never dictate.

AI can:

  • Suggest implementations
  • Generate boilerplate code
  • Help debug and document

Engineers must:

  • Review all AI-generated code
  • Ensure adherence to architecture, security, and business logic
  • Validate correctness and maintainability

Rule: Engineers guide the AI, never the reverse.

Treat AI output like untrusted input

Verify correctness, security, and licensing compatibility. If you can’t explain it, don’t ship it.

14. Local Testing and Pre-Commit Discipline

Before pushing code:

  • Run unit, integration, and critical tests locally
  • Ensure tests pass reliably
  • Avoid excessive tests that slow local development

Goal: Shared repositories contain working, reliable code.

Protect production

Don’t “ship and hope.” If local runs are flaky, fix the flakiness before merging.

15. Code Formatting and Style Consistency

Engineers must:

  • Use framework/language-specific style conventions
  • Run automated formatters (Prettier, ESLint, PHP-CS-Fixer, etc.) before commits
  • Follow CI/CD enforcement rules

Benefit: Every developer reads and works with code in a consistent style.

16. Secure Handling of Secrets and Environment Variables

  • Never hardcode credentials, passwords, API keys, or environment-specific data
  • Store environment variables (URLs, ports, DB usernames) in .env files or secure vaults

Principle: Code is portable, secure, and framework-agnostic.

17. Docker Awareness and Responsibility

Every engineer must have basic Docker knowledge and follow secure, reproducible build practices.

Responsibilities:

  • Maintain the Dockerfile for their project
  • Use multi-stage builds for optimized images
  • Ensure reproducible local environments
  • Run services locally in containers for testing

Security Best Practices:

  • Do not hardcode sensitive information such as ports, API keys, database credentials, or environment-specific secrets
  • Pass all sensitive data as build arguments (ARG) or environment variables (ENV)
  • Ensure production secrets never appear in Docker images stored in repositories

Goal: Reduce security risks, maintain portability, and prevent accidental exposure of sensitive information.

18. Git and Branching Rules

Engineers must follow safe Git workflows to protect production and maintain a stable codebase.

Branching Discipline:

  • Never push directly to the main branch (production)
  • Commit and push work to feature branches or the dev branch
  • Create PRs/MRs from feature branches to dev
  • CI/CD must pass before merging into dev
  • Only tested, reviewed code from dev can be merged into main

Commit and Merge Practices:

  • Keep commits small and focused
  • Include meaningful commit messages
  • Avoid force-pushing to shared branches unless approved
  • Resolve merge conflicts carefully

Goal: Maintain stable production, predictable integration, effective reviews, and safe deployments.

Main is protected

Direct pushes to main are not allowed. Use feature branches and reviewed PRs.

19. Security Awareness and Vulnerability Knowledge

Engineers are responsible for writing secure code and protecting systems from known threats.

Responsibilities:

  • Stay informed about top security vulnerabilities relevant to their frameworks and languages (e.g., Laravel, Flutter, TypeScript, Node.js)
  • Follow the OWASP Top 10 and apply relevant mitigations in web-facing systems
  • Review security advisories for dependencies and libraries regularly
  • Report and remediate security issues promptly

Principles:

  • Proactive security: anticipate threats rather than react
  • Framework awareness: understand built-in protections and common pitfalls
  • Defense in depth: combine input validation, authentication, authorization, and secure storage

Goal: Prevent vulnerabilities, ensure systems are secure by default, and cultivate security awareness across the engineering team.

20. Code Quality and Best Practices

Engineers must write clean, maintainable, and readable code.

Meaningful Names

Use descriptive names for variables, functions, and classes. Names should reflect intent, not implementation.

If a piece of code is hard to name clearly, it likely needs refactoring.

Functions Should Do One Thing

  • Each function should have one responsibility and one reason to change.
  • Functions that do multiple things should be split into smaller, focused functions.

Benefits: easier to test, debug, reuse, and maintain.

SOLID Principles

Engineers should follow SOLID to design scalable, maintainable systems:

  • S – Single Responsibility: one purpose per class/module/function
  • O – Open/Closed: extend behavior without modifying existing code
  • L – Liskov Substitution: replace components without breaking functionality
  • I – Interface Segregation: small, focused interfaces
  • D – Dependency Inversion: depend on abstractions, not concrete implementations

Keep It Simple (KISS)

  • Prefer the simplest solution that works
  • Avoid over-engineering, deep inheritance hierarchies, or unnecessary patterns
  • Complexity is allowed only if it solves a real, measurable problem

Avoid Duplication (DRY)

  • Do not repeat logic across the codebase
  • Extract reusable functions, shared utilities, or validation rules
  • Clarity is more important than forced reuse; premature abstraction is discouraged

Goal: All code should be readable, maintainable, and consistent, making it easier for the team to collaborate and for future engineers to understand the system.

Optimize for the next engineer

Write code as if the person maintaining it is you in six months—because it probably will be.

Conclusion

These guidelines are the shared baseline for how we build and operate software at Sadeem Informatique. Apply them consistently, keep solutions simple, document and test as you go, and treat security and reliability as non-negotiable. When something can be improved, propose the change openly—continuous improvement is part of the job.