Development Workflow Document
Development Workflow Document — Heimdall API
1. Purpose
This document defines how a use case moves from backlog to merged — the branch, the issue status transitions, the testing gate, and the pull request. It is the standard every contributor (human or agent) follows so that each use case (UC-01 … UC-29 in the Use Case Specification Document , plus later additions such as UC-30) is delivered the same way.
It complements the Testing Specification Document , which defines how the tests themselves are written; this document defines when they happen in the delivery flow.
One use case = one branch = one issue = one pull request.
2. Workflow at a glance
flowchart TD
A["Pick a use case<br/>(issue in Todo)"] --> B["Create branch from develop<br/>feature/uc-##-use-case-name"]
B --> C["Move issue → In Progress"]
C --> D["Implement the use case"]
D --> E["Move issue → Testing"]
E --> F["Write unit + functional tests"]
F --> G["Run tests"]
G --> H{All pass?}
H -->|No| I["Fix code / tests"]
I --> G
H -->|Yes| J["Open pull request into develop"]
J --> K["Human review"]
K --> L{Approved?}
L -->|Changes requested| I
L -->|Yes| M["Human merge to develop<br/>delete feature branch"]
M --> N["Move issue → Done and close it"]The diagram shows the default flow, where a human reviews and merges. In an authorized batch run the agent merges its own pull request instead — every other step, including the testing gate, is identical. See Step 7.1 .
3. Issue status lifecycle
Each use case is tracked by its GitHub issue on the project board. The Status field moves through
these columns, in order:
| Order | Status | Set when |
|---|---|---|
| 1 | Todo | The use case has not been started (default). |
| 2 | In Progress | A feature branch has been created and implementation has begun. |
| 3 | Testing | Implementation is finished; unit and functional tests are being written, run, and fixed until green. |
| 4 | Done | The pull request has been reviewed and merged to develop; the issue is then closed. |
An issue only ever moves forward during normal flow. If review requests changes, work continues on the same branch (still linked to the same issue) until tests pass again and the PR is re-reviewed.
4. Step-by-step
Step 1 — Branch from develop
Every use case is implemented on its own branch, created from an up-to-date develop — the
integration branch. main only ever receives releases (see §5
):
git switch develop
git pull
git switch -c feature/uc-01-create-scope
Branch naming pattern:
feature/uc-##-use-case-name
##— the zero-padded use case number (01,02, …29).use-case-name— the use case name in lower-case kebab-case.
A change that is not a use case — a defect, a dependency, documentation — goes on a
fix/<name> or feature/<name> branch in the same way. Those two prefixes are the only ones the
Branch Policy check accepts into develop (besides Dependabot’s), and it also refuses a branch
that was cut from main instead of develop.
| Use case | Branch |
|---|---|
| UC-01: Create Scope | feature/uc-01-create-scope |
| UC-11: Login (Authenticate) | feature/uc-11-login |
| UC-25: Sign Up / Sign In via Google | feature/uc-25-sign-up-sign-in-via-google |
Step 2 — Move the issue to In Progress
As soon as the branch exists and work starts, set the use case’s issue Status to In Progress
on the project board.
Step 3 — Implement the use case
Implement the use case per its specification (main flow and alternative flows) and the project’s architecture and technology stack. All commits for the use case go on its feature branch.
Step 4 — Move the issue to Testing
When the implementation is finished, set the issue Status to Testing. This signals that the
feature is code-complete and the testing gate is now in progress.
Step 4.1 — If the change touches personal data
A migration that adds a column holding personal data is not finished when it compiles. Before the testing gate:
- State the column’s purpose in §5.1 of the
Data Protection Document
.
PersonalDataPurposeTestsfails the build if a column is missing, so this is enforced rather than remembered. - Give it a retention period in the Data Retention Schedule , or say which existing row covers it. A column with no period is one kept forever, which NFR-19 forbids.
- Check whether it changes the record of processing — a new category of data, recipient, or transfer means the Data Protection Document needs more than a table row.
The order matters: a column that cannot be given a purpose in step 1 is a column not to add. That is what data protection by design (GDPR Art. 25, LGPD Art. 6 III) asks for, applied at the only moment it is cheap.
Step 4.2 — The periodic security review
GDPR Art. 32(1)(d) requires a process for regularly testing and evaluating the technical and organisational measures, not merely having them. That process is:
| When | What |
|---|---|
| Every quarter | Restore a backup into a scratch environment and run the erasure reconciliation against it (Operations & Infrastructure §0.1). A restore procedure that has never been run is a hypothesis |
| Every quarter | Confirm encryption at rest is still in force for the database volume and its backups, and that the database connection still requires TLS |
| Every six months | Re-read the Threat Model against the code. A threat closed by a control that has since been refactored away is worse than one still marked open |
| On any change to processing | Revisit the DPIA , the record of processing, and the retention schedule |
The cadence matters less than the fact that each item has one. An unscheduled review is one that happens after an incident.
Step 5 — Test until green
Following the Testing Specification Document :
- Write the unit tests for every Command/Query handler and any new Domain behavior (main flow +
each applicable
AF-xxalternative flow). - Write the functional tests for each endpoint (main flow + every
AF-xx, including the authorization flows), end-to-end against Testcontainers PostgreSQL. - Run the tests (
dotnet test, and/or filtered byCategory=Unit/Category=Functional). - Fix any failures — in the implementation or the tests.
- Re-run, and repeat steps 3–4 until every test passes.
A use case does not leave the Testing stage until the full suite is green.
Step 6 — Open a pull request
With all tests passing, push the branch and open a PR from feature/uc-##-… into develop. The PR
description should reference the use case and its issue (e.g. Closes #<issue-number>) so the issue
is linked to the PR.
Step 7 — Human review and merge
- The PR is reviewed by a human. Requested changes are addressed on the same branch (back to Step 5 whenever code changes, so the suite stays green).
- Once approved, a human merges the PR into
develop. - The feature branch is deleted after the merge.
Review and merge are human actions. An agent may prepare and push the PR, but must not self-approve or merge it. The single exception is an authorized batch run — see Step 7.1 .
Step 7.1 — Authorized batch runs
When several use cases are delivered in one unattended run, the human approval gates would stop the run at every use case, which defeats the point of batching them. For a batch run only, an agent may merge its own pull requests, subject to all of the following:
- The batch was authorized up front. A human agreed to the specific use cases, in order, and was told explicitly that the agent would merge, close the issues, and delete the branches. A general instruction to work autonomously is not this authorization.
- The invariant still holds. One use case = one branch = one issue = one pull request. Use cases are never batched into a shared branch or a shared pull request, so the run stays reviewable after the fact.
- The testing gate is unchanged. The full suite is run and read for every use case, per Step 5. A merge on an unread or failing suite is never permitted.
- No protection is bypassed. No
--adminmerge, no self-approval to satisfy a required review, no force-push, and no disabling or filtering of a test to make the suite green. - A failure stops the whole run. A red suite, a merge conflict, an ambiguous specification, or a requirement that does not exist ends the batch. Already-merged use cases stay merged; the failing branch and its pull request are left in place as evidence.
Outside an authorized batch run, Step 7 applies as written: a human reviews and a human merges.
Step 8 — Close the issue
After the merge, set the issue Status to Done and close it. If the PR used a
Closes #<issue-number> reference, the merge closes the issue automatically — still confirm the
board shows it in Done.
5. From develop to a release
A merged use case is on develop, not yet in production: Jenkins deploys every push to develop to
the development environment, which runs on demand — a stopped one stays stopped until
scripts/ygg.sh env start development on the VPS turns it on (the four environments are listed in
§0.2 of the Operations & Infrastructure Document
).
Releases are cut from develop as release/<major>.<minor>.<patch> branches and reach main only
through a pull request that Jenkins merges itself, after deploying the release to homologation (on
demand, like development) and then to production; it also tags the merge
v<major>.<minor>.<patch>. Nobody merges into main by hand, and a release branch carries no
commits of its own — a fix for a release lands on develop through a fix/ branch, and a new
release is cut. The full procedure, including finalizing the changelog before the release branch is cut, is
in CONTRIBUTING.md
.
6. Definition of Done
A use case is done only when all of the following hold:
- Implemented on a
feature/uc-##-use-case-namebranch created fromdevelop. - Main flow and every alternative flow from the use case specification are implemented.
- Unit tests cover each handler and new Domain behavior (main + applicable
AF-xx). - Functional tests cover each endpoint (main + every
AF-xx, including authorization). - The full test suite passes (
Category=UnitandCategory=Functional). - A pull request was merged to
develop— reviewed by a human, or merged by an agent under an authorized batch run (Step 7.1). - The feature branch was deleted.
- The issue is in Done and closed.
7. References
- Use Case Specification Document — the use cases and their flows.
- Testing Specification Document — how the tests are written.
- System Requirements Document — functional/non-functional requirements.
- Technology Stack Document — technologies and versions used.