Simpro Knowledge Base

Daily Engineering Hygiene Standard

Daily Engineering Hygiene Standard visual map

Purpose

This page defines the everyday engineering hygiene Simpro teams should follow across projects: common coding style, formatting, linting, static analysis, SAST, DAST, dependency checks, and minimum meaningful tests.

This is not glamorous work, but it is the work that keeps engineering from becoming expensive archaeology.

The Core Idea

Good teams do not rely on memory for basics. They automate the basics.

Coding standards, linting, code analysis, security scanning, and tests should be part of the normal development loop. They should not depend on one senior person repeatedly saying, "Please fix formatting," until their soul leaves the building.

Simpro Baseline

Every important repository should have:

  • A documented setup command.
  • A documented build command.
  • A documented test command.
  • Automatic formatting or clear formatting rules.
  • Linting.
  • Static code analysis.
  • Dependency scanning.
  • Secrets scanning.
  • SAST for code security.
  • DAST or API security testing for exposed web/API systems.
  • Minimum meaningful tests.
  • CI checks that run on pull requests.
  • A clear rule for whether warnings fail the build.

Common Coding Style

Coding style should make code easier to read, review, and maintain.

General rules:

  • Prefer clarity over cleverness.
  • Use meaningful names.
  • Keep functions and methods focused.
  • Keep files organized by responsibility.
  • Avoid duplicated business logic.
  • Avoid hidden side effects.
  • Handle errors deliberately.
  • Keep comments useful, not decorative.
  • Do not commit dead code.
  • Do not hide security, performance, or reliability risks behind "temporary" changes.

Style should be enforced by tools wherever possible:

  • .editorconfig for shared formatting rules.
  • Language formatters such as dotnet format, Prettier, Black, Ruff, or gofmt.
  • IDE settings committed where useful.

Linting

Linting catches common mistakes, style drift, risky patterns, and maintainability issues.

Examples:

Stack Typical Tools
C#/.NET Roslyn analyzers, StyleCop Analyzers, SonarAnalyzer, dotnet format
TypeScript/JavaScript ESLint, TypeScript compiler, Prettier
React ESLint React rules, React Hooks rules, accessibility plugins
Angular Angular ESLint, TypeScript compiler
Python Ruff, Black, mypy/pyright, pylint where useful
Docker/IaC Hadolint, Checkov, tfsec, kube-linter

Team rule:

If linting finds a real issue, fix it. If linting is noisy or wrong, tune the rule. Do not train the team to ignore red signals.

Static Code Analysis

Static code analysis goes beyond style. It finds maintainability, reliability, security, and complexity issues.

Common issue types:

  • Null/reference risks.
  • Unused code.
  • Too much complexity.
  • Duplicate logic.
  • Resource leaks.
  • Blocking async calls.
  • Unsafe parsing.
  • Weak error handling.
  • Security-sensitive code patterns.

Recommended behavior:

  • Fix new issues in code you touch.
  • Prioritize high-severity issues first.
  • Do not block urgent delivery on every historical issue.
  • Create a cleanup backlog for legacy hotspots.
  • Use a quality gate for new code.

The practical standard is: leave the codebase cleaner than you found it, without turning every PR into a heroic renovation project.

Security Scanning

Security checks should run close to the developer and inside CI.

Secrets Scanning

Purpose: catch committed secrets, tokens, passwords, private keys, and connection strings.

Use:

  • GitHub secret scanning.
  • Gitleaks.
  • TruffleHog.
  • Pre-commit hooks where practical.

Rule:

If a secret is committed, assume it is compromised. Remove it, rotate it, and check exposure. Deleting the line is not enough.

Dependency Scanning

Purpose: identify vulnerable third-party packages and risky licenses.

Use:

  • Dependabot.
  • OWASP Dependency-Check.
  • Snyk/Mend/GitHub Advanced Security where available.
  • npm audit/pip-audit/dotnet list package --vulnerable where useful.

Rule:

Treat dependency updates as normal maintenance, not festival work that happens once a year with fear and snacks.

SAST

SAST means Static Application Security Testing. It scans source code for security issues.

Use:

  • CodeQL.
  • Semgrep.
  • SonarQube/SonarCloud.
  • Commercial tools where required by customer/security posture.

SAST can find:

  • Injection risks.
  • Unsafe deserialization.
  • Path traversal.
  • SSRF patterns.
  • Weak crypto usage.
  • Hardcoded secrets.
  • Missing validation.
  • Insecure APIs.

Rule:

High-confidence/high-severity SAST findings should be fixed before release unless there is an explicit, documented risk acceptance.

DAST

DAST means Dynamic Application Security Testing. It tests a running application from the outside.

Use:

  • OWASP ZAP.
  • Burp Suite.
  • StackHawk.
  • API security tests.

DAST can find:

  • Missing security headers.
  • Authentication/session weaknesses.
  • Exposed endpoints.
  • Input handling issues.
  • Some injection vulnerabilities.
  • Runtime configuration problems.

Rule:

Use DAST/API scans for exposed web applications and APIs in test/staging environments. Do not aim noisy scans at production without approval.

Minimum Meaningful Tests

The goal is not maximum test count. The goal is confidence in the right places.

Every meaningful change should ask:

  • What can break?
  • What would be expensive to discover in production?
  • What behavior must stay true?
  • What boundary needs protection?
  • What risk deserves automation?

Test Pyramid For Simpro

Level Purpose
Unit tests Fast checks for business rules, transformations, edge cases
Component/module tests Verify a feature or module in realistic isolation
Integration tests Verify database/API/queue/file/external boundaries
Contract tests Verify service-to-service or frontend-backend expectations
End-to-end tests Verify critical user journeys
Exploratory testing Find risks automation did not imagine

Minimum expectation:

  • Unit tests for important business rules.
  • Integration tests for important boundaries.
  • At least one end-to-end or journey test for critical workflows.
  • Regression test when fixing a meaningful defect.
  • Authorization tests for sensitive APIs.
  • Performance/load checks for high-risk flows where needed.

What To Test First

Prioritize tests for:

  • Money, billing, entitlement, or permission logic.
  • Customer data access.
  • Tenant/customer boundaries.
  • State transitions.
  • Complex calculations.
  • Error handling and retries.
  • Integrations.
  • Critical workflows.
  • Past defect areas.
  • High-change/high-risk modules.

Avoid spending too much energy testing:

  • Trivial getters/setters.
  • Framework behavior.
  • Implementation details that change often.
  • Snapshots that fail without explaining risk.

Pull Request Hygiene Checklist

Before asking for review:

  • Code is formatted.
  • Lint passes or exceptions are explained.
  • Build passes locally or in CI.
  • Relevant tests pass.
  • New behavior has meaningful tests.
  • Security-sensitive changes were reviewed carefully.
  • No secrets, local paths, or debug hacks are committed.
  • Logs do not expose sensitive data.
  • Errors are handled deliberately.
  • Public/API contract changes are documented.
  • Performance impact is considered for hot paths.
  • Code analysis findings introduced by the PR are fixed or justified.

CI Quality Gate

A good CI gate should be firm but not theatrical.

Recommended PR checks:

  • Restore/install dependencies.
  • Format check.
  • Lint.
  • Build/compile.
  • Unit tests.
  • Integration tests where practical.
  • SAST/code scanning.
  • Dependency scan.
  • Secrets scan.
  • Container/IaC scan where relevant.

Recommended release checks:

  • Full test suite.
  • DAST/API scan for exposed systems.
  • Container scan.
  • Migration check.
  • Smoke test.
  • Rollback readiness.
  • Observability check.

Handling Legacy Code

Do not demand perfection from old code overnight. That creates paralysis.

Use a legacy improvement rule:

  • Do not make it worse.
  • Fix new issues in changed code.
  • Add tests before risky changes.
  • Identify hotspots.
  • Improve one boundary at a time.
  • Refactor when it reduces real risk or enables delivery.

This is how teams improve without pretending the past never happened.

Team Working Agreement

Simpro teams should agree:

  • Formatting is automated.
  • Linting is respected.
  • Code analysis findings are triaged, not ignored.
  • SAST/DAST findings have owners.
  • Tests protect important behavior, not vanity coverage.
  • CI failure is a team signal.
  • Quality gates are improved when they are noisy.
  • Standards are updated when reality teaches us something better.

Team Reference Guide

Guidelines For Teams

  • Automate basics so reviewers focus on design, behavior, risk, and value.
  • Keep quality gates fast enough that developers respect them.
  • Fix the rule if the rule is bad; fix the code if the code is bad.
  • Write fewer but stronger tests before chasing coverage numbers.
  • Treat security and code analysis findings as engineering work, not audit noise.

Reflection Questions

  • Which hygiene issue do we still rely on manual review to catch?
  • Which lint or analysis signal is noisy enough that people ignore it?
  • What minimum test would have caught our last meaningful defect?
  • Which repo needs a clearer build/test/security command?
  • What should become part of the golden path template?

Further Study

  • Microsoft Engineering Fundamentals Playbook: https://microsoft.github.io/code-with-engineering-playbook/
  • Google Engineering Practices, Code Review: https://google.github.io/eng-practices/review/
  • OWASP Secure Coding Practices: https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/
  • OWASP Web Security Testing Guide: https://owasp.org/www-project-web-security-testing-guide/
  • CodeQL documentation: https://codeql.github.com/docs/
  • Semgrep documentation: https://semgrep.dev/docs/
  • OWASP ZAP: https://www.zaproxy.org/
  • SonarQube documentation: https://docs.sonarsource.com/sonarqube-server/
  • ESLint documentation: https://eslint.org/docs/latest/
  • Prettier documentation: https://prettier.io/docs/
  • Ruff documentation: https://docs.astral.sh/ruff/
  • pytest documentation: https://docs.pytest.org/en/stable/
  • .NET testing documentation: https://learn.microsoft.com/en-us/dotnet/core/testing/